children
+ // reconciliation
+ postUpdateWrapper(domElement, nextRawProps);
+ break;
+ }
+ }
+ function getPossibleStandardName(propName) {
+ var lowerCasedName = propName.toLowerCase();
+ if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) return null;
+ return possibleStandardNames[lowerCasedName] || null;
+ }
+ function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement, isConcurrentMode, shouldWarnDev) {
+ var isCustomComponentTag;
+ var extraAttributeNames;
+ isCustomComponentTag = isCustomComponent(tag, rawProps);
+ validatePropertiesInDevelopment(tag, rawProps);
+ switch(tag){
+ case "dialog":
+ listenToNonDelegatedEvent("cancel", domElement);
+ listenToNonDelegatedEvent("close", domElement);
+ break;
+ case "iframe":
+ case "object":
+ case "embed":
+ // We listen to this event in case to ensure emulated bubble
+ // listeners still fire for the load event.
+ listenToNonDelegatedEvent("load", domElement);
+ break;
+ case "video":
+ case "audio":
+ // We listen to these events in case to ensure emulated bubble
+ // listeners still fire for all the media events.
+ for(var i = 0; i < mediaEventTypes.length; i++)listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
+ break;
+ case "source":
+ // We listen to this event in case to ensure emulated bubble
+ // listeners still fire for the error event.
+ listenToNonDelegatedEvent("error", domElement);
+ break;
+ case "img":
+ case "image":
+ case "link":
+ // We listen to these events in case to ensure emulated bubble
+ // listeners still fire for error and load events.
+ listenToNonDelegatedEvent("error", domElement);
+ listenToNonDelegatedEvent("load", domElement);
+ break;
+ case "details":
+ // We listen to this event in case to ensure emulated bubble
+ // listeners still fire for the toggle event.
+ listenToNonDelegatedEvent("toggle", domElement);
+ break;
+ case "input":
+ initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
+ // listeners still fire for the invalid event.
+ listenToNonDelegatedEvent("invalid", domElement);
+ break;
+ case "option":
+ validateProps(domElement, rawProps);
+ break;
+ case "select":
+ initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
+ // listeners still fire for the invalid event.
+ listenToNonDelegatedEvent("invalid", domElement);
+ break;
+ case "textarea":
+ initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
+ // listeners still fire for the invalid event.
+ listenToNonDelegatedEvent("invalid", domElement);
+ break;
+ }
+ assertValidProps(tag, rawProps);
+ extraAttributeNames = new Set();
+ var attributes = domElement.attributes;
+ for(var _i = 0; _i < attributes.length; _i++){
+ var name = attributes[_i].name.toLowerCase();
+ switch(name){
+ // Controlled attributes are not validated
+ // TODO: Only ignore them on controlled tags.
+ case "value":
+ break;
+ case "checked":
+ break;
+ case "selected":
+ break;
+ default:
+ // Intentionally use the original name.
+ // See discussion in https://github.com/facebook/react/pull/10676.
+ extraAttributeNames.add(attributes[_i].name);
+ }
+ }
+ var updatePayload = null;
+ for(var propKey in rawProps){
+ if (!rawProps.hasOwnProperty(propKey)) continue;
+ var nextProp = rawProps[propKey];
+ if (propKey === CHILDREN) {
+ // For text content children we compare against textContent. This
+ // might match additional HTML that is hidden when we read it using
+ // textContent. E.g. "foo" will match "foo " but that still
+ // satisfies our requirement. Our requirement is not to produce perfect
+ // HTML and attributes. Ideally we should preserve structure but it's
+ // ok not to if the visible content is still enough to indicate what
+ // even listeners these nodes might be wired up to.
+ // TODO: Warn if there is more than a single textNode as a child.
+ // TODO: Should we use domElement.firstChild.nodeValue to compare?
+ if (typeof nextProp === "string") {
+ if (domElement.textContent !== nextProp) {
+ if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
+ updatePayload = [
+ CHILDREN,
+ nextProp
+ ];
+ }
+ } else if (typeof nextProp === "number") {
+ if (domElement.textContent !== "" + nextProp) {
+ if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
+ updatePayload = [
+ CHILDREN,
+ "" + nextProp
+ ];
+ }
+ }
+ } else if (registrationNameDependencies.hasOwnProperty(propKey)) {
+ if (nextProp != null) {
+ if (typeof nextProp !== "function") warnForInvalidEventListener(propKey, nextProp);
+ if (propKey === "onScroll") listenToNonDelegatedEvent("scroll", domElement);
+ }
+ } else if (shouldWarnDev && true && // Convince Flow we've calculated it (it's DEV-only in this method.)
+ typeof isCustomComponentTag === "boolean") {
+ // Validate that the properties correspond to their expected values.
+ var serverValue = void 0;
+ var propertyInfo = isCustomComponentTag && enableCustomElementPropertySupport ? null : getPropertyInfo(propKey);
+ if (rawProps[SUPPRESS_HYDRATION_WARNING] === true) ;
+ else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
+ // TODO: Only ignore them on controlled tags.
+ propKey === "value" || propKey === "checked" || propKey === "selected") ;
+ else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
+ var serverHTML = domElement.innerHTML;
+ var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
+ if (nextHtml != null) {
+ var expectedHTML = normalizeHTML(domElement, nextHtml);
+ if (expectedHTML !== serverHTML) warnForPropDifference(propKey, serverHTML, expectedHTML);
+ }
+ } else if (propKey === STYLE) {
+ // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.delete(propKey);
+ if (canDiffStyleForHydrationWarning) {
+ var expectedStyle = createDangerousStringForStyles(nextProp);
+ serverValue = domElement.getAttribute("style");
+ if (expectedStyle !== serverValue) warnForPropDifference(propKey, serverValue, expectedStyle);
+ }
+ } else if (isCustomComponentTag && !enableCustomElementPropertySupport) {
+ // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.delete(propKey.toLowerCase());
+ serverValue = getValueForAttribute(domElement, propKey, nextProp);
+ if (nextProp !== serverValue) warnForPropDifference(propKey, serverValue, nextProp);
+ } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
+ var isMismatchDueToBadCasing = false;
+ if (propertyInfo !== null) {
+ // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.delete(propertyInfo.attributeName);
+ serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
+ } else {
+ var ownNamespace = parentNamespace;
+ if (ownNamespace === HTML_NAMESPACE) ownNamespace = getIntrinsicNamespace(tag);
+ if (ownNamespace === HTML_NAMESPACE) // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.delete(propKey.toLowerCase());
+ else {
+ var standardName = getPossibleStandardName(propKey);
+ if (standardName !== null && standardName !== propKey) {
+ // If an SVG prop is supplied with bad casing, it will
+ // be successfully parsed from HTML, but will produce a mismatch
+ // (and would be incorrectly rendered on the client).
+ // However, we already warn about bad casing elsewhere.
+ // So we'll skip the misleading extra mismatch warning in this case.
+ isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.delete(standardName);
+ } // $FlowFixMe - Should be inferred as not undefined.
+ extraAttributeNames.delete(propKey);
+ }
+ serverValue = getValueForAttribute(domElement, propKey, nextProp);
+ }
+ var dontWarnCustomElement = enableCustomElementPropertySupport;
+ if (!dontWarnCustomElement && nextProp !== serverValue && !isMismatchDueToBadCasing) warnForPropDifference(propKey, serverValue, nextProp);
+ }
+ }
+ }
+ if (shouldWarnDev) {
+ if (extraAttributeNames.size > 0 && rawProps[SUPPRESS_HYDRATION_WARNING] !== true) // $FlowFixMe - Should be inferred as not undefined.
+ warnForExtraAttributes(extraAttributeNames);
+ }
+ switch(tag){
+ case "input":
+ // TODO: Make sure we check if this is still unmounted or do any clean
+ // up necessary since we never stop tracking anymore.
+ track(domElement);
+ postMountWrapper(domElement, rawProps, true);
+ break;
+ case "textarea":
+ // TODO: Make sure we check if this is still unmounted or do any clean
+ // up necessary since we never stop tracking anymore.
+ track(domElement);
+ postMountWrapper$3(domElement);
+ break;
+ case "select":
+ case "option":
+ break;
+ default:
+ if (typeof rawProps.onClick === "function") // TODO: This cast may not be sound for SVG, MathML or custom elements.
+ trapClickOnNonInteractiveElement(domElement);
+ break;
+ }
+ return updatePayload;
+ }
+ function diffHydratedText(textNode, text, isConcurrentMode) {
+ var isDifferent = textNode.nodeValue !== text;
+ return isDifferent;
+ }
+ function warnForDeletedHydratableElement(parentNode, child) {
+ if (didWarnInvalidHydration) return;
+ didWarnInvalidHydration = true;
+ error("Did not expect server HTML to contain a <%s> in <%s>.", child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
+ }
+ function warnForDeletedHydratableText(parentNode, child) {
+ if (didWarnInvalidHydration) return;
+ didWarnInvalidHydration = true;
+ error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
+ }
+ function warnForInsertedHydratedElement(parentNode, tag, props) {
+ if (didWarnInvalidHydration) return;
+ didWarnInvalidHydration = true;
+ error("Expected server HTML to contain a matching <%s> in <%s>.", tag, parentNode.nodeName.toLowerCase());
+ }
+ function warnForInsertedHydratedText(parentNode, text) {
+ if (text === "") // We expect to insert empty text nodes since they're not represented in
+ // the HTML.
+ // TODO: Remove this special case if we can just avoid inserting empty
+ // text nodes.
+ return;
+ if (didWarnInvalidHydration) return;
+ didWarnInvalidHydration = true;
+ error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
+ }
+ function restoreControlledState$3(domElement, tag, props) {
+ switch(tag){
+ case "input":
+ restoreControlledState(domElement, props);
+ return;
+ case "textarea":
+ restoreControlledState$2(domElement, props);
+ return;
+ case "select":
+ restoreControlledState$1(domElement, props);
+ return;
+ }
+ }
+ var validateDOMNesting = function() {};
+ var updatedAncestorInfo = function() {};
+ // 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,
is invalid but we don't warn
+ // because it still parses correctly; we do warn for other cases like nested
+ // 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",
+ // TODO: Distinguish by namespace here -- for
, 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 = {
+ current: null,
+ formTag: null,
+ aTagInScope: null,
+ buttonTagInScope: null,
+ nobrTagInScope: null,
+ pTagInButtonScope: null,
+ listItemTagAutoclosing: null,
+ dlItemTagAutoclosing: null
+ };
+ updatedAncestorInfo = function(oldInfo, tag) {
+ var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
+ var info = {
+ tag: tag
+ };
+ 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.current = 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 doesn't mean we're in a
+ // 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" || tag === "frameset";
+ case "frameset":
+ return tag === "frame";
+ case "#document":
+ return tag === "html";
+ } // 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 "body":
+ case "caption":
+ case "col":
+ case "colgroup":
+ case "frameset":
+ case "frame":
+ case "head":
+ case "html":
+ 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;
+ };
+ var didWarn$1 = {};
+ validateDOMNesting = function(childTag, childText, ancestorInfo) {
+ ancestorInfo = ancestorInfo || emptyAncestorInfo;
+ var parentInfo = ancestorInfo.current;
+ var parentTag = parentInfo && parentInfo.tag;
+ if (childText != null) {
+ if (childTag != null) error("validateDOMNesting: when childText is passed, childTag should be null");
+ childTag = "#text";
+ }
+ var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
+ var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
+ var invalidParentOrAncestor = invalidParent || invalidAncestor;
+ if (!invalidParentOrAncestor) return;
+ var ancestorTag = invalidParentOrAncestor.tag;
+ var warnKey = !!invalidParent + "|" + childTag + "|" + ancestorTag;
+ if (didWarn$1[warnKey]) return;
+ didWarn$1[warnKey] = true;
+ var tagDisplayName = childTag;
+ var whitespaceInfo = "";
+ if (childTag === "#text") {
+ if (/\S/.test(childText)) tagDisplayName = "Text nodes";
+ else {
+ tagDisplayName = "Whitespace text nodes";
+ whitespaceInfo = " Make sure you don't have any extra whitespace between tags on each line of your source code.";
+ }
+ } else tagDisplayName = "<" + childTag + ">";
+ if (invalidParent) {
+ var info = "";
+ if (ancestorTag === "table" && childTag === "tr") info += " Add a , or to your code to match the DOM tree generated by the browser.";
+ error("validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s", tagDisplayName, ancestorTag, whitespaceInfo, info);
+ } else error("validateDOMNesting(...): %s cannot appear as a descendant of <%s>.", tagDisplayName, ancestorTag);
+ };
+ var SUPPRESS_HYDRATION_WARNING$1 = "suppressHydrationWarning";
+ var SUSPENSE_START_DATA = "$";
+ var SUSPENSE_END_DATA = "/$";
+ var SUSPENSE_PENDING_START_DATA = "$?";
+ var SUSPENSE_FALLBACK_START_DATA = "$!";
+ var STYLE$1 = "style";
+ var eventsEnabled = null;
+ var selectionInformation = null;
+ function getRootHostContext(rootContainerInstance) {
+ var type;
+ var namespace;
+ var nodeType = rootContainerInstance.nodeType;
+ switch(nodeType){
+ case DOCUMENT_NODE:
+ case DOCUMENT_FRAGMENT_NODE:
+ type = nodeType === DOCUMENT_NODE ? "#document" : "#fragment";
+ var root = rootContainerInstance.documentElement;
+ namespace = root ? root.namespaceURI : getChildNamespace(null, "");
+ break;
+ default:
+ var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
+ var ownNamespace = container.namespaceURI || null;
+ type = container.tagName;
+ namespace = getChildNamespace(ownNamespace, type);
+ break;
+ }
+ var validatedTag = type.toLowerCase();
+ var ancestorInfo = updatedAncestorInfo(null, validatedTag);
+ return {
+ namespace: namespace,
+ ancestorInfo: ancestorInfo
+ };
+ }
+ function getChildHostContext(parentHostContext, type, rootContainerInstance) {
+ var parentHostContextDev = parentHostContext;
+ var namespace = getChildNamespace(parentHostContextDev.namespace, type);
+ var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
+ return {
+ namespace: namespace,
+ ancestorInfo: ancestorInfo
+ };
+ }
+ function getPublicInstance(instance) {
+ return instance;
+ }
+ function prepareForCommit(containerInfo) {
+ eventsEnabled = isEnabled();
+ selectionInformation = getSelectionInformation();
+ var activeInstance = null;
+ setEnabled(false);
+ return activeInstance;
+ }
+ function resetAfterCommit(containerInfo) {
+ restoreSelection(selectionInformation);
+ setEnabled(eventsEnabled);
+ eventsEnabled = null;
+ selectionInformation = null;
+ }
+ function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
+ var parentNamespace;
+ // TODO: take namespace into account when validating.
+ var hostContextDev = hostContext;
+ validateDOMNesting(type, null, hostContextDev.ancestorInfo);
+ if (typeof props.children === "string" || typeof props.children === "number") {
+ var string = "" + props.children;
+ var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
+ validateDOMNesting(null, string, ownAncestorInfo);
+ }
+ parentNamespace = hostContextDev.namespace;
+ var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
+ precacheFiberNode(internalInstanceHandle, domElement);
+ updateFiberProps(domElement, props);
+ return domElement;
+ }
+ function appendInitialChild(parentInstance, child) {
+ parentInstance.appendChild(child);
+ }
+ function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
+ setInitialProperties(domElement, type, props, rootContainerInstance);
+ switch(type){
+ case "button":
+ case "input":
+ case "select":
+ case "textarea":
+ return !!props.autoFocus;
+ case "img":
+ return true;
+ default:
+ return false;
+ }
+ }
+ function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
+ var hostContextDev = hostContext;
+ if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === "string" || typeof newProps.children === "number")) {
+ var string = "" + newProps.children;
+ var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
+ validateDOMNesting(null, string, ownAncestorInfo);
+ }
+ return diffProperties(domElement, type, oldProps, newProps);
+ }
+ function shouldSetTextContent(type, props) {
+ return type === "textarea" || type === "noscript" || typeof props.children === "string" || typeof props.children === "number" || typeof props.dangerouslySetInnerHTML === "object" && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
+ }
+ function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
+ var hostContextDev = hostContext;
+ validateDOMNesting(null, text, hostContextDev.ancestorInfo);
+ var textNode = createTextNode(text, rootContainerInstance);
+ precacheFiberNode(internalInstanceHandle, textNode);
+ return textNode;
+ }
+ function getCurrentEventPriority() {
+ var currentEvent = window.event;
+ if (currentEvent === undefined) return DefaultEventPriority;
+ return getEventPriority(currentEvent.type);
+ }
+ // if a component just imports ReactDOM (e.g. for findDOMNode).
+ // Some environments might not have setTimeout or clearTimeout.
+ var scheduleTimeout = typeof setTimeout === "function" ? setTimeout : undefined;
+ var cancelTimeout = typeof clearTimeout === "function" ? clearTimeout : undefined;
+ var noTimeout = -1;
+ var localPromise = typeof Promise === "function" ? Promise : undefined; // -------------------
+ var scheduleMicrotask = typeof queueMicrotask === "function" ? queueMicrotask : typeof localPromise !== "undefined" ? function(callback) {
+ return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
+ } : scheduleTimeout; // TODO: Determine the best fallback here.
+ function handleErrorInNextTick(error) {
+ setTimeout(function() {
+ throw error;
+ });
+ } // -------------------
+ function commitMount(domElement, type, newProps, internalInstanceHandle) {
+ // Despite the naming that might imply otherwise, this method only
+ // fires if there is an `Update` effect scheduled during mounting.
+ // This happens if `finalizeInitialChildren` returns `true` (which it
+ // does to implement the `autoFocus` attribute on the client). But
+ // there are also other cases when this might happen (such as patching
+ // up text content during hydration mismatch). So we'll check this again.
+ switch(type){
+ case "button":
+ case "input":
+ case "select":
+ case "textarea":
+ if (newProps.autoFocus) domElement.focus();
+ return;
+ case "img":
+ if (newProps.src) domElement.src = newProps.src;
+ return;
+ }
+ }
+ function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
+ // Apply the diff to the DOM node.
+ updateProperties(domElement, updatePayload, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with
+ // with current event handlers.
+ updateFiberProps(domElement, newProps);
+ }
+ function resetTextContent(domElement) {
+ setTextContent(domElement, "");
+ }
+ function commitTextUpdate(textInstance, oldText, newText) {
+ textInstance.nodeValue = newText;
+ }
+ function appendChild(parentInstance, child) {
+ parentInstance.appendChild(child);
+ }
+ function appendChildToContainer(container, child) {
+ var parentNode;
+ if (container.nodeType === COMMENT_NODE) {
+ parentNode = container.parentNode;
+ parentNode.insertBefore(child, container);
+ } else {
+ parentNode = container;
+ parentNode.appendChild(child);
+ } // This container might be used for a portal.
+ // If something inside a portal is clicked, that click should bubble
+ // through the React tree. However, on Mobile Safari the click would
+ // never bubble through the *DOM* tree unless an ancestor with onclick
+ // event exists. So we wouldn't see it and dispatch it.
+ // This is why we ensure that non React root containers have inline onclick
+ // defined.
+ // https://github.com/facebook/react/issues/11918
+ var reactRootContainer = container._reactRootContainer;
+ if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) // TODO: This cast may not be sound for SVG, MathML or custom elements.
+ trapClickOnNonInteractiveElement(parentNode);
+ }
+ function insertBefore(parentInstance, child, beforeChild) {
+ parentInstance.insertBefore(child, beforeChild);
+ }
+ function insertInContainerBefore(container, child, beforeChild) {
+ if (container.nodeType === COMMENT_NODE) container.parentNode.insertBefore(child, beforeChild);
+ else container.insertBefore(child, beforeChild);
+ }
+ function removeChild(parentInstance, child) {
+ parentInstance.removeChild(child);
+ }
+ function removeChildFromContainer(container, child) {
+ if (container.nodeType === COMMENT_NODE) container.parentNode.removeChild(child);
+ else container.removeChild(child);
+ }
+ function clearSuspenseBoundary(parentInstance, suspenseInstance) {
+ var node = suspenseInstance; // Delete all nodes within this suspense boundary.
+ // There might be nested nodes so we need to keep track of how
+ // deep we are and only break out when we're back on top.
+ var depth = 0;
+ do {
+ var nextNode = node.nextSibling;
+ parentInstance.removeChild(node);
+ if (nextNode && nextNode.nodeType === COMMENT_NODE) {
+ var data = nextNode.data;
+ if (data === SUSPENSE_END_DATA) {
+ if (depth === 0) {
+ parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this.
+ retryIfBlockedOn(suspenseInstance);
+ return;
+ } else depth--;
+ } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) depth++;
+ }
+ node = nextNode;
+ }while (node); // TODO: Warn, we didn't find the end comment boundary.
+ // Retry if any event replaying was blocked on this.
+ retryIfBlockedOn(suspenseInstance);
+ }
+ function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
+ if (container.nodeType === COMMENT_NODE) clearSuspenseBoundary(container.parentNode, suspenseInstance);
+ else if (container.nodeType === ELEMENT_NODE) clearSuspenseBoundary(container, suspenseInstance);
+ // Retry if any event replaying was blocked on this.
+ retryIfBlockedOn(container);
+ }
+ function hideInstance(instance) {
+ instance;
+ var style = instance.style;
+ if (typeof style.setProperty === "function") style.setProperty("display", "none", "important");
+ else style.display = "none";
+ }
+ function hideTextInstance(textInstance) {
+ textInstance.nodeValue = "";
+ }
+ function unhideInstance(instance, props) {
+ instance;
+ var styleProp = props[STYLE$1];
+ var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty("display") ? styleProp.display : null;
+ instance.style.display = dangerousStyleValue("display", display);
+ }
+ function unhideTextInstance(textInstance, text) {
+ textInstance.nodeValue = text;
+ }
+ function clearContainer(container) {
+ if (container.nodeType === ELEMENT_NODE) container.textContent = "";
+ else if (container.nodeType === DOCUMENT_NODE) {
+ if (container.documentElement) container.removeChild(container.documentElement);
+ }
+ } // -------------------
+ function canHydrateInstance(instance, type, props) {
+ if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) return null;
+ // This has now been refined to an element node.
+ return instance;
+ }
+ function canHydrateTextInstance(instance, text) {
+ if (text === "" || instance.nodeType !== TEXT_NODE) // Empty strings are not parsed by HTML so there won't be a correct match here.
+ return null;
+ // This has now been refined to a text node.
+ return instance;
+ }
+ function canHydrateSuspenseInstance(instance) {
+ if (instance.nodeType !== COMMENT_NODE) // Empty strings are not parsed by HTML so there won't be a correct match here.
+ return null;
+ // This has now been refined to a suspense node.
+ return instance;
+ }
+ function isSuspenseInstancePending(instance) {
+ return instance.data === SUSPENSE_PENDING_START_DATA;
+ }
+ function isSuspenseInstanceFallback(instance) {
+ return instance.data === SUSPENSE_FALLBACK_START_DATA;
+ }
+ function getSuspenseInstanceFallbackErrorDetails(instance) {
+ var dataset = instance.nextSibling && instance.nextSibling.dataset;
+ var digest, message, stack;
+ if (dataset) {
+ digest = dataset.dgst;
+ message = dataset.msg;
+ stack = dataset.stck;
+ }
+ return {
+ message: message,
+ digest: digest,
+ stack: stack
+ };
+ // const nextSibling = instance.nextSibling;
+ // if (nextSibling) {
+ // const dataset = ((nextSibling: any): HTMLTemplateElement).dataset;
+ // value.message = dataset.msg;
+ // value.hash = dataset.hash;
+ // if (true) {
+ // value.stack = dataset.stack;
+ // }
+ // }
+ // return value;
+ }
+ function registerSuspenseInstanceRetry(instance, callback) {
+ instance._reactRetry = callback;
+ }
+ function getNextHydratable(node) {
+ // Skip non-hydratable nodes.
+ for(; node != null; node = node.nextSibling){
+ var nodeType = node.nodeType;
+ if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) break;
+ if (nodeType === COMMENT_NODE) {
+ var nodeData = node.data;
+ if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) break;
+ if (nodeData === SUSPENSE_END_DATA) return null;
+ }
+ }
+ return node;
+ }
+ function getNextHydratableSibling(instance) {
+ return getNextHydratable(instance.nextSibling);
+ }
+ function getFirstHydratableChild(parentInstance) {
+ return getNextHydratable(parentInstance.firstChild);
+ }
+ function getFirstHydratableChildWithinContainer(parentContainer) {
+ return getNextHydratable(parentContainer.firstChild);
+ }
+ function getFirstHydratableChildWithinSuspenseInstance(parentInstance) {
+ return getNextHydratable(parentInstance.nextSibling);
+ }
+ function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) {
+ precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
+ // get attached.
+ updateFiberProps(instance, props);
+ var parentNamespace;
+ var hostContextDev = hostContext;
+ parentNamespace = hostContextDev.namespace;
+ // when the legacy root API is removed.
+ var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
+ return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev);
+ }
+ function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) {
+ precacheFiberNode(internalInstanceHandle, textInstance); // TODO: Temporary hack to check if we're in a concurrent root. We can delete
+ // when the legacy root API is removed.
+ var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
+ return diffHydratedText(textInstance, text);
+ }
+ function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
+ precacheFiberNode(internalInstanceHandle, suspenseInstance);
+ }
+ function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
+ var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
+ // There might be nested nodes so we need to keep track of how
+ // deep we are and only break out when we're back on top.
+ var depth = 0;
+ while(node){
+ if (node.nodeType === COMMENT_NODE) {
+ var data = node.data;
+ if (data === SUSPENSE_END_DATA) {
+ if (depth === 0) return getNextHydratableSibling(node);
+ else depth--;
+ } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) depth++;
+ }
+ node = node.nextSibling;
+ } // TODO: Warn, we didn't find the end comment boundary.
+ return null;
+ } // Returns the SuspenseInstance if this node is a direct child of a
+ // SuspenseInstance. I.e. if its previous sibling is a Comment with
+ // SUSPENSE_x_START_DATA. Otherwise, null.
+ function getParentSuspenseInstance(targetInstance) {
+ var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
+ // There might be nested nodes so we need to keep track of how
+ // deep we are and only break out when we're back on top.
+ var depth = 0;
+ while(node){
+ if (node.nodeType === COMMENT_NODE) {
+ var data = node.data;
+ if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
+ if (depth === 0) return node;
+ else depth--;
+ } else if (data === SUSPENSE_END_DATA) depth++;
+ }
+ node = node.previousSibling;
+ }
+ return null;
+ }
+ function commitHydratedContainer(container) {
+ // Retry if any event replaying was blocked on this.
+ retryIfBlockedOn(container);
+ }
+ function commitHydratedSuspenseInstance(suspenseInstance) {
+ // Retry if any event replaying was blocked on this.
+ retryIfBlockedOn(suspenseInstance);
+ }
+ function shouldDeleteUnhydratedTailInstances(parentType) {
+ return parentType !== "head" && parentType !== "body";
+ }
+ function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) {
+ var shouldWarnDev = true;
+ checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
+ }
+ function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) {
+ if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
+ var shouldWarnDev = true;
+ checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
+ }
+ }
+ function didNotHydrateInstanceWithinContainer(parentContainer, instance) {
+ if (instance.nodeType === ELEMENT_NODE) warnForDeletedHydratableElement(parentContainer, instance);
+ else if (instance.nodeType === COMMENT_NODE) ;
+ else warnForDeletedHydratableText(parentContainer, instance);
+ }
+ function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) {
+ // $FlowFixMe: Only Element or Document can be parent nodes.
+ var parentNode = parentInstance.parentNode;
+ if (parentNode !== null) {
+ if (instance.nodeType === ELEMENT_NODE) warnForDeletedHydratableElement(parentNode, instance);
+ else if (instance.nodeType === COMMENT_NODE) ;
+ else warnForDeletedHydratableText(parentNode, instance);
+ }
+ }
+ function didNotHydrateInstance(parentType, parentProps, parentInstance, instance, isConcurrentMode) {
+ if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
+ if (instance.nodeType === ELEMENT_NODE) warnForDeletedHydratableElement(parentInstance, instance);
+ else if (instance.nodeType === COMMENT_NODE) ;
+ else warnForDeletedHydratableText(parentInstance, instance);
+ }
+ }
+ function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) {
+ warnForInsertedHydratedElement(parentContainer, type);
+ }
+ function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) {
+ warnForInsertedHydratedText(parentContainer, text);
+ }
+ function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) {
+ // $FlowFixMe: Only Element or Document can be parent nodes.
+ var parentNode = parentInstance.parentNode;
+ if (parentNode !== null) warnForInsertedHydratedElement(parentNode, type);
+ }
+ function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) {
+ // $FlowFixMe: Only Element or Document can be parent nodes.
+ var parentNode = parentInstance.parentNode;
+ if (parentNode !== null) warnForInsertedHydratedText(parentNode, text);
+ }
+ function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props, isConcurrentMode) {
+ if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) warnForInsertedHydratedElement(parentInstance, type);
+ }
+ function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text, isConcurrentMode) {
+ if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) warnForInsertedHydratedText(parentInstance, text);
+ }
+ function errorHydratingContainer(parentContainer) {
+ // TODO: This gets logged by onRecoverableError, too, so we should be
+ // able to remove it.
+ error("An error occurred during hydration. The server HTML was replaced with client content in <%s>.", parentContainer.nodeName.toLowerCase());
+ }
+ function preparePortalMount(portalInstance) {
+ listenToAllSupportedEvents(portalInstance);
+ }
+ var randomKey = Math.random().toString(36).slice(2);
+ var internalInstanceKey = "__reactFiber$" + randomKey;
+ var internalPropsKey = "__reactProps$" + randomKey;
+ var internalContainerInstanceKey = "__reactContainer$" + randomKey;
+ var internalEventHandlersKey = "__reactEvents$" + randomKey;
+ var internalEventHandlerListenersKey = "__reactListeners$" + randomKey;
+ var internalEventHandlesSetKey = "__reactHandles$" + randomKey;
+ function detachDeletedInstance(node) {
+ // TODO: This function is only called on host components. I don't think all of
+ // these fields are relevant.
+ delete node[internalInstanceKey];
+ delete node[internalPropsKey];
+ delete node[internalEventHandlersKey];
+ delete node[internalEventHandlerListenersKey];
+ delete node[internalEventHandlesSetKey];
+ }
+ function precacheFiberNode(hostInst, node) {
+ node[internalInstanceKey] = hostInst;
+ }
+ function markContainerAsRoot(hostRoot, node) {
+ node[internalContainerInstanceKey] = hostRoot;
+ }
+ function unmarkContainerAsRoot(node) {
+ node[internalContainerInstanceKey] = null;
+ }
+ function isContainerMarkedAsRoot(node) {
+ return !!node[internalContainerInstanceKey];
+ } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
+ // If the target node is part of a hydrated or not yet rendered subtree, then
+ // this may also return a SuspenseComponent or HostRoot to indicate that.
+ // Conceptually the HostRoot fiber is a child of the Container node. So if you
+ // pass the Container node as the targetNode, you will not actually get the
+ // HostRoot back. To get to the HostRoot, you need to pass a child of it.
+ // The same thing applies to Suspense boundaries.
+ function getClosestInstanceFromNode(targetNode) {
+ var targetInst = targetNode[internalInstanceKey];
+ if (targetInst) // Don't return HostRoot or SuspenseComponent here.
+ return targetInst;
+ // If the direct event target isn't a React owned DOM node, we need to look
+ // to see if one of its parents is a React owned DOM node.
+ var parentNode = targetNode.parentNode;
+ while(parentNode){
+ // We'll check if this is a container root that could include
+ // React nodes in the future. We need to check this first because
+ // if we're a child of a dehydrated container, we need to first
+ // find that inner container before moving on to finding the parent
+ // instance. Note that we don't check this field on the targetNode
+ // itself because the fibers are conceptually between the container
+ // node and the first child. It isn't surrounding the container node.
+ // If it's not a container, we check if it's an instance.
+ targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
+ if (targetInst) {
+ // Since this wasn't the direct target of the event, we might have
+ // stepped past dehydrated DOM nodes to get here. However they could
+ // also have been non-React nodes. We need to answer which one.
+ // If we the instance doesn't have any children, then there can't be
+ // a nested suspense boundary within it. So we can use this as a fast
+ // bailout. Most of the time, when people add non-React children to
+ // the tree, it is using a ref to a child-less DOM node.
+ // Normally we'd only need to check one of the fibers because if it
+ // has ever gone from having children to deleting them or vice versa
+ // it would have deleted the dehydrated boundary nested inside already.
+ // However, since the HostRoot starts out with an alternate it might
+ // have one on the alternate so we need to check in case this was a
+ // root.
+ var alternate = targetInst.alternate;
+ if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
+ // Next we need to figure out if the node that skipped past is
+ // nested within a dehydrated boundary and if so, which one.
+ var suspenseInstance = getParentSuspenseInstance(targetNode);
+ while(suspenseInstance !== null){
+ // We found a suspense instance. That means that we haven't
+ // hydrated it yet. Even though we leave the comments in the
+ // DOM after hydrating, and there are boundaries in the DOM
+ // that could already be hydrated, we wouldn't have found them
+ // through this pass since if the target is hydrated it would
+ // have had an internalInstanceKey on it.
+ // Let's get the fiber associated with the SuspenseComponent
+ // as the deepest instance.
+ var targetSuspenseInst = suspenseInstance[internalInstanceKey];
+ if (targetSuspenseInst) return targetSuspenseInst;
+ // If we don't find a Fiber on the comment, it might be because
+ // we haven't gotten to hydrate it yet. There might still be a
+ // parent boundary that hasn't above this one so we need to find
+ // the outer most that is known.
+ suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
+ // host component also hasn't hydrated yet. We can return it
+ // below since it will bail out on the isMounted check later.
+ }
+ }
+ return targetInst;
+ }
+ targetNode = parentNode;
+ parentNode = targetNode.parentNode;
+ }
+ return null;
+ }
+ /**
+ * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
+ * instance, or null if the node was not rendered by this React.
+ */ function getInstanceFromNode(node) {
+ var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
+ if (inst) {
+ if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) return inst;
+ else return null;
+ }
+ return null;
+ }
+ /**
+ * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
+ * DOM node.
+ */ function getNodeFromInstance(inst) {
+ if (inst.tag === HostComponent || inst.tag === HostText) // In Fiber this, is just the state node right now. We assume it will be
+ // a host component or host text.
+ return inst.stateNode;
+ // Without this first invariant, passing a non-DOM-component triggers the next
+ // invariant for a missing parent, which is super confusing.
+ throw new Error("getNodeFromInstance: Invalid argument.");
+ }
+ function getFiberCurrentPropsFromNode(node) {
+ return node[internalPropsKey] || null;
+ }
+ function updateFiberProps(node, props) {
+ node[internalPropsKey] = props;
+ }
+ function getEventListenerSet(node) {
+ var elementListenerSet = node[internalEventHandlersKey];
+ if (elementListenerSet === undefined) elementListenerSet = node[internalEventHandlersKey] = new Set();
+ return elementListenerSet;
+ }
+ var loggedTypeFailures = {};
+ var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
+ function setCurrentlyValidatingElement(element) {
+ if (element) {
+ var owner = element._owner;
+ var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
+ ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
+ } else ReactDebugCurrentFrame$1.setExtraStackFrame(null);
+ }
+ function checkPropTypes(typeSpecs, values, location, componentName, element) {
+ // $FlowFixMe This is okay but Flow doesn't know it.
+ var has = Function.call.bind(hasOwnProperty);
+ for(var typeSpecName in typeSpecs)if (has(typeSpecs, typeSpecName)) {
+ var error$1 = void 0; // 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.
+ if (typeof typeSpecs[typeSpecName] !== "function") {
+ // eslint-disable-next-line react-internal/prod-error-codes
+ var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; " + "it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`." + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
+ err.name = "Invariant Violation";
+ throw err;
+ }
+ error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
+ } catch (ex) {
+ error$1 = ex;
+ }
+ if (error$1 && !(error$1 instanceof Error)) {
+ setCurrentlyValidatingElement(element);
+ 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$1);
+ setCurrentlyValidatingElement(null);
+ }
+ if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
+ // Only monitor this failure once because there tends to be a lot of the
+ // same error.
+ loggedTypeFailures[error$1.message] = true;
+ setCurrentlyValidatingElement(element);
+ error("Failed %s type: %s", location, error$1.message);
+ setCurrentlyValidatingElement(null);
+ }
+ }
+ }
+ var valueStack = [];
+ var fiberStack;
+ fiberStack = [];
+ var index = -1;
+ function createCursor(defaultValue) {
+ return {
+ current: defaultValue
+ };
+ }
+ function pop(cursor, fiber) {
+ if (index < 0) {
+ error("Unexpected pop.");
+ return;
+ }
+ if (fiber !== fiberStack[index]) error("Unexpected Fiber popped.");
+ cursor.current = valueStack[index];
+ valueStack[index] = null;
+ fiberStack[index] = null;
+ index--;
+ }
+ function push(cursor, value, fiber) {
+ index++;
+ valueStack[index] = cursor.current;
+ fiberStack[index] = fiber;
+ cursor.current = value;
+ }
+ var warnedAboutMissingGetChildContext;
+ warnedAboutMissingGetChildContext = {};
+ var emptyContextObject = {};
+ Object.freeze(emptyContextObject);
+ var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
+ var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
+ // We use this to get access to the parent context after we have already
+ // pushed the next context provider, and now need to merge their contexts.
+ var previousContext = emptyContextObject;
+ function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
+ if (didPushOwnContextIfProvider && isContextProvider(Component)) // If the fiber is a context provider itself, when we read its context
+ // we may have already pushed its own child context on the stack. A context
+ // provider should not "see" its own child context. Therefore we read the
+ // previous (parent) context instead for a context provider.
+ return previousContext;
+ return contextStackCursor.current;
+ }
+ function cacheContext(workInProgress, unmaskedContext, maskedContext) {
+ var instance = workInProgress.stateNode;
+ instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
+ instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
+ }
+ function getMaskedContext(workInProgress, unmaskedContext) {
+ var type = workInProgress.type;
+ var contextTypes = type.contextTypes;
+ if (!contextTypes) return emptyContextObject;
+ // Avoid recreating masked context unless unmasked context has changed.
+ // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
+ // This may trigger infinite loops if componentWillReceiveProps calls setState.
+ var instance = workInProgress.stateNode;
+ if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) return instance.__reactInternalMemoizedMaskedChildContext;
+ var context = {};
+ for(var key in contextTypes)context[key] = unmaskedContext[key];
+ var name = getComponentNameFromFiber(workInProgress) || "Unknown";
+ checkPropTypes(contextTypes, context, "context", name);
+ // Context is created before the class component is instantiated so check for instance.
+ if (instance) cacheContext(workInProgress, unmaskedContext, context);
+ return context;
+ }
+ function hasContextChanged() {
+ return didPerformWorkStackCursor.current;
+ }
+ function isContextProvider(type) {
+ var childContextTypes = type.childContextTypes;
+ return childContextTypes !== null && childContextTypes !== undefined;
+ }
+ function popContext(fiber) {
+ pop(didPerformWorkStackCursor, fiber);
+ pop(contextStackCursor, fiber);
+ }
+ function popTopLevelContextObject(fiber) {
+ pop(didPerformWorkStackCursor, fiber);
+ pop(contextStackCursor, fiber);
+ }
+ function pushTopLevelContextObject(fiber, context, didChange) {
+ if (contextStackCursor.current !== emptyContextObject) throw new Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.");
+ push(contextStackCursor, context, fiber);
+ push(didPerformWorkStackCursor, didChange, fiber);
+ }
+ function processChildContext(fiber, type, parentContext) {
+ var instance = fiber.stateNode;
+ var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
+ // It has only been added in Fiber to match the (unintentional) behavior in Stack.
+ if (typeof instance.getChildContext !== "function") {
+ var componentName = getComponentNameFromFiber(fiber) || "Unknown";
+ if (!warnedAboutMissingGetChildContext[componentName]) {
+ warnedAboutMissingGetChildContext[componentName] = true;
+ error("%s.childContextTypes is specified but there is no getChildContext() method on the instance. You can either define getChildContext() on %s or remove childContextTypes from it.", componentName, componentName);
+ }
+ return parentContext;
+ }
+ var childContext = instance.getChildContext();
+ for(var contextKey in childContext){
+ if (!(contextKey in childContextTypes)) throw new Error((getComponentNameFromFiber(fiber) || "Unknown") + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.');
+ }
+ var name = getComponentNameFromFiber(fiber) || "Unknown";
+ checkPropTypes(childContextTypes, childContext, "child context", name);
+ return assign({}, parentContext, childContext);
+ }
+ function pushContextProvider(workInProgress) {
+ var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
+ // If the instance does not exist yet, we will push null at first,
+ // and replace it on the stack later when invalidating the context.
+ var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
+ // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
+ previousContext = contextStackCursor.current;
+ push(contextStackCursor, memoizedMergedChildContext, workInProgress);
+ push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
+ return true;
+ }
+ function invalidateContextProvider(workInProgress, type, didChange) {
+ var instance = workInProgress.stateNode;
+ if (!instance) throw new Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.");
+ if (didChange) {
+ // Merge parent and own context.
+ // Skip this if we're not updating due to sCU.
+ // This avoids unnecessarily recomputing memoized values.
+ var mergedContext = processChildContext(workInProgress, type, previousContext);
+ instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
+ // It is important to unwind the context in the reverse order.
+ pop(didPerformWorkStackCursor, workInProgress);
+ pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
+ push(contextStackCursor, mergedContext, workInProgress);
+ push(didPerformWorkStackCursor, didChange, workInProgress);
+ } else {
+ pop(didPerformWorkStackCursor, workInProgress);
+ push(didPerformWorkStackCursor, didChange, workInProgress);
+ }
+ }
+ function findCurrentUnmaskedContext(fiber) {
+ // Currently this is only used with renderSubtreeIntoContainer; not sure if it
+ // makes sense elsewhere
+ if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) throw new Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.");
+ var node = fiber;
+ do {
+ switch(node.tag){
+ case HostRoot:
+ return node.stateNode.context;
+ case ClassComponent:
+ var Component = node.type;
+ if (isContextProvider(Component)) return node.stateNode.__reactInternalMemoizedMergedChildContext;
+ break;
+ }
+ node = node.return;
+ }while (node !== null);
+ throw new Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.");
+ }
+ var LegacyRoot = 0;
+ var ConcurrentRoot = 1;
+ var syncQueue = null;
+ var includesLegacySyncCallbacks = false;
+ var isFlushingSyncQueue = false;
+ function scheduleSyncCallback(callback) {
+ // Push this callback into an internal queue. We'll flush these either in
+ // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
+ if (syncQueue === null) syncQueue = [
+ callback
+ ];
+ else // Push onto existing queue. Don't need to schedule a callback because
+ // we already scheduled one when we created the queue.
+ syncQueue.push(callback);
+ }
+ function scheduleLegacySyncCallback(callback) {
+ includesLegacySyncCallbacks = true;
+ scheduleSyncCallback(callback);
+ }
+ function flushSyncCallbacksOnlyInLegacyMode() {
+ // Only flushes the queue if there's a legacy sync callback scheduled.
+ // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So
+ // it might make more sense for the queue to be a list of roots instead of a
+ // list of generic callbacks. Then we can have two: one for legacy roots, one
+ // for concurrent roots. And this method would only flush the legacy ones.
+ if (includesLegacySyncCallbacks) flushSyncCallbacks();
+ }
+ function flushSyncCallbacks() {
+ if (!isFlushingSyncQueue && syncQueue !== null) {
+ // Prevent re-entrance.
+ isFlushingSyncQueue = true;
+ var i = 0;
+ var previousUpdatePriority = getCurrentUpdatePriority();
+ try {
+ var isSync = true;
+ var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this
+ // queue is in the render or commit phases.
+ setCurrentUpdatePriority(DiscreteEventPriority);
+ for(; i < queue.length; i++){
+ var callback = queue[i];
+ do callback = callback(isSync);
+ while (callback !== null);
+ }
+ syncQueue = null;
+ includesLegacySyncCallbacks = false;
+ } catch (error) {
+ // If something throws, leave the remaining callbacks on the queue.
+ if (syncQueue !== null) syncQueue = syncQueue.slice(i + 1);
+ // Resume flushing in the next tick
+ scheduleCallback(ImmediatePriority, flushSyncCallbacks);
+ throw error;
+ } finally{
+ setCurrentUpdatePriority(previousUpdatePriority);
+ isFlushingSyncQueue = false;
+ }
+ }
+ return null;
+ }
+ // TODO: Use the unified fiber stack module instead of this local one?
+ // Intentionally not using it yet to derisk the initial implementation, because
+ // the way we push/pop these values is a bit unusual. If there's a mistake, I'd
+ // rather the ids be wrong than crash the whole reconciler.
+ var forkStack = [];
+ var forkStackIndex = 0;
+ var treeForkProvider = null;
+ var treeForkCount = 0;
+ var idStack = [];
+ var idStackIndex = 0;
+ var treeContextProvider = null;
+ var treeContextId = 1;
+ var treeContextOverflow = "";
+ function isForkedChild(workInProgress) {
+ warnIfNotHydrating();
+ return (workInProgress.flags & Forked) !== NoFlags;
+ }
+ function getForksAtLevel(workInProgress) {
+ warnIfNotHydrating();
+ return treeForkCount;
+ }
+ function getTreeId() {
+ var overflow = treeContextOverflow;
+ var idWithLeadingBit = treeContextId;
+ var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit);
+ return id.toString(32) + overflow;
+ }
+ function pushTreeFork(workInProgress, totalChildren) {
+ // This is called right after we reconcile an array (or iterator) of child
+ // fibers, because that's the only place where we know how many children in
+ // the whole set without doing extra work later, or storing addtional
+ // information on the fiber.
+ //
+ // That's why this function is separate from pushTreeId \u2014 it's called during
+ // the render phase of the fork parent, not the child, which is where we push
+ // the other context values.
+ //
+ // In the Fizz implementation this is much simpler because the child is
+ // rendered in the same callstack as the parent.
+ //
+ // It might be better to just add a `forks` field to the Fiber type. It would
+ // make this module simpler.
+ warnIfNotHydrating();
+ forkStack[forkStackIndex++] = treeForkCount;
+ forkStack[forkStackIndex++] = treeForkProvider;
+ treeForkProvider = workInProgress;
+ treeForkCount = totalChildren;
+ }
+ function pushTreeId(workInProgress, totalChildren, index) {
+ warnIfNotHydrating();
+ idStack[idStackIndex++] = treeContextId;
+ idStack[idStackIndex++] = treeContextOverflow;
+ idStack[idStackIndex++] = treeContextProvider;
+ treeContextProvider = workInProgress;
+ var baseIdWithLeadingBit = treeContextId;
+ var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part
+ // of the id; we use it to account for leading 0s.
+ var baseLength = getBitLength(baseIdWithLeadingBit) - 1;
+ var baseId = baseIdWithLeadingBit & ~(1 << baseLength);
+ var slot = index + 1;
+ var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into
+ // consideration the leading 1 we use to mark the end of the sequence.
+ if (length > 30) {
+ // We overflowed the bitwise-safe range. Fall back to slower algorithm.
+ // This branch assumes the length of the base id is greater than 5; it won't
+ // work for smaller ids, because you need 5 bits per character.
+ //
+ // We encode the id in multiple steps: first the base id, then the
+ // remaining digits.
+ //
+ // Each 5 bit sequence corresponds to a single base 32 character. So for
+ // example, if the current id is 23 bits long, we can convert 20 of those
+ // bits into a string of 4 characters, with 3 bits left over.
+ //
+ // First calculate how many bits in the base id represent a complete
+ // sequence of characters.
+ var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits.
+ var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string.
+ var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id.
+ var restOfBaseId = baseId >> numberOfOverflowBits;
+ var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because
+ // we made more room, this time it won't overflow.
+ var restOfLength = getBitLength(totalChildren) + restOfBaseLength;
+ var restOfNewBits = slot << restOfBaseLength;
+ var id = restOfNewBits | restOfBaseId;
+ var overflow = newOverflow + baseOverflow;
+ treeContextId = 1 << restOfLength | id;
+ treeContextOverflow = overflow;
+ } else {
+ // Normal path
+ var newBits = slot << baseLength;
+ var _id = newBits | baseId;
+ var _overflow = baseOverflow;
+ treeContextId = 1 << length | _id;
+ treeContextOverflow = _overflow;
+ }
+ }
+ function pushMaterializedTreeId(workInProgress) {
+ warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear
+ // in its children.
+ var returnFiber = workInProgress.return;
+ if (returnFiber !== null) {
+ var numberOfForks = 1;
+ var slotIndex = 0;
+ pushTreeFork(workInProgress, numberOfForks);
+ pushTreeId(workInProgress, numberOfForks, slotIndex);
+ }
+ }
+ function getBitLength(number) {
+ return 32 - clz32(number);
+ }
+ function getLeadingBit(id) {
+ return 1 << getBitLength(id) - 1;
+ }
+ function popTreeContext(workInProgress) {
+ // Restore the previous values.
+ // This is a bit more complicated than other context-like modules in Fiber
+ // because the same Fiber may appear on the stack multiple times and for
+ // different reasons. We have to keep popping until the work-in-progress is
+ // no longer at the top of the stack.
+ while(workInProgress === treeForkProvider){
+ treeForkProvider = forkStack[--forkStackIndex];
+ forkStack[forkStackIndex] = null;
+ treeForkCount = forkStack[--forkStackIndex];
+ forkStack[forkStackIndex] = null;
+ }
+ while(workInProgress === treeContextProvider){
+ treeContextProvider = idStack[--idStackIndex];
+ idStack[idStackIndex] = null;
+ treeContextOverflow = idStack[--idStackIndex];
+ idStack[idStackIndex] = null;
+ treeContextId = idStack[--idStackIndex];
+ idStack[idStackIndex] = null;
+ }
+ }
+ function getSuspendedTreeContext() {
+ warnIfNotHydrating();
+ if (treeContextProvider !== null) return {
+ id: treeContextId,
+ overflow: treeContextOverflow
+ };
+ else return null;
+ }
+ function restoreSuspendedTreeContext(workInProgress, suspendedContext) {
+ warnIfNotHydrating();
+ idStack[idStackIndex++] = treeContextId;
+ idStack[idStackIndex++] = treeContextOverflow;
+ idStack[idStackIndex++] = treeContextProvider;
+ treeContextId = suspendedContext.id;
+ treeContextOverflow = suspendedContext.overflow;
+ treeContextProvider = workInProgress;
+ }
+ function warnIfNotHydrating() {
+ if (!getIsHydrating()) error("Expected to be hydrating. This is a bug in React. Please file an issue.");
+ }
+ // This may have been an insertion or a hydration.
+ var hydrationParentFiber = null;
+ var nextHydratableInstance = null;
+ var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches
+ // due to earlier mismatches or a suspended fiber.
+ var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary
+ var hydrationErrors = null;
+ function warnIfHydrating() {
+ if (isHydrating) error("We should not be hydrating here. This is a bug in React. Please file a bug.");
+ }
+ function markDidThrowWhileHydratingDEV() {
+ didSuspendOrErrorDEV = true;
+ }
+ function didSuspendOrErrorWhileHydratingDEV() {
+ return didSuspendOrErrorDEV;
+ }
+ function enterHydrationState(fiber) {
+ var parentInstance = fiber.stateNode.containerInfo;
+ nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance);
+ hydrationParentFiber = fiber;
+ isHydrating = true;
+ hydrationErrors = null;
+ didSuspendOrErrorDEV = false;
+ return true;
+ }
+ function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
+ nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance);
+ hydrationParentFiber = fiber;
+ isHydrating = true;
+ hydrationErrors = null;
+ didSuspendOrErrorDEV = false;
+ if (treeContext !== null) restoreSuspendedTreeContext(fiber, treeContext);
+ return true;
+ }
+ function warnUnhydratedInstance(returnFiber, instance) {
+ switch(returnFiber.tag){
+ case HostRoot:
+ didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance);
+ break;
+ case HostComponent:
+ var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
+ didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance, isConcurrentMode);
+ break;
+ case SuspenseComponent:
+ var suspenseState = returnFiber.memoizedState;
+ if (suspenseState.dehydrated !== null) didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance);
+ break;
+ }
+ }
+ function deleteHydratableInstance(returnFiber, instance) {
+ warnUnhydratedInstance(returnFiber, instance);
+ var childToDelete = createFiberFromHostInstanceForDeletion();
+ childToDelete.stateNode = instance;
+ childToDelete.return = returnFiber;
+ var deletions = returnFiber.deletions;
+ if (deletions === null) {
+ returnFiber.deletions = [
+ childToDelete
+ ];
+ returnFiber.flags |= ChildDeletion;
+ } else deletions.push(childToDelete);
+ }
+ function warnNonhydratedInstance(returnFiber, fiber) {
+ if (didSuspendOrErrorDEV) // Inside a boundary that already suspended. We're currently rendering the
+ // siblings of a suspended node. The mismatch may be due to the missing
+ // data, so it's probably a false positive.
+ return;
+ switch(returnFiber.tag){
+ case HostRoot:
+ var parentContainer = returnFiber.stateNode.containerInfo;
+ switch(fiber.tag){
+ case HostComponent:
+ var type = fiber.type;
+ var props = fiber.pendingProps;
+ didNotFindHydratableInstanceWithinContainer(parentContainer, type);
+ break;
+ case HostText:
+ var text = fiber.pendingProps;
+ didNotFindHydratableTextInstanceWithinContainer(parentContainer, text);
+ break;
+ }
+ break;
+ case HostComponent:
+ var parentType = returnFiber.type;
+ var parentProps = returnFiber.memoizedProps;
+ var parentInstance = returnFiber.stateNode;
+ switch(fiber.tag){
+ case HostComponent:
+ var _type = fiber.type;
+ var _props = fiber.pendingProps;
+ var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
+ didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props, isConcurrentMode);
+ break;
+ case HostText:
+ var _text = fiber.pendingProps;
+ var _isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
+ didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text, _isConcurrentMode);
+ break;
+ }
+ break;
+ case SuspenseComponent:
+ var suspenseState = returnFiber.memoizedState;
+ var _parentInstance = suspenseState.dehydrated;
+ if (_parentInstance !== null) switch(fiber.tag){
+ case HostComponent:
+ var _type2 = fiber.type;
+ var _props2 = fiber.pendingProps;
+ didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2);
+ break;
+ case HostText:
+ var _text2 = fiber.pendingProps;
+ didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2);
+ break;
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ function insertNonHydratedInstance(returnFiber, fiber) {
+ fiber.flags = fiber.flags & ~Hydrating | Placement;
+ warnNonhydratedInstance(returnFiber, fiber);
+ }
+ function tryHydrate(fiber, nextInstance) {
+ switch(fiber.tag){
+ case HostComponent:
+ var type = fiber.type;
+ var props = fiber.pendingProps;
+ var instance = canHydrateInstance(nextInstance, type);
+ if (instance !== null) {
+ fiber.stateNode = instance;
+ hydrationParentFiber = fiber;
+ nextHydratableInstance = getFirstHydratableChild(instance);
+ return true;
+ }
+ return false;
+ case HostText:
+ var text = fiber.pendingProps;
+ var textInstance = canHydrateTextInstance(nextInstance, text);
+ if (textInstance !== null) {
+ fiber.stateNode = textInstance;
+ hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate.
+ nextHydratableInstance = null;
+ return true;
+ }
+ return false;
+ case SuspenseComponent:
+ var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
+ if (suspenseInstance !== null) {
+ var suspenseState = {
+ dehydrated: suspenseInstance,
+ treeContext: getSuspendedTreeContext(),
+ retryLane: OffscreenLane
+ };
+ fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
+ // This simplifies the code for getHostSibling and deleting nodes,
+ // since it doesn't have to consider all Suspense boundaries and
+ // check if they're dehydrated ones or not.
+ var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
+ dehydratedFragment.return = fiber;
+ fiber.child = dehydratedFragment;
+ hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into
+ // it during the first pass. Instead, we'll reenter it later.
+ nextHydratableInstance = null;
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+ }
+ function shouldClientRenderOnMismatch(fiber) {
+ return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags;
+ }
+ function throwOnHydrationMismatch(fiber) {
+ throw new Error("Hydration failed because the initial UI does not match what was rendered on the server.");
+ }
+ function tryToClaimNextHydratableInstance(fiber) {
+ if (!isHydrating) return;
+ var nextInstance = nextHydratableInstance;
+ if (!nextInstance) {
+ if (shouldClientRenderOnMismatch(fiber)) {
+ warnNonhydratedInstance(hydrationParentFiber, fiber);
+ throwOnHydrationMismatch();
+ } // Nothing to hydrate. Make it an insertion.
+ insertNonHydratedInstance(hydrationParentFiber, fiber);
+ isHydrating = false;
+ hydrationParentFiber = fiber;
+ return;
+ }
+ var firstAttemptedInstance = nextInstance;
+ if (!tryHydrate(fiber, nextInstance)) {
+ if (shouldClientRenderOnMismatch(fiber)) {
+ warnNonhydratedInstance(hydrationParentFiber, fiber);
+ throwOnHydrationMismatch();
+ } // If we can't hydrate this instance let's try the next one.
+ // We use this as a heuristic. It's based on intuition and not data so it
+ // might be flawed or unnecessary.
+ nextInstance = getNextHydratableSibling(firstAttemptedInstance);
+ var prevHydrationParentFiber = hydrationParentFiber;
+ if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
+ // Nothing to hydrate. Make it an insertion.
+ insertNonHydratedInstance(hydrationParentFiber, fiber);
+ isHydrating = false;
+ hydrationParentFiber = fiber;
+ return;
+ } // We matched the next one, we'll now assume that the first one was
+ // superfluous and we'll delete it. Since we can't eagerly delete it
+ // we'll have to schedule a deletion. To do that, this node needs a dummy
+ // fiber associated with it.
+ deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
+ }
+ }
+ function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
+ var instance = fiber.stateNode;
+ var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV;
+ var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev); // TODO: Type this specific to this type of component.
+ fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
+ // is a new ref we mark this as an update.
+ if (updatePayload !== null) return true;
+ return false;
+ }
+ function prepareToHydrateHostTextInstance(fiber) {
+ var textInstance = fiber.stateNode;
+ var textContent = fiber.memoizedProps;
+ var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
+ if (shouldUpdate) {
+ // We assume that prepareToHydrateHostTextInstance is called in a context where the
+ // hydration parent is the parent host component of this host text.
+ var returnFiber = hydrationParentFiber;
+ if (returnFiber !== null) switch(returnFiber.tag){
+ case HostRoot:
+ var parentContainer = returnFiber.stateNode.containerInfo;
+ var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
+ didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, isConcurrentMode);
+ break;
+ case HostComponent:
+ var parentType = returnFiber.type;
+ var parentProps = returnFiber.memoizedProps;
+ var parentInstance = returnFiber.stateNode;
+ var _isConcurrentMode2 = (returnFiber.mode & ConcurrentMode) !== NoMode;
+ didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, _isConcurrentMode2);
+ break;
+ }
+ }
+ return shouldUpdate;
+ }
+ function prepareToHydrateHostSuspenseInstance(fiber) {
+ var suspenseState = fiber.memoizedState;
+ var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
+ if (!suspenseInstance) throw new Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");
+ hydrateSuspenseInstance(suspenseInstance, fiber);
+ }
+ function skipPastDehydratedSuspenseInstance(fiber) {
+ var suspenseState = fiber.memoizedState;
+ var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
+ if (!suspenseInstance) throw new Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");
+ return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
+ }
+ function popToNextHostParent(fiber) {
+ var parent = fiber.return;
+ while(parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent)parent = parent.return;
+ hydrationParentFiber = parent;
+ }
+ function popHydrationState(fiber) {
+ if (fiber !== hydrationParentFiber) // We're deeper than the current hydration context, inside an inserted
+ // tree.
+ return false;
+ if (!isHydrating) {
+ // If we're not currently hydrating but we're in a hydration context, then
+ // we were an insertion and now need to pop up reenter hydration of our
+ // siblings.
+ popToNextHostParent(fiber);
+ isHydrating = true;
+ return false;
+ } // If we have any remaining hydratable nodes, we need to delete them now.
+ // We only do this deeper than head and body since they tend to have random
+ // other nodes in them. We also ignore components with pure text content in
+ // side of them. We also don't delete anything inside the root container.
+ if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) {
+ var nextInstance = nextHydratableInstance;
+ if (nextInstance) {
+ if (shouldClientRenderOnMismatch(fiber)) {
+ warnIfUnhydratedTailNodes(fiber);
+ throwOnHydrationMismatch();
+ } else while(nextInstance){
+ deleteHydratableInstance(fiber, nextInstance);
+ nextInstance = getNextHydratableSibling(nextInstance);
+ }
+ }
+ }
+ popToNextHostParent(fiber);
+ if (fiber.tag === SuspenseComponent) nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
+ else nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
+ return true;
+ }
+ function hasUnhydratedTailNodes() {
+ return isHydrating && nextHydratableInstance !== null;
+ }
+ function warnIfUnhydratedTailNodes(fiber) {
+ var nextInstance = nextHydratableInstance;
+ while(nextInstance){
+ warnUnhydratedInstance(fiber, nextInstance);
+ nextInstance = getNextHydratableSibling(nextInstance);
+ }
+ }
+ function resetHydrationState() {
+ hydrationParentFiber = null;
+ nextHydratableInstance = null;
+ isHydrating = false;
+ didSuspendOrErrorDEV = false;
+ }
+ function upgradeHydrationErrorsToRecoverable() {
+ if (hydrationErrors !== null) {
+ // Successfully completed a forced client render. The errors that occurred
+ // during the hydration attempt are now recovered. We will log them in
+ // commit phase, once the entire tree has finished.
+ queueRecoverableErrors(hydrationErrors);
+ hydrationErrors = null;
+ }
+ }
+ function getIsHydrating() {
+ return isHydrating;
+ }
+ function queueHydrationError(error) {
+ if (hydrationErrors === null) hydrationErrors = [
+ error
+ ];
+ else hydrationErrors.push(error);
+ }
+ var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
+ var NoTransition = null;
+ function requestCurrentTransition() {
+ return ReactCurrentBatchConfig$1.transition;
+ }
+ var ReactStrictModeWarnings = {
+ recordUnsafeLifecycleWarnings: function(fiber, instance) {},
+ flushPendingUnsafeLifecycleWarnings: function() {},
+ recordLegacyContextWarning: function(fiber, instance) {},
+ flushLegacyContextWarning: function() {},
+ discardPendingWarnings: function() {}
+ };
+ var findStrictRoot = function(fiber) {
+ var maybeStrictRoot = null;
+ var node = fiber;
+ while(node !== null){
+ if (node.mode & StrictLegacyMode) maybeStrictRoot = node;
+ node = node.return;
+ }
+ return maybeStrictRoot;
+ };
+ var setToSortedString = function(set) {
+ var array = [];
+ set.forEach(function(value) {
+ array.push(value);
+ });
+ return array.sort().join(", ");
+ };
+ var pendingComponentWillMountWarnings = [];
+ var pendingUNSAFE_ComponentWillMountWarnings = [];
+ var pendingComponentWillReceivePropsWarnings = [];
+ var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
+ var pendingComponentWillUpdateWarnings = [];
+ var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
+ var didWarnAboutUnsafeLifecycles = new Set();
+ ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function(fiber, instance) {
+ // Dedupe strategy: Warn once per component.
+ if (didWarnAboutUnsafeLifecycles.has(fiber.type)) return;
+ if (typeof instance.componentWillMount === "function" && // Don't warn about react-lifecycles-compat polyfilled components.
+ instance.componentWillMount.__suppressDeprecationWarning !== true) pendingComponentWillMountWarnings.push(fiber);
+ if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function") pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
+ if (typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) pendingComponentWillReceivePropsWarnings.push(fiber);
+ if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function") pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
+ if (typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true) pendingComponentWillUpdateWarnings.push(fiber);
+ if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function") pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
+ };
+ ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() {
+ // We do an initial pass to gather component names
+ var componentWillMountUniqueNames = new Set();
+ if (pendingComponentWillMountWarnings.length > 0) {
+ pendingComponentWillMountWarnings.forEach(function(fiber) {
+ componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutUnsafeLifecycles.add(fiber.type);
+ });
+ pendingComponentWillMountWarnings = [];
+ }
+ var UNSAFE_componentWillMountUniqueNames = new Set();
+ if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
+ pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) {
+ UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutUnsafeLifecycles.add(fiber.type);
+ });
+ pendingUNSAFE_ComponentWillMountWarnings = [];
+ }
+ var componentWillReceivePropsUniqueNames = new Set();
+ if (pendingComponentWillReceivePropsWarnings.length > 0) {
+ pendingComponentWillReceivePropsWarnings.forEach(function(fiber) {
+ componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutUnsafeLifecycles.add(fiber.type);
+ });
+ pendingComponentWillReceivePropsWarnings = [];
+ }
+ var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
+ if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
+ pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) {
+ UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutUnsafeLifecycles.add(fiber.type);
+ });
+ pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
+ }
+ var componentWillUpdateUniqueNames = new Set();
+ if (pendingComponentWillUpdateWarnings.length > 0) {
+ pendingComponentWillUpdateWarnings.forEach(function(fiber) {
+ componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutUnsafeLifecycles.add(fiber.type);
+ });
+ pendingComponentWillUpdateWarnings = [];
+ }
+ var UNSAFE_componentWillUpdateUniqueNames = new Set();
+ if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
+ pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) {
+ UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutUnsafeLifecycles.add(fiber.type);
+ });
+ pendingUNSAFE_ComponentWillUpdateWarnings = [];
+ } // Finally, we flush all the warnings
+ // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
+ if (UNSAFE_componentWillMountUniqueNames.size > 0) {
+ var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
+ error("Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n\nPlease update the following components: %s", sortedNames);
+ }
+ if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
+ var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
+ error("Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n\nPlease update the following components: %s", _sortedNames);
+ }
+ if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
+ var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
+ error("Using UNSAFE_componentWillUpdate in strict mode is not recommended and may indicate bugs in your code. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n\nPlease update the following components: %s", _sortedNames2);
+ }
+ if (componentWillMountUniqueNames.size > 0) {
+ var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
+ warn("componentWillMount has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move code with side effects to componentDidMount, and set initial state in the constructor.\n* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames3);
+ }
+ if (componentWillReceivePropsUniqueNames.size > 0) {
+ var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
+ warn("componentWillReceiveProps has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames4);
+ }
+ if (componentWillUpdateUniqueNames.size > 0) {
+ var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
+ warn("componentWillUpdate has been renamed, and is not recommended for use. See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n* Move data fetching code or side effects to componentDidUpdate.\n* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n\nPlease update the following components: %s", _sortedNames5);
+ }
+ };
+ var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
+ var didWarnAboutLegacyContext = new Set();
+ ReactStrictModeWarnings.recordLegacyContextWarning = function(fiber, instance) {
+ var strictRoot = findStrictRoot(fiber);
+ if (strictRoot === null) {
+ error("Expected to find a StrictMode component in a strict mode tree. This error is likely caused by a bug in React. Please file an issue.");
+ return;
+ } // Dedup strategy: Warn once per component.
+ if (didWarnAboutLegacyContext.has(fiber.type)) return;
+ var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
+ if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === "function") {
+ if (warningsForRoot === undefined) {
+ warningsForRoot = [];
+ pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
+ }
+ warningsForRoot.push(fiber);
+ }
+ };
+ ReactStrictModeWarnings.flushLegacyContextWarning = function() {
+ pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) {
+ if (fiberArray.length === 0) return;
+ var firstFiber = fiberArray[0];
+ var uniqueNames = new Set();
+ fiberArray.forEach(function(fiber) {
+ uniqueNames.add(getComponentNameFromFiber(fiber) || "Component");
+ didWarnAboutLegacyContext.add(fiber.type);
+ });
+ var sortedNames = setToSortedString(uniqueNames);
+ try {
+ setCurrentFiber(firstFiber);
+ error("Legacy context API has been detected within a strict-mode tree.\n\nThe old API will be supported in all 16.x releases, but applications using it should migrate to the new version.\n\nPlease update the following components: %s\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context", sortedNames);
+ } finally{
+ resetCurrentFiber();
+ }
+ });
+ };
+ ReactStrictModeWarnings.discardPendingWarnings = function() {
+ pendingComponentWillMountWarnings = [];
+ pendingUNSAFE_ComponentWillMountWarnings = [];
+ pendingComponentWillReceivePropsWarnings = [];
+ pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
+ pendingComponentWillUpdateWarnings = [];
+ pendingUNSAFE_ComponentWillUpdateWarnings = [];
+ pendingLegacyContextWarning = new Map();
+ };
+ function resolveDefaultProps(Component, baseProps) {
+ if (Component && Component.defaultProps) {
+ // Resolve default props. Taken from ReactElement
+ var props = assign({}, baseProps);
+ var defaultProps = Component.defaultProps;
+ for(var propName in defaultProps)if (props[propName] === undefined) props[propName] = defaultProps[propName];
+ return props;
+ }
+ return baseProps;
+ }
+ var valueCursor = createCursor(null);
+ var rendererSigil;
+ // Use this to detect multiple renderers using the same context
+ rendererSigil = {};
+ var currentlyRenderingFiber = null;
+ var lastContextDependency = null;
+ var lastFullyObservedContext = null;
+ var isDisallowedContextReadInDEV = false;
+ function resetContextDependencies() {
+ // This is called right before React yields execution, to ensure `readContext`
+ // cannot be called outside the render phase.
+ currentlyRenderingFiber = null;
+ lastContextDependency = null;
+ lastFullyObservedContext = null;
+ isDisallowedContextReadInDEV = false;
+ }
+ function enterDisallowedContextReadInDEV() {
+ isDisallowedContextReadInDEV = true;
+ }
+ function exitDisallowedContextReadInDEV() {
+ isDisallowedContextReadInDEV = false;
+ }
+ function pushProvider(providerFiber, context, nextValue) {
+ push(valueCursor, context._currentValue, providerFiber);
+ context._currentValue = nextValue;
+ if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) error("Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported.");
+ context._currentRenderer = rendererSigil;
+ }
+ function popProvider(context, providerFiber) {
+ var currentValue = valueCursor.current;
+ pop(valueCursor, providerFiber);
+ context._currentValue = currentValue;
+ }
+ function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
+ // Update the child lanes of all the ancestors, including the alternates.
+ var node = parent;
+ while(node !== null){
+ var alternate = node.alternate;
+ if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
+ node.childLanes = mergeLanes(node.childLanes, renderLanes);
+ if (alternate !== null) alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
+ } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
+ if (node === propagationRoot) break;
+ node = node.return;
+ }
+ if (node !== propagationRoot) error("Expected to find the propagation root when scheduling context work. This error is likely caused by a bug in React. Please file an issue.");
+ }
+ function propagateContextChange(workInProgress, context, renderLanes) {
+ propagateContextChange_eager(workInProgress, context, renderLanes);
+ }
+ function propagateContextChange_eager(workInProgress, context, renderLanes) {
+ var fiber = workInProgress.child;
+ if (fiber !== null) // Set the return pointer of the child to the work-in-progress fiber.
+ fiber.return = workInProgress;
+ while(fiber !== null){
+ var nextFiber = void 0; // Visit this fiber.
+ var list = fiber.dependencies;
+ if (list !== null) {
+ nextFiber = fiber.child;
+ var dependency = list.firstContext;
+ while(dependency !== null){
+ // Check if the context matches.
+ if (dependency.context === context) {
+ // Match! Schedule an update on this fiber.
+ if (fiber.tag === ClassComponent) {
+ // Schedule a force update on the work-in-progress.
+ var lane = pickArbitraryLane(renderLanes);
+ var update = createUpdate(NoTimestamp, lane);
+ update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
+ // update to the current fiber, too, which means it will persist even if
+ // this render is thrown away. Since it's a race condition, not sure it's
+ // worth fixing.
+ // Inlined `enqueueUpdate` to remove interleaved update check
+ var updateQueue = fiber.updateQueue;
+ if (updateQueue === null) ;
+ else {
+ var sharedQueue = updateQueue.shared;
+ var pending = sharedQueue.pending;
+ if (pending === null) // This is the first update. Create a circular list.
+ update.next = update;
+ else {
+ update.next = pending.next;
+ pending.next = update;
+ }
+ sharedQueue.pending = update;
+ }
+ }
+ fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
+ var alternate = fiber.alternate;
+ if (alternate !== null) alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
+ scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
+ list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
+ break;
+ }
+ dependency = dependency.next;
+ }
+ } else if (fiber.tag === ContextProvider) // Don't scan deeper if this is a matching provider
+ nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
+ else if (fiber.tag === DehydratedFragment) {
+ // If a dehydrated suspense boundary is in this subtree, we don't know
+ // if it will have any context consumers in it. The best we can do is
+ // mark it as having updates.
+ var parentSuspense = fiber.return;
+ if (parentSuspense === null) throw new Error("We just came from a parent so we must have had a parent. This is a bug in React.");
+ parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes);
+ var _alternate = parentSuspense.alternate;
+ if (_alternate !== null) _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes);
+ // This is intentionally passing this fiber as the parent
+ // because we want to schedule this fiber as having work
+ // on its children. We'll use the childLanes on
+ // this fiber to indicate that a context has changed.
+ scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress);
+ nextFiber = fiber.sibling;
+ } else // Traverse down.
+ nextFiber = fiber.child;
+ if (nextFiber !== null) // Set the return pointer of the child to the work-in-progress fiber.
+ nextFiber.return = fiber;
+ else {
+ // No child. Traverse to next sibling.
+ nextFiber = fiber;
+ while(nextFiber !== null){
+ if (nextFiber === workInProgress) {
+ // We're back to the root of this subtree. Exit.
+ nextFiber = null;
+ break;
+ }
+ var sibling = nextFiber.sibling;
+ if (sibling !== null) {
+ // Set the return pointer of the sibling to the work-in-progress fiber.
+ sibling.return = nextFiber.return;
+ nextFiber = sibling;
+ break;
+ } // No more siblings. Traverse up.
+ nextFiber = nextFiber.return;
+ }
+ }
+ fiber = nextFiber;
+ }
+ }
+ function prepareToReadContext(workInProgress, renderLanes) {
+ currentlyRenderingFiber = workInProgress;
+ lastContextDependency = null;
+ lastFullyObservedContext = null;
+ var dependencies = workInProgress.dependencies;
+ if (dependencies !== null) {
+ var firstContext = dependencies.firstContext;
+ if (firstContext !== null) {
+ if (includesSomeLane(dependencies.lanes, renderLanes)) // Context list has a pending update. Mark that this fiber performed work.
+ markWorkInProgressReceivedUpdate();
+ // Reset the work-in-progress list
+ dependencies.firstContext = null;
+ }
+ }
+ }
+ function readContext(context) {
+ // This warning would fire if you read context inside a Hook like useMemo.
+ // Unlike the class check below, it's not enforced in production for perf.
+ if (isDisallowedContextReadInDEV) error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
+ var value = context._currentValue;
+ if (lastFullyObservedContext === context) ;
+ else {
+ var contextItem = {
+ context: context,
+ memoizedValue: value,
+ next: null
+ };
+ if (lastContextDependency === null) {
+ if (currentlyRenderingFiber === null) throw new Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
+ // This is the first dependency for this component. Create a new list.
+ lastContextDependency = contextItem;
+ currentlyRenderingFiber.dependencies = {
+ lanes: NoLanes,
+ firstContext: contextItem
+ };
+ } else // Append a new context item.
+ lastContextDependency = lastContextDependency.next = contextItem;
+ }
+ return value;
+ }
+ // render. When this render exits, either because it finishes or because it is
+ // interrupted, the interleaved updates will be transferred onto the main part
+ // of the queue.
+ var concurrentQueues = null;
+ function pushConcurrentUpdateQueue(queue) {
+ if (concurrentQueues === null) concurrentQueues = [
+ queue
+ ];
+ else concurrentQueues.push(queue);
+ }
+ function finishQueueingConcurrentUpdates() {
+ // Transfer the interleaved updates onto the main queue. Each queue has a
+ // `pending` field and an `interleaved` field. When they are not null, they
+ // point to the last node in a circular linked list. We need to append the
+ // interleaved list to the end of the pending list by joining them into a
+ // single, circular list.
+ if (concurrentQueues !== null) {
+ for(var i = 0; i < concurrentQueues.length; i++){
+ var queue = concurrentQueues[i];
+ var lastInterleavedUpdate = queue.interleaved;
+ if (lastInterleavedUpdate !== null) {
+ queue.interleaved = null;
+ var firstInterleavedUpdate = lastInterleavedUpdate.next;
+ var lastPendingUpdate = queue.pending;
+ if (lastPendingUpdate !== null) {
+ var firstPendingUpdate = lastPendingUpdate.next;
+ lastPendingUpdate.next = firstInterleavedUpdate;
+ lastInterleavedUpdate.next = firstPendingUpdate;
+ }
+ queue.pending = lastInterleavedUpdate;
+ }
+ }
+ concurrentQueues = null;
+ }
+ }
+ function enqueueConcurrentHookUpdate(fiber, queue, update, lane) {
+ var interleaved = queue.interleaved;
+ if (interleaved === null) {
+ // This is the first update. Create a circular list.
+ update.next = update; // At the end of the current render, this queue's interleaved updates will
+ // be transferred to the pending queue.
+ pushConcurrentUpdateQueue(queue);
+ } else {
+ update.next = interleaved.next;
+ interleaved.next = update;
+ }
+ queue.interleaved = update;
+ return markUpdateLaneFromFiberToRoot(fiber, lane);
+ }
+ function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane) {
+ var interleaved = queue.interleaved;
+ if (interleaved === null) {
+ // This is the first update. Create a circular list.
+ update.next = update; // At the end of the current render, this queue's interleaved updates will
+ // be transferred to the pending queue.
+ pushConcurrentUpdateQueue(queue);
+ } else {
+ update.next = interleaved.next;
+ interleaved.next = update;
+ }
+ queue.interleaved = update;
+ }
+ function enqueueConcurrentClassUpdate(fiber, queue, update, lane) {
+ var interleaved = queue.interleaved;
+ if (interleaved === null) {
+ // This is the first update. Create a circular list.
+ update.next = update; // At the end of the current render, this queue's interleaved updates will
+ // be transferred to the pending queue.
+ pushConcurrentUpdateQueue(queue);
+ } else {
+ update.next = interleaved.next;
+ interleaved.next = update;
+ }
+ queue.interleaved = update;
+ return markUpdateLaneFromFiberToRoot(fiber, lane);
+ }
+ function enqueueConcurrentRenderForLane(fiber, lane) {
+ return markUpdateLaneFromFiberToRoot(fiber, lane);
+ } // Calling this function outside this module should only be done for backwards
+ // compatibility and should always be accompanied by a warning.
+ var unsafe_markUpdateLaneFromFiberToRoot = markUpdateLaneFromFiberToRoot;
+ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
+ // Update the source fiber's lanes
+ sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
+ var alternate = sourceFiber.alternate;
+ if (alternate !== null) alternate.lanes = mergeLanes(alternate.lanes, lane);
+ if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
+ var node = sourceFiber;
+ var parent = sourceFiber.return;
+ while(parent !== null){
+ parent.childLanes = mergeLanes(parent.childLanes, lane);
+ alternate = parent.alternate;
+ if (alternate !== null) alternate.childLanes = mergeLanes(alternate.childLanes, lane);
+ else if ((parent.flags & (Placement | Hydrating)) !== NoFlags) warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
+ node = parent;
+ parent = parent.return;
+ }
+ if (node.tag === HostRoot) {
+ var root = node.stateNode;
+ return root;
+ } else return null;
+ }
+ var UpdateState = 0;
+ var ReplaceState = 1;
+ var ForceUpdate = 2;
+ var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
+ // It should only be read right after calling `processUpdateQueue`, via
+ // `checkHasForceUpdateAfterProcessing`.
+ var hasForceUpdate = false;
+ var didWarnUpdateInsideUpdate;
+ var currentlyProcessingQueue;
+ didWarnUpdateInsideUpdate = false;
+ currentlyProcessingQueue = null;
+ function initializeUpdateQueue(fiber) {
+ var queue = {
+ baseState: fiber.memoizedState,
+ firstBaseUpdate: null,
+ lastBaseUpdate: null,
+ shared: {
+ pending: null,
+ interleaved: null,
+ lanes: NoLanes
+ },
+ effects: null
+ };
+ fiber.updateQueue = queue;
+ }
+ function cloneUpdateQueue(current, workInProgress) {
+ // Clone the update queue from current. Unless it's already a clone.
+ var queue = workInProgress.updateQueue;
+ var currentQueue = current.updateQueue;
+ if (queue === currentQueue) {
+ var clone = {
+ baseState: currentQueue.baseState,
+ firstBaseUpdate: currentQueue.firstBaseUpdate,
+ lastBaseUpdate: currentQueue.lastBaseUpdate,
+ shared: currentQueue.shared,
+ effects: currentQueue.effects
+ };
+ workInProgress.updateQueue = clone;
+ }
+ }
+ function createUpdate(eventTime, lane) {
+ var update = {
+ eventTime: eventTime,
+ lane: lane,
+ tag: UpdateState,
+ payload: null,
+ callback: null,
+ next: null
+ };
+ return update;
+ }
+ function enqueueUpdate(fiber, update, lane) {
+ var updateQueue = fiber.updateQueue;
+ if (updateQueue === null) // Only occurs if the fiber has been unmounted.
+ return null;
+ var sharedQueue = updateQueue.shared;
+ if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
+ error("An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback.");
+ didWarnUpdateInsideUpdate = true;
+ }
+ if (isUnsafeClassRenderPhaseUpdate()) {
+ // This is an unsafe render phase update. Add directly to the update
+ // queue so we can process it immediately during the current render.
+ var pending = sharedQueue.pending;
+ if (pending === null) // This is the first update. Create a circular list.
+ update.next = update;
+ else {
+ update.next = pending.next;
+ pending.next = update;
+ }
+ sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering
+ // this fiber. This is for backwards compatibility in the case where you
+ // update a different component during render phase than the one that is
+ // currently renderings (a pattern that is accompanied by a warning).
+ return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane);
+ } else return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane);
+ }
+ function entangleTransitions(root, fiber, lane) {
+ var updateQueue = fiber.updateQueue;
+ if (updateQueue === null) // Only occurs if the fiber has been unmounted.
+ return;
+ var sharedQueue = updateQueue.shared;
+ if (isTransitionLane(lane)) {
+ var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
+ // have finished. We can remove them from the shared queue, which represents
+ // a superset of the actually pending lanes. In some cases we may entangle
+ // more than we need to, but that's OK. In fact it's worse if we *don't*
+ // entangle when we should.
+ queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
+ var newQueueLanes = mergeLanes(queueLanes, lane);
+ sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
+ // the lane finished since the last time we entangled it. So we need to
+ // entangle it again, just to be sure.
+ markRootEntangled(root, newQueueLanes);
+ }
+ }
+ function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
+ // Captured updates are updates that are thrown by a child during the render
+ // phase. They should be discarded if the render is aborted. Therefore,
+ // we should only put them on the work-in-progress queue, not the current one.
+ var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
+ var current = workInProgress.alternate;
+ if (current !== null) {
+ var currentQueue = current.updateQueue;
+ if (queue === currentQueue) {
+ // The work-in-progress queue is the same as current. This happens when
+ // we bail out on a parent fiber that then captures an error thrown by
+ // a child. Since we want to append the update only to the work-in
+ // -progress queue, we need to clone the updates. We usually clone during
+ // processUpdateQueue, but that didn't happen in this case because we
+ // skipped over the parent when we bailed out.
+ var newFirst = null;
+ var newLast = null;
+ var firstBaseUpdate = queue.firstBaseUpdate;
+ if (firstBaseUpdate !== null) {
+ // Loop through the updates and clone them.
+ var update = firstBaseUpdate;
+ do {
+ var clone = {
+ eventTime: update.eventTime,
+ lane: update.lane,
+ tag: update.tag,
+ payload: update.payload,
+ callback: update.callback,
+ next: null
+ };
+ if (newLast === null) newFirst = newLast = clone;
+ else {
+ newLast.next = clone;
+ newLast = clone;
+ }
+ update = update.next;
+ }while (update !== null); // Append the captured update the end of the cloned list.
+ if (newLast === null) newFirst = newLast = capturedUpdate;
+ else {
+ newLast.next = capturedUpdate;
+ newLast = capturedUpdate;
+ }
+ } else // There are no base updates.
+ newFirst = newLast = capturedUpdate;
+ queue = {
+ baseState: currentQueue.baseState,
+ firstBaseUpdate: newFirst,
+ lastBaseUpdate: newLast,
+ shared: currentQueue.shared,
+ effects: currentQueue.effects
+ };
+ workInProgress.updateQueue = queue;
+ return;
+ }
+ } // Append the update to the end of the list.
+ var lastBaseUpdate = queue.lastBaseUpdate;
+ if (lastBaseUpdate === null) queue.firstBaseUpdate = capturedUpdate;
+ else lastBaseUpdate.next = capturedUpdate;
+ queue.lastBaseUpdate = capturedUpdate;
+ }
+ function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
+ switch(update.tag){
+ case ReplaceState:
+ var payload = update.payload;
+ if (typeof payload === "function") {
+ enterDisallowedContextReadInDEV();
+ var nextState = payload.call(instance, prevState, nextProps);
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ payload.call(instance, prevState, nextProps);
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ exitDisallowedContextReadInDEV();
+ return nextState;
+ } // State object
+ return payload;
+ case CaptureUpdate:
+ workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
+ // Intentional fallthrough
+ case UpdateState:
+ var _payload = update.payload;
+ var partialState;
+ if (typeof _payload === "function") {
+ enterDisallowedContextReadInDEV();
+ partialState = _payload.call(instance, prevState, nextProps);
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ _payload.call(instance, prevState, nextProps);
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ exitDisallowedContextReadInDEV();
+ } else // Partial state object
+ partialState = _payload;
+ if (partialState === null || partialState === undefined) // Null and undefined are treated as no-ops.
+ return prevState;
+ // Merge the partial state and the previous state.
+ return assign({}, prevState, partialState);
+ case ForceUpdate:
+ hasForceUpdate = true;
+ return prevState;
+ }
+ return prevState;
+ }
+ function processUpdateQueue(workInProgress, props, instance, renderLanes) {
+ // This is always non-null on a ClassComponent or HostRoot
+ var queue = workInProgress.updateQueue;
+ hasForceUpdate = false;
+ currentlyProcessingQueue = queue.shared;
+ var firstBaseUpdate = queue.firstBaseUpdate;
+ var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
+ var pendingQueue = queue.shared.pending;
+ if (pendingQueue !== null) {
+ queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
+ // and last so that it's non-circular.
+ var lastPendingUpdate = pendingQueue;
+ var firstPendingUpdate = lastPendingUpdate.next;
+ lastPendingUpdate.next = null; // Append pending updates to base queue
+ if (lastBaseUpdate === null) firstBaseUpdate = firstPendingUpdate;
+ else lastBaseUpdate.next = firstPendingUpdate;
+ lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
+ // we need to transfer the updates to that queue, too. Because the base
+ // queue is a singly-linked list with no cycles, we can append to both
+ // lists and take advantage of structural sharing.
+ // TODO: Pass `current` as argument
+ var current = workInProgress.alternate;
+ if (current !== null) {
+ // This is always non-null on a ClassComponent or HostRoot
+ var currentQueue = current.updateQueue;
+ var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
+ if (currentLastBaseUpdate !== lastBaseUpdate) {
+ if (currentLastBaseUpdate === null) currentQueue.firstBaseUpdate = firstPendingUpdate;
+ else currentLastBaseUpdate.next = firstPendingUpdate;
+ currentQueue.lastBaseUpdate = lastPendingUpdate;
+ }
+ }
+ } // These values may change as we process the queue.
+ if (firstBaseUpdate !== null) {
+ // Iterate through the list of updates to compute the result.
+ var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
+ // from the original lanes.
+ var newLanes = NoLanes;
+ var newBaseState = null;
+ var newFirstBaseUpdate = null;
+ var newLastBaseUpdate = null;
+ var update = firstBaseUpdate;
+ do {
+ var updateLane = update.lane;
+ var updateEventTime = update.eventTime;
+ if (!isSubsetOfLanes(renderLanes, updateLane)) {
+ // Priority is insufficient. Skip this update. If this is the first
+ // skipped update, the previous update/state is the new base
+ // update/state.
+ var clone = {
+ eventTime: updateEventTime,
+ lane: updateLane,
+ tag: update.tag,
+ payload: update.payload,
+ callback: update.callback,
+ next: null
+ };
+ if (newLastBaseUpdate === null) {
+ newFirstBaseUpdate = newLastBaseUpdate = clone;
+ newBaseState = newState;
+ } else newLastBaseUpdate = newLastBaseUpdate.next = clone;
+ // Update the remaining priority in the queue.
+ newLanes = mergeLanes(newLanes, updateLane);
+ } else {
+ // This update does have sufficient priority.
+ if (newLastBaseUpdate !== null) {
+ var _clone = {
+ eventTime: updateEventTime,
+ // This update is going to be committed so we never want uncommit
+ // it. Using NoLane works because 0 is a subset of all bitmasks, so
+ // this will never be skipped by the check above.
+ lane: NoLane,
+ tag: update.tag,
+ payload: update.payload,
+ callback: update.callback,
+ next: null
+ };
+ newLastBaseUpdate = newLastBaseUpdate.next = _clone;
+ } // Process this update.
+ newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
+ var callback = update.callback;
+ if (callback !== null && // If the update was already committed, we should not queue its
+ // callback again.
+ update.lane !== NoLane) {
+ workInProgress.flags |= Callback;
+ var effects = queue.effects;
+ if (effects === null) queue.effects = [
+ update
+ ];
+ else effects.push(update);
+ }
+ }
+ update = update.next;
+ if (update === null) {
+ pendingQueue = queue.shared.pending;
+ if (pendingQueue === null) break;
+ else {
+ // An update was scheduled from inside a reducer. Add the new
+ // pending updates to the end of the list and keep processing.
+ var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
+ // unravel them when transferring them to the base queue.
+ var _firstPendingUpdate = _lastPendingUpdate.next;
+ _lastPendingUpdate.next = null;
+ update = _firstPendingUpdate;
+ queue.lastBaseUpdate = _lastPendingUpdate;
+ queue.shared.pending = null;
+ }
+ }
+ }while (true);
+ if (newLastBaseUpdate === null) newBaseState = newState;
+ queue.baseState = newBaseState;
+ queue.firstBaseUpdate = newFirstBaseUpdate;
+ queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to
+ // process them during this render, but we do need to track which lanes
+ // are remaining.
+ var lastInterleaved = queue.shared.interleaved;
+ if (lastInterleaved !== null) {
+ var interleaved = lastInterleaved;
+ do {
+ newLanes = mergeLanes(newLanes, interleaved.lane);
+ interleaved = interleaved.next;
+ }while (interleaved !== lastInterleaved);
+ } else if (firstBaseUpdate === null) // `queue.lanes` is used for entangling transitions. We can set it back to
+ // zero once the queue is empty.
+ queue.shared.lanes = NoLanes;
+ // Set the remaining expiration time to be whatever is remaining in the queue.
+ // This should be fine because the only two other things that contribute to
+ // expiration time are props and context. We're already in the middle of the
+ // begin phase by the time we start processing the queue, so we've already
+ // dealt with the props. Context in components that specify
+ // shouldComponentUpdate is tricky; but we'll have to account for
+ // that regardless.
+ markSkippedUpdateLanes(newLanes);
+ workInProgress.lanes = newLanes;
+ workInProgress.memoizedState = newState;
+ }
+ currentlyProcessingQueue = null;
+ }
+ function callCallback(callback, context) {
+ if (typeof callback !== "function") throw new Error("Invalid argument passed as callback. Expected a function. Instead " + ("received: " + callback));
+ callback.call(context);
+ }
+ function resetHasForceUpdateBeforeProcessing() {
+ hasForceUpdate = false;
+ }
+ function checkHasForceUpdateAfterProcessing() {
+ return hasForceUpdate;
+ }
+ function commitUpdateQueue(finishedWork, finishedQueue, instance) {
+ // Commit the effects
+ var effects = finishedQueue.effects;
+ finishedQueue.effects = null;
+ if (effects !== null) for(var i = 0; i < effects.length; i++){
+ var effect = effects[i];
+ var callback = effect.callback;
+ if (callback !== null) {
+ effect.callback = null;
+ callCallback(callback, instance);
+ }
+ }
+ }
+ var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default.
+ // We'll use it to determine whether we need to initialize legacy refs.
+ var emptyRefsObject = new React.Component().refs;
+ var didWarnAboutStateAssignmentForComponent;
+ var didWarnAboutUninitializedState;
+ var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
+ var didWarnAboutLegacyLifecyclesAndDerivedState;
+ var didWarnAboutUndefinedDerivedState;
+ var warnOnUndefinedDerivedState;
+ var warnOnInvalidCallback;
+ var didWarnAboutDirectlyAssigningPropsToState;
+ var didWarnAboutContextTypeAndContextTypes;
+ var didWarnAboutInvalidateContextType;
+ didWarnAboutStateAssignmentForComponent = new Set();
+ didWarnAboutUninitializedState = new Set();
+ didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
+ didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
+ didWarnAboutDirectlyAssigningPropsToState = new Set();
+ didWarnAboutUndefinedDerivedState = new Set();
+ didWarnAboutContextTypeAndContextTypes = new Set();
+ didWarnAboutInvalidateContextType = new Set();
+ var didWarnOnInvalidCallback = new Set();
+ warnOnInvalidCallback = function(callback, callerName) {
+ if (callback === null || typeof callback === "function") return;
+ var key = callerName + "_" + callback;
+ if (!didWarnOnInvalidCallback.has(key)) {
+ didWarnOnInvalidCallback.add(key);
+ error("%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callerName, callback);
+ }
+ };
+ warnOnUndefinedDerivedState = function(type, partialState) {
+ if (partialState === undefined) {
+ var componentName = getComponentNameFromType(type) || "Component";
+ if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
+ didWarnAboutUndefinedDerivedState.add(componentName);
+ error("%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. You have returned undefined.", componentName);
+ }
+ }
+ }; // This is so gross but it's at least non-critical and can be removed if
+ // it causes problems. This is meant to give a nicer error message for
+ // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
+ // ...)) which otherwise throws a "_processChildContext is not a function"
+ // exception.
+ Object.defineProperty(fakeInternalInstance, "_processChildContext", {
+ enumerable: false,
+ value: function() {
+ throw new Error("_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).");
+ }
+ });
+ Object.freeze(fakeInternalInstance);
+ function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
+ var prevState = workInProgress.memoizedState;
+ var partialState = getDerivedStateFromProps(nextProps, prevState);
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ // Invoke the function an extra time to help detect side-effects.
+ partialState = getDerivedStateFromProps(nextProps, prevState);
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ warnOnUndefinedDerivedState(ctor, partialState);
+ var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
+ workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
+ // base state.
+ if (workInProgress.lanes === NoLanes) {
+ // Queue is always non-null for classes
+ var updateQueue = workInProgress.updateQueue;
+ updateQueue.baseState = memoizedState;
+ }
+ }
+ var classComponentUpdater = {
+ isMounted: isMounted,
+ enqueueSetState: function(inst, payload, callback) {
+ var fiber = get(inst);
+ var eventTime = requestEventTime();
+ var lane = requestUpdateLane(fiber);
+ var update = createUpdate(eventTime, lane);
+ update.payload = payload;
+ if (callback !== undefined && callback !== null) {
+ warnOnInvalidCallback(callback, "setState");
+ update.callback = callback;
+ }
+ var root = enqueueUpdate(fiber, update, lane);
+ if (root !== null) {
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ entangleTransitions(root, fiber, lane);
+ }
+ markStateUpdateScheduled(fiber, lane);
+ },
+ enqueueReplaceState: function(inst, payload, callback) {
+ var fiber = get(inst);
+ var eventTime = requestEventTime();
+ var lane = requestUpdateLane(fiber);
+ var update = createUpdate(eventTime, lane);
+ update.tag = ReplaceState;
+ update.payload = payload;
+ if (callback !== undefined && callback !== null) {
+ warnOnInvalidCallback(callback, "replaceState");
+ update.callback = callback;
+ }
+ var root = enqueueUpdate(fiber, update, lane);
+ if (root !== null) {
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ entangleTransitions(root, fiber, lane);
+ }
+ markStateUpdateScheduled(fiber, lane);
+ },
+ enqueueForceUpdate: function(inst, callback) {
+ var fiber = get(inst);
+ var eventTime = requestEventTime();
+ var lane = requestUpdateLane(fiber);
+ var update = createUpdate(eventTime, lane);
+ update.tag = ForceUpdate;
+ if (callback !== undefined && callback !== null) {
+ warnOnInvalidCallback(callback, "forceUpdate");
+ update.callback = callback;
+ }
+ var root = enqueueUpdate(fiber, update, lane);
+ if (root !== null) {
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ entangleTransitions(root, fiber, lane);
+ }
+ markForceUpdateScheduled(fiber, lane);
+ }
+ };
+ function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
+ var instance = workInProgress.stateNode;
+ if (typeof instance.shouldComponentUpdate === "function") {
+ var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ // Invoke the function an extra time to help detect side-effects.
+ shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ if (shouldUpdate === undefined) error("%s.shouldComponentUpdate(): Returned undefined instead of a boolean value. Make sure to return true or false.", getComponentNameFromType(ctor) || "Component");
+ return shouldUpdate;
+ }
+ if (ctor.prototype && ctor.prototype.isPureReactComponent) return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
+ return true;
+ }
+ function checkClassInstance(workInProgress, ctor, newProps) {
+ var instance = workInProgress.stateNode;
+ var name = getComponentNameFromType(ctor) || "Component";
+ var renderPresent = instance.render;
+ if (!renderPresent) {
+ if (ctor.prototype && typeof ctor.prototype.render === "function") error("%s(...): No `render` method found on the returned component instance: did you accidentally return an object from the constructor?", name);
+ else error("%s(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.", name);
+ }
+ if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) error("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?", name);
+ if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) error("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.", name);
+ if (instance.propTypes) error("propTypes was defined as an instance property on %s. Use a static property to define propTypes instead.", name);
+ if (instance.contextType) error("contextType was defined as an instance property on %s. Use a static property to define contextType instead.", name);
+ if (instance.contextTypes) error("contextTypes was defined as an instance property on %s. Use a static property to define contextTypes instead.", name);
+ if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
+ didWarnAboutContextTypeAndContextTypes.add(ctor);
+ error("%s declares both contextTypes and contextType static properties. The legacy contextTypes property will be ignored.", name);
+ }
+ if (typeof instance.componentShouldUpdate === "function") error("%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.", name);
+ if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined") error("%s has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.", getComponentNameFromType(ctor) || "A pure component");
+ if (typeof instance.componentDidUnmount === "function") error("%s has a method called componentDidUnmount(). But there is no such lifecycle method. Did you mean componentWillUnmount()?", name);
+ if (typeof instance.componentDidReceiveProps === "function") error("%s has a method called componentDidReceiveProps(). But there is no such lifecycle method. If you meant to update the state in response to changing props, use componentWillReceiveProps(). If you meant to fetch data or run side-effects or mutations after React has updated the UI, use componentDidUpdate().", name);
+ if (typeof instance.componentWillRecieveProps === "function") error("%s has a method called componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", name);
+ if (typeof instance.UNSAFE_componentWillRecieveProps === "function") error("%s has a method called UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", name);
+ var hasMutatedProps = instance.props !== newProps;
+ if (instance.props !== undefined && hasMutatedProps) error("%s(...): When calling super() in `%s`, make sure to pass up the same props that your component's constructor was passed.", name, name);
+ if (instance.defaultProps) error("Setting defaultProps as an instance property on %s is not supported and will be ignored. Instead, define defaultProps as a static property on %s.", name, name);
+ if (typeof instance.getSnapshotBeforeUpdate === "function" && typeof instance.componentDidUpdate !== "function" && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
+ didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
+ error("%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). This component defines getSnapshotBeforeUpdate() only.", getComponentNameFromType(ctor));
+ }
+ if (typeof instance.getDerivedStateFromProps === "function") error("%s: getDerivedStateFromProps() is defined as an instance method and will be ignored. Instead, declare it as a static method.", name);
+ if (typeof instance.getDerivedStateFromError === "function") error("%s: getDerivedStateFromError() is defined as an instance method and will be ignored. Instead, declare it as a static method.", name);
+ if (typeof ctor.getSnapshotBeforeUpdate === "function") error("%s: getSnapshotBeforeUpdate() is defined as a static method and will be ignored. Instead, declare it as an instance method.", name);
+ var _state = instance.state;
+ if (_state && (typeof _state !== "object" || isArray(_state))) error("%s.state: must be set to an object or null", name);
+ if (typeof instance.getChildContext === "function" && typeof ctor.childContextTypes !== "object") error("%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().", name);
+ }
+ function adoptClassInstance(workInProgress, instance) {
+ instance.updater = classComponentUpdater;
+ workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
+ set(instance, workInProgress);
+ instance._reactInternalInstance = fakeInternalInstance;
+ }
+ function constructClassInstance(workInProgress, ctor, props) {
+ var isLegacyContextConsumer = false;
+ var unmaskedContext = emptyContextObject;
+ var context = emptyContextObject;
+ var contextType = ctor.contextType;
+ if ("contextType" in ctor) {
+ var isValid = contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a
+ if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
+ didWarnAboutInvalidateContextType.add(ctor);
+ var addendum = "";
+ if (contextType === undefined) addendum = " However, it is set to undefined. This can be caused by a typo or by mixing up named and default imports. This can also happen due to a circular dependency, so try moving the createContext() call to a separate file.";
+ else if (typeof contextType !== "object") addendum = " However, it is set to a " + typeof contextType + ".";
+ else if (contextType.$$typeof === REACT_PROVIDER_TYPE) addendum = " Did you accidentally pass the Context.Provider instead?";
+ else if (contextType._context !== undefined) //
+ addendum = " Did you accidentally pass the Context.Consumer instead?";
+ else addendum = " However, it is set to an object with keys {" + Object.keys(contextType).join(", ") + "}.";
+ error("%s defines an invalid contextType. contextType should point to the Context object returned by React.createContext().%s", getComponentNameFromType(ctor) || "Component", addendum);
+ }
+ }
+ if (typeof contextType === "object" && contextType !== null) context = readContext(contextType);
+ else {
+ unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
+ var contextTypes = ctor.contextTypes;
+ isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
+ context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
+ }
+ var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ instance = new ctor(props, context); // eslint-disable-line no-new
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
+ adoptClassInstance(workInProgress, instance);
+ if (typeof ctor.getDerivedStateFromProps === "function" && state === null) {
+ var componentName = getComponentNameFromType(ctor) || "Component";
+ if (!didWarnAboutUninitializedState.has(componentName)) {
+ didWarnAboutUninitializedState.add(componentName);
+ error("`%s` uses `getDerivedStateFromProps` but its initial state is %s. This is not recommended. Instead, define the initial state by assigning an object to `this.state` in the constructor of `%s`. This ensures that `getDerivedStateFromProps` arguments have a consistent shape.", componentName, instance.state === null ? "null" : "undefined", componentName);
+ }
+ } // If new component APIs are defined, "unsafe" lifecycles won't be called.
+ // Warn about these lifecycles if they are present.
+ // Don't warn about react-lifecycles-compat polyfilled methods though.
+ if (typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function") {
+ var foundWillMountName = null;
+ var foundWillReceivePropsName = null;
+ var foundWillUpdateName = null;
+ if (typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true) foundWillMountName = "componentWillMount";
+ else if (typeof instance.UNSAFE_componentWillMount === "function") foundWillMountName = "UNSAFE_componentWillMount";
+ if (typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) foundWillReceivePropsName = "componentWillReceiveProps";
+ else if (typeof instance.UNSAFE_componentWillReceiveProps === "function") foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps";
+ if (typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true) foundWillUpdateName = "componentWillUpdate";
+ else if (typeof instance.UNSAFE_componentWillUpdate === "function") foundWillUpdateName = "UNSAFE_componentWillUpdate";
+ if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
+ var _componentName = getComponentNameFromType(ctor) || "Component";
+ var newApiName = typeof ctor.getDerivedStateFromProps === "function" ? "getDerivedStateFromProps()" : "getSnapshotBeforeUpdate()";
+ if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
+ didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
+ error("Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://reactjs.org/link/unsafe-component-lifecycles", _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : "", foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : "", foundWillUpdateName !== null ? "\n " + foundWillUpdateName : "");
+ }
+ }
+ }
+ // ReactFiberContext usually updates this cache but can't for newly-created instances.
+ if (isLegacyContextConsumer) cacheContext(workInProgress, unmaskedContext, context);
+ return instance;
+ }
+ function callComponentWillMount(workInProgress, instance) {
+ var oldState = instance.state;
+ if (typeof instance.componentWillMount === "function") instance.componentWillMount();
+ if (typeof instance.UNSAFE_componentWillMount === "function") instance.UNSAFE_componentWillMount();
+ if (oldState !== instance.state) {
+ error("%s.componentWillMount(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", getComponentNameFromFiber(workInProgress) || "Component");
+ classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
+ }
+ }
+ function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
+ var oldState = instance.state;
+ if (typeof instance.componentWillReceiveProps === "function") instance.componentWillReceiveProps(newProps, nextContext);
+ if (typeof instance.UNSAFE_componentWillReceiveProps === "function") instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
+ if (instance.state !== oldState) {
+ var componentName = getComponentNameFromFiber(workInProgress) || "Component";
+ if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
+ didWarnAboutStateAssignmentForComponent.add(componentName);
+ error("%s.componentWillReceiveProps(): Assigning directly to this.state is deprecated (except inside a component's constructor). Use setState instead.", componentName);
+ }
+ classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
+ }
+ } // Invokes the mount life-cycles on a previously never rendered instance.
+ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
+ checkClassInstance(workInProgress, ctor, newProps);
+ var instance = workInProgress.stateNode;
+ instance.props = newProps;
+ instance.state = workInProgress.memoizedState;
+ instance.refs = emptyRefsObject;
+ initializeUpdateQueue(workInProgress);
+ var contextType = ctor.contextType;
+ if (typeof contextType === "object" && contextType !== null) instance.context = readContext(contextType);
+ else {
+ var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
+ instance.context = getMaskedContext(workInProgress, unmaskedContext);
+ }
+ if (instance.state === newProps) {
+ var componentName = getComponentNameFromType(ctor) || "Component";
+ if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
+ didWarnAboutDirectlyAssigningPropsToState.add(componentName);
+ error("%s: It is not recommended to assign props directly to state because updates to props won't be reflected in state. In most cases, it is better to use props directly.", componentName);
+ }
+ }
+ if (workInProgress.mode & StrictLegacyMode) ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
+ ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
+ instance.state = workInProgress.memoizedState;
+ var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
+ if (typeof getDerivedStateFromProps === "function") {
+ applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
+ instance.state = workInProgress.memoizedState;
+ } // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
+ if (typeof ctor.getDerivedStateFromProps !== "function" && typeof instance.getSnapshotBeforeUpdate !== "function" && (typeof instance.UNSAFE_componentWillMount === "function" || typeof instance.componentWillMount === "function")) {
+ callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
+ // process them now.
+ processUpdateQueue(workInProgress, newProps, instance, renderLanes);
+ instance.state = workInProgress.memoizedState;
+ }
+ if (typeof instance.componentDidMount === "function") {
+ var fiberFlags = Update;
+ fiberFlags |= LayoutStatic;
+ if ((workInProgress.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev;
+ workInProgress.flags |= fiberFlags;
+ }
+ }
+ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
+ var instance = workInProgress.stateNode;
+ var oldProps = workInProgress.memoizedProps;
+ instance.props = oldProps;
+ var oldContext = instance.context;
+ var contextType = ctor.contextType;
+ var nextContext = emptyContextObject;
+ if (typeof contextType === "object" && contextType !== null) nextContext = readContext(contextType);
+ else {
+ var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
+ nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
+ }
+ var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
+ var hasNewLifecycles = typeof getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what
+ // ever the previously attempted to render - not the "current". However,
+ // during componentDidUpdate we pass the "current" props.
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
+ if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || typeof instance.componentWillReceiveProps === "function")) {
+ if (oldProps !== newProps || oldContext !== nextContext) callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
+ }
+ resetHasForceUpdateBeforeProcessing();
+ var oldState = workInProgress.memoizedState;
+ var newState = instance.state = oldState;
+ processUpdateQueue(workInProgress, newProps, instance, renderLanes);
+ newState = workInProgress.memoizedState;
+ if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
+ // If an update was already in progress, we should schedule an Update
+ // effect even though we're bailing out, so that cWU/cDU are called.
+ if (typeof instance.componentDidMount === "function") {
+ var fiberFlags = Update;
+ fiberFlags |= LayoutStatic;
+ if ((workInProgress.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev;
+ workInProgress.flags |= fiberFlags;
+ }
+ return false;
+ }
+ if (typeof getDerivedStateFromProps === "function") {
+ applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
+ newState = workInProgress.memoizedState;
+ }
+ var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
+ if (shouldUpdate) {
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
+ if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === "function" || typeof instance.componentWillMount === "function")) {
+ if (typeof instance.componentWillMount === "function") instance.componentWillMount();
+ if (typeof instance.UNSAFE_componentWillMount === "function") instance.UNSAFE_componentWillMount();
+ }
+ if (typeof instance.componentDidMount === "function") {
+ var _fiberFlags = Update;
+ _fiberFlags |= LayoutStatic;
+ if ((workInProgress.mode & StrictEffectsMode) !== NoMode) _fiberFlags |= MountLayoutDev;
+ workInProgress.flags |= _fiberFlags;
+ }
+ } else {
+ // If an update was already in progress, we should schedule an Update
+ // effect even though we're bailing out, so that cWU/cDU are called.
+ if (typeof instance.componentDidMount === "function") {
+ var _fiberFlags2 = Update;
+ _fiberFlags2 |= LayoutStatic;
+ if ((workInProgress.mode & StrictEffectsMode) !== NoMode) _fiberFlags2 |= MountLayoutDev;
+ workInProgress.flags |= _fiberFlags2;
+ } // If shouldComponentUpdate returned false, we should still update the
+ // memoized state to indicate that this work can be reused.
+ workInProgress.memoizedProps = newProps;
+ workInProgress.memoizedState = newState;
+ } // Update the existing instance's state, props, and context pointers even
+ // if shouldComponentUpdate returns false.
+ instance.props = newProps;
+ instance.state = newState;
+ instance.context = nextContext;
+ return shouldUpdate;
+ } // Invokes the update life-cycles and returns false if it shouldn't rerender.
+ function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
+ var instance = workInProgress.stateNode;
+ cloneUpdateQueue(current, workInProgress);
+ var unresolvedOldProps = workInProgress.memoizedProps;
+ var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
+ instance.props = oldProps;
+ var unresolvedNewProps = workInProgress.pendingProps;
+ var oldContext = instance.context;
+ var contextType = ctor.contextType;
+ var nextContext = emptyContextObject;
+ if (typeof contextType === "object" && contextType !== null) nextContext = readContext(contextType);
+ else {
+ var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
+ nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
+ }
+ var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
+ var hasNewLifecycles = typeof getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what
+ // ever the previously attempted to render - not the "current". However,
+ // during componentDidUpdate we pass the "current" props.
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
+ if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || typeof instance.componentWillReceiveProps === "function")) {
+ if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
+ }
+ resetHasForceUpdateBeforeProcessing();
+ var oldState = workInProgress.memoizedState;
+ var newState = instance.state = oldState;
+ processUpdateQueue(workInProgress, newProps, instance, renderLanes);
+ newState = workInProgress.memoizedState;
+ if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !enableLazyContextPropagation) {
+ // If an update was already in progress, we should schedule an Update
+ // effect even though we're bailing out, so that cWU/cDU are called.
+ if (typeof instance.componentDidUpdate === "function") {
+ if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Update;
+ }
+ if (typeof instance.getSnapshotBeforeUpdate === "function") {
+ if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Snapshot;
+ }
+ return false;
+ }
+ if (typeof getDerivedStateFromProps === "function") {
+ applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
+ newState = workInProgress.memoizedState;
+ }
+ var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice,
+ // both before and after `shouldComponentUpdate` has been called. Not ideal,
+ // but I'm loath to refactor this function. This only happens for memoized
+ // components so it's not that common.
+ enableLazyContextPropagation;
+ if (shouldUpdate) {
+ // In order to support react-lifecycles-compat polyfilled components,
+ // Unsafe lifecycles should not be invoked for components using the new APIs.
+ if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === "function" || typeof instance.componentWillUpdate === "function")) {
+ if (typeof instance.componentWillUpdate === "function") instance.componentWillUpdate(newProps, newState, nextContext);
+ if (typeof instance.UNSAFE_componentWillUpdate === "function") instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
+ }
+ if (typeof instance.componentDidUpdate === "function") workInProgress.flags |= Update;
+ if (typeof instance.getSnapshotBeforeUpdate === "function") workInProgress.flags |= Snapshot;
+ } else {
+ // If an update was already in progress, we should schedule an Update
+ // effect even though we're bailing out, so that cWU/cDU are called.
+ if (typeof instance.componentDidUpdate === "function") {
+ if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Update;
+ }
+ if (typeof instance.getSnapshotBeforeUpdate === "function") {
+ if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) workInProgress.flags |= Snapshot;
+ } // If shouldComponentUpdate returned false, we should still update the
+ // memoized props/state to indicate that this work can be reused.
+ workInProgress.memoizedProps = newProps;
+ workInProgress.memoizedState = newState;
+ } // Update the existing instance's state, props, and context pointers even
+ // if shouldComponentUpdate returns false.
+ instance.props = newProps;
+ instance.state = newState;
+ instance.context = nextContext;
+ return shouldUpdate;
+ }
+ var didWarnAboutMaps;
+ var didWarnAboutGenerators;
+ var didWarnAboutStringRefs;
+ var ownerHasKeyUseWarning;
+ var ownerHasFunctionTypeWarning;
+ var warnForMissingKey = function(child, returnFiber) {};
+ didWarnAboutMaps = false;
+ didWarnAboutGenerators = false;
+ didWarnAboutStringRefs = {};
+ /**
+ * 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.
+ */ ownerHasKeyUseWarning = {};
+ ownerHasFunctionTypeWarning = {};
+ warnForMissingKey = function(child, returnFiber) {
+ if (child === null || typeof child !== "object") return;
+ if (!child._store || child._store.validated || child.key != null) return;
+ if (typeof child._store !== "object") throw new Error("React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.");
+ child._store.validated = true;
+ var componentName = getComponentNameFromFiber(returnFiber) || "Component";
+ if (ownerHasKeyUseWarning[componentName]) return;
+ ownerHasKeyUseWarning[componentName] = true;
+ error('Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.');
+ };
+ function coerceRef(returnFiber, current, element) {
+ var mixedRef = element.ref;
+ if (mixedRef !== null && typeof mixedRef !== "function" && typeof mixedRef !== "object") {
+ // TODO: Clean this up once we turn on the string ref warning for
+ // everyone, because the strict mode case will no longer be relevant
+ if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
+ // because these cannot be automatically converted to an arrow function
+ // using a codemod. Therefore, we don't have to warn about string refs again.
+ !(element._owner && element._self && element._owner.stateNode !== element._self)) {
+ var componentName = getComponentNameFromFiber(returnFiber) || "Component";
+ if (!didWarnAboutStringRefs[componentName]) {
+ error('A string ref, "%s", has been found within a strict mode tree. String refs are a source of potential bugs and should be avoided. We recommend using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', mixedRef);
+ didWarnAboutStringRefs[componentName] = true;
+ }
+ }
+ if (element._owner) {
+ var owner = element._owner;
+ var inst;
+ if (owner) {
+ var ownerFiber = owner;
+ if (ownerFiber.tag !== ClassComponent) throw new Error("Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref");
+ inst = ownerFiber.stateNode;
+ }
+ if (!inst) throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + "bug in React. Please file an issue.");
+ // Assigning this to a const so Flow knows it won't change in the closure
+ var resolvedInst = inst;
+ checkPropStringCoercion(mixedRef, "ref");
+ var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref
+ if (current !== null && current.ref !== null && typeof current.ref === "function" && current.ref._stringRef === stringRef) return current.ref;
+ var ref = function(value) {
+ var refs = resolvedInst.refs;
+ if (refs === emptyRefsObject) // This is a lazy pooled frozen object, so we need to initialize.
+ refs = resolvedInst.refs = {};
+ if (value === null) delete refs[stringRef];
+ else refs[stringRef] = value;
+ };
+ ref._stringRef = stringRef;
+ return ref;
+ } else {
+ if (typeof mixedRef !== "string") throw new Error("Expected ref to be a function, a string, an object returned by React.createRef(), or null.");
+ if (!element._owner) throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of" + " the following reasons:\n" + "1. You may be adding a ref to a function component\n" + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + "3. You have multiple copies of React loaded\n" + "See https://reactjs.org/link/refs-must-have-owner for more information.");
+ }
+ }
+ return mixedRef;
+ }
+ function throwOnInvalidObjectType(returnFiber, newChild) {
+ var childString = Object.prototype.toString.call(newChild);
+ throw new Error("Objects are not valid as a React child (found: " + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" : childString) + "). " + "If you meant to render a collection of children, use an array " + "instead.");
+ }
+ function warnOnFunctionType(returnFiber) {
+ var componentName = getComponentNameFromFiber(returnFiber) || "Component";
+ if (ownerHasFunctionTypeWarning[componentName]) return;
+ ownerHasFunctionTypeWarning[componentName] = true;
+ error("Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.");
+ }
+ function resolveLazy(lazyType) {
+ var payload = lazyType._payload;
+ var init = lazyType._init;
+ return init(payload);
+ } // This wrapper function exists because I expect to clone the code in each path
+ // to be able to optimize each path individually by branching early. This needs
+ // a compiler or we can do it manually. Helpers that don't need this branching
+ // live outside of this function.
+ function ChildReconciler(shouldTrackSideEffects) {
+ function deleteChild(returnFiber, childToDelete) {
+ if (!shouldTrackSideEffects) // Noop.
+ return;
+ var deletions = returnFiber.deletions;
+ if (deletions === null) {
+ returnFiber.deletions = [
+ childToDelete
+ ];
+ returnFiber.flags |= ChildDeletion;
+ } else deletions.push(childToDelete);
+ }
+ function deleteRemainingChildren(returnFiber, currentFirstChild) {
+ if (!shouldTrackSideEffects) // Noop.
+ return null;
+ // TODO: For the shouldClone case, this could be micro-optimized a bit by
+ // assuming that after the first child we've already added everything.
+ var childToDelete = currentFirstChild;
+ while(childToDelete !== null){
+ deleteChild(returnFiber, childToDelete);
+ childToDelete = childToDelete.sibling;
+ }
+ return null;
+ }
+ function mapRemainingChildren(returnFiber, currentFirstChild) {
+ // Add the remaining children to a temporary map so that we can find them by
+ // keys quickly. Implicit (null) keys get added to this set with their index
+ // instead.
+ var existingChildren = new Map();
+ var existingChild = currentFirstChild;
+ while(existingChild !== null){
+ if (existingChild.key !== null) existingChildren.set(existingChild.key, existingChild);
+ else existingChildren.set(existingChild.index, existingChild);
+ existingChild = existingChild.sibling;
+ }
+ return existingChildren;
+ }
+ function useFiber(fiber, pendingProps) {
+ // We currently set sibling to null and index to 0 here because it is easy
+ // to forget to do before returning it. E.g. for the single child case.
+ var clone = createWorkInProgress(fiber, pendingProps);
+ clone.index = 0;
+ clone.sibling = null;
+ return clone;
+ }
+ function placeChild(newFiber, lastPlacedIndex, newIndex) {
+ newFiber.index = newIndex;
+ if (!shouldTrackSideEffects) {
+ // During hydration, the useId algorithm needs to know which fibers are
+ // part of a list of children (arrays, iterators).
+ newFiber.flags |= Forked;
+ return lastPlacedIndex;
+ }
+ var current = newFiber.alternate;
+ if (current !== null) {
+ var oldIndex = current.index;
+ if (oldIndex < lastPlacedIndex) {
+ // This is a move.
+ newFiber.flags |= Placement;
+ return lastPlacedIndex;
+ } else // This item can stay in place.
+ return oldIndex;
+ } else {
+ // This is an insertion.
+ newFiber.flags |= Placement;
+ return lastPlacedIndex;
+ }
+ }
+ function placeSingleChild(newFiber) {
+ // This is simpler for the single child case. We only need to do a
+ // placement for inserting new children.
+ if (shouldTrackSideEffects && newFiber.alternate === null) newFiber.flags |= Placement;
+ return newFiber;
+ }
+ function updateTextNode(returnFiber, current, textContent, lanes) {
+ if (current === null || current.tag !== HostText) {
+ // Insert
+ var created = createFiberFromText(textContent, returnFiber.mode, lanes);
+ created.return = returnFiber;
+ return created;
+ } else {
+ // Update
+ var existing = useFiber(current, textContent);
+ existing.return = returnFiber;
+ return existing;
+ }
+ }
+ function updateElement(returnFiber, current, element, lanes) {
+ var elementType = element.type;
+ if (elementType === REACT_FRAGMENT_TYPE) return updateFragment(returnFiber, current, element.props.children, lanes, element.key);
+ if (current !== null) {
+ if (current.elementType === elementType || isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type.
+ // We need to do this after the Hot Reloading check above,
+ // because hot reloading has different semantics than prod because
+ // it doesn't resuspend. So we can't let the call below suspend.
+ typeof elementType === "object" && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) {
+ // Move based on index
+ var existing = useFiber(current, element.props);
+ existing.ref = coerceRef(returnFiber, current, element);
+ existing.return = returnFiber;
+ existing._debugSource = element._source;
+ existing._debugOwner = element._owner;
+ return existing;
+ }
+ } // Insert
+ var created = createFiberFromElement(element, returnFiber.mode, lanes);
+ created.ref = coerceRef(returnFiber, current, element);
+ created.return = returnFiber;
+ return created;
+ }
+ function updatePortal(returnFiber, current, portal, lanes) {
+ if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
+ // Insert
+ var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
+ created.return = returnFiber;
+ return created;
+ } else {
+ // Update
+ var existing = useFiber(current, portal.children || []);
+ existing.return = returnFiber;
+ return existing;
+ }
+ }
+ function updateFragment(returnFiber, current, fragment, lanes, key) {
+ if (current === null || current.tag !== Fragment) {
+ // Insert
+ var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
+ created.return = returnFiber;
+ return created;
+ } else {
+ // Update
+ var existing = useFiber(current, fragment);
+ existing.return = returnFiber;
+ return existing;
+ }
+ }
+ function createChild(returnFiber, newChild, lanes) {
+ if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
+ // Text nodes don't have keys. If the previous node is implicitly keyed
+ // we can continue to replace it without aborting even if it is not a text
+ // node.
+ var created = createFiberFromText("" + newChild, returnFiber.mode, lanes);
+ created.return = returnFiber;
+ return created;
+ }
+ if (typeof newChild === "object" && newChild !== null) {
+ switch(newChild.$$typeof){
+ case REACT_ELEMENT_TYPE:
+ var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
+ _created.ref = coerceRef(returnFiber, null, newChild);
+ _created.return = returnFiber;
+ return _created;
+ case REACT_PORTAL_TYPE:
+ var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
+ _created2.return = returnFiber;
+ return _created2;
+ case REACT_LAZY_TYPE:
+ var payload = newChild._payload;
+ var init = newChild._init;
+ return createChild(returnFiber, init(payload), lanes);
+ }
+ if (isArray(newChild) || getIteratorFn(newChild)) {
+ var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
+ _created3.return = returnFiber;
+ return _created3;
+ }
+ throwOnInvalidObjectType(returnFiber, newChild);
+ }
+ if (typeof newChild === "function") warnOnFunctionType(returnFiber);
+ return null;
+ }
+ function updateSlot(returnFiber, oldFiber, newChild, lanes) {
+ // Update the fiber if the keys match, otherwise return null.
+ var key = oldFiber !== null ? oldFiber.key : null;
+ if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
+ // Text nodes don't have keys. If the previous node is implicitly keyed
+ // we can continue to replace it without aborting even if it is not a text
+ // node.
+ if (key !== null) return null;
+ return updateTextNode(returnFiber, oldFiber, "" + newChild, lanes);
+ }
+ if (typeof newChild === "object" && newChild !== null) {
+ switch(newChild.$$typeof){
+ case REACT_ELEMENT_TYPE:
+ if (newChild.key === key) return updateElement(returnFiber, oldFiber, newChild, lanes);
+ else return null;
+ case REACT_PORTAL_TYPE:
+ if (newChild.key === key) return updatePortal(returnFiber, oldFiber, newChild, lanes);
+ else return null;
+ case REACT_LAZY_TYPE:
+ var payload = newChild._payload;
+ var init = newChild._init;
+ return updateSlot(returnFiber, oldFiber, init(payload), lanes);
+ }
+ if (isArray(newChild) || getIteratorFn(newChild)) {
+ if (key !== null) return null;
+ return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
+ }
+ throwOnInvalidObjectType(returnFiber, newChild);
+ }
+ if (typeof newChild === "function") warnOnFunctionType(returnFiber);
+ return null;
+ }
+ function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
+ if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") {
+ // Text nodes don't have keys, so we neither have to check the old nor
+ // new node for the key. If both are text nodes, they match.
+ var matchedFiber = existingChildren.get(newIdx) || null;
+ return updateTextNode(returnFiber, matchedFiber, "" + newChild, lanes);
+ }
+ if (typeof newChild === "object" && newChild !== null) {
+ switch(newChild.$$typeof){
+ case REACT_ELEMENT_TYPE:
+ var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
+ return updateElement(returnFiber, _matchedFiber, newChild, lanes);
+ case REACT_PORTAL_TYPE:
+ var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
+ return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
+ case REACT_LAZY_TYPE:
+ var payload = newChild._payload;
+ var init = newChild._init;
+ return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes);
+ }
+ if (isArray(newChild) || getIteratorFn(newChild)) {
+ var _matchedFiber3 = existingChildren.get(newIdx) || null;
+ return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
+ }
+ throwOnInvalidObjectType(returnFiber, newChild);
+ }
+ if (typeof newChild === "function") warnOnFunctionType(returnFiber);
+ return null;
+ }
+ /**
+ * Warns if there is a duplicate or missing key
+ */ function warnOnInvalidKey(child, knownKeys, returnFiber) {
+ if (typeof child !== "object" || child === null) return knownKeys;
+ switch(child.$$typeof){
+ case REACT_ELEMENT_TYPE:
+ case REACT_PORTAL_TYPE:
+ warnForMissingKey(child, returnFiber);
+ var key = child.key;
+ if (typeof key !== "string") break;
+ if (knownKeys === null) {
+ knownKeys = new Set();
+ knownKeys.add(key);
+ break;
+ }
+ if (!knownKeys.has(key)) {
+ knownKeys.add(key);
+ break;
+ }
+ error("Encountered two children with the same key, `%s`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted \u2014 the behavior is unsupported and could change in a future version.", key);
+ break;
+ case REACT_LAZY_TYPE:
+ var payload = child._payload;
+ var init = child._init;
+ warnOnInvalidKey(init(payload), knownKeys, returnFiber);
+ break;
+ }
+ return knownKeys;
+ }
+ function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
+ // First, validate keys.
+ var knownKeys = null;
+ for(var i = 0; i < newChildren.length; i++){
+ var child = newChildren[i];
+ knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
+ }
+ var resultingFirstChild = null;
+ var previousNewFiber = null;
+ var oldFiber = currentFirstChild;
+ var lastPlacedIndex = 0;
+ var newIdx = 0;
+ var nextOldFiber = null;
+ for(; oldFiber !== null && newIdx < newChildren.length; newIdx++){
+ if (oldFiber.index > newIdx) {
+ nextOldFiber = oldFiber;
+ oldFiber = null;
+ } else nextOldFiber = oldFiber.sibling;
+ var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
+ if (newFiber === null) {
+ // TODO: This breaks on empty slots like null children. That's
+ // unfortunate because it triggers the slow path all the time. We need
+ // a better way to communicate whether this was a miss or null,
+ // boolean, undefined, etc.
+ if (oldFiber === null) oldFiber = nextOldFiber;
+ break;
+ }
+ if (shouldTrackSideEffects) {
+ if (oldFiber && newFiber.alternate === null) // We matched the slot, but we didn't reuse the existing fiber, so we
+ // need to delete the existing child.
+ deleteChild(returnFiber, oldFiber);
+ }
+ lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
+ if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run.
+ resultingFirstChild = newFiber;
+ else // TODO: Defer siblings if we're not at the right index for this slot.
+ // I.e. if we had null values before, then we want to defer this
+ // for each null value. However, we also don't want to call updateSlot
+ // with the previous one.
+ previousNewFiber.sibling = newFiber;
+ previousNewFiber = newFiber;
+ oldFiber = nextOldFiber;
+ }
+ if (newIdx === newChildren.length) {
+ // We've reached the end of the new children. We can delete the rest.
+ deleteRemainingChildren(returnFiber, oldFiber);
+ if (getIsHydrating()) {
+ var numberOfForks = newIdx;
+ pushTreeFork(returnFiber, numberOfForks);
+ }
+ return resultingFirstChild;
+ }
+ if (oldFiber === null) {
+ // If we don't have any more existing children we can choose a fast path
+ // since the rest will all be insertions.
+ for(; newIdx < newChildren.length; newIdx++){
+ var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
+ if (_newFiber === null) continue;
+ lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
+ if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run.
+ resultingFirstChild = _newFiber;
+ else previousNewFiber.sibling = _newFiber;
+ previousNewFiber = _newFiber;
+ }
+ if (getIsHydrating()) {
+ var _numberOfForks = newIdx;
+ pushTreeFork(returnFiber, _numberOfForks);
+ }
+ return resultingFirstChild;
+ } // Add all children to a key map for quick lookups.
+ var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
+ for(; newIdx < newChildren.length; newIdx++){
+ var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
+ if (_newFiber2 !== null) {
+ if (shouldTrackSideEffects) {
+ if (_newFiber2.alternate !== null) // The new fiber is a work in progress, but if there exists a
+ // current, that means that we reused the fiber. We need to delete
+ // it from the child list so that we don't add it to the deletion
+ // list.
+ existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
+ }
+ lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
+ if (previousNewFiber === null) resultingFirstChild = _newFiber2;
+ else previousNewFiber.sibling = _newFiber2;
+ previousNewFiber = _newFiber2;
+ }
+ }
+ if (shouldTrackSideEffects) // Any existing children that weren't consumed above were deleted. We need
+ // to add them to the deletion list.
+ existingChildren.forEach(function(child) {
+ return deleteChild(returnFiber, child);
+ });
+ if (getIsHydrating()) {
+ var _numberOfForks2 = newIdx;
+ pushTreeFork(returnFiber, _numberOfForks2);
+ }
+ return resultingFirstChild;
+ }
+ function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
+ // This is the same implementation as reconcileChildrenArray(),
+ // but using the iterator instead.
+ var iteratorFn = getIteratorFn(newChildrenIterable);
+ if (typeof iteratorFn !== "function") throw new Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.");
+ // We don't support rendering Generators because it's a mutation.
+ // See https://github.com/facebook/react/issues/12995
+ if (typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag
+ newChildrenIterable[Symbol.toStringTag] === "Generator") {
+ if (!didWarnAboutGenerators) error("Using Generators as children is unsupported and will likely yield unexpected results because enumerating a generator mutates it. You may convert it to an array with `Array.from()` or the `[...spread]` operator before rendering. Keep in mind you might need to polyfill these features for older browsers.");
+ didWarnAboutGenerators = true;
+ } // Warn about using Maps as children
+ if (newChildrenIterable.entries === iteratorFn) {
+ if (!didWarnAboutMaps) error("Using Maps as children is not supported. Use an array of keyed ReactElements instead.");
+ didWarnAboutMaps = true;
+ } // First, validate keys.
+ // We'll get a different iterator later for the main pass.
+ var _newChildren = iteratorFn.call(newChildrenIterable);
+ if (_newChildren) {
+ var knownKeys = null;
+ var _step = _newChildren.next();
+ for(; !_step.done; _step = _newChildren.next()){
+ var child = _step.value;
+ knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
+ }
+ }
+ var newChildren = iteratorFn.call(newChildrenIterable);
+ if (newChildren == null) throw new Error("An iterable object provided no iterator.");
+ var resultingFirstChild = null;
+ var previousNewFiber = null;
+ var oldFiber = currentFirstChild;
+ var lastPlacedIndex = 0;
+ var newIdx = 0;
+ var nextOldFiber = null;
+ var step = newChildren.next();
+ for(; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()){
+ if (oldFiber.index > newIdx) {
+ nextOldFiber = oldFiber;
+ oldFiber = null;
+ } else nextOldFiber = oldFiber.sibling;
+ var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
+ if (newFiber === null) {
+ // TODO: This breaks on empty slots like null children. That's
+ // unfortunate because it triggers the slow path all the time. We need
+ // a better way to communicate whether this was a miss or null,
+ // boolean, undefined, etc.
+ if (oldFiber === null) oldFiber = nextOldFiber;
+ break;
+ }
+ if (shouldTrackSideEffects) {
+ if (oldFiber && newFiber.alternate === null) // We matched the slot, but we didn't reuse the existing fiber, so we
+ // need to delete the existing child.
+ deleteChild(returnFiber, oldFiber);
+ }
+ lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
+ if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run.
+ resultingFirstChild = newFiber;
+ else // TODO: Defer siblings if we're not at the right index for this slot.
+ // I.e. if we had null values before, then we want to defer this
+ // for each null value. However, we also don't want to call updateSlot
+ // with the previous one.
+ previousNewFiber.sibling = newFiber;
+ previousNewFiber = newFiber;
+ oldFiber = nextOldFiber;
+ }
+ if (step.done) {
+ // We've reached the end of the new children. We can delete the rest.
+ deleteRemainingChildren(returnFiber, oldFiber);
+ if (getIsHydrating()) {
+ var numberOfForks = newIdx;
+ pushTreeFork(returnFiber, numberOfForks);
+ }
+ return resultingFirstChild;
+ }
+ if (oldFiber === null) {
+ // If we don't have any more existing children we can choose a fast path
+ // since the rest will all be insertions.
+ for(; !step.done; newIdx++, step = newChildren.next()){
+ var _newFiber3 = createChild(returnFiber, step.value, lanes);
+ if (_newFiber3 === null) continue;
+ lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
+ if (previousNewFiber === null) // TODO: Move out of the loop. This only happens for the first run.
+ resultingFirstChild = _newFiber3;
+ else previousNewFiber.sibling = _newFiber3;
+ previousNewFiber = _newFiber3;
+ }
+ if (getIsHydrating()) {
+ var _numberOfForks3 = newIdx;
+ pushTreeFork(returnFiber, _numberOfForks3);
+ }
+ return resultingFirstChild;
+ } // Add all children to a key map for quick lookups.
+ var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
+ for(; !step.done; newIdx++, step = newChildren.next()){
+ var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
+ if (_newFiber4 !== null) {
+ if (shouldTrackSideEffects) {
+ if (_newFiber4.alternate !== null) // The new fiber is a work in progress, but if there exists a
+ // current, that means that we reused the fiber. We need to delete
+ // it from the child list so that we don't add it to the deletion
+ // list.
+ existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
+ }
+ lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
+ if (previousNewFiber === null) resultingFirstChild = _newFiber4;
+ else previousNewFiber.sibling = _newFiber4;
+ previousNewFiber = _newFiber4;
+ }
+ }
+ if (shouldTrackSideEffects) // Any existing children that weren't consumed above were deleted. We need
+ // to add them to the deletion list.
+ existingChildren.forEach(function(child) {
+ return deleteChild(returnFiber, child);
+ });
+ if (getIsHydrating()) {
+ var _numberOfForks4 = newIdx;
+ pushTreeFork(returnFiber, _numberOfForks4);
+ }
+ return resultingFirstChild;
+ }
+ function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
+ // There's no need to check for keys on text nodes since we don't have a
+ // way to define them.
+ if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
+ // We already have an existing node so let's just update it and delete
+ // the rest.
+ deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
+ var existing = useFiber(currentFirstChild, textContent);
+ existing.return = returnFiber;
+ return existing;
+ } // The existing first child is not a text node so we need to create one
+ // and delete the existing ones.
+ deleteRemainingChildren(returnFiber, currentFirstChild);
+ var created = createFiberFromText(textContent, returnFiber.mode, lanes);
+ created.return = returnFiber;
+ return created;
+ }
+ function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
+ var key = element.key;
+ var child = currentFirstChild;
+ while(child !== null){
+ // TODO: If key === null and child.key === null, then this only applies to
+ // the first item in the list.
+ if (child.key === key) {
+ var elementType = element.type;
+ if (elementType === REACT_FRAGMENT_TYPE) {
+ if (child.tag === Fragment) {
+ deleteRemainingChildren(returnFiber, child.sibling);
+ var existing = useFiber(child, element.props.children);
+ existing.return = returnFiber;
+ existing._debugSource = element._source;
+ existing._debugOwner = element._owner;
+ return existing;
+ }
+ } else if (child.elementType === elementType || isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type.
+ // We need to do this after the Hot Reloading check above,
+ // because hot reloading has different semantics than prod because
+ // it doesn't resuspend. So we can't let the call below suspend.
+ typeof elementType === "object" && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
+ deleteRemainingChildren(returnFiber, child.sibling);
+ var _existing = useFiber(child, element.props);
+ _existing.ref = coerceRef(returnFiber, child, element);
+ _existing.return = returnFiber;
+ _existing._debugSource = element._source;
+ _existing._debugOwner = element._owner;
+ return _existing;
+ }
+ // Didn't match.
+ deleteRemainingChildren(returnFiber, child);
+ break;
+ } else deleteChild(returnFiber, child);
+ child = child.sibling;
+ }
+ if (element.type === REACT_FRAGMENT_TYPE) {
+ var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
+ created.return = returnFiber;
+ return created;
+ } else {
+ var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
+ _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
+ _created4.return = returnFiber;
+ return _created4;
+ }
+ }
+ function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
+ var key = portal.key;
+ var child = currentFirstChild;
+ while(child !== null){
+ // TODO: If key === null and child.key === null, then this only applies to
+ // the first item in the list.
+ if (child.key === key) {
+ if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
+ deleteRemainingChildren(returnFiber, child.sibling);
+ var existing = useFiber(child, portal.children || []);
+ existing.return = returnFiber;
+ return existing;
+ } else {
+ deleteRemainingChildren(returnFiber, child);
+ break;
+ }
+ } else deleteChild(returnFiber, child);
+ child = child.sibling;
+ }
+ var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
+ created.return = returnFiber;
+ return created;
+ } // This API will tag the children with the side-effect of the reconciliation
+ // itself. They will be added to the side-effect list as we pass through the
+ // children and the parent.
+ function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
+ // This function is not recursive.
+ // If the top level item is an array, we treat it as a set of children,
+ // not as a fragment. Nested arrays on the other hand will be treated as
+ // fragment nodes. Recursion happens at the normal flow.
+ // Handle top level unkeyed fragments as if they were arrays.
+ // This leads to an ambiguity between <>{[...]}> and <>...>.
+ // We treat the ambiguous cases above the same.
+ var isUnkeyedTopLevelFragment = typeof newChild === "object" && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
+ if (isUnkeyedTopLevelFragment) newChild = newChild.props.children;
+ // Handle object types
+ if (typeof newChild === "object" && newChild !== null) {
+ switch(newChild.$$typeof){
+ case REACT_ELEMENT_TYPE:
+ return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
+ case REACT_PORTAL_TYPE:
+ return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
+ case REACT_LAZY_TYPE:
+ var payload = newChild._payload;
+ var init = newChild._init; // TODO: This function is supposed to be non-recursive.
+ return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes);
+ }
+ if (isArray(newChild)) return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
+ if (getIteratorFn(newChild)) return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
+ throwOnInvalidObjectType(returnFiber, newChild);
+ }
+ if (typeof newChild === "string" && newChild !== "" || typeof newChild === "number") return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, "" + newChild, lanes));
+ if (typeof newChild === "function") warnOnFunctionType(returnFiber);
+ return deleteRemainingChildren(returnFiber, currentFirstChild);
+ }
+ return reconcileChildFibers;
+ }
+ var reconcileChildFibers = ChildReconciler(true);
+ var mountChildFibers = ChildReconciler(false);
+ function cloneChildFibers(current, workInProgress) {
+ if (current !== null && workInProgress.child !== current.child) throw new Error("Resuming work not yet implemented.");
+ if (workInProgress.child === null) return;
+ var currentChild = workInProgress.child;
+ var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
+ workInProgress.child = newChild;
+ newChild.return = workInProgress;
+ while(currentChild.sibling !== null){
+ currentChild = currentChild.sibling;
+ newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
+ newChild.return = workInProgress;
+ }
+ newChild.sibling = null;
+ } // Reset a workInProgress child set to prepare it for a second pass.
+ function resetChildFibers(workInProgress, lanes) {
+ var child = workInProgress.child;
+ while(child !== null){
+ resetWorkInProgress(child, lanes);
+ child = child.sibling;
+ }
+ }
+ var NO_CONTEXT = {};
+ var contextStackCursor$1 = createCursor(NO_CONTEXT);
+ var contextFiberStackCursor = createCursor(NO_CONTEXT);
+ var rootInstanceStackCursor = createCursor(NO_CONTEXT);
+ function requiredContext(c) {
+ if (c === NO_CONTEXT) throw new Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.");
+ return c;
+ }
+ function getRootHostContainer() {
+ var rootInstance = requiredContext(rootInstanceStackCursor.current);
+ return rootInstance;
+ }
+ function pushHostContainer(fiber, nextRootInstance) {
+ // Push current root instance onto the stack;
+ // This allows us to reset root when portals are popped.
+ push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
+ // This enables us to pop only Fibers that provide unique contexts.
+ push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
+ // However, we can't just call getRootHostContext() and push it because
+ // we'd have a different number of entries on the stack depending on
+ // whether getRootHostContext() throws somewhere in renderer code or not.
+ // So we push an empty value first. This lets us safely unwind on errors.
+ push(contextStackCursor$1, NO_CONTEXT, fiber);
+ var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
+ pop(contextStackCursor$1, fiber);
+ push(contextStackCursor$1, nextRootContext, fiber);
+ }
+ function popHostContainer(fiber) {
+ pop(contextStackCursor$1, fiber);
+ pop(contextFiberStackCursor, fiber);
+ pop(rootInstanceStackCursor, fiber);
+ }
+ function getHostContext() {
+ var context = requiredContext(contextStackCursor$1.current);
+ return context;
+ }
+ function pushHostContext(fiber) {
+ var rootInstance = requiredContext(rootInstanceStackCursor.current);
+ var context = requiredContext(contextStackCursor$1.current);
+ var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
+ if (context === nextContext) return;
+ // Track the context and the Fiber that provided it.
+ // This enables us to pop only Fibers that provide unique contexts.
+ push(contextFiberStackCursor, fiber, fiber);
+ push(contextStackCursor$1, nextContext, fiber);
+ }
+ function popHostContext(fiber) {
+ // Do not pop unless this Fiber provided the current context.
+ // pushHostContext() only pushes Fibers that provide unique contexts.
+ if (contextFiberStackCursor.current !== fiber) return;
+ pop(contextStackCursor$1, fiber);
+ pop(contextFiberStackCursor, fiber);
+ }
+ var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
+ // inherited deeply down the subtree. The upper bits only affect
+ // this immediate suspense boundary and gets reset each new
+ // boundary or suspense list.
+ var SubtreeSuspenseContextMask = 1; // Subtree Flags:
+ // InvisibleParentSuspenseContext indicates that one of our parent Suspense
+ // boundaries is not currently showing visible main content.
+ // Either because it is already showing a fallback or is not mounted at all.
+ // We can use this to determine if it is desirable to trigger a fallback at
+ // the parent. If not, then we might need to trigger undesirable boundaries
+ // and/or suspend the commit to avoid hiding the parent content.
+ var InvisibleParentSuspenseContext = 1; // Shallow Flags:
+ // ForceSuspenseFallback can be used by SuspenseList to force newly added
+ // items into their fallback state during one of the render passes.
+ var ForceSuspenseFallback = 2;
+ var suspenseStackCursor = createCursor(DefaultSuspenseContext);
+ function hasSuspenseContext(parentContext, flag) {
+ return (parentContext & flag) !== 0;
+ }
+ function setDefaultShallowSuspenseContext(parentContext) {
+ return parentContext & SubtreeSuspenseContextMask;
+ }
+ function setShallowSuspenseContext(parentContext, shallowContext) {
+ return parentContext & SubtreeSuspenseContextMask | shallowContext;
+ }
+ function addSubtreeSuspenseContext(parentContext, subtreeContext) {
+ return parentContext | subtreeContext;
+ }
+ function pushSuspenseContext(fiber, newContext) {
+ push(suspenseStackCursor, newContext, fiber);
+ }
+ function popSuspenseContext(fiber) {
+ pop(suspenseStackCursor, fiber);
+ }
+ function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
+ // If it was the primary children that just suspended, capture and render the
+ // fallback. Otherwise, don't capture and bubble to the next boundary.
+ var nextState = workInProgress.memoizedState;
+ if (nextState !== null) {
+ if (nextState.dehydrated !== null) // A dehydrated boundary always captures.
+ return true;
+ return false;
+ }
+ var props = workInProgress.memoizedProps; // Regular boundaries always capture.
+ return true;
+ }
+ function findFirstSuspended(row) {
+ var node = row;
+ while(node !== null){
+ if (node.tag === SuspenseComponent) {
+ var state = node.memoizedState;
+ if (state !== null) {
+ var dehydrated = state.dehydrated;
+ if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) return node;
+ }
+ } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
+ // keep track of whether it suspended or not.
+ node.memoizedProps.revealOrder !== undefined) {
+ var didSuspend = (node.flags & DidCapture) !== NoFlags;
+ if (didSuspend) return node;
+ } else if (node.child !== null) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === row) return null;
+ while(node.sibling === null){
+ if (node.return === null || node.return === row) return null;
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ return null;
+ }
+ var NoFlags$1 = /* */ 0; // Represents whether effect should fire.
+ var HasEffect = /* */ 1; // Represents the phase in which the effect (not the clean-up) fires.
+ var Insertion = /* */ 2;
+ var Layout = /* */ 4;
+ var Passive$1 = /* */ 8;
+ // and should be reset before starting a new render.
+ // This tracks which mutable sources need to be reset after a render.
+ var workInProgressSources = [];
+ function resetWorkInProgressVersions() {
+ for(var i = 0; i < workInProgressSources.length; i++){
+ var mutableSource = workInProgressSources[i];
+ mutableSource._workInProgressVersionPrimary = null;
+ }
+ workInProgressSources.length = 0;
+ }
+ // This ensures that the version used for server rendering matches the one
+ // that is eventually read during hydration.
+ // If they don't match there's a potential tear and a full deopt render is required.
+ function registerMutableSourceForHydration(root, mutableSource) {
+ var getVersion = mutableSource._getVersion;
+ var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished.
+ // Retaining it forever may interfere with GC.
+ if (root.mutableSourceEagerHydrationData == null) root.mutableSourceEagerHydrationData = [
+ mutableSource,
+ version
+ ];
+ else root.mutableSourceEagerHydrationData.push(mutableSource, version);
+ }
+ var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig;
+ var didWarnAboutMismatchedHooksForComponent;
+ var didWarnUncachedGetSnapshot;
+ didWarnAboutMismatchedHooksForComponent = new Set();
+ // These are set right before calling the component.
+ var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
+ // the work-in-progress hook.
+ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
+ // current hook list is the list that belongs to the current fiber. The
+ // work-in-progress hook list is a new list that will be added to the
+ // work-in-progress fiber.
+ var currentHook = null;
+ var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
+ // does not get reset if we do another render pass; only when we're completely
+ // finished evaluating this component. This is an optimization so we know
+ // whether we need to clear render phase updates after a throw.
+ var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
+ // gets reset after each attempt.
+ // TODO: Maybe there's some way to consolidate this with
+ // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
+ var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component.
+ var localIdCounter = 0; // Used for ids that are generated completely client-side (i.e. not during
+ // hydration). This counter is global, so client ids are not stable across
+ // render attempts.
+ var globalClientIdCounter = 0;
+ var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
+ var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
+ // The list stores the order of hooks used during the initial render (mount).
+ // Subsequent renders (updates) reference this list.
+ var hookTypesDev = null;
+ var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
+ // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
+ // When true, such Hooks will always be "remounted". Only used during hot reload.
+ var ignorePreviousDependencies = false;
+ function mountHookTypesDev() {
+ var hookName = currentHookNameInDev;
+ if (hookTypesDev === null) hookTypesDev = [
+ hookName
+ ];
+ else hookTypesDev.push(hookName);
+ }
+ function updateHookTypesDev() {
+ var hookName = currentHookNameInDev;
+ if (hookTypesDev !== null) {
+ hookTypesUpdateIndexDev++;
+ if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) warnOnHookMismatchInDev(hookName);
+ }
+ }
+ function checkDepsAreArrayDev(deps) {
+ if (deps !== undefined && deps !== null && !isArray(deps)) // Verify deps, but only on mount to avoid extra checks.
+ // It's unlikely their type would change as usually you define them inline.
+ error("%s received a final argument that is not an array (instead, received `%s`). When specified, the final argument must be an array.", currentHookNameInDev, typeof deps);
+ }
+ function warnOnHookMismatchInDev(currentHookName) {
+ var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
+ if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
+ didWarnAboutMismatchedHooksForComponent.add(componentName);
+ if (hookTypesDev !== null) {
+ var table = "";
+ var secondColumnStart = 30;
+ for(var i = 0; i <= hookTypesUpdateIndexDev; i++){
+ var oldHookName = hookTypesDev[i];
+ var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
+ var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
+ // lol @ IE not supporting String#repeat
+ while(row.length < secondColumnStart)row += " ";
+ row += newHookName + "\n";
+ table += row;
+ }
+ error("React has detected a change in the order of Hooks called by %s. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n Previous render Next render\n ------------------------------------------------------\n%s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", componentName, table);
+ }
+ }
+ }
+ function throwInvalidHookError() {
+ throw new Error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.");
+ }
+ function areHookInputsEqual(nextDeps, prevDeps) {
+ if (ignorePreviousDependencies) // Only true when this component is being hot reloaded.
+ return false;
+ if (prevDeps === null) {
+ error("%s received a final argument during this render, but not during the previous render. Even though the final argument is optional, its type cannot change between renders.", currentHookNameInDev);
+ return false;
+ }
+ // Don't bother comparing lengths in prod because these arrays should be
+ // passed inline.
+ if (nextDeps.length !== prevDeps.length) error("The final argument passed to %s changed size between renders. The order and size of this array must remain constant.\n\nPrevious: %s\nIncoming: %s", currentHookNameInDev, "[" + prevDeps.join(", ") + "]", "[" + nextDeps.join(", ") + "]");
+ for(var i = 0; i < prevDeps.length && i < nextDeps.length; i++){
+ if (objectIs(nextDeps[i], prevDeps[i])) continue;
+ return false;
+ }
+ return true;
+ }
+ function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
+ renderLanes = nextRenderLanes;
+ currentlyRenderingFiber$1 = workInProgress;
+ hookTypesDev = current !== null ? current._debugHookTypes : null;
+ hookTypesUpdateIndexDev = -1; // Used for hot reloading:
+ ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
+ workInProgress.memoizedState = null;
+ workInProgress.updateQueue = null;
+ workInProgress.lanes = NoLanes; // The following should have already been reset
+ if (current !== null && current.memoizedState !== null) ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
+ else if (hookTypesDev !== null) // This dispatcher handles an edge case where a component is updating,
+ // but no stateful hooks have been used.
+ // We want to match the production code behavior (which will use HooksDispatcherOnMount),
+ // but with the extra DEV validation to ensure hooks ordering hasn't changed.
+ // This dispatcher does that.
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
+ else ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
+ var children = Component(props, secondArg); // Check if there was a render phase update
+ if (didScheduleRenderPhaseUpdateDuringThisPass) {
+ // Keep rendering in a loop for as long as render phase updates continue to
+ // be scheduled. Use a counter to prevent infinite loops.
+ var numberOfReRenders = 0;
+ do {
+ didScheduleRenderPhaseUpdateDuringThisPass = false;
+ localIdCounter = 0;
+ if (numberOfReRenders >= RE_RENDER_LIMIT) throw new Error("Too many re-renders. React limits the number of renders to prevent an infinite loop.");
+ numberOfReRenders += 1;
+ // Even when hot reloading, allow dependencies to stabilize
+ // after first render to prevent infinite render phase updates.
+ ignorePreviousDependencies = false;
+ currentHook = null;
+ workInProgressHook = null;
+ workInProgress.updateQueue = null;
+ // Also validate hook order for cascading updates.
+ hookTypesUpdateIndexDev = -1;
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV;
+ children = Component(props, secondArg);
+ }while (didScheduleRenderPhaseUpdateDuringThisPass);
+ } // We can assume the previous dispatcher is always this one, since we set it
+ // at the beginning of the render phase and there's no re-entrance.
+ ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
+ workInProgress._debugHookTypes = hookTypesDev;
+ // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
+ var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
+ renderLanes = NoLanes;
+ currentlyRenderingFiber$1 = null;
+ currentHook = null;
+ workInProgressHook = null;
+ currentHookNameInDev = null;
+ hookTypesDev = null;
+ hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
+ // render. If this fires, it suggests that we incorrectly reset the static
+ // flags in some other part of the codebase. This has happened before, for
+ // example, in the SuspenseList implementation.
+ if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird
+ // and creates false positives. To make this work in legacy mode, we'd
+ // need to mark fibers that commit in an incomplete state, somehow. For
+ // now I'll disable the warning that most of the bugs that would trigger
+ // it are either exclusive to concurrent mode or exist in both.
+ (current.mode & ConcurrentMode) !== NoMode) error("Internal React error: Expected static flag was missing. Please notify the React team.");
+ didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
+ // localIdCounter = 0;
+ if (didRenderTooFewHooks) throw new Error("Rendered fewer hooks than expected. This may be caused by an accidental early return statement.");
+ return children;
+ }
+ function checkDidRenderIdHook() {
+ // This should be called immediately after every renderWithHooks call.
+ // Conceptually, it's part of the return value of renderWithHooks; it's only a
+ // separate function to avoid using an array tuple.
+ var didRenderIdHook = localIdCounter !== 0;
+ localIdCounter = 0;
+ return didRenderIdHook;
+ }
+ function bailoutHooks(current, workInProgress, lanes) {
+ workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
+ // complete phase (bubbleProperties).
+ if ((workInProgress.mode & StrictEffectsMode) !== NoMode) workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update);
+ else workInProgress.flags &= ~(Passive | Update);
+ current.lanes = removeLanes(current.lanes, lanes);
+ }
+ function resetHooksAfterThrow() {
+ // We can assume the previous dispatcher is always this one, since we set it
+ // at the beginning of the render phase and there's no re-entrance.
+ ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
+ if (didScheduleRenderPhaseUpdate) {
+ // There were render phase updates. These are only valid for this render
+ // phase, which we are now aborting. Remove the updates from the queues so
+ // they do not persist to the next render. Do not remove updates from hooks
+ // that weren't processed.
+ //
+ // Only reset the updates from the queue if it has a clone. If it does
+ // not have a clone, that means it wasn't processed, and the updates were
+ // scheduled before we entered the render phase.
+ var hook = currentlyRenderingFiber$1.memoizedState;
+ while(hook !== null){
+ var queue = hook.queue;
+ if (queue !== null) queue.pending = null;
+ hook = hook.next;
+ }
+ didScheduleRenderPhaseUpdate = false;
+ }
+ renderLanes = NoLanes;
+ currentlyRenderingFiber$1 = null;
+ currentHook = null;
+ workInProgressHook = null;
+ hookTypesDev = null;
+ hookTypesUpdateIndexDev = -1;
+ currentHookNameInDev = null;
+ isUpdatingOpaqueValueInRenderPhase = false;
+ didScheduleRenderPhaseUpdateDuringThisPass = false;
+ localIdCounter = 0;
+ }
+ function mountWorkInProgressHook() {
+ var hook = {
+ memoizedState: null,
+ baseState: null,
+ baseQueue: null,
+ queue: null,
+ next: null
+ };
+ if (workInProgressHook === null) // This is the first hook in the list
+ currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
+ else // Append to the end of the list
+ workInProgressHook = workInProgressHook.next = hook;
+ return workInProgressHook;
+ }
+ function updateWorkInProgressHook() {
+ // This function is used both for updates and for re-renders triggered by a
+ // render phase update. It assumes there is either a current hook we can
+ // clone, or a work-in-progress hook from a previous render pass that we can
+ // use as a base. When we reach the end of the base list, we must switch to
+ // the dispatcher used for mounts.
+ var nextCurrentHook;
+ if (currentHook === null) {
+ var current = currentlyRenderingFiber$1.alternate;
+ if (current !== null) nextCurrentHook = current.memoizedState;
+ else nextCurrentHook = null;
+ } else nextCurrentHook = currentHook.next;
+ var nextWorkInProgressHook;
+ if (workInProgressHook === null) nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
+ else nextWorkInProgressHook = workInProgressHook.next;
+ if (nextWorkInProgressHook !== null) {
+ // There's already a work-in-progress. Reuse it.
+ workInProgressHook = nextWorkInProgressHook;
+ nextWorkInProgressHook = workInProgressHook.next;
+ currentHook = nextCurrentHook;
+ } else {
+ // Clone from the current hook.
+ if (nextCurrentHook === null) throw new Error("Rendered more hooks than during the previous render.");
+ currentHook = nextCurrentHook;
+ var newHook = {
+ memoizedState: currentHook.memoizedState,
+ baseState: currentHook.baseState,
+ baseQueue: currentHook.baseQueue,
+ queue: currentHook.queue,
+ next: null
+ };
+ if (workInProgressHook === null) // This is the first hook in the list.
+ currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
+ else // Append to the end of the list.
+ workInProgressHook = workInProgressHook.next = newHook;
+ }
+ return workInProgressHook;
+ }
+ function createFunctionComponentUpdateQueue() {
+ return {
+ lastEffect: null,
+ stores: null
+ };
+ }
+ function basicStateReducer(state, action) {
+ // $FlowFixMe: Flow doesn't like mixed types
+ return typeof action === "function" ? action(state) : action;
+ }
+ function mountReducer(reducer, initialArg, init) {
+ var hook = mountWorkInProgressHook();
+ var initialState;
+ if (init !== undefined) initialState = init(initialArg);
+ else initialState = initialArg;
+ hook.memoizedState = hook.baseState = initialState;
+ var queue = {
+ pending: null,
+ interleaved: null,
+ lanes: NoLanes,
+ dispatch: null,
+ lastRenderedReducer: reducer,
+ lastRenderedState: initialState
+ };
+ hook.queue = queue;
+ var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
+ return [
+ hook.memoizedState,
+ dispatch
+ ];
+ }
+ function updateReducer(reducer, initialArg, init) {
+ var hook = updateWorkInProgressHook();
+ var queue = hook.queue;
+ if (queue === null) throw new Error("Should have a queue. This is likely a bug in React. Please file an issue.");
+ queue.lastRenderedReducer = reducer;
+ var current = currentHook; // The last rebase update that is NOT part of the base state.
+ var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
+ var pendingQueue = queue.pending;
+ if (pendingQueue !== null) {
+ // We have new updates that haven't been processed yet.
+ // We'll add them to the base queue.
+ if (baseQueue !== null) {
+ // Merge the pending queue and the base queue.
+ var baseFirst = baseQueue.next;
+ var pendingFirst = pendingQueue.next;
+ baseQueue.next = pendingFirst;
+ pendingQueue.next = baseFirst;
+ }
+ if (current.baseQueue !== baseQueue) // Internal invariant that should never happen, but feasibly could in
+ // the future if we implement resuming, or some form of that.
+ error("Internal error: Expected work-in-progress queue to be a clone. This is a bug in React.");
+ current.baseQueue = baseQueue = pendingQueue;
+ queue.pending = null;
+ }
+ if (baseQueue !== null) {
+ // We have a queue to process.
+ var first = baseQueue.next;
+ var newState = current.baseState;
+ var newBaseState = null;
+ var newBaseQueueFirst = null;
+ var newBaseQueueLast = null;
+ var update = first;
+ do {
+ var updateLane = update.lane;
+ if (!isSubsetOfLanes(renderLanes, updateLane)) {
+ // Priority is insufficient. Skip this update. If this is the first
+ // skipped update, the previous update/state is the new base
+ // update/state.
+ var clone = {
+ lane: updateLane,
+ action: update.action,
+ hasEagerState: update.hasEagerState,
+ eagerState: update.eagerState,
+ next: null
+ };
+ if (newBaseQueueLast === null) {
+ newBaseQueueFirst = newBaseQueueLast = clone;
+ newBaseState = newState;
+ } else newBaseQueueLast = newBaseQueueLast.next = clone;
+ // Update the remaining priority in the queue.
+ // TODO: Don't need to accumulate this. Instead, we can remove
+ // renderLanes from the original lanes.
+ currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
+ markSkippedUpdateLanes(updateLane);
+ } else {
+ // This update does have sufficient priority.
+ if (newBaseQueueLast !== null) {
+ var _clone = {
+ // This update is going to be committed so we never want uncommit
+ // it. Using NoLane works because 0 is a subset of all bitmasks, so
+ // this will never be skipped by the check above.
+ lane: NoLane,
+ action: update.action,
+ hasEagerState: update.hasEagerState,
+ eagerState: update.eagerState,
+ next: null
+ };
+ newBaseQueueLast = newBaseQueueLast.next = _clone;
+ } // Process this update.
+ if (update.hasEagerState) // If this update is a state update (not a reducer) and was processed eagerly,
+ // we can use the eagerly computed state
+ newState = update.eagerState;
+ else {
+ var action = update.action;
+ newState = reducer(newState, action);
+ }
+ }
+ update = update.next;
+ }while (update !== null && update !== first);
+ if (newBaseQueueLast === null) newBaseState = newState;
+ else newBaseQueueLast.next = newBaseQueueFirst;
+ // Mark that the fiber performed work, but only if the new state is
+ // different from the current state.
+ if (!objectIs(newState, hook.memoizedState)) markWorkInProgressReceivedUpdate();
+ hook.memoizedState = newState;
+ hook.baseState = newBaseState;
+ hook.baseQueue = newBaseQueueLast;
+ queue.lastRenderedState = newState;
+ } // Interleaved updates are stored on a separate queue. We aren't going to
+ // process them during this render, but we do need to track which lanes
+ // are remaining.
+ var lastInterleaved = queue.interleaved;
+ if (lastInterleaved !== null) {
+ var interleaved = lastInterleaved;
+ do {
+ var interleavedLane = interleaved.lane;
+ currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
+ markSkippedUpdateLanes(interleavedLane);
+ interleaved = interleaved.next;
+ }while (interleaved !== lastInterleaved);
+ } else if (baseQueue === null) // `queue.lanes` is used for entangling transitions. We can set it back to
+ // zero once the queue is empty.
+ queue.lanes = NoLanes;
+ var dispatch = queue.dispatch;
+ return [
+ hook.memoizedState,
+ dispatch
+ ];
+ }
+ function rerenderReducer(reducer, initialArg, init) {
+ var hook = updateWorkInProgressHook();
+ var queue = hook.queue;
+ if (queue === null) throw new Error("Should have a queue. This is likely a bug in React. Please file an issue.");
+ queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
+ // work-in-progress hook.
+ var dispatch = queue.dispatch;
+ var lastRenderPhaseUpdate = queue.pending;
+ var newState = hook.memoizedState;
+ if (lastRenderPhaseUpdate !== null) {
+ // The queue doesn't persist past this render pass.
+ queue.pending = null;
+ var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
+ var update = firstRenderPhaseUpdate;
+ do {
+ // Process this render phase update. We don't have to check the
+ // priority because it will always be the same as the current
+ // render's.
+ var action = update.action;
+ newState = reducer(newState, action);
+ update = update.next;
+ }while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
+ // different from the current state.
+ if (!objectIs(newState, hook.memoizedState)) markWorkInProgressReceivedUpdate();
+ hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
+ // the base state unless the queue is empty.
+ // TODO: Not sure if this is the desired semantics, but it's what we
+ // do for gDSFP. I can't remember why.
+ if (hook.baseQueue === null) hook.baseState = newState;
+ queue.lastRenderedState = newState;
+ }
+ return [
+ newState,
+ dispatch
+ ];
+ }
+ function mountMutableSource(source, getSnapshot, subscribe) {
+ return undefined;
+ }
+ function updateMutableSource(source, getSnapshot, subscribe) {
+ return undefined;
+ }
+ function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
+ var fiber = currentlyRenderingFiber$1;
+ var hook = mountWorkInProgressHook();
+ var nextSnapshot;
+ var isHydrating = getIsHydrating();
+ if (isHydrating) {
+ if (getServerSnapshot === undefined) throw new Error("Missing getServerSnapshot, which is required for server-rendered content. Will revert to client rendering.");
+ nextSnapshot = getServerSnapshot();
+ if (!didWarnUncachedGetSnapshot) {
+ if (nextSnapshot !== getServerSnapshot()) {
+ error("The result of getServerSnapshot should be cached to avoid an infinite loop");
+ didWarnUncachedGetSnapshot = true;
+ }
+ }
+ } else {
+ nextSnapshot = getSnapshot();
+ if (!didWarnUncachedGetSnapshot) {
+ var cachedSnapshot = getSnapshot();
+ if (!objectIs(nextSnapshot, cachedSnapshot)) {
+ error("The result of getSnapshot should be cached to avoid an infinite loop");
+ didWarnUncachedGetSnapshot = true;
+ }
+ }
+ // Right before committing, we will walk the tree and check if any of the
+ // stores were mutated.
+ //
+ // We won't do this if we're hydrating server-rendered content, because if
+ // the content is stale, it's already visible anyway. Instead we'll patch
+ // it up in a passive effect.
+ var root = getWorkInProgressRoot();
+ if (root === null) throw new Error("Expected a work-in-progress root. This is a bug in React. Please file an issue.");
+ if (!includesBlockingLane(root, renderLanes)) pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
+ } // Read the current snapshot from the store on every render. This breaks the
+ // normal rules of React, and only works because store updates are
+ // always synchronous.
+ hook.memoizedState = nextSnapshot;
+ var inst = {
+ value: nextSnapshot,
+ getSnapshot: getSnapshot
+ };
+ hook.queue = inst; // Schedule an effect to subscribe to the store.
+ mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [
+ subscribe
+ ]); // Schedule an effect to update the mutable instance fields. We will update
+ // this whenever subscribe, getSnapshot, or value changes. Because there's no
+ // clean-up function, and we track the deps correctly, we can call pushEffect
+ // directly, without storing any additional state. For the same reason, we
+ // don't need to set a static flag, either.
+ // TODO: We can move this to the passive phase once we add a pre-commit
+ // consistency check. See the next comment.
+ fiber.flags |= Passive;
+ pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null);
+ return nextSnapshot;
+ }
+ function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
+ var fiber = currentlyRenderingFiber$1;
+ var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
+ // normal rules of React, and only works because store updates are
+ // always synchronous.
+ var nextSnapshot = getSnapshot();
+ if (!didWarnUncachedGetSnapshot) {
+ var cachedSnapshot = getSnapshot();
+ if (!objectIs(nextSnapshot, cachedSnapshot)) {
+ error("The result of getSnapshot should be cached to avoid an infinite loop");
+ didWarnUncachedGetSnapshot = true;
+ }
+ }
+ var prevSnapshot = hook.memoizedState;
+ var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
+ if (snapshotChanged) {
+ hook.memoizedState = nextSnapshot;
+ markWorkInProgressReceivedUpdate();
+ }
+ var inst = hook.queue;
+ updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [
+ subscribe
+ ]); // Whenever getSnapshot or subscribe changes, we need to check in the
+ // commit phase if there was an interleaved mutation. In concurrent mode
+ // this can happen all the time, but even in synchronous mode, an earlier
+ // effect may have mutated the store.
+ if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
+ // checking whether we scheduled a subscription effect above.
+ workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
+ fiber.flags |= Passive;
+ pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check.
+ // Right before committing, we will walk the tree and check if any of the
+ // stores were mutated.
+ var root = getWorkInProgressRoot();
+ if (root === null) throw new Error("Expected a work-in-progress root. This is a bug in React. Please file an issue.");
+ if (!includesBlockingLane(root, renderLanes)) pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
+ }
+ return nextSnapshot;
+ }
+ function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
+ fiber.flags |= StoreConsistency;
+ var check = {
+ getSnapshot: getSnapshot,
+ value: renderedSnapshot
+ };
+ var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
+ if (componentUpdateQueue === null) {
+ componentUpdateQueue = createFunctionComponentUpdateQueue();
+ currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
+ componentUpdateQueue.stores = [
+ check
+ ];
+ } else {
+ var stores = componentUpdateQueue.stores;
+ if (stores === null) componentUpdateQueue.stores = [
+ check
+ ];
+ else stores.push(check);
+ }
+ }
+ function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
+ // These are updated in the passive phase
+ inst.value = nextSnapshot;
+ inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
+ // have been in an event that fired before the passive effects, or it could
+ // have been in a layout effect. In that case, we would have used the old
+ // snapsho and getSnapshot values to bail out. We need to check one more time.
+ if (checkIfSnapshotChanged(inst)) // Force a re-render.
+ forceStoreRerender(fiber);
+ }
+ function subscribeToStore(fiber, inst, subscribe) {
+ var handleStoreChange = function() {
+ // The store changed. Check if the snapshot changed since the last time we
+ // read from the store.
+ if (checkIfSnapshotChanged(inst)) // Force a re-render.
+ forceStoreRerender(fiber);
+ }; // Subscribe to the store and return a clean-up function.
+ return subscribe(handleStoreChange);
+ }
+ function checkIfSnapshotChanged(inst) {
+ var latestGetSnapshot = inst.getSnapshot;
+ var prevValue = inst.value;
+ try {
+ var nextValue = latestGetSnapshot();
+ return !objectIs(prevValue, nextValue);
+ } catch (error) {
+ return true;
+ }
+ }
+ function forceStoreRerender(fiber) {
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ }
+ function mountState(initialState) {
+ var hook = mountWorkInProgressHook();
+ if (typeof initialState === "function") // $FlowFixMe: Flow doesn't like mixed types
+ initialState = initialState();
+ hook.memoizedState = hook.baseState = initialState;
+ var queue = {
+ pending: null,
+ interleaved: null,
+ lanes: NoLanes,
+ dispatch: null,
+ lastRenderedReducer: basicStateReducer,
+ lastRenderedState: initialState
+ };
+ hook.queue = queue;
+ var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
+ return [
+ hook.memoizedState,
+ dispatch
+ ];
+ }
+ function updateState(initialState) {
+ return updateReducer(basicStateReducer);
+ }
+ function rerenderState(initialState) {
+ return rerenderReducer(basicStateReducer);
+ }
+ function pushEffect(tag, create, destroy, deps) {
+ var effect = {
+ tag: tag,
+ create: create,
+ destroy: destroy,
+ deps: deps,
+ // Circular
+ next: null
+ };
+ var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
+ if (componentUpdateQueue === null) {
+ componentUpdateQueue = createFunctionComponentUpdateQueue();
+ currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
+ componentUpdateQueue.lastEffect = effect.next = effect;
+ } else {
+ var lastEffect = componentUpdateQueue.lastEffect;
+ if (lastEffect === null) componentUpdateQueue.lastEffect = effect.next = effect;
+ else {
+ var firstEffect = lastEffect.next;
+ lastEffect.next = effect;
+ effect.next = firstEffect;
+ componentUpdateQueue.lastEffect = effect;
+ }
+ }
+ return effect;
+ }
+ function mountRef(initialValue) {
+ var hook = mountWorkInProgressHook();
+ var _ref2 = {
+ current: initialValue
+ };
+ hook.memoizedState = _ref2;
+ return _ref2;
+ }
+ function updateRef(initialValue) {
+ var hook = updateWorkInProgressHook();
+ return hook.memoizedState;
+ }
+ function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
+ var hook = mountWorkInProgressHook();
+ var nextDeps = deps === undefined ? null : deps;
+ currentlyRenderingFiber$1.flags |= fiberFlags;
+ hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
+ }
+ function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
+ var hook = updateWorkInProgressHook();
+ var nextDeps = deps === undefined ? null : deps;
+ var destroy = undefined;
+ if (currentHook !== null) {
+ var prevEffect = currentHook.memoizedState;
+ destroy = prevEffect.destroy;
+ if (nextDeps !== null) {
+ var prevDeps = prevEffect.deps;
+ if (areHookInputsEqual(nextDeps, prevDeps)) {
+ hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
+ return;
+ }
+ }
+ }
+ currentlyRenderingFiber$1.flags |= fiberFlags;
+ hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
+ }
+ function mountEffect(create, deps) {
+ if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps);
+ else return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
+ }
+ function updateEffect(create, deps) {
+ return updateEffectImpl(Passive, Passive$1, create, deps);
+ }
+ function mountInsertionEffect(create, deps) {
+ return mountEffectImpl(Update, Insertion, create, deps);
+ }
+ function updateInsertionEffect(create, deps) {
+ return updateEffectImpl(Update, Insertion, create, deps);
+ }
+ function mountLayoutEffect(create, deps) {
+ var fiberFlags = Update;
+ fiberFlags |= LayoutStatic;
+ if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev;
+ return mountEffectImpl(fiberFlags, Layout, create, deps);
+ }
+ function updateLayoutEffect(create, deps) {
+ return updateEffectImpl(Update, Layout, create, deps);
+ }
+ function imperativeHandleEffect(create, ref) {
+ if (typeof ref === "function") {
+ var refCallback = ref;
+ var _inst = create();
+ refCallback(_inst);
+ return function() {
+ refCallback(null);
+ };
+ } else if (ref !== null && ref !== undefined) {
+ var refObject = ref;
+ if (!refObject.hasOwnProperty("current")) error("Expected useImperativeHandle() first argument to either be a ref callback or React.createRef() object. Instead received: %s.", "an object with keys {" + Object.keys(refObject).join(", ") + "}");
+ var _inst2 = create();
+ refObject.current = _inst2;
+ return function() {
+ refObject.current = null;
+ };
+ }
+ }
+ function mountImperativeHandle(ref, create, deps) {
+ if (typeof create !== "function") error("Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", create !== null ? typeof create : "null");
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([
+ ref
+ ]) : null;
+ var fiberFlags = Update;
+ fiberFlags |= LayoutStatic;
+ if ((currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) fiberFlags |= MountLayoutDev;
+ return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
+ }
+ function updateImperativeHandle(ref, create, deps) {
+ if (typeof create !== "function") error("Expected useImperativeHandle() second argument to be a function that creates a handle. Instead received: %s.", create !== null ? typeof create : "null");
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([
+ ref
+ ]) : null;
+ return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
+ }
+ function mountDebugValue(value, formatterFn) {
+ // The react-debug-hooks package injects its own implementation
+ // so that e.g. DevTools can display custom hook values.
+ }
+ var updateDebugValue = mountDebugValue;
+ function mountCallback(callback, deps) {
+ var hook = mountWorkInProgressHook();
+ var nextDeps = deps === undefined ? null : deps;
+ hook.memoizedState = [
+ callback,
+ nextDeps
+ ];
+ return callback;
+ }
+ function updateCallback(callback, deps) {
+ var hook = updateWorkInProgressHook();
+ var nextDeps = deps === undefined ? null : deps;
+ var prevState = hook.memoizedState;
+ if (prevState !== null) {
+ if (nextDeps !== null) {
+ var prevDeps = prevState[1];
+ if (areHookInputsEqual(nextDeps, prevDeps)) return prevState[0];
+ }
+ }
+ hook.memoizedState = [
+ callback,
+ nextDeps
+ ];
+ return callback;
+ }
+ function mountMemo(nextCreate, deps) {
+ var hook = mountWorkInProgressHook();
+ var nextDeps = deps === undefined ? null : deps;
+ var nextValue = nextCreate();
+ hook.memoizedState = [
+ nextValue,
+ nextDeps
+ ];
+ return nextValue;
+ }
+ function updateMemo(nextCreate, deps) {
+ var hook = updateWorkInProgressHook();
+ var nextDeps = deps === undefined ? null : deps;
+ var prevState = hook.memoizedState;
+ if (prevState !== null) // Assume these are defined. If they're not, areHookInputsEqual will warn.
+ {
+ if (nextDeps !== null) {
+ var prevDeps = prevState[1];
+ if (areHookInputsEqual(nextDeps, prevDeps)) return prevState[0];
+ }
+ }
+ var nextValue = nextCreate();
+ hook.memoizedState = [
+ nextValue,
+ nextDeps
+ ];
+ return nextValue;
+ }
+ function mountDeferredValue(value) {
+ var hook = mountWorkInProgressHook();
+ hook.memoizedState = value;
+ return value;
+ }
+ function updateDeferredValue(value) {
+ var hook = updateWorkInProgressHook();
+ var resolvedCurrentHook = currentHook;
+ var prevValue = resolvedCurrentHook.memoizedState;
+ return updateDeferredValueImpl(hook, prevValue, value);
+ }
+ function rerenderDeferredValue(value) {
+ var hook = updateWorkInProgressHook();
+ if (currentHook === null) {
+ // This is a rerender during a mount.
+ hook.memoizedState = value;
+ return value;
+ } else {
+ // This is a rerender during an update.
+ var prevValue = currentHook.memoizedState;
+ return updateDeferredValueImpl(hook, prevValue, value);
+ }
+ }
+ function updateDeferredValueImpl(hook, prevValue, value) {
+ var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
+ if (shouldDeferValue) {
+ // This is an urgent update. If the value has changed, keep using the
+ // previous value and spawn a deferred render to update it later.
+ if (!objectIs(value, prevValue)) {
+ // Schedule a deferred render
+ var deferredLane = claimNextTransitionLane();
+ currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
+ markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent
+ // from the latest value. The name "baseState" doesn't really match how we
+ // use it because we're reusing a state hook field instead of creating a
+ // new one.
+ hook.baseState = true;
+ } // Reuse the previous value
+ return prevValue;
+ } else {
+ // This is not an urgent update, so we can use the latest value regardless
+ // of what it is. No need to defer it.
+ // However, if we're currently inside a spawned render, then we need to mark
+ // this as an update to prevent the fiber from bailing out.
+ //
+ // `baseState` is true when the current value is different from the rendered
+ // value. The name doesn't really match how we use it because we're reusing
+ // a state hook field instead of creating a new one.
+ if (hook.baseState) {
+ // Flip this back to false.
+ hook.baseState = false;
+ markWorkInProgressReceivedUpdate();
+ }
+ hook.memoizedState = value;
+ return value;
+ }
+ }
+ function startTransition(setPending, callback, options) {
+ var previousPriority = getCurrentUpdatePriority();
+ setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
+ setPending(true);
+ var prevTransition = ReactCurrentBatchConfig$2.transition;
+ ReactCurrentBatchConfig$2.transition = {};
+ var currentTransition = ReactCurrentBatchConfig$2.transition;
+ ReactCurrentBatchConfig$2.transition._updatedFibers = new Set();
+ try {
+ setPending(false);
+ callback();
+ } finally{
+ setCurrentUpdatePriority(previousPriority);
+ ReactCurrentBatchConfig$2.transition = prevTransition;
+ if (prevTransition === null && currentTransition._updatedFibers) {
+ var updatedFibersCount = currentTransition._updatedFibers.size;
+ if (updatedFibersCount > 10) warn("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.");
+ currentTransition._updatedFibers.clear();
+ }
+ }
+ }
+ function mountTransition() {
+ var _mountState = mountState(false), isPending = _mountState[0], setPending = _mountState[1]; // The `start` method never changes.
+ var start = startTransition.bind(null, setPending);
+ var hook = mountWorkInProgressHook();
+ hook.memoizedState = start;
+ return [
+ isPending,
+ start
+ ];
+ }
+ function updateTransition() {
+ var _updateState = updateState(), isPending = _updateState[0];
+ var hook = updateWorkInProgressHook();
+ var start = hook.memoizedState;
+ return [
+ isPending,
+ start
+ ];
+ }
+ function rerenderTransition() {
+ var _rerenderState = rerenderState(), isPending = _rerenderState[0];
+ var hook = updateWorkInProgressHook();
+ var start = hook.memoizedState;
+ return [
+ isPending,
+ start
+ ];
+ }
+ var isUpdatingOpaqueValueInRenderPhase = false;
+ function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
+ return isUpdatingOpaqueValueInRenderPhase;
+ }
+ function mountId() {
+ var hook = mountWorkInProgressHook();
+ var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
+ // should do this in Fiber, too? Deferring this decision for now because
+ // there's no other place to store the prefix except for an internal field on
+ // the public createRoot object, which the fiber tree does not currently have
+ // a reference to.
+ var identifierPrefix = root.identifierPrefix;
+ var id;
+ if (getIsHydrating()) {
+ var treeId = getTreeId(); // Use a captial R prefix for server-generated ids.
+ id = ":" + identifierPrefix + "R" + treeId; // Unless this is the first id at this level, append a number at the end
+ // that represents the position of this useId hook among all the useId
+ // hooks for this fiber.
+ var localId = localIdCounter++;
+ if (localId > 0) id += "H" + localId.toString(32);
+ id += ":";
+ } else {
+ // Use a lowercase r prefix for client-generated ids.
+ var globalClientId = globalClientIdCounter++;
+ id = ":" + identifierPrefix + "r" + globalClientId.toString(32) + ":";
+ }
+ hook.memoizedState = id;
+ return id;
+ }
+ function updateId() {
+ var hook = updateWorkInProgressHook();
+ var id = hook.memoizedState;
+ return id;
+ }
+ function dispatchReducerAction(fiber, queue, action) {
+ if (typeof arguments[3] === "function") error("State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().");
+ var lane = requestUpdateLane(fiber);
+ var update = {
+ lane: lane,
+ action: action,
+ hasEagerState: false,
+ eagerState: null,
+ next: null
+ };
+ if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update);
+ else {
+ var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
+ if (root !== null) {
+ var eventTime = requestEventTime();
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ entangleTransitionUpdate(root, queue, lane);
+ }
+ }
+ markUpdateInDevTools(fiber, lane);
+ }
+ function dispatchSetState(fiber, queue, action) {
+ if (typeof arguments[3] === "function") error("State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().");
+ var lane = requestUpdateLane(fiber);
+ var update = {
+ lane: lane,
+ action: action,
+ hasEagerState: false,
+ eagerState: null,
+ next: null
+ };
+ if (isRenderPhaseUpdate(fiber)) enqueueRenderPhaseUpdate(queue, update);
+ else {
+ var alternate = fiber.alternate;
+ if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
+ // The queue is currently empty, which means we can eagerly compute the
+ // next state before entering the render phase. If the new state is the
+ // same as the current state, we may be able to bail out entirely.
+ var lastRenderedReducer = queue.lastRenderedReducer;
+ if (lastRenderedReducer !== null) {
+ var prevDispatcher;
+ prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ var currentState = queue.lastRenderedState;
+ var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
+ // it, on the update object. If the reducer hasn't changed by the
+ // time we enter the render phase, then the eager state can be used
+ // without calling the reducer again.
+ update.hasEagerState = true;
+ update.eagerState = eagerState;
+ if (objectIs(eagerState, currentState)) {
+ // Fast path. We can bail out without scheduling React to re-render.
+ // It's still possible that we'll need to rebase this update later,
+ // if the component re-renders for a different reason and by that
+ // time the reducer has changed.
+ // TODO: Do we still need to entangle transitions in this case?
+ enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane);
+ return;
+ }
+ } catch (error) {} finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ }
+ }
+ var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
+ if (root !== null) {
+ var eventTime = requestEventTime();
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ entangleTransitionUpdate(root, queue, lane);
+ }
+ }
+ markUpdateInDevTools(fiber, lane);
+ }
+ function isRenderPhaseUpdate(fiber) {
+ var alternate = fiber.alternate;
+ return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
+ }
+ function enqueueRenderPhaseUpdate(queue, update) {
+ // This is a render phase update. Stash it in a lazily-created map of
+ // queue -> linked list of updates. After this render pass, we'll restart
+ // and apply the stashed updates on top of the work-in-progress hook.
+ didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
+ var pending = queue.pending;
+ if (pending === null) // This is the first update. Create a circular list.
+ update.next = update;
+ else {
+ update.next = pending.next;
+ pending.next = update;
+ }
+ queue.pending = update;
+ } // TODO: Move to ReactFiberConcurrentUpdates?
+ function entangleTransitionUpdate(root, queue, lane) {
+ if (isTransitionLane(lane)) {
+ var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
+ // must have finished. We can remove them from the shared queue, which
+ // represents a superset of the actually pending lanes. In some cases we
+ // may entangle more than we need to, but that's OK. In fact it's worse if
+ // we *don't* entangle when we should.
+ queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
+ var newQueueLanes = mergeLanes(queueLanes, lane);
+ queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
+ // the lane finished since the last time we entangled it. So we need to
+ // entangle it again, just to be sure.
+ markRootEntangled(root, newQueueLanes);
+ }
+ }
+ function markUpdateInDevTools(fiber, lane, action) {
+ markStateUpdateScheduled(fiber, lane);
+ }
+ var ContextOnlyDispatcher = {
+ readContext: readContext,
+ useCallback: throwInvalidHookError,
+ useContext: throwInvalidHookError,
+ useEffect: throwInvalidHookError,
+ useImperativeHandle: throwInvalidHookError,
+ useInsertionEffect: throwInvalidHookError,
+ useLayoutEffect: throwInvalidHookError,
+ useMemo: throwInvalidHookError,
+ useReducer: throwInvalidHookError,
+ useRef: throwInvalidHookError,
+ useState: throwInvalidHookError,
+ useDebugValue: throwInvalidHookError,
+ useDeferredValue: throwInvalidHookError,
+ useTransition: throwInvalidHookError,
+ useMutableSource: throwInvalidHookError,
+ useSyncExternalStore: throwInvalidHookError,
+ useId: throwInvalidHookError,
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ var HooksDispatcherOnMountInDEV = null;
+ var HooksDispatcherOnMountWithHookTypesInDEV = null;
+ var HooksDispatcherOnUpdateInDEV = null;
+ var HooksDispatcherOnRerenderInDEV = null;
+ var InvalidNestedHooksDispatcherOnMountInDEV = null;
+ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
+ var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
+ var warnInvalidContextAccess = function() {
+ error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
+ };
+ var warnInvalidHookAccess = function() {
+ error("Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://reactjs.org/link/rules-of-hooks");
+ };
+ HooksDispatcherOnMountInDEV = {
+ readContext: function(context) {
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ mountHookTypesDev();
+ checkDepsAreArrayDev(deps);
+ return mountCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ mountHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ mountHookTypesDev();
+ checkDepsAreArrayDev(deps);
+ return mountEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ mountHookTypesDev();
+ checkDepsAreArrayDev(deps);
+ return mountImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ mountHookTypesDev();
+ checkDepsAreArrayDev(deps);
+ return mountInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ mountHookTypesDev();
+ checkDepsAreArrayDev(deps);
+ return mountLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ mountHookTypesDev();
+ checkDepsAreArrayDev(deps);
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ mountHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ mountHookTypesDev();
+ return mountRef(initialValue);
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ mountHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ mountHookTypesDev();
+ return mountDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ mountHookTypesDev();
+ return mountDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ mountHookTypesDev();
+ return mountTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ mountHookTypesDev();
+ return mountMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ mountHookTypesDev();
+ return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ mountHookTypesDev();
+ return mountId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ HooksDispatcherOnMountWithHookTypesInDEV = {
+ readContext: function(context) {
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ updateHookTypesDev();
+ return mountCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ updateHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ updateHookTypesDev();
+ return mountEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ updateHookTypesDev();
+ return mountImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ updateHookTypesDev();
+ return mountInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ updateHookTypesDev();
+ return mountLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ updateHookTypesDev();
+ return mountRef(initialValue);
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ updateHookTypesDev();
+ return mountDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ updateHookTypesDev();
+ return mountDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ updateHookTypesDev();
+ return mountTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ updateHookTypesDev();
+ return mountMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ updateHookTypesDev();
+ return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ updateHookTypesDev();
+ return mountId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ HooksDispatcherOnUpdateInDEV = {
+ readContext: function(context) {
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ updateHookTypesDev();
+ return updateCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ updateHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ updateHookTypesDev();
+ return updateEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ updateHookTypesDev();
+ return updateImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ updateHookTypesDev();
+ return updateInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ updateHookTypesDev();
+ return updateLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ updateHookTypesDev();
+ return updateRef();
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ updateHookTypesDev();
+ return updateDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ updateHookTypesDev();
+ return updateDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ updateHookTypesDev();
+ return updateTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ updateHookTypesDev();
+ return updateMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ updateHookTypesDev();
+ return updateSyncExternalStore(subscribe, getSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ updateHookTypesDev();
+ return updateId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ HooksDispatcherOnRerenderInDEV = {
+ readContext: function(context) {
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ updateHookTypesDev();
+ return updateCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ updateHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ updateHookTypesDev();
+ return updateEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ updateHookTypesDev();
+ return updateImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ updateHookTypesDev();
+ return updateInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ updateHookTypesDev();
+ return updateLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
+ try {
+ return updateMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
+ try {
+ return rerenderReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ updateHookTypesDev();
+ return updateRef();
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
+ try {
+ return rerenderState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ updateHookTypesDev();
+ return updateDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ updateHookTypesDev();
+ return rerenderDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ updateHookTypesDev();
+ return rerenderTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ updateHookTypesDev();
+ return updateMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ updateHookTypesDev();
+ return updateSyncExternalStore(subscribe, getSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ updateHookTypesDev();
+ return updateId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ InvalidNestedHooksDispatcherOnMountInDEV = {
+ readContext: function(context) {
+ warnInvalidContextAccess();
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountRef(initialValue);
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
+ try {
+ return mountState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ warnInvalidHookAccess();
+ mountHookTypesDev();
+ return mountId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ InvalidNestedHooksDispatcherOnUpdateInDEV = {
+ readContext: function(context) {
+ warnInvalidContextAccess();
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateRef();
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateSyncExternalStore(subscribe, getSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ InvalidNestedHooksDispatcherOnRerenderInDEV = {
+ readContext: function(context) {
+ warnInvalidContextAccess();
+ return readContext(context);
+ },
+ useCallback: function(callback, deps) {
+ currentHookNameInDev = "useCallback";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateCallback(callback, deps);
+ },
+ useContext: function(context) {
+ currentHookNameInDev = "useContext";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return readContext(context);
+ },
+ useEffect: function(create, deps) {
+ currentHookNameInDev = "useEffect";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateEffect(create, deps);
+ },
+ useImperativeHandle: function(ref, create, deps) {
+ currentHookNameInDev = "useImperativeHandle";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateImperativeHandle(ref, create, deps);
+ },
+ useInsertionEffect: function(create, deps) {
+ currentHookNameInDev = "useInsertionEffect";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateInsertionEffect(create, deps);
+ },
+ useLayoutEffect: function(create, deps) {
+ currentHookNameInDev = "useLayoutEffect";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateLayoutEffect(create, deps);
+ },
+ useMemo: function(create, deps) {
+ currentHookNameInDev = "useMemo";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return updateMemo(create, deps);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useReducer: function(reducer, initialArg, init) {
+ currentHookNameInDev = "useReducer";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return rerenderReducer(reducer, initialArg, init);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useRef: function(initialValue) {
+ currentHookNameInDev = "useRef";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateRef();
+ },
+ useState: function(initialState) {
+ currentHookNameInDev = "useState";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
+ try {
+ return rerenderState(initialState);
+ } finally{
+ ReactCurrentDispatcher$1.current = prevDispatcher;
+ }
+ },
+ useDebugValue: function(value, formatterFn) {
+ currentHookNameInDev = "useDebugValue";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateDebugValue();
+ },
+ useDeferredValue: function(value) {
+ currentHookNameInDev = "useDeferredValue";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return rerenderDeferredValue(value);
+ },
+ useTransition: function() {
+ currentHookNameInDev = "useTransition";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return rerenderTransition();
+ },
+ useMutableSource: function(source, getSnapshot, subscribe) {
+ currentHookNameInDev = "useMutableSource";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateMutableSource();
+ },
+ useSyncExternalStore: function(subscribe, getSnapshot, getServerSnapshot) {
+ currentHookNameInDev = "useSyncExternalStore";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateSyncExternalStore(subscribe, getSnapshot);
+ },
+ useId: function() {
+ currentHookNameInDev = "useId";
+ warnInvalidHookAccess();
+ updateHookTypesDev();
+ return updateId();
+ },
+ unstable_isNewReconciler: enableNewReconciler
+ };
+ var now$1 = Scheduler.unstable_now;
+ var commitTime = 0;
+ var layoutEffectStartTime = -1;
+ var profilerStartTime = -1;
+ var passiveEffectStartTime = -1;
+ /**
+ * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
+ *
+ * The overall sequence is:
+ * 1. render
+ * 2. commit (and call `onRender`, `onCommit`)
+ * 3. check for nested updates
+ * 4. flush passive effects (and call `onPostCommit`)
+ *
+ * Nested updates are identified in step 3 above,
+ * but step 4 still applies to the work that was just committed.
+ * We use two flags to track nested updates then:
+ * one tracks whether the upcoming update is a nested update,
+ * and the other tracks whether the current update was a nested update.
+ * The first value gets synced to the second at the start of the render phase.
+ */ var currentUpdateIsNested = false;
+ var nestedUpdateScheduled = false;
+ function isCurrentUpdateNested() {
+ return currentUpdateIsNested;
+ }
+ function markNestedUpdateScheduled() {
+ nestedUpdateScheduled = true;
+ }
+ function resetNestedUpdateFlag() {
+ currentUpdateIsNested = false;
+ nestedUpdateScheduled = false;
+ }
+ function syncNestedUpdateFlag() {
+ currentUpdateIsNested = nestedUpdateScheduled;
+ nestedUpdateScheduled = false;
+ }
+ function getCommitTime() {
+ return commitTime;
+ }
+ function recordCommitTime() {
+ commitTime = now$1();
+ }
+ function startProfilerTimer(fiber) {
+ profilerStartTime = now$1();
+ if (fiber.actualStartTime < 0) fiber.actualStartTime = now$1();
+ }
+ function stopProfilerTimerIfRunning(fiber) {
+ profilerStartTime = -1;
+ }
+ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
+ if (profilerStartTime >= 0) {
+ var elapsedTime = now$1() - profilerStartTime;
+ fiber.actualDuration += elapsedTime;
+ if (overrideBaseTime) fiber.selfBaseDuration = elapsedTime;
+ profilerStartTime = -1;
+ }
+ }
+ function recordLayoutEffectDuration(fiber) {
+ if (layoutEffectStartTime >= 0) {
+ var elapsedTime = now$1() - layoutEffectStartTime;
+ layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
+ // Or the root (for the DevTools Profiler to read)
+ var parentFiber = fiber.return;
+ while(parentFiber !== null){
+ switch(parentFiber.tag){
+ case HostRoot:
+ var root = parentFiber.stateNode;
+ root.effectDuration += elapsedTime;
+ return;
+ case Profiler:
+ var parentStateNode = parentFiber.stateNode;
+ parentStateNode.effectDuration += elapsedTime;
+ return;
+ }
+ parentFiber = parentFiber.return;
+ }
+ }
+ }
+ function recordPassiveEffectDuration(fiber) {
+ if (passiveEffectStartTime >= 0) {
+ var elapsedTime = now$1() - passiveEffectStartTime;
+ passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
+ // Or the root (for the DevTools Profiler to read)
+ var parentFiber = fiber.return;
+ while(parentFiber !== null){
+ switch(parentFiber.tag){
+ case HostRoot:
+ var root = parentFiber.stateNode;
+ if (root !== null) root.passiveEffectDuration += elapsedTime;
+ return;
+ case Profiler:
+ var parentStateNode = parentFiber.stateNode;
+ if (parentStateNode !== null) // Detached fibers have their state node cleared out.
+ // In this case, the return pointer is also cleared out,
+ // so we won't be able to report the time spent in this Profiler's subtree.
+ parentStateNode.passiveEffectDuration += elapsedTime;
+ return;
+ }
+ parentFiber = parentFiber.return;
+ }
+ }
+ }
+ function startLayoutEffectTimer() {
+ layoutEffectStartTime = now$1();
+ }
+ function startPassiveEffectTimer() {
+ passiveEffectStartTime = now$1();
+ }
+ function transferActualDuration(fiber) {
+ // Transfer time spent rendering these children so we don't lose it
+ // after we rerender. This is used as a helper in special cases
+ // where we should count the work of multiple passes.
+ var child = fiber.child;
+ while(child){
+ fiber.actualDuration += child.actualDuration;
+ child = child.sibling;
+ }
+ }
+ function createCapturedValueAtFiber(value, source) {
+ // If the value is an error, call this function immediately after it is thrown
+ // so the stack is accurate.
+ return {
+ value: value,
+ source: source,
+ stack: getStackByFiberInDevAndProd(source),
+ digest: null
+ };
+ }
+ function createCapturedValue(value, digest, stack) {
+ return {
+ value: value,
+ source: null,
+ stack: stack != null ? stack : null,
+ digest: digest != null ? digest : null
+ };
+ }
+ // This module is forked in different environments.
+ // By default, return `true` to log errors to the console.
+ // Forks can return `false` if this isn't desirable.
+ function showErrorDialog(boundary, errorInfo) {
+ return true;
+ }
+ function logCapturedError(boundary, errorInfo) {
+ try {
+ var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
+ // This enables renderers like ReactNative to better manage redbox behavior.
+ if (logError === false) return;
+ var error = errorInfo.value;
+ var source = errorInfo.source;
+ var stack = errorInfo.stack;
+ var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling
+ // `preventDefault()` in window `error` handler.
+ // We record this information as an expando on the error.
+ if (error != null && error._suppressLogging) {
+ if (boundary.tag === ClassComponent) // The error is recoverable and was silenced.
+ // Ignore it and don't print the stack addendum.
+ // This is handy for testing error boundaries without noise.
+ return;
+ // The error is fatal. Since the silencing might have
+ // been accidental, we'll surface it anyway.
+ // However, the browser would have silenced the original error
+ // so we'll print it first, and then print the stack addendum.
+ console["error"](error); // Don't transform to our wrapper
+ // For a more detailed description of this block, see:
+ // https://github.com/facebook/react/pull/13384
+ }
+ var componentName = source ? getComponentNameFromFiber(source) : null;
+ var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : "The above error occurred in one of your React components:";
+ var errorBoundaryMessage;
+ if (boundary.tag === HostRoot) errorBoundaryMessage = "Consider adding an error boundary to your tree to customize error handling behavior.\nVisit https://reactjs.org/link/error-boundaries to learn more about error boundaries.";
+ else {
+ var errorBoundaryName = getComponentNameFromFiber(boundary) || "Anonymous";
+ errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
+ }
+ var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
+ // We don't include the original error message and JS stack because the browser
+ // has already printed it. Even if the application swallows the error, it is still
+ // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
+ console["error"](combinedMessage); // Don't transform to our wrapper
+ } catch (e) {
+ // This method must not throw, or React internal state will get messed up.
+ // If console.error is overridden, or logCapturedError() shows a dialog that throws,
+ // we want to report this error outside of the normal stack as a last resort.
+ // https://github.com/facebook/react/issues/13188
+ setTimeout(function() {
+ throw e;
+ });
+ }
+ }
+ var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map;
+ function createRootErrorUpdate(fiber, errorInfo, lane) {
+ var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
+ update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
+ // being called "element".
+ update.payload = {
+ element: null
+ };
+ var error = errorInfo.value;
+ update.callback = function() {
+ onUncaughtError(error);
+ logCapturedError(fiber, errorInfo);
+ };
+ return update;
+ }
+ function createClassErrorUpdate(fiber, errorInfo, lane) {
+ var update = createUpdate(NoTimestamp, lane);
+ update.tag = CaptureUpdate;
+ var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
+ if (typeof getDerivedStateFromError === "function") {
+ var error$1 = errorInfo.value;
+ update.payload = function() {
+ return getDerivedStateFromError(error$1);
+ };
+ update.callback = function() {
+ markFailedErrorBoundaryForHotReloading(fiber);
+ logCapturedError(fiber, errorInfo);
+ };
+ }
+ var inst = fiber.stateNode;
+ if (inst !== null && typeof inst.componentDidCatch === "function") update.callback = function callback() {
+ markFailedErrorBoundaryForHotReloading(fiber);
+ logCapturedError(fiber, errorInfo);
+ if (typeof getDerivedStateFromError !== "function") // To preserve the preexisting retry behavior of error boundaries,
+ // we keep track of which ones already failed during this batch.
+ // This gets reset before we yield back to the browser.
+ // TODO: Warn in strict mode if getDerivedStateFromError is
+ // not defined.
+ markLegacyErrorBoundaryAsFailed(this);
+ var error$1 = errorInfo.value;
+ var stack = errorInfo.stack;
+ this.componentDidCatch(error$1, {
+ componentStack: stack !== null ? stack : ""
+ });
+ if (typeof getDerivedStateFromError !== "function") // If componentDidCatch is the only error boundary method defined,
+ // then it needs to call setState to recover from errors.
+ // If no state update is scheduled then the boundary will swallow the error.
+ {
+ if (!includesSomeLane(fiber.lanes, SyncLane)) error("%s: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI.", getComponentNameFromFiber(fiber) || "Unknown");
+ }
+ };
+ return update;
+ }
+ function attachPingListener(root, wakeable, lanes) {
+ // Attach a ping listener
+ //
+ // The data might resolve before we have a chance to commit the fallback. Or,
+ // in the case of a refresh, we'll never commit a fallback. So we need to
+ // attach a listener now. When it resolves ("pings"), we can decide whether to
+ // try rendering the tree again.
+ //
+ // Only attach a listener if one does not already exist for the lanes
+ // we're currently rendering (which acts like a "thread ID" here).
+ //
+ // We only need to do this in concurrent mode. Legacy Suspense always
+ // commits fallbacks synchronously, so there are no pings.
+ var pingCache = root.pingCache;
+ var threadIDs;
+ if (pingCache === null) {
+ pingCache = root.pingCache = new PossiblyWeakMap$1();
+ threadIDs = new Set();
+ pingCache.set(wakeable, threadIDs);
+ } else {
+ threadIDs = pingCache.get(wakeable);
+ if (threadIDs === undefined) {
+ threadIDs = new Set();
+ pingCache.set(wakeable, threadIDs);
+ }
+ }
+ if (!threadIDs.has(lanes)) {
+ // Memoize using the thread ID to prevent redundant listeners.
+ threadIDs.add(lanes);
+ var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
+ if (isDevToolsPresent) // If we have pending work still, restore the original updaters
+ restorePendingUpdaters(root, lanes);
+ wakeable.then(ping, ping);
+ }
+ }
+ function attachRetryListener(suspenseBoundary, root, wakeable, lanes) {
+ // Retry listener
+ //
+ // If the fallback does commit, we need to attach a different type of
+ // listener. This one schedules an update on the Suspense boundary to turn
+ // the fallback state off.
+ //
+ // Stash the wakeable on the boundary fiber so we can access it in the
+ // commit phase.
+ //
+ // When the wakeable resolves, we'll attempt to render the boundary
+ // again ("retry").
+ var wakeables = suspenseBoundary.updateQueue;
+ if (wakeables === null) {
+ var updateQueue = new Set();
+ updateQueue.add(wakeable);
+ suspenseBoundary.updateQueue = updateQueue;
+ } else wakeables.add(wakeable);
+ }
+ function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
+ // A legacy mode Suspense quirk, only relevant to hook components.
+ var tag = sourceFiber.tag;
+ if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
+ var currentSource = sourceFiber.alternate;
+ if (currentSource) {
+ sourceFiber.updateQueue = currentSource.updateQueue;
+ sourceFiber.memoizedState = currentSource.memoizedState;
+ sourceFiber.lanes = currentSource.lanes;
+ } else {
+ sourceFiber.updateQueue = null;
+ sourceFiber.memoizedState = null;
+ }
+ }
+ }
+ function getNearestSuspenseBoundaryToCapture(returnFiber) {
+ var node = returnFiber;
+ do {
+ if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) return node;
+ // This boundary already captured during this render. Continue to the next
+ // boundary.
+ node = node.return;
+ }while (node !== null);
+ return null;
+ }
+ function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
+ // This marks a Suspense boundary so that when we're unwinding the stack,
+ // it captures the suspended "exception" and does a second (fallback) pass.
+ if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
+ // Legacy Mode Suspense
+ //
+ // If the boundary is in legacy mode, we should *not*
+ // suspend the commit. Pretend as if the suspended component rendered
+ // null and keep rendering. When the Suspense boundary completes,
+ // we'll do a second pass to render the fallback.
+ if (suspenseBoundary === returnFiber) // Special case where we suspended while reconciling the children of
+ // a Suspense boundary's inner Offscreen wrapper fiber. This happens
+ // when a React.lazy component is a direct child of a
+ // Suspense boundary.
+ //
+ // Suspense boundaries are implemented as multiple fibers, but they
+ // are a single conceptual unit. The legacy mode behavior where we
+ // pretend the suspended fiber committed as `null` won't work,
+ // because in this case the "suspended" fiber is the inner
+ // Offscreen wrapper.
+ //
+ // Because the contents of the boundary haven't started rendering
+ // yet (i.e. nothing in the tree has partially rendered) we can
+ // switch to the regular, concurrent mode behavior: mark the
+ // boundary with ShouldCapture and enter the unwind phase.
+ suspenseBoundary.flags |= ShouldCapture;
+ else {
+ suspenseBoundary.flags |= DidCapture;
+ sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
+ // But we shouldn't call any lifecycle methods or callbacks. Remove
+ // all lifecycle effect tags.
+ sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
+ if (sourceFiber.tag === ClassComponent) {
+ var currentSourceFiber = sourceFiber.alternate;
+ if (currentSourceFiber === null) // This is a new mount. Change the tag so it's not mistaken for a
+ // completed class component. For example, we should not call
+ // componentWillUnmount if it is deleted.
+ sourceFiber.tag = IncompleteClassComponent;
+ else {
+ // When we try rendering again, we should not reuse the current fiber,
+ // since it's known to be in an inconsistent state. Use a force update to
+ // prevent a bail out.
+ var update = createUpdate(NoTimestamp, SyncLane);
+ update.tag = ForceUpdate;
+ enqueueUpdate(sourceFiber, update, SyncLane);
+ }
+ } // The source fiber did not complete. Mark it with Sync priority to
+ // indicate that it still has pending work.
+ sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
+ }
+ return suspenseBoundary;
+ } // Confirmed that the boundary is in a concurrent mode tree. Continue
+ // with the normal suspend path.
+ //
+ // After this we'll use a set of heuristics to determine whether this
+ // render pass will run to completion or restart or "suspend" the commit.
+ // The actual logic for this is spread out in different places.
+ //
+ // This first principle is that if we're going to suspend when we complete
+ // a root, then we should also restart if we get an update or ping that
+ // might unsuspend it, and vice versa. The only reason to suspend is
+ // because you think you might want to restart before committing. However,
+ // it doesn't make sense to restart only while in the period we're suspended.
+ //
+ // Restarting too aggressively is also not good because it starves out any
+ // intermediate loading state. So we use heuristics to determine when.
+ // Suspense Heuristics
+ //
+ // If nothing threw a Promise or all the same fallbacks are already showing,
+ // then don't suspend/restart.
+ //
+ // If this is an initial render of a new tree of Suspense boundaries and
+ // those trigger a fallback, then don't suspend/restart. We want to ensure
+ // that we can show the initial loading state as quickly as possible.
+ //
+ // If we hit a "Delayed" case, such as when we'd switch from content back into
+ // a fallback, then we should always suspend/restart. Transitions apply
+ // to this case. If none is defined, JND is used instead.
+ //
+ // If we're already showing a fallback and it gets "retried", allowing us to show
+ // another level, but there's still an inner boundary that would show a fallback,
+ // then we suspend/restart for 500ms since the last time we showed a fallback
+ // anywhere in the tree. This effectively throttles progressive loading into a
+ // consistent train of commits. This also gives us an opportunity to restart to
+ // get to the completed state slightly earlier.
+ //
+ // If there's ambiguity due to batching it's resolved in preference of:
+ // 1) "delayed", 2) "initial render", 3) "retry".
+ //
+ // We want to ensure that a "busy" state doesn't get force committed. We want to
+ // ensure that new initial loading states can commit as soon as possible.
+ suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
+ // the begin phase to prevent an early bailout.
+ suspenseBoundary.lanes = rootRenderLanes;
+ return suspenseBoundary;
+ }
+ function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
+ // The source fiber did not complete.
+ sourceFiber.flags |= Incomplete;
+ if (isDevToolsPresent) // If we have pending work still, restore the original updaters
+ restorePendingUpdaters(root, rootRenderLanes);
+ if (value !== null && typeof value === "object" && typeof value.then === "function") {
+ // This is a wakeable. The component suspended.
+ var wakeable = value;
+ resetSuspendedComponent(sourceFiber);
+ if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) markDidThrowWhileHydratingDEV();
+ var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
+ if (suspenseBoundary !== null) {
+ suspenseBoundary.flags &= ~ForceClientRender;
+ markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always
+ // commits fallbacks synchronously, so there are no pings.
+ if (suspenseBoundary.mode & ConcurrentMode) attachPingListener(root, wakeable, rootRenderLanes);
+ attachRetryListener(suspenseBoundary, root, wakeable);
+ return;
+ } else {
+ // No boundary was found. Unless this is a sync update, this is OK.
+ // We can suspend and wait for more data to arrive.
+ if (!includesSyncLane(rootRenderLanes)) {
+ // This is not a sync update. Suspend. Since we're not activating a
+ // Suspense boundary, this will unwind all the way to the root without
+ // performing a second pass to render a fallback. (This is arguably how
+ // refresh transitions should work, too, since we're not going to commit
+ // the fallbacks anyway.)
+ //
+ // This case also applies to initial hydration.
+ attachPingListener(root, wakeable, rootRenderLanes);
+ renderDidSuspendDelayIfPossible();
+ return;
+ } // This is a sync/discrete update. We treat this case like an error
+ // because discrete renders are expected to produce a complete tree
+ // synchronously to maintain consistency with external state.
+ var uncaughtSuspenseError = new Error("A component suspended while responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition."); // If we're outside a transition, fall through to the regular error path.
+ // The error will be caught by the nearest suspense boundary.
+ value = uncaughtSuspenseError;
+ }
+ } else // This is a regular error, not a Suspense wakeable.
+ if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
+ markDidThrowWhileHydratingDEV();
+ var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); // If the error was thrown during hydration, we may be able to recover by
+ // discarding the dehydrated content and switching to a client render.
+ // Instead of surfacing the error, find the nearest Suspense boundary
+ // and render it again without hydration.
+ if (_suspenseBoundary !== null) {
+ if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) // Set a flag to indicate that we should try rendering the normal
+ // children again, not the fallback.
+ _suspenseBoundary.flags |= ForceClientRender;
+ markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should
+ // still log it so it can be fixed.
+ queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
+ return;
+ }
+ }
+ value = createCapturedValueAtFiber(value, sourceFiber);
+ renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
+ // over and traverse parent path again, this time treating the exception
+ // as an error.
+ var workInProgress = returnFiber;
+ do {
+ switch(workInProgress.tag){
+ case HostRoot:
+ var _errorInfo = value;
+ workInProgress.flags |= ShouldCapture;
+ var lane = pickArbitraryLane(rootRenderLanes);
+ workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
+ var update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
+ enqueueCapturedUpdate(workInProgress, update);
+ return;
+ case ClassComponent:
+ // Capture and retry
+ var errorInfo = value;
+ var ctor = workInProgress.type;
+ var instance = workInProgress.stateNode;
+ if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === "function" || instance !== null && typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance))) {
+ workInProgress.flags |= ShouldCapture;
+ var _lane = pickArbitraryLane(rootRenderLanes);
+ workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
+ var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane);
+ enqueueCapturedUpdate(workInProgress, _update);
+ return;
+ }
+ break;
+ }
+ workInProgress = workInProgress.return;
+ }while (workInProgress !== null);
+ }
+ function getSuspendedCache() {
+ return null;
+ }
+ var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
+ var didReceiveUpdate = false;
+ var didWarnAboutBadClass;
+ var didWarnAboutModulePatternComponent;
+ var didWarnAboutContextTypeOnFunctionComponent;
+ var didWarnAboutGetDerivedStateOnFunctionComponent;
+ var didWarnAboutFunctionRefs;
+ var didWarnAboutReassigningProps;
+ var didWarnAboutRevealOrder;
+ var didWarnAboutTailOptions;
+ didWarnAboutBadClass = {};
+ didWarnAboutModulePatternComponent = {};
+ didWarnAboutContextTypeOnFunctionComponent = {};
+ didWarnAboutGetDerivedStateOnFunctionComponent = {};
+ didWarnAboutFunctionRefs = {};
+ didWarnAboutReassigningProps = false;
+ didWarnAboutRevealOrder = {};
+ didWarnAboutTailOptions = {};
+ function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
+ if (current === null) // If this is a fresh new component that hasn't been rendered yet, we
+ // won't update its child set by applying minimal side-effects. Instead,
+ // we will add them all to the child before it gets rendered. That means
+ // we can optimize this reconciliation pass by not tracking side-effects.
+ workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
+ else // If the current child is the same as the work in progress, it means that
+ // we haven't yet started any work on these children. Therefore, we use
+ // the clone algorithm to create a copy of all the current children.
+ // If we had any progressed work already, that is invalid at this point so
+ // let's throw it out.
+ workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
+ }
+ function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
+ // This function is fork of reconcileChildren. It's used in cases where we
+ // want to reconcile without matching against the existing set. This has the
+ // effect of all current children being unmounted; even if the type and key
+ // are the same, the old child is unmounted and a new child is created.
+ //
+ // To do this, we're going to go through the reconcile algorithm twice. In
+ // the first pass, we schedule a deletion for all the current children by
+ // passing null.
+ workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
+ // pass null in place of where we usually pass the current child set. This has
+ // the effect of remounting all children regardless of whether their
+ // identities match.
+ workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
+ }
+ function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
+ if (workInProgress.type !== workInProgress.elementType) {
+ // Lazy component props can't be validated in createElement
+ // because they're only guaranteed to be resolved here.
+ var innerPropTypes = Component.propTypes;
+ if (innerPropTypes) checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component));
+ }
+ var render = Component.render;
+ var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
+ var nextChildren;
+ var hasId;
+ prepareToReadContext(workInProgress, renderLanes);
+ markComponentRenderStarted(workInProgress);
+ ReactCurrentOwner$1.current = workInProgress;
+ setIsRendering(true);
+ nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
+ hasId = checkDidRenderIdHook();
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
+ hasId = checkDidRenderIdHook();
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ setIsRendering(false);
+ markComponentRenderStopped();
+ if (current !== null && !didReceiveUpdate) {
+ bailoutHooks(current, workInProgress, renderLanes);
+ return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ }
+ if (getIsHydrating() && hasId) pushMaterializedTreeId(workInProgress);
+ // React DevTools reads this flag.
+ workInProgress.flags |= PerformedWork;
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
+ if (current === null) {
+ var type = Component.type;
+ if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
+ Component.defaultProps === undefined) {
+ var resolvedType = type;
+ resolvedType = resolveFunctionForHotReloading(type);
+ // and with only the default shallow comparison, we upgrade it
+ // to a SimpleMemoComponent to allow fast path updates.
+ workInProgress.tag = SimpleMemoComponent;
+ workInProgress.type = resolvedType;
+ validateFunctionComponentInDev(workInProgress, type);
+ return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
+ }
+ var innerPropTypes = type.propTypes;
+ if (innerPropTypes) // Inner memo component props aren't currently validated in createElement.
+ // We could move it there, but we'd still need this for lazy code path.
+ checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(type));
+ var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
+ child.ref = workInProgress.ref;
+ child.return = workInProgress;
+ workInProgress.child = child;
+ return child;
+ }
+ var _type = Component.type;
+ var _innerPropTypes = _type.propTypes;
+ if (_innerPropTypes) // Inner memo component props aren't currently validated in createElement.
+ // We could move it there, but we'd still need this for lazy code path.
+ checkPropTypes(_innerPropTypes, nextProps, "prop", getComponentNameFromType(_type));
+ var currentChild = current.child; // This is always exactly one child
+ var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
+ if (!hasScheduledUpdateOrContext) {
+ // This will be the props with resolved defaultProps,
+ // unlike current.memoizedProps which will be the unresolved ones.
+ var prevProps = currentChild.memoizedProps; // Default to shallow comparison
+ var compare = Component.compare;
+ compare = compare !== null ? compare : shallowEqual;
+ if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ } // React DevTools reads this flag.
+ workInProgress.flags |= PerformedWork;
+ var newChild = createWorkInProgress(currentChild, nextProps);
+ newChild.ref = workInProgress.ref;
+ newChild.return = workInProgress;
+ workInProgress.child = newChild;
+ return newChild;
+ }
+ function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
+ if (workInProgress.type !== workInProgress.elementType) {
+ // Lazy component props can't be validated in createElement
+ // because they're only guaranteed to be resolved here.
+ var outerMemoType = workInProgress.elementType;
+ if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
+ // We warn when you define propTypes on lazy()
+ // so let's just skip over it to find memo() outer wrapper.
+ // Inner props for memo are validated later.
+ var lazyComponent = outerMemoType;
+ var payload = lazyComponent._payload;
+ var init = lazyComponent._init;
+ try {
+ outerMemoType = init(payload);
+ } catch (x) {
+ outerMemoType = null;
+ } // Inner propTypes will be validated in the function component path.
+ var outerPropTypes = outerMemoType && outerMemoType.propTypes;
+ if (outerPropTypes) checkPropTypes(outerPropTypes, nextProps, "prop", getComponentNameFromType(outerMemoType));
+ }
+ }
+ if (current !== null) {
+ var prevProps = current.memoizedProps;
+ if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && workInProgress.type === current.type) {
+ didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we
+ // would during a normal fiber bailout.
+ //
+ // We don't have strong guarantees that the props object is referentially
+ // equal during updates where we can't bail out anyway \u2014 like if the props
+ // are shallowly equal, but there's a local state or context update in the
+ // same batch.
+ //
+ // However, as a principle, we should aim to make the behavior consistent
+ // across different ways of memoizing a component. For example, React.memo
+ // has a different internal Fiber layout if you pass a normal function
+ // component (SimpleMemoComponent) versus if you pass a different type
+ // like forwardRef (MemoComponent). But this is an implementation detail.
+ // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't
+ // affect whether the props object is reused during a bailout.
+ workInProgress.pendingProps = nextProps = prevProps;
+ if (!checkScheduledUpdateOrContext(current, renderLanes)) {
+ // The pending lanes were cleared at the beginning of beginWork. We're
+ // about to bail out, but there might be other lanes that weren't
+ // included in the current render. Usually, the priority level of the
+ // remaining updates is accumulated during the evaluation of the
+ // component (i.e. when processing the update queue). But since since
+ // we're bailing out early *without* evaluating the component, we need
+ // to account for it here, too. Reset to the value of the current fiber.
+ // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
+ // because a MemoComponent fiber does not have hooks or an update queue;
+ // rather, it wraps around an inner component, which may or may not
+ // contains hooks.
+ // TODO: Move the reset at in beginWork out of the common path so that
+ // this is no longer necessary.
+ workInProgress.lanes = current.lanes;
+ return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) // This is a special case that only exists for legacy mode.
+ // See https://github.com/facebook/react/pull/19216.
+ didReceiveUpdate = true;
+ }
+ }
+ return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
+ }
+ function updateOffscreenComponent(current, workInProgress, renderLanes) {
+ var nextProps = workInProgress.pendingProps;
+ var nextChildren = nextProps.children;
+ var prevState = current !== null ? current.memoizedState : null;
+ if (nextProps.mode === "hidden" || enableLegacyHidden) {
+ // Rendering a hidden tree.
+ if ((workInProgress.mode & ConcurrentMode) === NoMode) {
+ // In legacy sync mode, don't defer the subtree. Render it now.
+ // TODO: Consider how Offscreen should work with transitions in the future
+ var nextState = {
+ baseLanes: NoLanes,
+ cachePool: null,
+ transitions: null
+ };
+ workInProgress.memoizedState = nextState;
+ pushRenderLanes(workInProgress, renderLanes);
+ } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
+ var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out
+ // and resume this tree later.
+ var nextBaseLanes;
+ if (prevState !== null) {
+ var prevBaseLanes = prevState.baseLanes;
+ nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
+ } else nextBaseLanes = renderLanes;
+ // Schedule this fiber to re-render at offscreen priority. Then bailout.
+ workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
+ var _nextState = {
+ baseLanes: nextBaseLanes,
+ cachePool: spawnedCachePool,
+ transitions: null
+ };
+ workInProgress.memoizedState = _nextState;
+ workInProgress.updateQueue = null;
+ // to avoid a push/pop misalignment.
+ pushRenderLanes(workInProgress, nextBaseLanes);
+ return null;
+ } else {
+ // This is the second render. The surrounding visible content has already
+ // committed. Now we resume rendering the hidden tree.
+ // Rendering at offscreen, so we can clear the base lanes.
+ var _nextState2 = {
+ baseLanes: NoLanes,
+ cachePool: null,
+ transitions: null
+ };
+ workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
+ var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
+ pushRenderLanes(workInProgress, subtreeRenderLanes);
+ }
+ } else {
+ // Rendering a visible tree.
+ var _subtreeRenderLanes;
+ if (prevState !== null) {
+ // We're going from hidden -> visible.
+ _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);
+ workInProgress.memoizedState = null;
+ } else // We weren't previously hidden, and we still aren't, so there's nothing
+ // special to do. Need to push to the stack regardless, though, to avoid
+ // a push/pop misalignment.
+ _subtreeRenderLanes = renderLanes;
+ pushRenderLanes(workInProgress, _subtreeRenderLanes);
+ }
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ } // Note: These happen to have identical begin phases, for now. We shouldn't hold
+ function updateFragment(current, workInProgress, renderLanes) {
+ var nextChildren = workInProgress.pendingProps;
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function updateMode(current, workInProgress, renderLanes) {
+ var nextChildren = workInProgress.pendingProps.children;
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function updateProfiler(current, workInProgress, renderLanes) {
+ workInProgress.flags |= Update;
+ // Reset effect durations for the next eventual effect phase.
+ // These are reset during render to allow the DevTools commit hook a chance to read them,
+ var stateNode = workInProgress.stateNode;
+ stateNode.effectDuration = 0;
+ stateNode.passiveEffectDuration = 0;
+ var nextProps = workInProgress.pendingProps;
+ var nextChildren = nextProps.children;
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function markRef(current, workInProgress) {
+ var ref = workInProgress.ref;
+ if (current === null && ref !== null || current !== null && current.ref !== ref) {
+ // Schedule a Ref effect
+ workInProgress.flags |= Ref;
+ workInProgress.flags |= RefStatic;
+ }
+ }
+ function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
+ if (workInProgress.type !== workInProgress.elementType) {
+ // Lazy component props can't be validated in createElement
+ // because they're only guaranteed to be resolved here.
+ var innerPropTypes = Component.propTypes;
+ if (innerPropTypes) checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component));
+ }
+ var context;
+ var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
+ context = getMaskedContext(workInProgress, unmaskedContext);
+ var nextChildren;
+ var hasId;
+ prepareToReadContext(workInProgress, renderLanes);
+ markComponentRenderStarted(workInProgress);
+ ReactCurrentOwner$1.current = workInProgress;
+ setIsRendering(true);
+ nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
+ hasId = checkDidRenderIdHook();
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
+ hasId = checkDidRenderIdHook();
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ setIsRendering(false);
+ markComponentRenderStopped();
+ if (current !== null && !didReceiveUpdate) {
+ bailoutHooks(current, workInProgress, renderLanes);
+ return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ }
+ if (getIsHydrating() && hasId) pushMaterializedTreeId(workInProgress);
+ // React DevTools reads this flag.
+ workInProgress.flags |= PerformedWork;
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
+ // This is used by DevTools to force a boundary to error.
+ switch(shouldError(workInProgress)){
+ case false:
+ var _instance = workInProgress.stateNode;
+ var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
+ // Is there a better way to do this?
+ var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
+ var state = tempInstance.state;
+ _instance.updater.enqueueSetState(_instance, state, null);
+ break;
+ case true:
+ workInProgress.flags |= DidCapture;
+ workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
+ var error$1 = new Error("Simulated error coming from DevTools");
+ var lane = pickArbitraryLane(renderLanes);
+ workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
+ var update = createClassErrorUpdate(workInProgress, createCapturedValueAtFiber(error$1, workInProgress), lane);
+ enqueueCapturedUpdate(workInProgress, update);
+ break;
+ }
+ if (workInProgress.type !== workInProgress.elementType) {
+ // Lazy component props can't be validated in createElement
+ // because they're only guaranteed to be resolved here.
+ var innerPropTypes = Component.propTypes;
+ if (innerPropTypes) checkPropTypes(innerPropTypes, nextProps, "prop", getComponentNameFromType(Component));
+ }
+ // During mounting we don't know the child context yet as the instance doesn't exist.
+ // We will invalidate the child context in finishClassComponent() right after rendering.
+ var hasContext;
+ if (isContextProvider(Component)) {
+ hasContext = true;
+ pushContextProvider(workInProgress);
+ } else hasContext = false;
+ prepareToReadContext(workInProgress, renderLanes);
+ var instance = workInProgress.stateNode;
+ var shouldUpdate;
+ if (instance === null) {
+ resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance.
+ constructClassInstance(workInProgress, Component, nextProps);
+ mountClassInstance(workInProgress, Component, nextProps, renderLanes);
+ shouldUpdate = true;
+ } else if (current === null) // In a resume, we'll already have an instance we can reuse.
+ shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
+ else shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
+ var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
+ var inst = workInProgress.stateNode;
+ if (shouldUpdate && inst.props !== nextProps) {
+ if (!didWarnAboutReassigningProps) error("It looks like %s is reassigning its own `this.props` while rendering. This is not supported and can lead to confusing bugs.", getComponentNameFromFiber(workInProgress) || "a component");
+ didWarnAboutReassigningProps = true;
+ }
+ return nextUnitOfWork;
+ }
+ function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
+ // Refs should update even if shouldComponentUpdate returns false
+ markRef(current, workInProgress);
+ var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
+ if (!shouldUpdate && !didCaptureError) {
+ // Context providers should defer to sCU for rendering
+ if (hasContext) invalidateContextProvider(workInProgress, Component, false);
+ return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ }
+ var instance = workInProgress.stateNode; // Rerender
+ ReactCurrentOwner$1.current = workInProgress;
+ var nextChildren;
+ if (didCaptureError && typeof Component.getDerivedStateFromError !== "function") {
+ // If we captured an error, but getDerivedStateFromError is not defined,
+ // unmount all the children. componentDidCatch will schedule an update to
+ // re-render a fallback. This is temporary until we migrate everyone to
+ // the new API.
+ // TODO: Warn in a future release.
+ nextChildren = null;
+ stopProfilerTimerIfRunning();
+ } else {
+ markComponentRenderStarted(workInProgress);
+ setIsRendering(true);
+ nextChildren = instance.render();
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ instance.render();
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ setIsRendering(false);
+ markComponentRenderStopped();
+ } // React DevTools reads this flag.
+ workInProgress.flags |= PerformedWork;
+ if (current !== null && didCaptureError) // If we're recovering from an error, reconcile without reusing any of
+ // the existing children. Conceptually, the normal children and the children
+ // that are shown on error are two different sets, so we shouldn't reuse
+ // normal children even if their identities match.
+ forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
+ else reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ // Memoize state using the values we just used to render.
+ // TODO: Restructure so we never read values from the instance.
+ workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
+ if (hasContext) invalidateContextProvider(workInProgress, Component, true);
+ return workInProgress.child;
+ }
+ function pushHostRootContext(workInProgress) {
+ var root = workInProgress.stateNode;
+ if (root.pendingContext) pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
+ else if (root.context) // Should always be set
+ pushTopLevelContextObject(workInProgress, root.context, false);
+ pushHostContainer(workInProgress, root.containerInfo);
+ }
+ function updateHostRoot(current, workInProgress, renderLanes) {
+ pushHostRootContext(workInProgress);
+ if (current === null) throw new Error("Should have a current fiber. This is a bug in React.");
+ var nextProps = workInProgress.pendingProps;
+ var prevState = workInProgress.memoizedState;
+ var prevChildren = prevState.element;
+ cloneUpdateQueue(current, workInProgress);
+ processUpdateQueue(workInProgress, nextProps, null, renderLanes);
+ var nextState = workInProgress.memoizedState;
+ var root = workInProgress.stateNode;
+ // being called "element".
+ var nextChildren = nextState.element;
+ if (prevState.isDehydrated) {
+ // This is a hydration root whose shell has not yet hydrated. We should
+ // attempt to hydrate.
+ // Flip isDehydrated to false to indicate that when this render
+ // finishes, the root will no longer be dehydrated.
+ var overrideState = {
+ element: nextChildren,
+ isDehydrated: false,
+ cache: nextState.cache,
+ pendingSuspenseBoundaries: nextState.pendingSuspenseBoundaries,
+ transitions: nextState.transitions
+ };
+ var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't
+ // have reducer functions so it doesn't need rebasing.
+ updateQueue.baseState = overrideState;
+ workInProgress.memoizedState = overrideState;
+ if (workInProgress.flags & ForceClientRender) {
+ // Something errored during a previous attempt to hydrate the shell, so we
+ // forced a client render.
+ var recoverableError = createCapturedValueAtFiber(new Error("There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering."), workInProgress);
+ return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError);
+ } else if (nextChildren !== prevChildren) {
+ var _recoverableError = createCapturedValueAtFiber(new Error("This root received an early update, before anything was able hydrate. Switched the entire root to client rendering."), workInProgress);
+ return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, _recoverableError);
+ } else {
+ // The outermost shell has not hydrated yet. Start hydrating.
+ enterHydrationState(workInProgress);
+ var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
+ workInProgress.child = child;
+ var node = child;
+ while(node){
+ // Mark each child as hydrating. This is a fast path to know whether this
+ // tree is part of a hydrating tree. This is used to determine if a child
+ // node has fully mounted yet, and for scheduling event replaying.
+ // Conceptually this is similar to Placement in that a new subtree is
+ // inserted into the React tree here. It just happens to not need DOM
+ // mutations because it already exists.
+ node.flags = node.flags & ~Placement | Hydrating;
+ node = node.sibling;
+ }
+ }
+ } else {
+ // Root is not dehydrated. Either this is a client-only root, or it
+ // already hydrated.
+ resetHydrationState();
+ if (nextChildren === prevChildren) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ }
+ return workInProgress.child;
+ }
+ function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError) {
+ // Revert to client rendering.
+ resetHydrationState();
+ queueHydrationError(recoverableError);
+ workInProgress.flags |= ForceClientRender;
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function updateHostComponent(current, workInProgress, renderLanes) {
+ pushHostContext(workInProgress);
+ if (current === null) tryToClaimNextHydratableInstance(workInProgress);
+ var type = workInProgress.type;
+ var nextProps = workInProgress.pendingProps;
+ var prevProps = current !== null ? current.memoizedProps : null;
+ var nextChildren = nextProps.children;
+ var isDirectTextChild = shouldSetTextContent(type, nextProps);
+ if (isDirectTextChild) // We special case a direct text child of a host node. This is a common
+ // case. We won't handle it as a reified child. We will instead handle
+ // this in the host environment that also has access to this prop. That
+ // avoids allocating another HostText fiber and traversing it.
+ nextChildren = null;
+ else if (prevProps !== null && shouldSetTextContent(type, prevProps)) // If we're switching from a direct text child to a normal child, or to
+ // empty, we need to schedule the text content to be reset.
+ workInProgress.flags |= ContentReset;
+ markRef(current, workInProgress);
+ reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function updateHostText(current, workInProgress) {
+ if (current === null) tryToClaimNextHydratableInstance(workInProgress);
+ // Nothing to do here. This is terminal. We'll do the completion step
+ // immediately after.
+ return null;
+ }
+ function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
+ resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
+ var props = workInProgress.pendingProps;
+ var lazyComponent = elementType;
+ var payload = lazyComponent._payload;
+ var init = lazyComponent._init;
+ var Component = init(payload); // Store the unwrapped component in the type.
+ workInProgress.type = Component;
+ var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
+ var resolvedProps = resolveDefaultProps(Component, props);
+ var child;
+ switch(resolvedTag){
+ case FunctionComponent:
+ validateFunctionComponentInDev(workInProgress, Component);
+ workInProgress.type = Component = resolveFunctionForHotReloading(Component);
+ child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
+ return child;
+ case ClassComponent:
+ workInProgress.type = Component = resolveClassForHotReloading(Component);
+ child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
+ return child;
+ case ForwardRef:
+ workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
+ child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
+ return child;
+ case MemoComponent:
+ if (workInProgress.type !== workInProgress.elementType) {
+ var outerPropTypes = Component.propTypes;
+ if (outerPropTypes) checkPropTypes(outerPropTypes, resolvedProps, "prop", getComponentNameFromType(Component));
+ }
+ child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), renderLanes);
+ return child;
+ }
+ var hint = "";
+ if (Component !== null && typeof Component === "object" && Component.$$typeof === REACT_LAZY_TYPE) hint = " Did you wrap a component in React.lazy() more than once?";
+ // because the fact that it's a separate type of work is an
+ // implementation detail.
+ throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint));
+ }
+ function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
+ resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again.
+ workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
+ // Push context providers early to prevent context stack mismatches.
+ // During mounting we don't know the child context yet as the instance doesn't exist.
+ // We will invalidate the child context in finishClassComponent() right after rendering.
+ var hasContext;
+ if (isContextProvider(Component)) {
+ hasContext = true;
+ pushContextProvider(workInProgress);
+ } else hasContext = false;
+ prepareToReadContext(workInProgress, renderLanes);
+ constructClassInstance(workInProgress, Component, nextProps);
+ mountClassInstance(workInProgress, Component, nextProps, renderLanes);
+ return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
+ }
+ function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
+ resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
+ var props = workInProgress.pendingProps;
+ var context;
+ var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
+ context = getMaskedContext(workInProgress, unmaskedContext);
+ prepareToReadContext(workInProgress, renderLanes);
+ var value;
+ var hasId;
+ markComponentRenderStarted(workInProgress);
+ if (Component.prototype && typeof Component.prototype.render === "function") {
+ var componentName = getComponentNameFromType(Component) || "Unknown";
+ if (!didWarnAboutBadClass[componentName]) {
+ error("The <%s /> component appears to have a render method, but doesn't extend React.Component. This is likely to cause errors. Change %s to extend React.Component instead.", componentName, componentName);
+ didWarnAboutBadClass[componentName] = true;
+ }
+ }
+ if (workInProgress.mode & StrictLegacyMode) ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
+ setIsRendering(true);
+ ReactCurrentOwner$1.current = workInProgress;
+ value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
+ hasId = checkDidRenderIdHook();
+ setIsRendering(false);
+ markComponentRenderStopped();
+ workInProgress.flags |= PerformedWork;
+ // Support for module components is deprecated and is removed behind a flag.
+ // Whether or not it would crash later, we want to show a good message in DEV first.
+ if (typeof value === "object" && value !== null && typeof value.render === "function" && value.$$typeof === undefined) {
+ var _componentName = getComponentNameFromType(Component) || "Unknown";
+ if (!didWarnAboutModulePatternComponent[_componentName]) {
+ error("The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.", _componentName, _componentName, _componentName);
+ didWarnAboutModulePatternComponent[_componentName] = true;
+ }
+ }
+ if (// Eventually we'll delete this branch altogether.
+ typeof value === "object" && value !== null && typeof value.render === "function" && value.$$typeof === undefined) {
+ var _componentName2 = getComponentNameFromType(Component) || "Unknown";
+ if (!didWarnAboutModulePatternComponent[_componentName2]) {
+ error("The <%s /> component appears to be a function component that returns a class instance. Change %s to a class that extends React.Component instead. If you can't use a class try assigning the prototype on the function as a workaround. `%s.prototype = React.Component.prototype`. Don't use an arrow function since it cannot be called with `new` by React.", _componentName2, _componentName2, _componentName2);
+ didWarnAboutModulePatternComponent[_componentName2] = true;
+ }
+ workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
+ workInProgress.memoizedState = null;
+ workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
+ // During mounting we don't know the child context yet as the instance doesn't exist.
+ // We will invalidate the child context in finishClassComponent() right after rendering.
+ var hasContext = false;
+ if (isContextProvider(Component)) {
+ hasContext = true;
+ pushContextProvider(workInProgress);
+ } else hasContext = false;
+ workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
+ initializeUpdateQueue(workInProgress);
+ adoptClassInstance(workInProgress, value);
+ mountClassInstance(workInProgress, Component, props, renderLanes);
+ return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
+ } else {
+ // Proceed under the assumption that this is a function component
+ workInProgress.tag = FunctionComponent;
+ if (workInProgress.mode & StrictLegacyMode) {
+ setIsStrictModeForDevtools(true);
+ try {
+ value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
+ hasId = checkDidRenderIdHook();
+ } finally{
+ setIsStrictModeForDevtools(false);
+ }
+ }
+ if (getIsHydrating() && hasId) pushMaterializedTreeId(workInProgress);
+ reconcileChildren(null, workInProgress, value, renderLanes);
+ validateFunctionComponentInDev(workInProgress, Component);
+ return workInProgress.child;
+ }
+ }
+ function validateFunctionComponentInDev(workInProgress, Component) {
+ if (Component) {
+ if (Component.childContextTypes) error("%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component");
+ }
+ if (workInProgress.ref !== null) {
+ var info = "";
+ var ownerName = getCurrentFiberOwnerNameInDevOrNull();
+ if (ownerName) info += "\n\nCheck the render method of `" + ownerName + "`.";
+ var warningKey = ownerName || "";
+ var debugSource = workInProgress._debugSource;
+ if (debugSource) warningKey = debugSource.fileName + ":" + debugSource.lineNumber;
+ if (!didWarnAboutFunctionRefs[warningKey]) {
+ didWarnAboutFunctionRefs[warningKey] = true;
+ error("Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?%s", info);
+ }
+ }
+ if (typeof Component.getDerivedStateFromProps === "function") {
+ var _componentName3 = getComponentNameFromType(Component) || "Unknown";
+ if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
+ error("%s: Function components do not support getDerivedStateFromProps.", _componentName3);
+ didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
+ }
+ }
+ if (typeof Component.contextType === "object" && Component.contextType !== null) {
+ var _componentName4 = getComponentNameFromType(Component) || "Unknown";
+ if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
+ error("%s: Function components do not support contextType.", _componentName4);
+ didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
+ }
+ }
+ }
+ var SUSPENDED_MARKER = {
+ dehydrated: null,
+ treeContext: null,
+ retryLane: NoLane
+ };
+ function mountSuspenseOffscreenState(renderLanes) {
+ return {
+ baseLanes: renderLanes,
+ cachePool: getSuspendedCache(),
+ transitions: null
+ };
+ }
+ function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
+ var cachePool = null;
+ return {
+ baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
+ cachePool: cachePool,
+ transitions: prevOffscreenState.transitions
+ };
+ } // TODO: Probably should inline this back
+ function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
+ // If we're already showing a fallback, there are cases where we need to
+ // remain on that fallback regardless of whether the content has resolved.
+ // For example, SuspenseList coordinates when nested content appears.
+ if (current !== null) {
+ var suspenseState = current.memoizedState;
+ if (suspenseState === null) // Currently showing content. Don't hide it, even if ForceSuspenseFallback
+ // is true. More precise name might be "ForceRemainSuspenseFallback".
+ // Note: This is a factoring smell. Can't remain on a fallback if there's
+ // no fallback to remain on.
+ return false;
+ } // Not currently showing content. Consult the Suspense context.
+ return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
+ }
+ function getRemainingWorkInPrimaryTree(current, renderLanes) {
+ // TODO: Should not remove render lanes that were pinged during this render
+ return removeLanes(current.childLanes, renderLanes);
+ }
+ function updateSuspenseComponent(current, workInProgress, renderLanes) {
+ var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
+ if (shouldSuspend(workInProgress)) workInProgress.flags |= DidCapture;
+ var suspenseContext = suspenseStackCursor.current;
+ var showFallback = false;
+ var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
+ if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
+ // Something in this boundary's subtree already suspended. Switch to
+ // rendering the fallback children.
+ showFallback = true;
+ workInProgress.flags &= ~DidCapture;
+ } else // Attempting the main content
+ if (current === null || current.memoizedState !== null) suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
+ suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
+ pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
+ // boundary's children. This involves some custom reconciliation logic. Two
+ // main reasons this is so complicated.
+ //
+ // First, Legacy Mode has different semantics for backwards compatibility. The
+ // primary tree will commit in an inconsistent state, so when we do the
+ // second pass to render the fallback, we do some exceedingly, uh, clever
+ // hacks to make that not totally break. Like transferring effects and
+ // deletions from hidden tree. In Concurrent Mode, it's much simpler,
+ // because we bailout on the primary tree completely and leave it in its old
+ // state, no effects. Same as what we do for Offscreen (except that
+ // Offscreen doesn't have the first render pass).
+ //
+ // Second is hydration. During hydration, the Suspense fiber has a slightly
+ // different layout, where the child points to a dehydrated fragment, which
+ // contains the DOM rendered by the server.
+ //
+ // Third, even if you set all that aside, Suspense is like error boundaries in
+ // that we first we try to render one tree, and if that fails, we render again
+ // and switch to a different tree. Like a try/catch block. So we have to track
+ // which branch we're currently rendering. Ideally we would model this using
+ // a stack.
+ if (current === null) {
+ // Initial mount
+ // Special path for hydration
+ // If we're currently hydrating, try to hydrate this boundary.
+ tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
+ var suspenseState = workInProgress.memoizedState;
+ if (suspenseState !== null) {
+ var dehydrated = suspenseState.dehydrated;
+ if (dehydrated !== null) return mountDehydratedSuspenseComponent(workInProgress, dehydrated);
+ }
+ var nextPrimaryChildren = nextProps.children;
+ var nextFallbackChildren = nextProps.fallback;
+ if (showFallback) {
+ var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
+ var primaryChildFragment = workInProgress.child;
+ primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
+ workInProgress.memoizedState = SUSPENDED_MARKER;
+ return fallbackFragment;
+ } else return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
+ } else {
+ // This is an update.
+ // Special path for hydration
+ var prevState = current.memoizedState;
+ if (prevState !== null) {
+ var _dehydrated = prevState.dehydrated;
+ if (_dehydrated !== null) return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, _dehydrated, prevState, renderLanes);
+ }
+ if (showFallback) {
+ var _nextFallbackChildren = nextProps.fallback;
+ var _nextPrimaryChildren = nextProps.children;
+ var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes);
+ var _primaryChildFragment2 = workInProgress.child;
+ var prevOffscreenState = current.child.memoizedState;
+ _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
+ _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
+ workInProgress.memoizedState = SUSPENDED_MARKER;
+ return fallbackChildFragment;
+ } else {
+ var _nextPrimaryChildren2 = nextProps.children;
+ var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2, renderLanes);
+ workInProgress.memoizedState = null;
+ return _primaryChildFragment3;
+ }
+ }
+ }
+ function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
+ var mode = workInProgress.mode;
+ var primaryChildProps = {
+ mode: "visible",
+ children: primaryChildren
+ };
+ var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
+ primaryChildFragment.return = workInProgress;
+ workInProgress.child = primaryChildFragment;
+ return primaryChildFragment;
+ }
+ function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
+ var mode = workInProgress.mode;
+ var progressedPrimaryFragment = workInProgress.child;
+ var primaryChildProps = {
+ mode: "hidden",
+ children: primaryChildren
+ };
+ var primaryChildFragment;
+ var fallbackChildFragment;
+ if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
+ // In legacy mode, we commit the primary tree as if it successfully
+ // completed, even though it's in an inconsistent state.
+ primaryChildFragment = progressedPrimaryFragment;
+ primaryChildFragment.childLanes = NoLanes;
+ primaryChildFragment.pendingProps = primaryChildProps;
+ if (workInProgress.mode & ProfileMode) {
+ // Reset the durations from the first pass so they aren't included in the
+ // final amounts. This seems counterintuitive, since we're intentionally
+ // not measuring part of the render phase, but this makes it match what we
+ // do in Concurrent Mode.
+ primaryChildFragment.actualDuration = 0;
+ primaryChildFragment.actualStartTime = -1;
+ primaryChildFragment.selfBaseDuration = 0;
+ primaryChildFragment.treeBaseDuration = 0;
+ }
+ fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
+ } else {
+ primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
+ fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
+ }
+ primaryChildFragment.return = workInProgress;
+ fallbackChildFragment.return = workInProgress;
+ primaryChildFragment.sibling = fallbackChildFragment;
+ workInProgress.child = primaryChildFragment;
+ return fallbackChildFragment;
+ }
+ function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
+ // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
+ // this wrapper function to constrain it.
+ return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
+ }
+ function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
+ // The props argument to `createWorkInProgress` is `any` typed, so we use this
+ // wrapper function to constrain it.
+ return createWorkInProgress(current, offscreenProps);
+ }
+ function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
+ var currentPrimaryChildFragment = current.child;
+ var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
+ var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
+ mode: "visible",
+ children: primaryChildren
+ });
+ if ((workInProgress.mode & ConcurrentMode) === NoMode) primaryChildFragment.lanes = renderLanes;
+ primaryChildFragment.return = workInProgress;
+ primaryChildFragment.sibling = null;
+ if (currentFallbackChildFragment !== null) {
+ // Delete the fallback child fragment
+ var deletions = workInProgress.deletions;
+ if (deletions === null) {
+ workInProgress.deletions = [
+ currentFallbackChildFragment
+ ];
+ workInProgress.flags |= ChildDeletion;
+ } else deletions.push(currentFallbackChildFragment);
+ }
+ workInProgress.child = primaryChildFragment;
+ return primaryChildFragment;
+ }
+ function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
+ var mode = workInProgress.mode;
+ var currentPrimaryChildFragment = current.child;
+ var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
+ var primaryChildProps = {
+ mode: "hidden",
+ children: primaryChildren
+ };
+ var primaryChildFragment;
+ if (// completed, even though it's in an inconsistent state.
+ (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
+ // already cloned. In legacy mode, the only case where this isn't true is
+ // when DevTools forces us to display a fallback; we skip the first render
+ // pass entirely and go straight to rendering the fallback. (In Concurrent
+ // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
+ // only codepath.)
+ workInProgress.child !== currentPrimaryChildFragment) {
+ var progressedPrimaryFragment = workInProgress.child;
+ primaryChildFragment = progressedPrimaryFragment;
+ primaryChildFragment.childLanes = NoLanes;
+ primaryChildFragment.pendingProps = primaryChildProps;
+ if (workInProgress.mode & ProfileMode) {
+ // Reset the durations from the first pass so they aren't included in the
+ // final amounts. This seems counterintuitive, since we're intentionally
+ // not measuring part of the render phase, but this makes it match what we
+ // do in Concurrent Mode.
+ primaryChildFragment.actualDuration = 0;
+ primaryChildFragment.actualStartTime = -1;
+ primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
+ primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
+ } // The fallback fiber was added as a deletion during the first pass.
+ // However, since we're going to remain on the fallback, we no longer want
+ // to delete it.
+ workInProgress.deletions = null;
+ } else {
+ primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too.
+ // (We don't do this in legacy mode, because in legacy mode we don't re-use
+ // the current tree; see previous branch.)
+ primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
+ }
+ var fallbackChildFragment;
+ if (currentFallbackChildFragment !== null) fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
+ else {
+ fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
+ // mounted but this is a new fiber.
+ fallbackChildFragment.flags |= Placement;
+ }
+ fallbackChildFragment.return = workInProgress;
+ primaryChildFragment.return = workInProgress;
+ primaryChildFragment.sibling = fallbackChildFragment;
+ workInProgress.child = primaryChildFragment;
+ return fallbackChildFragment;
+ }
+ function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) {
+ // Falling back to client rendering. Because this has performance
+ // implications, it's considered a recoverable error, even though the user
+ // likely won't observe anything wrong with the UI.
+ //
+ // The error is passed in as an argument to enforce that every caller provide
+ // a custom message, or explicitly opt out (currently the only path that opts
+ // out is legacy mode; every concurrent path provides an error).
+ if (recoverableError !== null) queueHydrationError(recoverableError);
+ // This will add the old fiber to the deletion list
+ reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
+ var nextProps = workInProgress.pendingProps;
+ var primaryChildren = nextProps.children;
+ var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already
+ // mounted but this is a new fiber.
+ primaryChildFragment.flags |= Placement;
+ workInProgress.memoizedState = null;
+ return primaryChildFragment;
+ }
+ function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
+ var fiberMode = workInProgress.mode;
+ var primaryChildProps = {
+ mode: "visible",
+ children: primaryChildren
+ };
+ var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
+ var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense
+ // boundary) already mounted but this is a new fiber.
+ fallbackChildFragment.flags |= Placement;
+ primaryChildFragment.return = workInProgress;
+ fallbackChildFragment.return = workInProgress;
+ primaryChildFragment.sibling = fallbackChildFragment;
+ workInProgress.child = primaryChildFragment;
+ if ((workInProgress.mode & ConcurrentMode) !== NoMode) // We will have dropped the effect list which contains the
+ // deletion. We need to reconcile to delete the current child.
+ reconcileChildFibers(workInProgress, current.child, null, renderLanes);
+ return fallbackChildFragment;
+ }
+ function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) {
+ // During the first pass, we'll bail out and not drill into the children.
+ // Instead, we'll leave the content in place and try to hydrate it later.
+ if ((workInProgress.mode & ConcurrentMode) === NoMode) {
+ error("Cannot hydrate Suspense in legacy mode. Switch from ReactDOM.hydrate(element, container) to ReactDOMClient.hydrateRoot(container, ).render(element) or remove the Suspense components from the server rendered components.");
+ workInProgress.lanes = laneToLanes(SyncLane);
+ } else if (isSuspenseInstanceFallback(suspenseInstance)) // This is a client-only boundary. Since we won't get any content from the server
+ // for this, we need to schedule that at a higher priority based on when it would
+ // have timed out. In theory we could render it in this pass but it would have the
+ // wrong priority associated with it and will prevent hydration of parent path.
+ // Instead, we'll leave work left on it to render it in a separate commit.
+ // TODO This time should be the time at which the server rendered response that is
+ // a parent to this boundary was displayed. However, since we currently don't have
+ // a protocol to transfer that time, we'll just estimate it by using the current
+ // time. This will mean that Suspense timeouts are slightly shifted to later than
+ // they should be.
+ // Schedule a normal pri update to render this content.
+ workInProgress.lanes = laneToLanes(DefaultHydrationLane);
+ else // We'll continue hydrating the rest at offscreen priority since we'll already
+ // be showing the right content coming from the server, it is no rush.
+ workInProgress.lanes = laneToLanes(OffscreenLane);
+ return null;
+ }
+ function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, suspenseInstance, suspenseState, renderLanes) {
+ if (!didSuspend) {
+ // This is the first render pass. Attempt to hydrate.
+ // We should never be hydrating at this point because it is the first pass,
+ // but after we've already committed once.
+ warnIfHydrating();
+ if ((workInProgress.mode & ConcurrentMode) === NoMode) return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // required \u2014 every concurrent mode path that causes hydration to
+ // de-opt to client rendering should have an error message.
+ null);
+ if (isSuspenseInstanceFallback(suspenseInstance)) {
+ // This boundary is in a permanent fallback state. In this case, we'll never
+ // get an update and we'll never be able to hydrate the final content. Let's just try the
+ // client side render instead.
+ var digest, message, stack;
+ var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(suspenseInstance);
+ digest = _getSuspenseInstanceF.digest;
+ message = _getSuspenseInstanceF.message;
+ stack = _getSuspenseInstanceF.stack;
+ var error;
+ if (message) // eslint-disable-next-line react-internal/prod-error-codes
+ error = new Error(message);
+ else error = new Error("The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.");
+ var capturedValue = createCapturedValue(error, digest, stack);
+ return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, capturedValue);
+ }
+ // any context has changed, we need to treat is as if the input might have changed.
+ var hasContextChanged = includesSomeLane(renderLanes, current.childLanes);
+ if (didReceiveUpdate || hasContextChanged) {
+ // This boundary has changed since the first render. This means that we are now unable to
+ // hydrate it. We might still be able to hydrate it using a higher priority lane.
+ var root = getWorkInProgressRoot();
+ if (root !== null) {
+ var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes);
+ if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
+ // Intentionally mutating since this render will get interrupted. This
+ // is one of the very rare times where we mutate the current tree
+ // during the render phase.
+ suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render
+ var eventTime = NoTimestamp;
+ enqueueConcurrentRenderForLane(current, attemptHydrationAtLane);
+ scheduleUpdateOnFiber(root, current, attemptHydrationAtLane, eventTime);
+ }
+ } // If we have scheduled higher pri work above, this will probably just abort the render
+ // since we now have higher priority work, but in case it doesn't, we need to prepare to
+ // render something, if we time out. Even if that requires us to delete everything and
+ // skip hydration.
+ // Delay having to do this as long as the suspense timeout allows us.
+ renderDidSuspendDelayIfPossible();
+ var _capturedValue = createCapturedValue(new Error("This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition."));
+ return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue);
+ } else if (isSuspenseInstancePending(suspenseInstance)) {
+ // This component is still pending more data from the server, so we can't hydrate its
+ // content. We treat it as if this component suspended itself. It might seem as if
+ // we could just try to render it client-side instead. However, this will perform a
+ // lot of unnecessary work and is unlikely to complete since it often will suspend
+ // on missing data anyway. Additionally, the server might be able to render more
+ // than we can on the client yet. In that case we'd end up with more fallback states
+ // on the client than if we just leave it alone. If the server times out or errors
+ // these should update this boundary to the permanent Fallback state instead.
+ // Mark it as having captured (i.e. suspended).
+ workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
+ workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
+ var retry = retryDehydratedSuspenseBoundary.bind(null, current);
+ registerSuspenseInstanceRetry(suspenseInstance, retry);
+ return null;
+ } else {
+ // This is the first attempt.
+ reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext);
+ var primaryChildren = nextProps.children;
+ var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this
+ // tree is part of a hydrating tree. This is used to determine if a child
+ // node has fully mounted yet, and for scheduling event replaying.
+ // Conceptually this is similar to Placement in that a new subtree is
+ // inserted into the React tree here. It just happens to not need DOM
+ // mutations because it already exists.
+ primaryChildFragment.flags |= Hydrating;
+ return primaryChildFragment;
+ }
+ } else {
+ // This is the second render pass. We already attempted to hydrated, but
+ // something either suspended or errored.
+ if (workInProgress.flags & ForceClientRender) {
+ // Something errored during hydration. Try again without hydrating.
+ workInProgress.flags &= ~ForceClientRender;
+ var _capturedValue2 = createCapturedValue(new Error("There was an error while hydrating this Suspense boundary. Switched to client rendering."));
+ return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue2);
+ } else if (workInProgress.memoizedState !== null) {
+ // Something suspended and we should still be in dehydrated mode.
+ // Leave the existing child in place.
+ workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
+ // but the normal suspense pass doesn't.
+ workInProgress.flags |= DidCapture;
+ return null;
+ } else {
+ // Suspended but we should no longer be in dehydrated mode.
+ // Therefore we now have to render the fallback.
+ var nextPrimaryChildren = nextProps.children;
+ var nextFallbackChildren = nextProps.fallback;
+ var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
+ var _primaryChildFragment4 = workInProgress.child;
+ _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes);
+ workInProgress.memoizedState = SUSPENDED_MARKER;
+ return fallbackChildFragment;
+ }
+ }
+ }
+ function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
+ fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
+ var alternate = fiber.alternate;
+ if (alternate !== null) alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
+ scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
+ }
+ function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
+ // Mark any Suspense boundaries with fallbacks as having work to do.
+ // If they were previously forced into fallbacks, they may now be able
+ // to unblock.
+ var node = firstChild;
+ while(node !== null){
+ if (node.tag === SuspenseComponent) {
+ var state = node.memoizedState;
+ if (state !== null) scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
+ } else if (node.tag === SuspenseListComponent) // If the tail is hidden there might not be an Suspense boundaries
+ // to schedule work on. In this case we have to schedule it on the
+ // list itself.
+ // We don't have to traverse to the children of the list since
+ // the list will propagate the change when it rerenders.
+ scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
+ else if (node.child !== null) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === workInProgress) return;
+ while(node.sibling === null){
+ if (node.return === null || node.return === workInProgress) return;
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ }
+ function findLastContentRow(firstChild) {
+ // This is going to find the last row among these children that is already
+ // showing content on the screen, as opposed to being in fallback state or
+ // new. If a row has multiple Suspense boundaries, any of them being in the
+ // fallback state, counts as the whole row being in a fallback state.
+ // Note that the "rows" will be workInProgress, but any nested children
+ // will still be current since we haven't rendered them yet. The mounted
+ // order may not be the same as the new order. We use the new order.
+ var row = firstChild;
+ var lastContentRow = null;
+ while(row !== null){
+ var currentRow = row.alternate; // New rows can't be content rows.
+ if (currentRow !== null && findFirstSuspended(currentRow) === null) lastContentRow = row;
+ row = row.sibling;
+ }
+ return lastContentRow;
+ }
+ function validateRevealOrder(revealOrder) {
+ if (revealOrder !== undefined && revealOrder !== "forwards" && revealOrder !== "backwards" && revealOrder !== "together" && !didWarnAboutRevealOrder[revealOrder]) {
+ didWarnAboutRevealOrder[revealOrder] = true;
+ if (typeof revealOrder === "string") switch(revealOrder.toLowerCase()){
+ case "together":
+ case "forwards":
+ case "backwards":
+ error('"%s" is not a valid value for revealOrder on . Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
+ break;
+ case "forward":
+ case "backward":
+ error('"%s" is not a valid value for revealOrder on . React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
+ break;
+ default:
+ error('"%s" is not a supported revealOrder on . Did you mean "together", "forwards" or "backwards"?', revealOrder);
+ break;
+ }
+ else error('%s is not a supported value for revealOrder on . Did you mean "together", "forwards" or "backwards"?', revealOrder);
+ }
+ }
+ function validateTailOptions(tailMode, revealOrder) {
+ if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
+ if (tailMode !== "collapsed" && tailMode !== "hidden") {
+ didWarnAboutTailOptions[tailMode] = true;
+ error('"%s" is not a supported value for tail on . Did you mean "collapsed" or "hidden"?', tailMode);
+ } else if (revealOrder !== "forwards" && revealOrder !== "backwards") {
+ didWarnAboutTailOptions[tailMode] = true;
+ error(' is only valid if revealOrder is "forwards" or "backwards". Did you mean to specify revealOrder="forwards"?', tailMode);
+ }
+ }
+ }
+ function validateSuspenseListNestedChild(childSlot, index) {
+ var isAnArray = isArray(childSlot);
+ var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === "function";
+ if (isAnArray || isIterable) {
+ var type = isAnArray ? "array" : "iterable";
+ error("A nested %s was passed to row #%s in . Wrap it in an additional SuspenseList to configure its revealOrder: ... {%s} ... ", type, index, type);
+ return false;
+ }
+ return true;
+ }
+ function validateSuspenseListChildren(children, revealOrder) {
+ if ((revealOrder === "forwards" || revealOrder === "backwards") && children !== undefined && children !== null && children !== false) {
+ if (isArray(children)) for(var i = 0; i < children.length; i++){
+ if (!validateSuspenseListNestedChild(children[i], i)) return;
+ }
+ else {
+ var iteratorFn = getIteratorFn(children);
+ if (typeof iteratorFn === "function") {
+ var childrenIterator = iteratorFn.call(children);
+ if (childrenIterator) {
+ var step = childrenIterator.next();
+ var _i = 0;
+ for(; !step.done; step = childrenIterator.next()){
+ if (!validateSuspenseListNestedChild(step.value, _i)) return;
+ _i++;
+ }
+ }
+ } else error('A single row was passed to a . This is not useful since it needs multiple rows. Did you mean to pass multiple children or an array?', revealOrder);
+ }
+ }
+ }
+ function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
+ var renderState = workInProgress.memoizedState;
+ if (renderState === null) workInProgress.memoizedState = {
+ isBackwards: isBackwards,
+ rendering: null,
+ renderingStartTime: 0,
+ last: lastContentRow,
+ tail: tail,
+ tailMode: tailMode
+ };
+ else {
+ // We can reuse the existing object from previous renders.
+ renderState.isBackwards = isBackwards;
+ renderState.rendering = null;
+ renderState.renderingStartTime = 0;
+ renderState.last = lastContentRow;
+ renderState.tail = tail;
+ renderState.tailMode = tailMode;
+ }
+ } // This can end up rendering this component multiple passes.
+ // The first pass splits the children fibers into two sets. A head and tail.
+ // We first render the head. If anything is in fallback state, we do another
+ // pass through beginWork to rerender all children (including the tail) with
+ // the force suspend context. If the first render didn't have anything in
+ // in fallback state. Then we render each row in the tail one-by-one.
+ // That happens in the completeWork phase without going back to beginWork.
+ function updateSuspenseListComponent(current, workInProgress, renderLanes) {
+ var nextProps = workInProgress.pendingProps;
+ var revealOrder = nextProps.revealOrder;
+ var tailMode = nextProps.tail;
+ var newChildren = nextProps.children;
+ validateRevealOrder(revealOrder);
+ validateTailOptions(tailMode, revealOrder);
+ validateSuspenseListChildren(newChildren, revealOrder);
+ reconcileChildren(current, workInProgress, newChildren, renderLanes);
+ var suspenseContext = suspenseStackCursor.current;
+ var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
+ if (shouldForceFallback) {
+ suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
+ workInProgress.flags |= DidCapture;
+ } else {
+ var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
+ if (didSuspendBefore) // If we previously forced a fallback, we need to schedule work
+ // on any nested boundaries to let them know to try to render
+ // again. This is the same as context updating.
+ propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
+ suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
+ }
+ pushSuspenseContext(workInProgress, suspenseContext);
+ if ((workInProgress.mode & ConcurrentMode) === NoMode) // In legacy mode, SuspenseList doesn't work so we just
+ // use make it a noop by treating it as the default revealOrder.
+ workInProgress.memoizedState = null;
+ else switch(revealOrder){
+ case "forwards":
+ var lastContentRow = findLastContentRow(workInProgress.child);
+ var tail;
+ if (lastContentRow === null) {
+ // The whole list is part of the tail.
+ // TODO: We could fast path by just rendering the tail now.
+ tail = workInProgress.child;
+ workInProgress.child = null;
+ } else {
+ // Disconnect the tail rows after the content row.
+ // We're going to render them separately later.
+ tail = lastContentRow.sibling;
+ lastContentRow.sibling = null;
+ }
+ initSuspenseListRenderState(workInProgress, false, tail, lastContentRow, tailMode);
+ break;
+ case "backwards":
+ // We're going to find the first row that has existing content.
+ // At the same time we're going to reverse the list of everything
+ // we pass in the meantime. That's going to be our tail in reverse
+ // order.
+ var _tail = null;
+ var row = workInProgress.child;
+ workInProgress.child = null;
+ while(row !== null){
+ var currentRow = row.alternate; // New rows can't be content rows.
+ if (currentRow !== null && findFirstSuspended(currentRow) === null) {
+ // This is the beginning of the main content.
+ workInProgress.child = row;
+ break;
+ }
+ var nextRow = row.sibling;
+ row.sibling = _tail;
+ _tail = row;
+ row = nextRow;
+ } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
+ initSuspenseListRenderState(workInProgress, true, _tail, null, tailMode);
+ break;
+ case "together":
+ initSuspenseListRenderState(workInProgress, false, null, null, undefined);
+ break;
+ default:
+ // The default reveal order is the same as not having
+ // a boundary.
+ workInProgress.memoizedState = null;
+ }
+ return workInProgress.child;
+ }
+ function updatePortalComponent(current, workInProgress, renderLanes) {
+ pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
+ var nextChildren = workInProgress.pendingProps;
+ if (current === null) // Portals are special because we don't append the children during mount
+ // but at commit. Therefore we need to track insertions which the normal
+ // flow doesn't do during mount. This doesn't happen at the root because
+ // the root always starts with a "current" with a null child.
+ // TODO: Consider unifying this with how the root works.
+ workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
+ else reconcileChildren(current, workInProgress, nextChildren, renderLanes);
+ return workInProgress.child;
+ }
+ var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
+ function updateContextProvider(current, workInProgress, renderLanes) {
+ var providerType = workInProgress.type;
+ var context = providerType._context;
+ var newProps = workInProgress.pendingProps;
+ var oldProps = workInProgress.memoizedProps;
+ var newValue = newProps.value;
+ if (!("value" in newProps)) {
+ if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
+ hasWarnedAboutUsingNoValuePropOnContextProvider = true;
+ error("The `value` prop is required for the ``. Did you misspell it or forget to pass it?");
+ }
+ }
+ var providerPropTypes = workInProgress.type.propTypes;
+ if (providerPropTypes) checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider");
+ pushProvider(workInProgress, context, newValue);
+ if (oldProps !== null) {
+ var oldValue = oldProps.value;
+ if (objectIs(oldValue, newValue)) {
+ // No change. Bailout early if children are the same.
+ if (oldProps.children === newProps.children && !hasContextChanged()) return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ } else // The context value changed. Search for matching consumers and schedule
+ // them to update.
+ propagateContextChange(workInProgress, context, renderLanes);
+ }
+ var newChildren = newProps.children;
+ reconcileChildren(current, workInProgress, newChildren, renderLanes);
+ return workInProgress.child;
+ }
+ var hasWarnedAboutUsingContextAsConsumer = false;
+ function updateContextConsumer(current, workInProgress, renderLanes) {
+ var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
+ if (context._context === undefined) {
+ // This may be because it's a Context (rather than a Consumer).
+ // Or it may be because it's older React where they're the same thing.
+ // We only want to warn if we're sure it's a new React.
+ if (context !== context.Consumer) {
+ if (!hasWarnedAboutUsingContextAsConsumer) {
+ hasWarnedAboutUsingContextAsConsumer = true;
+ error("Rendering directly is not supported and will be removed in a future major release. Did you mean to render instead?");
+ }
+ }
+ } else context = context._context;
+ var newProps = workInProgress.pendingProps;
+ var render = newProps.children;
+ if (typeof render !== "function") error("A context consumer was rendered with multiple children, or a child that isn't a function. A context consumer expects a single child that is a function. If you did pass a function, make sure there is no trailing or leading whitespace around it.");
+ prepareToReadContext(workInProgress, renderLanes);
+ var newValue = readContext(context);
+ markComponentRenderStarted(workInProgress);
+ var newChildren;
+ ReactCurrentOwner$1.current = workInProgress;
+ setIsRendering(true);
+ newChildren = render(newValue);
+ setIsRendering(false);
+ markComponentRenderStopped();
+ workInProgress.flags |= PerformedWork;
+ reconcileChildren(current, workInProgress, newChildren, renderLanes);
+ return workInProgress.child;
+ }
+ function markWorkInProgressReceivedUpdate() {
+ didReceiveUpdate = true;
+ }
+ function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) {
+ if ((workInProgress.mode & ConcurrentMode) === NoMode) {
+ if (current !== null) {
+ // A lazy component only mounts if it suspended inside a non-
+ // concurrent tree, in an inconsistent state. We want to treat it like
+ // a new mount, even though an empty version of it already committed.
+ // Disconnect the alternate pointers.
+ current.alternate = null;
+ workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
+ workInProgress.flags |= Placement;
+ }
+ }
+ }
+ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
+ if (current !== null) // Reuse previous dependencies
+ workInProgress.dependencies = current.dependencies;
+ // Don't update "base" render times for bailouts.
+ stopProfilerTimerIfRunning();
+ markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
+ if (!includesSomeLane(renderLanes, workInProgress.childLanes)) return null;
+ // This fiber doesn't have work, but its subtree does. Clone the child
+ // fibers and continue.
+ cloneChildFibers(current, workInProgress);
+ return workInProgress.child;
+ }
+ function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
+ var returnFiber = oldWorkInProgress.return;
+ if (returnFiber === null) // eslint-disable-next-line react-internal/prod-error-codes
+ throw new Error("Cannot swap the root fiber.");
+ // Disconnect from the old current.
+ // It will get deleted.
+ current.alternate = null;
+ oldWorkInProgress.alternate = null; // Connect to the new tree.
+ newWorkInProgress.index = oldWorkInProgress.index;
+ newWorkInProgress.sibling = oldWorkInProgress.sibling;
+ newWorkInProgress.return = oldWorkInProgress.return;
+ newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
+ if (oldWorkInProgress === returnFiber.child) returnFiber.child = newWorkInProgress;
+ else {
+ var prevSibling = returnFiber.child;
+ if (prevSibling === null) // eslint-disable-next-line react-internal/prod-error-codes
+ throw new Error("Expected parent to have a child.");
+ while(prevSibling.sibling !== oldWorkInProgress){
+ prevSibling = prevSibling.sibling;
+ if (prevSibling === null) // eslint-disable-next-line react-internal/prod-error-codes
+ throw new Error("Expected to find the previous sibling.");
+ }
+ prevSibling.sibling = newWorkInProgress;
+ } // Delete the old fiber and place the new one.
+ // Since the old fiber is disconnected, we have to schedule it manually.
+ var deletions = returnFiber.deletions;
+ if (deletions === null) {
+ returnFiber.deletions = [
+ current
+ ];
+ returnFiber.flags |= ChildDeletion;
+ } else deletions.push(current);
+ newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
+ return newWorkInProgress;
+ }
+ function checkScheduledUpdateOrContext(current, renderLanes) {
+ // Before performing an early bailout, we must check if there are pending
+ // updates or context.
+ var updateLanes = current.lanes;
+ if (includesSomeLane(updateLanes, renderLanes)) return true;
+ // No pending update, but because context is propagated lazily, we need
+ return false;
+ }
+ function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
+ // This fiber does not have any pending work. Bailout without entering
+ // the begin phase. There's still some bookkeeping we that needs to be done
+ // in this optimized path, mostly pushing stuff onto the stack.
+ switch(workInProgress.tag){
+ case HostRoot:
+ pushHostRootContext(workInProgress);
+ var root = workInProgress.stateNode;
+ resetHydrationState();
+ break;
+ case HostComponent:
+ pushHostContext(workInProgress);
+ break;
+ case ClassComponent:
+ var Component = workInProgress.type;
+ if (isContextProvider(Component)) pushContextProvider(workInProgress);
+ break;
+ case HostPortal:
+ pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
+ break;
+ case ContextProvider:
+ var newValue = workInProgress.memoizedProps.value;
+ var context = workInProgress.type._context;
+ pushProvider(workInProgress, context, newValue);
+ break;
+ case Profiler:
+ // Profiler should only call onRender when one of its descendants actually rendered.
+ var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
+ if (hasChildWork) workInProgress.flags |= Update;
+ // Reset effect durations for the next eventual effect phase.
+ // These are reset during render to allow the DevTools commit hook a chance to read them,
+ var stateNode = workInProgress.stateNode;
+ stateNode.effectDuration = 0;
+ stateNode.passiveEffectDuration = 0;
+ break;
+ case SuspenseComponent:
+ var state = workInProgress.memoizedState;
+ if (state !== null) {
+ if (state.dehydrated !== null) {
+ pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
+ // been unsuspended it has committed as a resolved Suspense component.
+ // If it needs to be retried, it should have work scheduled on it.
+ workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we
+ // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork.
+ return null;
+ } // If this boundary is currently timed out, we need to decide
+ // whether to retry the primary children, or to skip over it and
+ // go straight to the fallback. Check the priority of the primary
+ // child fragment.
+ var primaryChildFragment = workInProgress.child;
+ var primaryChildLanes = primaryChildFragment.childLanes;
+ if (includesSomeLane(renderLanes, primaryChildLanes)) // The primary children have pending work. Use the normal path
+ // to attempt to render the primary children again.
+ return updateSuspenseComponent(current, workInProgress, renderLanes);
+ else {
+ // The primary child fragment does not have pending work marked
+ // on it
+ pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
+ // priority. Bailout.
+ var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ if (child !== null) // The fallback children have pending work. Skip over the
+ // primary children and work on the fallback.
+ return child.sibling;
+ else // Note: We can return `null` here because we already checked
+ // whether there were nested context consumers, via the call to
+ // `bailoutOnAlreadyFinishedWork` above.
+ return null;
+ }
+ } else pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
+ break;
+ case SuspenseListComponent:
+ var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
+ var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
+ if (didSuspendBefore) {
+ if (_hasChildWork) // If something was in fallback state last time, and we have all the
+ // same children then we're still in progressive loading state.
+ // Something might get unblocked by state updates or retries in the
+ // tree which will affect the tail. So we need to use the normal
+ // path to compute the correct tail.
+ return updateSuspenseListComponent(current, workInProgress, renderLanes);
+ // If none of the children had any work, that means that none of
+ // them got retried so they'll still be blocked in the same way
+ // as before. We can fast bail out.
+ workInProgress.flags |= DidCapture;
+ } // If nothing suspended before and we're rendering the same children,
+ // then the tail doesn't matter. Anything new that suspends will work
+ // in the "together" mode, so we can continue from the state we had.
+ var renderState = workInProgress.memoizedState;
+ if (renderState !== null) {
+ // Reset to the "together" mode in case we've started a different
+ // update in the past but didn't complete it.
+ renderState.rendering = null;
+ renderState.tail = null;
+ renderState.lastEffect = null;
+ }
+ pushSuspenseContext(workInProgress, suspenseStackCursor.current);
+ if (_hasChildWork) break;
+ else // If none of the children had any work, that means that none of
+ // them got retried so they'll still be blocked in the same way
+ // as before. We can fast bail out.
+ return null;
+ case OffscreenComponent:
+ case LegacyHiddenComponent:
+ // Need to check if the tree still needs to be deferred. This is
+ // almost identical to the logic used in the normal update path,
+ // so we'll just enter that. The only difference is we'll bail out
+ // at the next level instead of this one, because the child props
+ // have not changed. Which is fine.
+ // TODO: Probably should refactor `beginWork` to split the bailout
+ // path from the normal path. I'm tempted to do a labeled break here
+ // but I won't :)
+ workInProgress.lanes = NoLanes;
+ return updateOffscreenComponent(current, workInProgress, renderLanes);
+ }
+ return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
+ }
+ function beginWork(current, workInProgress, renderLanes) {
+ if (workInProgress._debugNeedsRemount && current !== null) // This will restart the begin phase with a new fiber.
+ return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
+ if (current !== null) {
+ var oldProps = current.memoizedProps;
+ var newProps = workInProgress.pendingProps;
+ if (oldProps !== newProps || hasContextChanged() || workInProgress.type !== current.type) // If props or context changed, mark the fiber as having performed work.
+ // This may be unset if the props are determined to be equal later (memo).
+ didReceiveUpdate = true;
+ else {
+ // Neither props nor legacy context changes. Check if there's a pending
+ // update or context change.
+ var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
+ if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
+ // may not be work scheduled on `current`, so we check for this flag.
+ (workInProgress.flags & DidCapture) === NoFlags) {
+ // No pending updates or context. Bail out now.
+ didReceiveUpdate = false;
+ return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
+ }
+ if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) // This is a special case that only exists for legacy mode.
+ // See https://github.com/facebook/react/pull/19216.
+ didReceiveUpdate = true;
+ else // An update was scheduled on this fiber, but there are no new props
+ // nor legacy context. Set this to false. If an update queue or context
+ // consumer produces a changed value, it will set this to true. Otherwise,
+ // the component will assume the children have not changed and bail out.
+ didReceiveUpdate = false;
+ }
+ } else {
+ didReceiveUpdate = false;
+ if (getIsHydrating() && isForkedChild(workInProgress)) {
+ // Check if this child belongs to a list of muliple children in
+ // its parent.
+ //
+ // In a true multi-threaded implementation, we would render children on
+ // parallel threads. This would represent the beginning of a new render
+ // thread for this subtree.
+ //
+ // We only use this for id generation during hydration, which is why the
+ // logic is located in this special branch.
+ var slotIndex = workInProgress.index;
+ var numberOfForks = getForksAtLevel();
+ pushTreeId(workInProgress, numberOfForks, slotIndex);
+ }
+ } // Before entering the begin phase, clear pending update priority.
+ // TODO: This assumes that we're about to evaluate the component and process
+ // the update queue. However, there's an exception: SimpleMemoComponent
+ // sometimes bails out later in the begin phase. This indicates that we should
+ // move this assignment out of the common path and into each branch.
+ workInProgress.lanes = NoLanes;
+ switch(workInProgress.tag){
+ case IndeterminateComponent:
+ return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
+ case LazyComponent:
+ var elementType = workInProgress.elementType;
+ return mountLazyComponent(current, workInProgress, elementType, renderLanes);
+ case FunctionComponent:
+ var Component = workInProgress.type;
+ var unresolvedProps = workInProgress.pendingProps;
+ var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
+ return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
+ case ClassComponent:
+ var _Component = workInProgress.type;
+ var _unresolvedProps = workInProgress.pendingProps;
+ var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
+ return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes);
+ case HostRoot:
+ return updateHostRoot(current, workInProgress, renderLanes);
+ case HostComponent:
+ return updateHostComponent(current, workInProgress, renderLanes);
+ case HostText:
+ return updateHostText(current, workInProgress);
+ case SuspenseComponent:
+ return updateSuspenseComponent(current, workInProgress, renderLanes);
+ case HostPortal:
+ return updatePortalComponent(current, workInProgress, renderLanes);
+ case ForwardRef:
+ var type = workInProgress.type;
+ var _unresolvedProps2 = workInProgress.pendingProps;
+ var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
+ return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
+ case Fragment:
+ return updateFragment(current, workInProgress, renderLanes);
+ case Mode:
+ return updateMode(current, workInProgress, renderLanes);
+ case Profiler:
+ return updateProfiler(current, workInProgress, renderLanes);
+ case ContextProvider:
+ return updateContextProvider(current, workInProgress, renderLanes);
+ case ContextConsumer:
+ return updateContextConsumer(current, workInProgress, renderLanes);
+ case MemoComponent:
+ var _type2 = workInProgress.type;
+ var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
+ var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
+ if (workInProgress.type !== workInProgress.elementType) {
+ var outerPropTypes = _type2.propTypes;
+ if (outerPropTypes) checkPropTypes(outerPropTypes, _resolvedProps3, "prop", getComponentNameFromType(_type2));
+ }
+ _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
+ return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes);
+ case SimpleMemoComponent:
+ return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
+ case IncompleteClassComponent:
+ var _Component2 = workInProgress.type;
+ var _unresolvedProps4 = workInProgress.pendingProps;
+ var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
+ return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes);
+ case SuspenseListComponent:
+ return updateSuspenseListComponent(current, workInProgress, renderLanes);
+ case ScopeComponent:
+ break;
+ case OffscreenComponent:
+ return updateOffscreenComponent(current, workInProgress, renderLanes);
+ }
+ throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + "React. Please file an issue.");
+ }
+ function markUpdate(workInProgress) {
+ // Tag the fiber with an update effect. This turns a Placement into
+ // a PlacementAndUpdate.
+ workInProgress.flags |= Update;
+ }
+ function markRef$1(workInProgress) {
+ workInProgress.flags |= Ref;
+ workInProgress.flags |= RefStatic;
+ }
+ var appendAllChildren;
+ var updateHostContainer;
+ var updateHostComponent$1;
+ var updateHostText$1;
+ // Mutation mode
+ appendAllChildren = function(parent, workInProgress, needsVisibilityToggle, isHidden) {
+ // We only have the top Fiber that was created but we need recurse down its
+ // children to find all the terminal nodes.
+ var node = workInProgress.child;
+ while(node !== null){
+ if (node.tag === HostComponent || node.tag === HostText) appendInitialChild(parent, node.stateNode);
+ else if (node.tag === HostPortal) ;
+ else if (node.child !== null) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === workInProgress) return;
+ while(node.sibling === null){
+ if (node.return === null || node.return === workInProgress) return;
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ };
+ updateHostContainer = function(current, workInProgress) {};
+ updateHostComponent$1 = function(current, workInProgress, type, newProps, rootContainerInstance) {
+ // If we have an alternate, that means this is an update and we need to
+ // schedule a side-effect to do the updates.
+ var oldProps = current.memoizedProps;
+ if (oldProps === newProps) // In mutation mode, this is sufficient for a bailout because
+ // we won't touch this node even if children changed.
+ return;
+ // If we get updated because one of our children updated, we don't
+ // have newProps so we'll have to reuse them.
+ // TODO: Split the update API as separate for the props vs. children.
+ // Even better would be if children weren't special cased at all tho.
+ var instance = workInProgress.stateNode;
+ var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
+ // component is hitting the resume path. Figure out why. Possibly
+ // related to `hidden`.
+ var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
+ workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
+ // is a new ref we mark this as an update. All the work is done in commitWork.
+ if (updatePayload) markUpdate(workInProgress);
+ };
+ updateHostText$1 = function(current, workInProgress, oldText, newText) {
+ // If the text differs, mark it as an update. All the work in done in commitWork.
+ if (oldText !== newText) markUpdate(workInProgress);
+ };
+ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
+ if (getIsHydrating()) // If we're hydrating, we should consume as many items as we can
+ // so we don't leave any behind.
+ return;
+ switch(renderState.tailMode){
+ case "hidden":
+ // Any insertions at the end of the tail list after this point
+ // should be invisible. If there are already mounted boundaries
+ // anything before them are not considered for collapsing.
+ // Therefore we need to go through the whole tail to find if
+ // there are any.
+ var tailNode = renderState.tail;
+ var lastTailNode = null;
+ while(tailNode !== null){
+ if (tailNode.alternate !== null) lastTailNode = tailNode;
+ tailNode = tailNode.sibling;
+ } // Next we're simply going to delete all insertions after the
+ // last rendered item.
+ if (lastTailNode === null) // All remaining items in the tail are insertions.
+ renderState.tail = null;
+ else // Detach the insertion after the last node that was already
+ // inserted.
+ lastTailNode.sibling = null;
+ break;
+ case "collapsed":
+ // Any insertions at the end of the tail list after this point
+ // should be invisible. If there are already mounted boundaries
+ // anything before them are not considered for collapsing.
+ // Therefore we need to go through the whole tail to find if
+ // there are any.
+ var _tailNode = renderState.tail;
+ var _lastTailNode = null;
+ while(_tailNode !== null){
+ if (_tailNode.alternate !== null) _lastTailNode = _tailNode;
+ _tailNode = _tailNode.sibling;
+ } // Next we're simply going to delete all insertions after the
+ // last rendered item.
+ if (_lastTailNode === null) {
+ // All remaining items in the tail are insertions.
+ if (!hasRenderedATailFallback && renderState.tail !== null) // We suspended during the head. We want to show at least one
+ // row at the tail. So we'll keep on and cut off the rest.
+ renderState.tail.sibling = null;
+ else renderState.tail = null;
+ } else // Detach the insertion after the last node that was already
+ // inserted.
+ _lastTailNode.sibling = null;
+ break;
+ }
+ }
+ function bubbleProperties(completedWork) {
+ var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
+ var newChildLanes = NoLanes;
+ var subtreeFlags = NoFlags;
+ if (!didBailout) {
+ // Bubble up the earliest expiration time.
+ if ((completedWork.mode & ProfileMode) !== NoMode) {
+ // In profiling mode, resetChildExpirationTime is also used to reset
+ // profiler durations.
+ var actualDuration = completedWork.actualDuration;
+ var treeBaseDuration = completedWork.selfBaseDuration;
+ var child = completedWork.child;
+ while(child !== null){
+ newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
+ subtreeFlags |= child.subtreeFlags;
+ subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
+ // only be updated if work is done on the fiber (i.e. it doesn't bailout).
+ // When work is done, it should bubble to the parent's actualDuration. If
+ // the fiber has not been cloned though, (meaning no work was done), then
+ // this value will reflect the amount of time spent working on a previous
+ // render. In that case it should not bubble. We determine whether it was
+ // cloned by comparing the child pointer.
+ actualDuration += child.actualDuration;
+ treeBaseDuration += child.treeBaseDuration;
+ child = child.sibling;
+ }
+ completedWork.actualDuration = actualDuration;
+ completedWork.treeBaseDuration = treeBaseDuration;
+ } else {
+ var _child = completedWork.child;
+ while(_child !== null){
+ newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
+ subtreeFlags |= _child.subtreeFlags;
+ subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
+ // smell because it assumes the commit phase is never concurrent with
+ // the render phase. Will address during refactor to alternate model.
+ _child.return = completedWork;
+ _child = _child.sibling;
+ }
+ }
+ completedWork.subtreeFlags |= subtreeFlags;
+ } else {
+ // Bubble up the earliest expiration time.
+ if ((completedWork.mode & ProfileMode) !== NoMode) {
+ // In profiling mode, resetChildExpirationTime is also used to reset
+ // profiler durations.
+ var _treeBaseDuration = completedWork.selfBaseDuration;
+ var _child2 = completedWork.child;
+ while(_child2 !== null){
+ newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
+ // so we should bubble those up even during a bailout. All the other
+ // flags have a lifetime only of a single render + commit, so we should
+ // ignore them.
+ subtreeFlags |= _child2.subtreeFlags & StaticMask;
+ subtreeFlags |= _child2.flags & StaticMask;
+ _treeBaseDuration += _child2.treeBaseDuration;
+ _child2 = _child2.sibling;
+ }
+ completedWork.treeBaseDuration = _treeBaseDuration;
+ } else {
+ var _child3 = completedWork.child;
+ while(_child3 !== null){
+ newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
+ // so we should bubble those up even during a bailout. All the other
+ // flags have a lifetime only of a single render + commit, so we should
+ // ignore them.
+ subtreeFlags |= _child3.subtreeFlags & StaticMask;
+ subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
+ // smell because it assumes the commit phase is never concurrent with
+ // the render phase. Will address during refactor to alternate model.
+ _child3.return = completedWork;
+ _child3 = _child3.sibling;
+ }
+ }
+ completedWork.subtreeFlags |= subtreeFlags;
+ }
+ completedWork.childLanes = newChildLanes;
+ return didBailout;
+ }
+ function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) {
+ if (hasUnhydratedTailNodes() && (workInProgress.mode & ConcurrentMode) !== NoMode && (workInProgress.flags & DidCapture) === NoFlags) {
+ warnIfUnhydratedTailNodes(workInProgress);
+ resetHydrationState();
+ workInProgress.flags |= ForceClientRender | Incomplete | ShouldCapture;
+ return false;
+ }
+ var wasHydrated = popHydrationState(workInProgress);
+ if (nextState !== null && nextState.dehydrated !== null) {
+ // We might be inside a hydration state the first time we're picking up this
+ // Suspense boundary, and also after we've reentered it for further hydration.
+ if (current === null) {
+ if (!wasHydrated) throw new Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.");
+ prepareToHydrateHostSuspenseInstance(workInProgress);
+ bubbleProperties(workInProgress);
+ if ((workInProgress.mode & ProfileMode) !== NoMode) {
+ var isTimedOutSuspense = nextState !== null;
+ if (isTimedOutSuspense) {
+ // Don't count time spent in a timed out Suspense subtree as part of the base duration.
+ var primaryChildFragment = workInProgress.child;
+ if (primaryChildFragment !== null) // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
+ workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
+ }
+ }
+ return false;
+ } else {
+ // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration
+ // state since we're now exiting out of it. popHydrationState doesn't do that for us.
+ resetHydrationState();
+ if ((workInProgress.flags & DidCapture) === NoFlags) // This boundary did not suspend so it's now hydrated and unsuspended.
+ workInProgress.memoizedState = null;
+ // If nothing suspended, we need to schedule an effect to mark this boundary
+ // as having hydrated so events know that they're free to be invoked.
+ // It's also a signal to replay events and the suspense callback.
+ // If something suspended, schedule an effect to attach retry listeners.
+ // So we might as well always mark this.
+ workInProgress.flags |= Update;
+ bubbleProperties(workInProgress);
+ if ((workInProgress.mode & ProfileMode) !== NoMode) {
+ var _isTimedOutSuspense = nextState !== null;
+ if (_isTimedOutSuspense) {
+ // Don't count time spent in a timed out Suspense subtree as part of the base duration.
+ var _primaryChildFragment = workInProgress.child;
+ if (_primaryChildFragment !== null) // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
+ workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
+ }
+ }
+ return false;
+ }
+ } else {
+ // Successfully completed this tree. If this was a forced client render,
+ // there may have been recoverable errors during first hydration
+ // attempt. If so, add them to a queue so we can log them in the
+ // commit phase.
+ upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path
+ return true;
+ }
+ }
+ function completeWork(current, workInProgress, renderLanes) {
+ var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
+ // to the current tree provider fiber is just as fast and less error-prone.
+ // Ideally we would have a special version of the work loop only
+ // for hydration.
+ popTreeContext(workInProgress);
+ switch(workInProgress.tag){
+ case IndeterminateComponent:
+ case LazyComponent:
+ case SimpleMemoComponent:
+ case FunctionComponent:
+ case ForwardRef:
+ case Fragment:
+ case Mode:
+ case Profiler:
+ case ContextConsumer:
+ case MemoComponent:
+ bubbleProperties(workInProgress);
+ return null;
+ case ClassComponent:
+ var Component = workInProgress.type;
+ if (isContextProvider(Component)) popContext(workInProgress);
+ bubbleProperties(workInProgress);
+ return null;
+ case HostRoot:
+ var fiberRoot = workInProgress.stateNode;
+ popHostContainer(workInProgress);
+ popTopLevelContextObject(workInProgress);
+ resetWorkInProgressVersions();
+ if (fiberRoot.pendingContext) {
+ fiberRoot.context = fiberRoot.pendingContext;
+ fiberRoot.pendingContext = null;
+ }
+ if (current === null || current.child === null) {
+ // If we hydrated, pop so that we can delete any remaining children
+ // that weren't hydrated.
+ var wasHydrated = popHydrationState(workInProgress);
+ if (wasHydrated) // If we hydrated, then we'll need to schedule an update for
+ // the commit side-effects on the root.
+ markUpdate(workInProgress);
+ else if (current !== null) {
+ var prevState = current.memoizedState;
+ if (!prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
+ (workInProgress.flags & ForceClientRender) !== NoFlags) {
+ // Schedule an effect to clear this container at the start of the
+ // next commit. This handles the case of React rendering into a
+ // container with previous children. It's also safe to do for
+ // updates too, because current.child would only be null if the
+ // previous render was null (so the container would already
+ // be empty).
+ workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
+ // recoverable errors during first hydration attempt. If so, add
+ // them to a queue so we can log them in the commit phase.
+ upgradeHydrationErrorsToRecoverable();
+ }
+ }
+ }
+ updateHostContainer(current, workInProgress);
+ bubbleProperties(workInProgress);
+ return null;
+ case HostComponent:
+ popHostContext(workInProgress);
+ var rootContainerInstance = getRootHostContainer();
+ var type = workInProgress.type;
+ if (current !== null && workInProgress.stateNode != null) {
+ updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
+ if (current.ref !== workInProgress.ref) markRef$1(workInProgress);
+ } else {
+ if (!newProps) {
+ if (workInProgress.stateNode === null) throw new Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");
+ // This can happen when we abort work.
+ bubbleProperties(workInProgress);
+ return null;
+ }
+ var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
+ // "stack" as the parent. Then append children as we go in beginWork
+ // or completeWork depending on whether we want to add them top->down or
+ // bottom->up. Top->down is faster in IE11.
+ var _wasHydrated = popHydrationState(workInProgress);
+ if (_wasHydrated) // TODO: Move this and createInstance step into the beginPhase
+ // to consolidate.
+ {
+ if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) // If changes to the hydrated node need to be applied at the
+ // commit-phase we mark this as such.
+ markUpdate(workInProgress);
+ } else {
+ var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
+ appendAllChildren(instance, workInProgress, false, false);
+ workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
+ // (eg DOM renderer supports auto-focus for certain elements).
+ // Make sure such renderers get scheduled for later work.
+ if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) markUpdate(workInProgress);
+ }
+ if (workInProgress.ref !== null) // If there is a ref on a host node we need to schedule a callback
+ markRef$1(workInProgress);
+ }
+ bubbleProperties(workInProgress);
+ return null;
+ case HostText:
+ var newText = newProps;
+ if (current && workInProgress.stateNode != null) {
+ var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
+ // to schedule a side-effect to do the updates.
+ updateHostText$1(current, workInProgress, oldText, newText);
+ } else {
+ if (typeof newText !== "string") {
+ if (workInProgress.stateNode === null) throw new Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");
+ // This can happen when we abort work.
+ }
+ var _rootContainerInstance = getRootHostContainer();
+ var _currentHostContext = getHostContext();
+ var _wasHydrated2 = popHydrationState(workInProgress);
+ if (_wasHydrated2) {
+ if (prepareToHydrateHostTextInstance(workInProgress)) markUpdate(workInProgress);
+ } else workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
+ }
+ bubbleProperties(workInProgress);
+ return null;
+ case SuspenseComponent:
+ popSuspenseContext(workInProgress);
+ var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this
+ // to its own fiber type so that we can add other kinds of hydration
+ // boundaries that aren't associated with a Suspense tree. In anticipation
+ // of such a refactor, all the hydration logic is contained in
+ // this branch.
+ if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) {
+ var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState);
+ if (!fallthroughToNormalSuspensePath) {
+ if (workInProgress.flags & ShouldCapture) // Special case. There were remaining unhydrated nodes. We treat
+ // this as a mismatch. Revert to client rendering.
+ return workInProgress;
+ else // Did not finish hydrating, either because this is the initial
+ // render or because something suspended.
+ return null;
+ } // Continue with the normal Suspense path.
+ }
+ if ((workInProgress.flags & DidCapture) !== NoFlags) {
+ // Something suspended. Re-render with the fallback children.
+ workInProgress.lanes = renderLanes; // Do not reset the effect list.
+ if ((workInProgress.mode & ProfileMode) !== NoMode) transferActualDuration(workInProgress);
+ // Don't bubble properties in this case.
+ return workInProgress;
+ }
+ var nextDidTimeout = nextState !== null;
+ var prevDidTimeout = current !== null && current.memoizedState !== null;
+ // a passive effect, which is when we process the transitions
+ if (nextDidTimeout !== prevDidTimeout) // an effect to toggle the subtree's visibility. When we switch from
+ // fallback -> primary, the inner Offscreen fiber schedules this effect
+ // as part of its normal complete phase. But when we switch from
+ // primary -> fallback, the inner Offscreen fiber does not have a complete
+ // phase. So we need to schedule its effect here.
+ //
+ // We also use this flag to connect/disconnect the effects, but the same
+ // logic applies: when re-connecting, the Offscreen fiber's complete
+ // phase will handle scheduling the effect. It's only when the fallback
+ // is active that we have to do anything special.
+ {
+ if (nextDidTimeout) {
+ var _offscreenFiber2 = workInProgress.child;
+ _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything
+ // in the concurrent tree already suspended during this render.
+ // This is a known bug.
+ if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
+ // TODO: Move this back to throwException because this is too late
+ // if this is a large tree which is common for initial loads. We
+ // don't know if we should restart a render or not until we get
+ // this marker, and this is too late.
+ // If this render already had a ping or lower pri updates,
+ // and this is the first time we know we're going to suspend we
+ // should be able to immediately restart from within throwException.
+ var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
+ if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) // If this was in an invisible tree or a new render, then showing
+ // this boundary is ok.
+ renderDidSuspend();
+ else // Otherwise, we're going to have to hide content so we should
+ // suspend for longer if possible.
+ renderDidSuspendDelayIfPossible();
+ }
+ }
+ }
+ var wakeables = workInProgress.updateQueue;
+ if (wakeables !== null) // Schedule an effect to attach a retry listener to the promise.
+ // TODO: Move to passive phase
+ workInProgress.flags |= Update;
+ bubbleProperties(workInProgress);
+ if ((workInProgress.mode & ProfileMode) !== NoMode) {
+ if (nextDidTimeout) {
+ // Don't count time spent in a timed out Suspense subtree as part of the base duration.
+ var primaryChildFragment = workInProgress.child;
+ if (primaryChildFragment !== null) // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
+ workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
+ }
+ }
+ return null;
+ case HostPortal:
+ popHostContainer(workInProgress);
+ updateHostContainer(current, workInProgress);
+ if (current === null) preparePortalMount(workInProgress.stateNode.containerInfo);
+ bubbleProperties(workInProgress);
+ return null;
+ case ContextProvider:
+ // Pop provider fiber
+ var context = workInProgress.type._context;
+ popProvider(context, workInProgress);
+ bubbleProperties(workInProgress);
+ return null;
+ case IncompleteClassComponent:
+ // Same as class component case. I put it down here so that the tags are
+ // sequential to ensure this switch is compiled to a jump table.
+ var _Component = workInProgress.type;
+ if (isContextProvider(_Component)) popContext(workInProgress);
+ bubbleProperties(workInProgress);
+ return null;
+ case SuspenseListComponent:
+ popSuspenseContext(workInProgress);
+ var renderState = workInProgress.memoizedState;
+ if (renderState === null) {
+ // We're running in the default, "independent" mode.
+ // We don't do anything in this mode.
+ bubbleProperties(workInProgress);
+ return null;
+ }
+ var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
+ var renderedTail = renderState.rendering;
+ if (renderedTail === null) {
+ // We just rendered the head.
+ if (!didSuspendAlready) {
+ // This is the first pass. We need to figure out if anything is still
+ // suspended in the rendered set.
+ // If new content unsuspended, but there's still some content that
+ // didn't. Then we need to do a second pass that forces everything
+ // to keep showing their fallbacks.
+ // We might be suspended if something in this render pass suspended, or
+ // something in the previous committed pass suspended. Otherwise,
+ // there's no chance so we can skip the expensive call to
+ // findFirstSuspended.
+ var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
+ if (!cannotBeSuspended) {
+ var row = workInProgress.child;
+ while(row !== null){
+ var suspended = findFirstSuspended(row);
+ if (suspended !== null) {
+ didSuspendAlready = true;
+ workInProgress.flags |= DidCapture;
+ cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
+ // part of the second pass. In that case nothing will subscribe to
+ // its thenables. Instead, we'll transfer its thenables to the
+ // SuspenseList so that it can retry if they resolve.
+ // There might be multiple of these in the list but since we're
+ // going to wait for all of them anyway, it doesn't really matter
+ // which ones gets to ping. In theory we could get clever and keep
+ // track of how many dependencies remain but it gets tricky because
+ // in the meantime, we can add/remove/change items and dependencies.
+ // We might bail out of the loop before finding any but that
+ // doesn't matter since that means that the other boundaries that
+ // we did find already has their listeners attached.
+ var newThenables = suspended.updateQueue;
+ if (newThenables !== null) {
+ workInProgress.updateQueue = newThenables;
+ workInProgress.flags |= Update;
+ } // Rerender the whole list, but this time, we'll force fallbacks
+ // to stay in place.
+ // Reset the effect flags before doing the second pass since that's now invalid.
+ // Reset the child fibers to their original state.
+ workInProgress.subtreeFlags = NoFlags;
+ resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
+ // rerender the children.
+ pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
+ return workInProgress.child;
+ }
+ row = row.sibling;
+ }
+ }
+ if (renderState.tail !== null && now() > getRenderTargetTime()) {
+ // We have already passed our CPU deadline but we still have rows
+ // left in the tail. We'll just give up further attempts to render
+ // the main content and only render fallbacks.
+ workInProgress.flags |= DidCapture;
+ didSuspendAlready = true;
+ cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
+ // to get it started back up to attempt the next item. While in terms
+ // of priority this work has the same priority as this current render,
+ // it's not part of the same transition once the transition has
+ // committed. If it's sync, we still want to yield so that it can be
+ // painted. Conceptually, this is really the same as pinging.
+ // We can use any RetryLane even if it's the one currently rendering
+ // since we're leaving it behind on this node.
+ workInProgress.lanes = SomeRetryLane;
+ }
+ } else cutOffTailIfNeeded(renderState, false);
+ // Next we're going to render the tail.
+ } else {
+ // Append the rendered row to the child list.
+ if (!didSuspendAlready) {
+ var _suspended = findFirstSuspended(renderedTail);
+ if (_suspended !== null) {
+ workInProgress.flags |= DidCapture;
+ didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
+ // get lost if this row ends up dropped during a second pass.
+ var _newThenables = _suspended.updateQueue;
+ if (_newThenables !== null) {
+ workInProgress.updateQueue = _newThenables;
+ workInProgress.flags |= Update;
+ }
+ cutOffTailIfNeeded(renderState, true); // This might have been modified.
+ if (renderState.tail === null && renderState.tailMode === "hidden" && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
+ ) {
+ // We're done.
+ bubbleProperties(workInProgress);
+ return null;
+ }
+ } else if (// time we have to render. So rendering one more row would likely
+ // exceed it.
+ now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
+ // We have now passed our CPU deadline and we'll just give up further
+ // attempts to render the main content and only render fallbacks.
+ // The assumption is that this is usually faster.
+ workInProgress.flags |= DidCapture;
+ didSuspendAlready = true;
+ cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
+ // to get it started back up to attempt the next item. While in terms
+ // of priority this work has the same priority as this current render,
+ // it's not part of the same transition once the transition has
+ // committed. If it's sync, we still want to yield so that it can be
+ // painted. Conceptually, this is really the same as pinging.
+ // We can use any RetryLane even if it's the one currently rendering
+ // since we're leaving it behind on this node.
+ workInProgress.lanes = SomeRetryLane;
+ }
+ }
+ if (renderState.isBackwards) {
+ // The effect list of the backwards tail will have been added
+ // to the end. This breaks the guarantee that life-cycles fire in
+ // sibling order but that isn't a strong guarantee promised by React.
+ // Especially since these might also just pop in during future commits.
+ // Append to the beginning of the list.
+ renderedTail.sibling = workInProgress.child;
+ workInProgress.child = renderedTail;
+ } else {
+ var previousSibling = renderState.last;
+ if (previousSibling !== null) previousSibling.sibling = renderedTail;
+ else workInProgress.child = renderedTail;
+ renderState.last = renderedTail;
+ }
+ }
+ if (renderState.tail !== null) {
+ // We still have tail rows to render.
+ // Pop a row.
+ var next = renderState.tail;
+ renderState.rendering = next;
+ renderState.tail = next.sibling;
+ renderState.renderingStartTime = now();
+ next.sibling = null; // Restore the context.
+ // TODO: We can probably just avoid popping it instead and only
+ // setting it the first time we go from not suspended to suspended.
+ var suspenseContext = suspenseStackCursor.current;
+ if (didSuspendAlready) suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
+ else suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
+ pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
+ // Don't bubble properties in this case.
+ return next;
+ }
+ bubbleProperties(workInProgress);
+ return null;
+ case ScopeComponent:
+ break;
+ case OffscreenComponent:
+ case LegacyHiddenComponent:
+ popRenderLanes(workInProgress);
+ var _nextState = workInProgress.memoizedState;
+ var nextIsHidden = _nextState !== null;
+ if (current !== null) {
+ var _prevState = current.memoizedState;
+ var prevIsHidden = _prevState !== null;
+ if (prevIsHidden !== nextIsHidden && !enableLegacyHidden) workInProgress.flags |= Visibility;
+ }
+ if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) bubbleProperties(workInProgress);
+ else // Don't bubble properties for hidden children unless we're rendering
+ // at offscreen priority.
+ if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
+ bubbleProperties(workInProgress);
+ // Check if there was an insertion or update in the hidden subtree.
+ // If so, we need to hide those nodes in the commit phase, so
+ // schedule a visibility effect.
+ if (workInProgress.subtreeFlags & (Placement | Update)) workInProgress.flags |= Visibility;
+ }
+ return null;
+ case CacheComponent:
+ return null;
+ case TracingMarkerComponent:
+ return null;
+ }
+ throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + "React. Please file an issue.");
+ }
+ function unwindWork(current, workInProgress, renderLanes) {
+ // Note: This intentionally doesn't check if we're hydrating because comparing
+ // to the current tree provider fiber is just as fast and less error-prone.
+ // Ideally we would have a special version of the work loop only
+ // for hydration.
+ popTreeContext(workInProgress);
+ switch(workInProgress.tag){
+ case ClassComponent:
+ var Component = workInProgress.type;
+ if (isContextProvider(Component)) popContext(workInProgress);
+ var flags = workInProgress.flags;
+ if (flags & ShouldCapture) {
+ workInProgress.flags = flags & ~ShouldCapture | DidCapture;
+ if ((workInProgress.mode & ProfileMode) !== NoMode) transferActualDuration(workInProgress);
+ return workInProgress;
+ }
+ return null;
+ case HostRoot:
+ var root = workInProgress.stateNode;
+ popHostContainer(workInProgress);
+ popTopLevelContextObject(workInProgress);
+ resetWorkInProgressVersions();
+ var _flags = workInProgress.flags;
+ if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
+ // There was an error during render that wasn't captured by a suspense
+ // boundary. Do a second pass on the root to unmount the children.
+ workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
+ return workInProgress;
+ } // We unwound to the root without completing it. Exit.
+ return null;
+ case HostComponent:
+ // TODO: popHydrationState
+ popHostContext(workInProgress);
+ return null;
+ case SuspenseComponent:
+ popSuspenseContext(workInProgress);
+ var suspenseState = workInProgress.memoizedState;
+ if (suspenseState !== null && suspenseState.dehydrated !== null) {
+ if (workInProgress.alternate === null) throw new Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue.");
+ resetHydrationState();
+ }
+ var _flags2 = workInProgress.flags;
+ if (_flags2 & ShouldCapture) {
+ workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
+ if ((workInProgress.mode & ProfileMode) !== NoMode) transferActualDuration(workInProgress);
+ return workInProgress;
+ }
+ return null;
+ case SuspenseListComponent:
+ popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
+ // caught by a nested boundary. If not, it should bubble through.
+ return null;
+ case HostPortal:
+ popHostContainer(workInProgress);
+ return null;
+ case ContextProvider:
+ var context = workInProgress.type._context;
+ popProvider(context, workInProgress);
+ return null;
+ case OffscreenComponent:
+ case LegacyHiddenComponent:
+ popRenderLanes(workInProgress);
+ return null;
+ case CacheComponent:
+ return null;
+ default:
+ return null;
+ }
+ }
+ function unwindInterruptedWork(current, interruptedWork, renderLanes) {
+ // Note: This intentionally doesn't check if we're hydrating because comparing
+ // to the current tree provider fiber is just as fast and less error-prone.
+ // Ideally we would have a special version of the work loop only
+ // for hydration.
+ popTreeContext(interruptedWork);
+ switch(interruptedWork.tag){
+ case ClassComponent:
+ var childContextTypes = interruptedWork.type.childContextTypes;
+ if (childContextTypes !== null && childContextTypes !== undefined) popContext(interruptedWork);
+ break;
+ case HostRoot:
+ var root = interruptedWork.stateNode;
+ popHostContainer(interruptedWork);
+ popTopLevelContextObject(interruptedWork);
+ resetWorkInProgressVersions();
+ break;
+ case HostComponent:
+ popHostContext(interruptedWork);
+ break;
+ case HostPortal:
+ popHostContainer(interruptedWork);
+ break;
+ case SuspenseComponent:
+ popSuspenseContext(interruptedWork);
+ break;
+ case SuspenseListComponent:
+ popSuspenseContext(interruptedWork);
+ break;
+ case ContextProvider:
+ var context = interruptedWork.type._context;
+ popProvider(context, interruptedWork);
+ break;
+ case OffscreenComponent:
+ case LegacyHiddenComponent:
+ popRenderLanes(interruptedWork);
+ break;
+ }
+ }
+ var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
+ didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
+ // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor.
+ // Only used when enableSuspenseLayoutEffectSemantics is enabled.
+ var offscreenSubtreeIsHidden = false;
+ var offscreenSubtreeWasHidden = false;
+ var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set;
+ var nextEffect = null; // Used for Profiling builds to track updaters.
+ var inProgressLanes = null;
+ var inProgressRoot = null;
+ function reportUncaughtErrorInDEV(error) {
+ invokeGuardedCallback(null, function() {
+ throw error;
+ });
+ clearCaughtError();
+ }
+ var callComponentWillUnmountWithTimer = function(current, instance) {
+ instance.props = current.memoizedProps;
+ instance.state = current.memoizedState;
+ if (current.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ instance.componentWillUnmount();
+ } finally{
+ recordLayoutEffectDuration(current);
+ }
+ else instance.componentWillUnmount();
+ }; // Capture errors so they don't interrupt mounting.
+ function safelyCallCommitHookLayoutEffectListMount(current, nearestMountedAncestor) {
+ try {
+ commitHookEffectListMount(Layout, current);
+ } catch (error) {
+ captureCommitPhaseError(current, nearestMountedAncestor, error);
+ }
+ } // Capture errors so they don't interrupt unmounting.
+ function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
+ try {
+ callComponentWillUnmountWithTimer(current, instance);
+ } catch (error) {
+ captureCommitPhaseError(current, nearestMountedAncestor, error);
+ }
+ } // Capture errors so they don't interrupt mounting.
+ function safelyCallComponentDidMount(current, nearestMountedAncestor, instance) {
+ try {
+ instance.componentDidMount();
+ } catch (error) {
+ captureCommitPhaseError(current, nearestMountedAncestor, error);
+ }
+ } // Capture errors so they don't interrupt mounting.
+ function safelyAttachRef(current, nearestMountedAncestor) {
+ try {
+ commitAttachRef(current);
+ } catch (error) {
+ captureCommitPhaseError(current, nearestMountedAncestor, error);
+ }
+ }
+ function safelyDetachRef(current, nearestMountedAncestor) {
+ var ref = current.ref;
+ if (ref !== null) {
+ if (typeof ref === "function") {
+ var retVal;
+ try {
+ if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ retVal = ref(null);
+ } finally{
+ recordLayoutEffectDuration(current);
+ }
+ else retVal = ref(null);
+ } catch (error) {
+ captureCommitPhaseError(current, nearestMountedAncestor, error);
+ }
+ if (typeof retVal === "function") error("Unexpected return value from a callback ref in %s. A callback ref should not return a function.", getComponentNameFromFiber(current));
+ } else ref.current = null;
+ }
+ }
+ function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
+ try {
+ destroy();
+ } catch (error) {
+ captureCommitPhaseError(current, nearestMountedAncestor, error);
+ }
+ }
+ var focusedInstanceHandle = null;
+ var shouldFireAfterActiveInstanceBlur = false;
+ function commitBeforeMutationEffects(root, firstChild) {
+ focusedInstanceHandle = prepareForCommit(root.containerInfo);
+ nextEffect = firstChild;
+ commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
+ var shouldFire = shouldFireAfterActiveInstanceBlur;
+ shouldFireAfterActiveInstanceBlur = false;
+ focusedInstanceHandle = null;
+ return shouldFire;
+ }
+ function commitBeforeMutationEffects_begin() {
+ while(nextEffect !== null){
+ var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
+ var child = fiber.child;
+ if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
+ child.return = fiber;
+ nextEffect = child;
+ } else commitBeforeMutationEffects_complete();
+ }
+ }
+ function commitBeforeMutationEffects_complete() {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ setCurrentFiber(fiber);
+ try {
+ commitBeforeMutationEffectsOnFiber(fiber);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ resetCurrentFiber();
+ var sibling = fiber.sibling;
+ if (sibling !== null) {
+ sibling.return = fiber.return;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = fiber.return;
+ }
+ }
+ function commitBeforeMutationEffectsOnFiber(finishedWork) {
+ var current = finishedWork.alternate;
+ var flags = finishedWork.flags;
+ if ((flags & Snapshot) !== NoFlags) {
+ setCurrentFiber(finishedWork);
+ switch(finishedWork.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ break;
+ case ClassComponent:
+ if (current !== null) {
+ var prevProps = current.memoizedProps;
+ var prevState = current.memoizedState;
+ var instance = finishedWork.stateNode; // We could update instance props and state here,
+ if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
+ if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before getSnapshotBeforeUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ }
+ var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
+ var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
+ if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
+ didWarnSet.add(finishedWork.type);
+ error("%s.getSnapshotBeforeUpdate(): A snapshot value (or null) must be returned. You have returned undefined.", getComponentNameFromFiber(finishedWork));
+ }
+ instance.__reactInternalSnapshotBeforeUpdate = snapshot;
+ }
+ break;
+ case HostRoot:
+ var root = finishedWork.stateNode;
+ clearContainer(root.containerInfo);
+ break;
+ case HostComponent:
+ case HostText:
+ case HostPortal:
+ case IncompleteClassComponent:
+ break;
+ default:
+ throw new Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
+ }
+ resetCurrentFiber();
+ }
+ }
+ function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
+ var updateQueue = finishedWork.updateQueue;
+ var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
+ if (lastEffect !== null) {
+ var firstEffect = lastEffect.next;
+ var effect = firstEffect;
+ do {
+ if ((effect.tag & flags) === flags) {
+ // Unmount
+ var destroy = effect.destroy;
+ effect.destroy = undefined;
+ if (destroy !== undefined) {
+ if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectUnmountStarted(finishedWork);
+ else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectUnmountStarted(finishedWork);
+ if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(true);
+ safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
+ if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(false);
+ if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectUnmountStopped();
+ else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectUnmountStopped();
+ }
+ }
+ effect = effect.next;
+ }while (effect !== firstEffect);
+ }
+ }
+ function commitHookEffectListMount(flags, finishedWork) {
+ var updateQueue = finishedWork.updateQueue;
+ var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
+ if (lastEffect !== null) {
+ var firstEffect = lastEffect.next;
+ var effect = firstEffect;
+ do {
+ if ((effect.tag & flags) === flags) {
+ if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectMountStarted(finishedWork);
+ else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectMountStarted(finishedWork);
+ var create = effect.create;
+ if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(true);
+ effect.destroy = create();
+ if ((flags & Insertion) !== NoFlags$1) setIsRunningInsertionEffect(false);
+ if ((flags & Passive$1) !== NoFlags$1) markComponentPassiveEffectMountStopped();
+ else if ((flags & Layout) !== NoFlags$1) markComponentLayoutEffectMountStopped();
+ var destroy = effect.destroy;
+ if (destroy !== undefined && typeof destroy !== "function") {
+ var hookName = void 0;
+ if ((effect.tag & Layout) !== NoFlags) hookName = "useLayoutEffect";
+ else if ((effect.tag & Insertion) !== NoFlags) hookName = "useInsertionEffect";
+ else hookName = "useEffect";
+ var addendum = void 0;
+ if (destroy === null) addendum = " You returned null. If your effect does not require clean up, return undefined (or nothing).";
+ else if (typeof destroy.then === "function") addendum = "\n\nIt looks like you wrote " + hookName + "(async () => ...) or returned a Promise. " + "Instead, write the async function inside your effect " + "and call it immediately:\n\n" + hookName + "(() => {\n" + " async function fetchData() {\n" + " // You can await here\n" + " const response = await MyAPI.getData(someId);\n" + " // ...\n" + " }\n" + " fetchData();\n" + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching";
+ else addendum = " You returned: " + destroy;
+ error("%s must not return anything besides a function, which is used for clean-up.%s", hookName, addendum);
+ }
+ }
+ effect = effect.next;
+ }while (effect !== firstEffect);
+ }
+ }
+ function commitPassiveEffectDurations(finishedRoot, finishedWork) {
+ // Only Profilers with work in their subtree will have an Update effect scheduled.
+ if ((finishedWork.flags & Update) !== NoFlags) switch(finishedWork.tag){
+ case Profiler:
+ var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
+ var _finishedWork$memoize = finishedWork.memoizedProps, id = _finishedWork$memoize.id, onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
+ // It does not get reset until the start of the next commit phase.
+ var commitTime = getCommitTime();
+ var phase = finishedWork.alternate === null ? "mount" : "update";
+ if (isCurrentUpdateNested()) phase = "nested-update";
+ if (typeof onPostCommit === "function") onPostCommit(id, phase, passiveEffectDuration, commitTime);
+ // Bubble times to the next nearest ancestor Profiler.
+ // After we process that Profiler, we'll bubble further up.
+ var parentFiber = finishedWork.return;
+ outer: while(parentFiber !== null){
+ switch(parentFiber.tag){
+ case HostRoot:
+ var root = parentFiber.stateNode;
+ root.passiveEffectDuration += passiveEffectDuration;
+ break outer;
+ case Profiler:
+ var parentStateNode = parentFiber.stateNode;
+ parentStateNode.passiveEffectDuration += passiveEffectDuration;
+ break outer;
+ }
+ parentFiber = parentFiber.return;
+ }
+ break;
+ }
+ }
+ function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
+ if ((finishedWork.flags & LayoutMask) !== NoFlags) switch(finishedWork.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ if (!offscreenSubtreeWasHidden) {
+ // At this point layout effects have already been destroyed (during mutation phase).
+ // This is done to prevent sibling component effects from interfering with each other,
+ // e.g. a destroy function in one component should never override a ref set
+ // by a create function in another component during the same commit.
+ if (finishedWork.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ commitHookEffectListMount(Layout | HasEffect, finishedWork);
+ } finally{
+ recordLayoutEffectDuration(finishedWork);
+ }
+ else commitHookEffectListMount(Layout | HasEffect, finishedWork);
+ }
+ break;
+ case ClassComponent:
+ var instance = finishedWork.stateNode;
+ if (finishedWork.flags & Update) {
+ if (!offscreenSubtreeWasHidden) {
+ if (current === null) {
+ if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
+ if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before componentDidMount. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ }
+ if (finishedWork.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ instance.componentDidMount();
+ } finally{
+ recordLayoutEffectDuration(finishedWork);
+ }
+ else instance.componentDidMount();
+ } else {
+ var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
+ var prevState = current.memoizedState; // We could update instance props and state here,
+ if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
+ if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before componentDidUpdate. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ }
+ if (finishedWork.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
+ } finally{
+ recordLayoutEffectDuration(finishedWork);
+ }
+ else instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
+ }
+ }
+ } // TODO: I think this is now always non-null by the time it reaches the
+ // commit phase. Consider removing the type check.
+ var updateQueue = finishedWork.updateQueue;
+ if (updateQueue !== null) {
+ if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
+ if (instance.props !== finishedWork.memoizedProps) error("Expected %s props to match memoized props before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.props`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ if (instance.state !== finishedWork.memoizedState) error("Expected %s state to match memoized state before processing the update queue. This might either be because of a bug in React, or because a component reassigns its own `this.state`. Please file an issue.", getComponentNameFromFiber(finishedWork) || "instance");
+ }
+ // but instead we rely on them being set during last render.
+ // TODO: revisit this when we implement resuming.
+ commitUpdateQueue(finishedWork, updateQueue, instance);
+ }
+ break;
+ case HostRoot:
+ // TODO: I think this is now always non-null by the time it reaches the
+ // commit phase. Consider removing the type check.
+ var _updateQueue = finishedWork.updateQueue;
+ if (_updateQueue !== null) {
+ var _instance = null;
+ if (finishedWork.child !== null) switch(finishedWork.child.tag){
+ case HostComponent:
+ _instance = getPublicInstance(finishedWork.child.stateNode);
+ break;
+ case ClassComponent:
+ _instance = finishedWork.child.stateNode;
+ break;
+ }
+ commitUpdateQueue(finishedWork, _updateQueue, _instance);
+ }
+ break;
+ case HostComponent:
+ var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
+ // (eg DOM renderer may schedule auto-focus for inputs and form controls).
+ // These effects should only be committed when components are first mounted,
+ // aka when there is no current/alternate.
+ if (current === null && finishedWork.flags & Update) {
+ var type = finishedWork.type;
+ var props = finishedWork.memoizedProps;
+ commitMount(_instance2, type, props);
+ }
+ break;
+ case HostText:
+ break;
+ case HostPortal:
+ break;
+ case Profiler:
+ var _finishedWork$memoize2 = finishedWork.memoizedProps, onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender;
+ var effectDuration = finishedWork.stateNode.effectDuration;
+ var commitTime = getCommitTime();
+ var phase = current === null ? "mount" : "update";
+ if (isCurrentUpdateNested()) phase = "nested-update";
+ if (typeof onRender === "function") onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
+ if (typeof onCommit === "function") onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
+ // Schedule a passive effect for this Profiler to call onPostCommit hooks.
+ // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
+ // because the effect is also where times bubble to parent Profilers.
+ enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
+ // Do not reset these values until the next render so DevTools has a chance to read them first.
+ var parentFiber = finishedWork.return;
+ outer: while(parentFiber !== null){
+ switch(parentFiber.tag){
+ case HostRoot:
+ var root = parentFiber.stateNode;
+ root.effectDuration += effectDuration;
+ break outer;
+ case Profiler:
+ var parentStateNode = parentFiber.stateNode;
+ parentStateNode.effectDuration += effectDuration;
+ break outer;
+ }
+ parentFiber = parentFiber.return;
+ }
+ break;
+ case SuspenseComponent:
+ commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
+ break;
+ case SuspenseListComponent:
+ case IncompleteClassComponent:
+ case ScopeComponent:
+ case OffscreenComponent:
+ case LegacyHiddenComponent:
+ case TracingMarkerComponent:
+ break;
+ default:
+ throw new Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
+ }
+ if (!offscreenSubtreeWasHidden) {
+ if (finishedWork.flags & Ref) commitAttachRef(finishedWork);
+ }
+ }
+ function reappearLayoutEffectsOnFiber(node) {
+ // Turn on layout effects in a tree that previously disappeared.
+ // TODO (Offscreen) Check: flags & LayoutStatic
+ switch(node.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ if (node.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ safelyCallCommitHookLayoutEffectListMount(node, node.return);
+ } finally{
+ recordLayoutEffectDuration(node);
+ }
+ else safelyCallCommitHookLayoutEffectListMount(node, node.return);
+ break;
+ case ClassComponent:
+ var instance = node.stateNode;
+ if (typeof instance.componentDidMount === "function") safelyCallComponentDidMount(node, node.return, instance);
+ safelyAttachRef(node, node.return);
+ break;
+ case HostComponent:
+ safelyAttachRef(node, node.return);
+ break;
+ }
+ }
+ function hideOrUnhideAllChildren(finishedWork, isHidden) {
+ // Only hide or unhide the top-most host nodes.
+ var hostSubtreeRoot = null;
+ // We only have the top Fiber that was inserted but we need to recurse down its
+ // children to find all the terminal nodes.
+ var node = finishedWork;
+ while(true){
+ if (node.tag === HostComponent) {
+ if (hostSubtreeRoot === null) {
+ hostSubtreeRoot = node;
+ try {
+ var instance = node.stateNode;
+ if (isHidden) hideInstance(instance);
+ else unhideInstance(node.stateNode, node.memoizedProps);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ }
+ } else if (node.tag === HostText) {
+ if (hostSubtreeRoot === null) try {
+ var _instance3 = node.stateNode;
+ if (isHidden) hideTextInstance(_instance3);
+ else unhideTextInstance(_instance3, node.memoizedProps);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ;
+ else if (node.child !== null) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === finishedWork) return;
+ while(node.sibling === null){
+ if (node.return === null || node.return === finishedWork) return;
+ if (hostSubtreeRoot === node) hostSubtreeRoot = null;
+ node = node.return;
+ }
+ if (hostSubtreeRoot === node) hostSubtreeRoot = null;
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ }
+ function commitAttachRef(finishedWork) {
+ var ref = finishedWork.ref;
+ if (ref !== null) {
+ var instance = finishedWork.stateNode;
+ var instanceToUse;
+ switch(finishedWork.tag){
+ case HostComponent:
+ instanceToUse = getPublicInstance(instance);
+ break;
+ default:
+ instanceToUse = instance;
+ } // Moved outside to ensure DCE works with this flag
+ if (typeof ref === "function") {
+ var retVal;
+ if (finishedWork.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ retVal = ref(instanceToUse);
+ } finally{
+ recordLayoutEffectDuration(finishedWork);
+ }
+ else retVal = ref(instanceToUse);
+ if (typeof retVal === "function") error("Unexpected return value from a callback ref in %s. A callback ref should not return a function.", getComponentNameFromFiber(finishedWork));
+ } else {
+ if (!ref.hasOwnProperty("current")) error("Unexpected ref object provided for %s. Use either a ref-setter function or React.createRef().", getComponentNameFromFiber(finishedWork));
+ ref.current = instanceToUse;
+ }
+ }
+ }
+ function detachFiberMutation(fiber) {
+ // Cut off the return pointer to disconnect it from the tree.
+ // This enables us to detect and warn against state updates on an unmounted component.
+ // It also prevents events from bubbling from within disconnected components.
+ //
+ // Ideally, we should also clear the child pointer of the parent alternate to let this
+ // get GC:ed but we don't know which for sure which parent is the current
+ // one so we'll settle for GC:ing the subtree of this child.
+ // This child itself will be GC:ed when the parent updates the next time.
+ //
+ // Note that we can't clear child or sibling pointers yet.
+ // They're needed for passive effects and for findDOMNode.
+ // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
+ //
+ // Don't reset the alternate yet, either. We need that so we can detach the
+ // alternate's fields in the passive phase. Clearing the return pointer is
+ // sufficient for findDOMNode semantics.
+ var alternate = fiber.alternate;
+ if (alternate !== null) alternate.return = null;
+ fiber.return = null;
+ }
+ function detachFiberAfterEffects(fiber) {
+ var alternate = fiber.alternate;
+ if (alternate !== null) {
+ fiber.alternate = null;
+ detachFiberAfterEffects(alternate);
+ } // Note: Defensively using negation instead of < in case
+ // Clear cyclical Fiber fields. This level alone is designed to roughly
+ // approximate the planned Fiber refactor. In that world, `setState` will be
+ // bound to a special "instance" object instead of a Fiber. The Instance
+ // object will not have any of these fields. It will only be connected to
+ // the fiber tree via a single link at the root. So if this level alone is
+ // sufficient to fix memory issues, that bodes well for our plans.
+ fiber.child = null;
+ fiber.deletions = null;
+ fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
+ // tree, which has its own pointers to children, parents, and siblings.
+ // The other host nodes also point back to fibers, so we should detach that
+ // one, too.
+ if (fiber.tag === HostComponent) {
+ var hostInstance = fiber.stateNode;
+ if (hostInstance !== null) detachDeletedInstance(hostInstance);
+ }
+ fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We
+ fiber._debugOwner = null;
+ // Theoretically, nothing in here should be necessary, because we already
+ // disconnected the fiber from the tree. So even if something leaks this
+ // particular fiber, it won't leak anything else
+ //
+ // The purpose of this branch is to be super aggressive so we can measure
+ // if there's any difference in memory impact. If there is, that could
+ // indicate a React leak we don't know about.
+ fiber.return = null;
+ fiber.dependencies = null;
+ fiber.memoizedProps = null;
+ fiber.memoizedState = null;
+ fiber.pendingProps = null;
+ fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
+ fiber.updateQueue = null;
+ }
+ function getHostParentFiber(fiber) {
+ var parent = fiber.return;
+ while(parent !== null){
+ if (isHostParent(parent)) return parent;
+ parent = parent.return;
+ }
+ throw new Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.");
+ }
+ function isHostParent(fiber) {
+ return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
+ }
+ function getHostSibling(fiber) {
+ // We're going to search forward into the tree until we find a sibling host
+ // node. Unfortunately, if multiple insertions are done in a row we have to
+ // search past them. This leads to exponential search for the next sibling.
+ // TODO: Find a more efficient way to do this.
+ var node = fiber;
+ siblings: while(true){
+ // If we didn't find anything, let's try the next sibling.
+ while(node.sibling === null){
+ if (node.return === null || isHostParent(node.return)) // If we pop out of the root or hit the parent the fiber we are the
+ // last sibling.
+ return null;
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ while(node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment){
+ // If it is not host node and, we might have a host node inside it.
+ // Try to search down until we find one.
+ if (node.flags & Placement) continue siblings;
+ // If we don't have a child, try the siblings instead.
+ // We also skip portals because they are not part of this host tree.
+ if (node.child === null || node.tag === HostPortal) continue siblings;
+ else {
+ node.child.return = node;
+ node = node.child;
+ }
+ } // Check if this host node is stable or about to be placed.
+ if (!(node.flags & Placement)) // Found it!
+ return node.stateNode;
+ }
+ }
+ function commitPlacement(finishedWork) {
+ var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
+ switch(parentFiber.tag){
+ case HostComponent:
+ var parent = parentFiber.stateNode;
+ if (parentFiber.flags & ContentReset) {
+ // Reset the text content of the parent before doing any insertions
+ resetTextContent(parent); // Clear ContentReset from the effect tag
+ parentFiber.flags &= ~ContentReset;
+ }
+ var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
+ // children to find all the terminal nodes.
+ insertOrAppendPlacementNode(finishedWork, before, parent);
+ break;
+ case HostRoot:
+ case HostPortal:
+ var _parent = parentFiber.stateNode.containerInfo;
+ var _before = getHostSibling(finishedWork);
+ insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
+ break;
+ // eslint-disable-next-line-no-fallthrough
+ default:
+ throw new Error("Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.");
+ }
+ }
+ function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
+ var tag = node.tag;
+ var isHost = tag === HostComponent || tag === HostText;
+ if (isHost) {
+ var stateNode = node.stateNode;
+ if (before) insertInContainerBefore(parent, stateNode, before);
+ else appendChildToContainer(parent, stateNode);
+ } else if (tag === HostPortal) ;
+ else {
+ var child = node.child;
+ if (child !== null) {
+ insertOrAppendPlacementNodeIntoContainer(child, before, parent);
+ var sibling = child.sibling;
+ while(sibling !== null){
+ insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
+ sibling = sibling.sibling;
+ }
+ }
+ }
+ }
+ function insertOrAppendPlacementNode(node, before, parent) {
+ var tag = node.tag;
+ var isHost = tag === HostComponent || tag === HostText;
+ if (isHost) {
+ var stateNode = node.stateNode;
+ if (before) insertBefore(parent, stateNode, before);
+ else appendChild(parent, stateNode);
+ } else if (tag === HostPortal) ;
+ else {
+ var child = node.child;
+ if (child !== null) {
+ insertOrAppendPlacementNode(child, before, parent);
+ var sibling = child.sibling;
+ while(sibling !== null){
+ insertOrAppendPlacementNode(sibling, before, parent);
+ sibling = sibling.sibling;
+ }
+ }
+ }
+ } // These are tracked on the stack as we recursively traverse a
+ // deleted subtree.
+ // TODO: Update these during the whole mutation phase, not just during
+ // a deletion.
+ var hostParent = null;
+ var hostParentIsContainer = false;
+ function commitDeletionEffects(root, returnFiber, deletedFiber) {
+ // We only have the top Fiber that was deleted but we need to recurse down its
+ // children to find all the terminal nodes.
+ // Recursively delete all host nodes from the parent, detach refs, clean
+ // up mounted layout effects, and call componentWillUnmount.
+ // We only need to remove the topmost host child in each branch. But then we
+ // still need to keep traversing to unmount effects, refs, and cWU. TODO: We
+ // could split this into two separate traversals functions, where the second
+ // one doesn't include any removeChild logic. This is maybe the same
+ // function as "disappearLayoutEffects" (or whatever that turns into after
+ // the layout phase is refactored to use recursion).
+ // Before starting, find the nearest host parent on the stack so we know
+ // which instance/container to remove the children from.
+ // TODO: Instead of searching up the fiber return path on every deletion, we
+ // can track the nearest host component on the JS stack as we traverse the
+ // tree during the commit phase. This would make insertions faster, too.
+ var parent = returnFiber;
+ findParent: while(parent !== null){
+ switch(parent.tag){
+ case HostComponent:
+ hostParent = parent.stateNode;
+ hostParentIsContainer = false;
+ break findParent;
+ case HostRoot:
+ hostParent = parent.stateNode.containerInfo;
+ hostParentIsContainer = true;
+ break findParent;
+ case HostPortal:
+ hostParent = parent.stateNode.containerInfo;
+ hostParentIsContainer = true;
+ break findParent;
+ }
+ parent = parent.return;
+ }
+ if (hostParent === null) throw new Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.");
+ commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber);
+ hostParent = null;
+ hostParentIsContainer = false;
+ detachFiberMutation(deletedFiber);
+ }
+ function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) {
+ // TODO: Use a static flag to skip trees that don't have unmount effects
+ var child = parent.child;
+ while(child !== null){
+ commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child);
+ child = child.sibling;
+ }
+ }
+ function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) {
+ onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse
+ // into their subtree. There are simpler cases in the inner switch
+ // that don't modify the stack.
+ switch(deletedFiber.tag){
+ case HostComponent:
+ if (!offscreenSubtreeWasHidden) safelyDetachRef(deletedFiber, nearestMountedAncestor);
+ // Intentional fallthrough to next branch
+ // eslint-disable-next-line-no-fallthrough
+ case HostText:
+ var prevHostParent = hostParent;
+ var prevHostParentIsContainer = hostParentIsContainer;
+ hostParent = null;
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ hostParent = prevHostParent;
+ hostParentIsContainer = prevHostParentIsContainer;
+ if (hostParent !== null) {
+ // Now that all the child effects have unmounted, we can remove the
+ // node from the tree.
+ if (hostParentIsContainer) removeChildFromContainer(hostParent, deletedFiber.stateNode);
+ else removeChild(hostParent, deletedFiber.stateNode);
+ }
+ return;
+ case DehydratedFragment:
+ if (hostParent !== null) {
+ if (hostParentIsContainer) clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode);
+ else clearSuspenseBoundary(hostParent, deletedFiber.stateNode);
+ }
+ return;
+ case HostPortal:
+ // When we go into a portal, it becomes the parent to remove from.
+ var _prevHostParent = hostParent;
+ var _prevHostParentIsContainer = hostParentIsContainer;
+ hostParent = deletedFiber.stateNode.containerInfo;
+ hostParentIsContainer = true;
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ hostParent = _prevHostParent;
+ hostParentIsContainer = _prevHostParentIsContainer;
+ return;
+ case FunctionComponent:
+ case ForwardRef:
+ case MemoComponent:
+ case SimpleMemoComponent:
+ if (!offscreenSubtreeWasHidden) {
+ var updateQueue = deletedFiber.updateQueue;
+ if (updateQueue !== null) {
+ var lastEffect = updateQueue.lastEffect;
+ if (lastEffect !== null) {
+ var firstEffect = lastEffect.next;
+ var effect = firstEffect;
+ do {
+ var _effect = effect, destroy = _effect.destroy, tag = _effect.tag;
+ if (destroy !== undefined) {
+ if ((tag & Insertion) !== NoFlags$1) safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
+ else if ((tag & Layout) !== NoFlags$1) {
+ markComponentLayoutEffectUnmountStarted(deletedFiber);
+ if (deletedFiber.mode & ProfileMode) {
+ startLayoutEffectTimer();
+ safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
+ recordLayoutEffectDuration(deletedFiber);
+ } else safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
+ markComponentLayoutEffectUnmountStopped();
+ }
+ }
+ effect = effect.next;
+ }while (effect !== firstEffect);
+ }
+ }
+ }
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ return;
+ case ClassComponent:
+ if (!offscreenSubtreeWasHidden) {
+ safelyDetachRef(deletedFiber, nearestMountedAncestor);
+ var instance = deletedFiber.stateNode;
+ if (typeof instance.componentWillUnmount === "function") safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance);
+ }
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ return;
+ case ScopeComponent:
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ return;
+ case OffscreenComponent:
+ if (deletedFiber.mode & ConcurrentMode) {
+ // If this offscreen component is hidden, we already unmounted it. Before
+ // deleting the children, track that it's already unmounted so that we
+ // don't attempt to unmount the effects again.
+ // TODO: If the tree is hidden, in most cases we should be able to skip
+ // over the nested children entirely. An exception is we haven't yet found
+ // the topmost host node to delete, which we already track on the stack.
+ // But the other case is portals, which need to be detached no matter how
+ // deeply they are nested. We should use a subtree flag to track whether a
+ // subtree includes a nested portal.
+ var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
+ offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null;
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
+ } else recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ break;
+ default:
+ recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
+ return;
+ }
+ }
+ function commitSuspenseCallback(finishedWork) {
+ // TODO: Move this to passive phase
+ var newState = finishedWork.memoizedState;
+ }
+ function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
+ var newState = finishedWork.memoizedState;
+ if (newState === null) {
+ var current = finishedWork.alternate;
+ if (current !== null) {
+ var prevState = current.memoizedState;
+ if (prevState !== null) {
+ var suspenseInstance = prevState.dehydrated;
+ if (suspenseInstance !== null) commitHydratedSuspenseInstance(suspenseInstance);
+ }
+ }
+ }
+ }
+ function attachSuspenseRetryListeners(finishedWork) {
+ // If this boundary just timed out, then it will have a set of wakeables.
+ // For each wakeable, attach a listener so that when it resolves, React
+ // attempts to re-render the boundary in the primary (pre-timeout) state.
+ var wakeables = finishedWork.updateQueue;
+ if (wakeables !== null) {
+ finishedWork.updateQueue = null;
+ var retryCache = finishedWork.stateNode;
+ if (retryCache === null) retryCache = finishedWork.stateNode = new PossiblyWeakSet();
+ wakeables.forEach(function(wakeable) {
+ // Memoize using the boundary fiber to prevent redundant listeners.
+ var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
+ if (!retryCache.has(wakeable)) {
+ retryCache.add(wakeable);
+ if (isDevToolsPresent) {
+ if (inProgressLanes !== null && inProgressRoot !== null) // If we have pending work still, associate the original updaters with it.
+ restorePendingUpdaters(inProgressRoot, inProgressLanes);
+ else throw Error("Expected finished root and lanes to be set. This is a bug in React.");
+ }
+ wakeable.then(retry, retry);
+ }
+ });
+ }
+ } // This function detects when a Suspense boundary goes from visible to hidden.
+ function commitMutationEffects(root, finishedWork, committedLanes) {
+ inProgressLanes = committedLanes;
+ inProgressRoot = root;
+ setCurrentFiber(finishedWork);
+ commitMutationEffectsOnFiber(finishedWork, root);
+ setCurrentFiber(finishedWork);
+ inProgressLanes = null;
+ inProgressRoot = null;
+ }
+ function recursivelyTraverseMutationEffects(root, parentFiber, lanes) {
+ // Deletions effects can be scheduled on any fiber type. They need to happen
+ // before the children effects hae fired.
+ var deletions = parentFiber.deletions;
+ if (deletions !== null) for(var i = 0; i < deletions.length; i++){
+ var childToDelete = deletions[i];
+ try {
+ commitDeletionEffects(root, parentFiber, childToDelete);
+ } catch (error) {
+ captureCommitPhaseError(childToDelete, parentFiber, error);
+ }
+ }
+ var prevDebugFiber = getCurrentFiber();
+ if (parentFiber.subtreeFlags & MutationMask) {
+ var child = parentFiber.child;
+ while(child !== null){
+ setCurrentFiber(child);
+ commitMutationEffectsOnFiber(child, root);
+ child = child.sibling;
+ }
+ }
+ setCurrentFiber(prevDebugFiber);
+ }
+ function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
+ var current = finishedWork.alternate;
+ var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber,
+ // because the fiber tag is more specific. An exception is any flag related
+ // to reconcilation, because those can be set on all fiber types.
+ switch(finishedWork.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case MemoComponent:
+ case SimpleMemoComponent:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Update) {
+ try {
+ commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
+ commitHookEffectListMount(Insertion | HasEffect, finishedWork);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ } // Layout effects are destroyed during the mutation phase so that all
+ // destroy functions for all fibers are called before any create functions.
+ // This prevents sibling component effects from interfering with each other,
+ // e.g. a destroy function in one component should never override a ref set
+ // by a create function in another component during the same commit.
+ if (finishedWork.mode & ProfileMode) {
+ try {
+ startLayoutEffectTimer();
+ commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ recordLayoutEffectDuration(finishedWork);
+ } else try {
+ commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ }
+ return;
+ case ClassComponent:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Ref) {
+ if (current !== null) safelyDetachRef(current, current.return);
+ }
+ return;
+ case HostComponent:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Ref) {
+ if (current !== null) safelyDetachRef(current, current.return);
+ }
+ // TODO: ContentReset gets cleared by the children during the commit
+ // phase. This is a refactor hazard because it means we must read
+ // flags the flags after `commitReconciliationEffects` has already run;
+ // the order matters. We should refactor so that ContentReset does not
+ // rely on mutating the flag during commit. Like by setting a flag
+ // during the render phase instead.
+ if (finishedWork.flags & ContentReset) {
+ var instance = finishedWork.stateNode;
+ try {
+ resetTextContent(instance);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ }
+ if (flags & Update) {
+ var _instance4 = finishedWork.stateNode;
+ if (_instance4 != null) {
+ // Commit the work prepared earlier.
+ var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
+ // as the newProps. The updatePayload will contain the real change in
+ // this case.
+ var oldProps = current !== null ? current.memoizedProps : newProps;
+ var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
+ var updatePayload = finishedWork.updateQueue;
+ finishedWork.updateQueue = null;
+ if (updatePayload !== null) try {
+ commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ }
+ }
+ return;
+ case HostText:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Update) {
+ if (finishedWork.stateNode === null) throw new Error("This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.");
+ var textInstance = finishedWork.stateNode;
+ var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
+ // as the newProps. The updatePayload will contain the real change in
+ // this case.
+ var oldText = current !== null ? current.memoizedProps : newText;
+ try {
+ commitTextUpdate(textInstance, oldText, newText);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ }
+ return;
+ case HostRoot:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Update) {
+ if (current !== null) {
+ var prevRootState = current.memoizedState;
+ if (prevRootState.isDehydrated) try {
+ commitHydratedContainer(root.containerInfo);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ }
+ }
+ return;
+ case HostPortal:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ return;
+ case SuspenseComponent:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ var offscreenFiber = finishedWork.child;
+ if (offscreenFiber.flags & Visibility) {
+ var offscreenInstance = offscreenFiber.stateNode;
+ var newState = offscreenFiber.memoizedState;
+ var isHidden = newState !== null; // Track the current state on the Offscreen instance so we can
+ // read it during an event
+ offscreenInstance.isHidden = isHidden;
+ if (isHidden) {
+ var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null;
+ if (!wasHidden) // TODO: Move to passive phase
+ markCommitTimeOfFallback();
+ }
+ }
+ if (flags & Update) {
+ try {
+ commitSuspenseCallback(finishedWork);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ }
+ attachSuspenseRetryListeners(finishedWork);
+ }
+ return;
+ case OffscreenComponent:
+ var _wasHidden = current !== null && current.memoizedState !== null;
+ if (finishedWork.mode & ConcurrentMode) {
+ // Before committing the children, track on the stack whether this
+ // offscreen subtree was already hidden, so that we don't unmount the
+ // effects again.
+ var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
+ offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || _wasHidden;
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
+ } else recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Visibility) {
+ var _offscreenInstance = finishedWork.stateNode;
+ var _newState = finishedWork.memoizedState;
+ var _isHidden = _newState !== null;
+ var offscreenBoundary = finishedWork; // Track the current state on the Offscreen instance so we can
+ // read it during an event
+ _offscreenInstance.isHidden = _isHidden;
+ if (_isHidden) {
+ if (!_wasHidden) {
+ if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
+ nextEffect = offscreenBoundary;
+ var offscreenChild = offscreenBoundary.child;
+ while(offscreenChild !== null){
+ nextEffect = offscreenChild;
+ disappearLayoutEffects_begin(offscreenChild);
+ offscreenChild = offscreenChild.sibling;
+ }
+ }
+ }
+ }
+ // TODO: This needs to run whenever there's an insertion or update
+ // inside a hidden Offscreen tree.
+ hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
+ }
+ return;
+ case SuspenseListComponent:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ if (flags & Update) attachSuspenseRetryListeners(finishedWork);
+ return;
+ case ScopeComponent:
+ return;
+ default:
+ recursivelyTraverseMutationEffects(root, finishedWork);
+ commitReconciliationEffects(finishedWork);
+ return;
+ }
+ }
+ function commitReconciliationEffects(finishedWork) {
+ // Placement effects (insertions, reorders) can be scheduled on any fiber
+ // type. They needs to happen after the children effects have fired, but
+ // before the effects on this fiber have fired.
+ var flags = finishedWork.flags;
+ if (flags & Placement) {
+ try {
+ commitPlacement(finishedWork);
+ } catch (error) {
+ captureCommitPhaseError(finishedWork, finishedWork.return, error);
+ } // Clear the "placement" from effect tag so that we know that this is
+ // inserted, before any life-cycles like componentDidMount gets called.
+ // TODO: findDOMNode doesn't rely on this any more but isMounted does
+ // and isMounted is deprecated anyway so we should be able to kill this.
+ finishedWork.flags &= ~Placement;
+ }
+ if (flags & Hydrating) finishedWork.flags &= ~Hydrating;
+ }
+ function commitLayoutEffects(finishedWork, root, committedLanes) {
+ inProgressLanes = committedLanes;
+ inProgressRoot = root;
+ nextEffect = finishedWork;
+ commitLayoutEffects_begin(finishedWork, root, committedLanes);
+ inProgressLanes = null;
+ inProgressRoot = null;
+ }
+ function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) {
+ // Suspense layout effects semantics don't change for legacy roots.
+ var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ var firstChild = fiber.child;
+ if (fiber.tag === OffscreenComponent && isModernRoot) {
+ // Keep track of the current Offscreen stack's state.
+ var isHidden = fiber.memoizedState !== null;
+ var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden;
+ if (newOffscreenSubtreeIsHidden) {
+ // The Offscreen tree is hidden. Skip over its layout effects.
+ commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
+ continue;
+ } else {
+ // TODO (Offscreen) Also check: subtreeFlags & LayoutMask
+ var current = fiber.alternate;
+ var wasHidden = current !== null && current.memoizedState !== null;
+ var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden;
+ var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
+ var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; // Traverse the Offscreen subtree with the current Offscreen as the root.
+ offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden;
+ offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden;
+ if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) {
+ // This is the root of a reappearing boundary. Turn its layout effects
+ // back on.
+ nextEffect = fiber;
+ reappearLayoutEffects_begin(fiber);
+ }
+ var child = firstChild;
+ while(child !== null){
+ nextEffect = child;
+ commitLayoutEffects_begin(child, root, committedLanes);
+ child = child.sibling;
+ } // Restore Offscreen state and resume in our-progress traversal.
+ nextEffect = fiber;
+ offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
+ offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
+ commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
+ continue;
+ }
+ }
+ if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
+ firstChild.return = fiber;
+ nextEffect = firstChild;
+ } else commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
+ }
+ }
+ function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ if ((fiber.flags & LayoutMask) !== NoFlags) {
+ var current = fiber.alternate;
+ setCurrentFiber(fiber);
+ try {
+ commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ resetCurrentFiber();
+ }
+ if (fiber === subtreeRoot) {
+ nextEffect = null;
+ return;
+ }
+ var sibling = fiber.sibling;
+ if (sibling !== null) {
+ sibling.return = fiber.return;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = fiber.return;
+ }
+ }
+ function disappearLayoutEffects_begin(subtreeRoot) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ var firstChild = fiber.child; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
+ switch(fiber.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case MemoComponent:
+ case SimpleMemoComponent:
+ if (fiber.mode & ProfileMode) try {
+ startLayoutEffectTimer();
+ commitHookEffectListUnmount(Layout, fiber, fiber.return);
+ } finally{
+ recordLayoutEffectDuration(fiber);
+ }
+ else commitHookEffectListUnmount(Layout, fiber, fiber.return);
+ break;
+ case ClassComponent:
+ // TODO (Offscreen) Check: flags & RefStatic
+ safelyDetachRef(fiber, fiber.return);
+ var instance = fiber.stateNode;
+ if (typeof instance.componentWillUnmount === "function") safelyCallComponentWillUnmount(fiber, fiber.return, instance);
+ break;
+ case HostComponent:
+ safelyDetachRef(fiber, fiber.return);
+ break;
+ case OffscreenComponent:
+ // Check if this is a
+ var isHidden = fiber.memoizedState !== null;
+ if (isHidden) {
+ // Nested Offscreen tree is already hidden. Don't disappear
+ // its effects.
+ disappearLayoutEffects_complete(subtreeRoot);
+ continue;
+ }
+ break;
+ } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
+ if (firstChild !== null) {
+ firstChild.return = fiber;
+ nextEffect = firstChild;
+ } else disappearLayoutEffects_complete(subtreeRoot);
+ }
+ }
+ function disappearLayoutEffects_complete(subtreeRoot) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ if (fiber === subtreeRoot) {
+ nextEffect = null;
+ return;
+ }
+ var sibling = fiber.sibling;
+ if (sibling !== null) {
+ sibling.return = fiber.return;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = fiber.return;
+ }
+ }
+ function reappearLayoutEffects_begin(subtreeRoot) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ var firstChild = fiber.child;
+ if (fiber.tag === OffscreenComponent) {
+ var isHidden = fiber.memoizedState !== null;
+ if (isHidden) {
+ // Nested Offscreen tree is still hidden. Don't re-appear its effects.
+ reappearLayoutEffects_complete(subtreeRoot);
+ continue;
+ }
+ } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
+ if (firstChild !== null) {
+ // This node may have been reused from a previous render, so we can't
+ // assume its return pointer is correct.
+ firstChild.return = fiber;
+ nextEffect = firstChild;
+ } else reappearLayoutEffects_complete(subtreeRoot);
+ }
+ }
+ function reappearLayoutEffects_complete(subtreeRoot) {
+ while(nextEffect !== null){
+ var fiber = nextEffect; // TODO (Offscreen) Check: flags & LayoutStatic
+ setCurrentFiber(fiber);
+ try {
+ reappearLayoutEffectsOnFiber(fiber);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ resetCurrentFiber();
+ if (fiber === subtreeRoot) {
+ nextEffect = null;
+ return;
+ }
+ var sibling = fiber.sibling;
+ if (sibling !== null) {
+ // This node may have been reused from a previous render, so we can't
+ // assume its return pointer is correct.
+ sibling.return = fiber.return;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = fiber.return;
+ }
+ }
+ function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) {
+ nextEffect = finishedWork;
+ commitPassiveMountEffects_begin(finishedWork, root, committedLanes, committedTransitions);
+ }
+ function commitPassiveMountEffects_begin(subtreeRoot, root, committedLanes, committedTransitions) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ var firstChild = fiber.child;
+ if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
+ firstChild.return = fiber;
+ nextEffect = firstChild;
+ } else commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions);
+ }
+ }
+ function commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ if ((fiber.flags & Passive) !== NoFlags) {
+ setCurrentFiber(fiber);
+ try {
+ commitPassiveMountOnFiber(root, fiber, committedLanes, committedTransitions);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ resetCurrentFiber();
+ }
+ if (fiber === subtreeRoot) {
+ nextEffect = null;
+ return;
+ }
+ var sibling = fiber.sibling;
+ if (sibling !== null) {
+ sibling.return = fiber.return;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = fiber.return;
+ }
+ }
+ function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) {
+ switch(finishedWork.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ if (finishedWork.mode & ProfileMode) {
+ startPassiveEffectTimer();
+ try {
+ commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
+ } finally{
+ recordPassiveEffectDuration(finishedWork);
+ }
+ } else commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
+ break;
+ }
+ }
+ function commitPassiveUnmountEffects(firstChild) {
+ nextEffect = firstChild;
+ commitPassiveUnmountEffects_begin();
+ }
+ function commitPassiveUnmountEffects_begin() {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ var child = fiber.child;
+ if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
+ var deletions = fiber.deletions;
+ if (deletions !== null) {
+ for(var i = 0; i < deletions.length; i++){
+ var fiberToDelete = deletions[i];
+ nextEffect = fiberToDelete;
+ commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
+ }
+ // A fiber was deleted from this parent fiber, but it's still part of
+ // the previous (alternate) parent fiber's list of children. Because
+ // children are a linked list, an earlier sibling that's still alive
+ // will be connected to the deleted fiber via its `alternate`:
+ //
+ // live fiber
+ // --alternate--> previous live fiber
+ // --sibling--> deleted fiber
+ //
+ // We can't disconnect `alternate` on nodes that haven't been deleted
+ // yet, but we can disconnect the `sibling` and `child` pointers.
+ var previousFiber = fiber.alternate;
+ if (previousFiber !== null) {
+ var detachedChild = previousFiber.child;
+ if (detachedChild !== null) {
+ previousFiber.child = null;
+ do {
+ var detachedSibling = detachedChild.sibling;
+ detachedChild.sibling = null;
+ detachedChild = detachedSibling;
+ }while (detachedChild !== null);
+ }
+ }
+ nextEffect = fiber;
+ }
+ }
+ if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
+ child.return = fiber;
+ nextEffect = child;
+ } else commitPassiveUnmountEffects_complete();
+ }
+ }
+ function commitPassiveUnmountEffects_complete() {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ if ((fiber.flags & Passive) !== NoFlags) {
+ setCurrentFiber(fiber);
+ commitPassiveUnmountOnFiber(fiber);
+ resetCurrentFiber();
+ }
+ var sibling = fiber.sibling;
+ if (sibling !== null) {
+ sibling.return = fiber.return;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = fiber.return;
+ }
+ }
+ function commitPassiveUnmountOnFiber(finishedWork) {
+ switch(finishedWork.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ if (finishedWork.mode & ProfileMode) {
+ startPassiveEffectTimer();
+ commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
+ recordPassiveEffectDuration(finishedWork);
+ } else commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
+ break;
+ }
+ }
+ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
+ while(nextEffect !== null){
+ var fiber = nextEffect; // Deletion effects fire in parent -> child order
+ // TODO: Check if fiber has a PassiveStatic flag
+ setCurrentFiber(fiber);
+ commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
+ resetCurrentFiber();
+ var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
+ // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
+ if (child !== null) {
+ child.return = fiber;
+ nextEffect = child;
+ } else commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
+ }
+ }
+ function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
+ while(nextEffect !== null){
+ var fiber = nextEffect;
+ var sibling = fiber.sibling;
+ var returnFiber = fiber.return;
+ // Recursively traverse the entire deleted tree and clean up fiber fields.
+ // This is more aggressive than ideal, and the long term goal is to only
+ // have to detach the deleted tree at the root.
+ detachFiberAfterEffects(fiber);
+ if (fiber === deletedSubtreeRoot) {
+ nextEffect = null;
+ return;
+ }
+ if (sibling !== null) {
+ sibling.return = returnFiber;
+ nextEffect = sibling;
+ return;
+ }
+ nextEffect = returnFiber;
+ }
+ }
+ function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
+ switch(current.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ if (current.mode & ProfileMode) {
+ startPassiveEffectTimer();
+ commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
+ recordPassiveEffectDuration(current);
+ } else commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
+ break;
+ }
+ } // TODO: Reuse reappearLayoutEffects traversal here?
+ function invokeLayoutEffectMountInDEV(fiber) {
+ // We don't need to re-check StrictEffectsMode here.
+ // This function is only called if that check has already passed.
+ switch(fiber.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ try {
+ commitHookEffectListMount(Layout | HasEffect, fiber);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ break;
+ case ClassComponent:
+ var instance = fiber.stateNode;
+ try {
+ instance.componentDidMount();
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ break;
+ }
+ }
+ function invokePassiveEffectMountInDEV(fiber) {
+ // We don't need to re-check StrictEffectsMode here.
+ // This function is only called if that check has already passed.
+ switch(fiber.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ try {
+ commitHookEffectListMount(Passive$1 | HasEffect, fiber);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ break;
+ }
+ }
+ function invokeLayoutEffectUnmountInDEV(fiber) {
+ // We don't need to re-check StrictEffectsMode here.
+ // This function is only called if that check has already passed.
+ switch(fiber.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ try {
+ commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ break;
+ case ClassComponent:
+ var instance = fiber.stateNode;
+ if (typeof instance.componentWillUnmount === "function") safelyCallComponentWillUnmount(fiber, fiber.return, instance);
+ break;
+ }
+ }
+ function invokePassiveEffectUnmountInDEV(fiber) {
+ // We don't need to re-check StrictEffectsMode here.
+ // This function is only called if that check has already passed.
+ switch(fiber.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ try {
+ commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return);
+ } catch (error) {
+ captureCommitPhaseError(fiber, fiber.return, error);
+ }
+ }
+ }
+ var COMPONENT_TYPE = 0;
+ var HAS_PSEUDO_CLASS_TYPE = 1;
+ var ROLE_TYPE = 2;
+ var TEST_NAME_TYPE = 3;
+ var TEXT_TYPE = 4;
+ if (typeof Symbol === "function" && Symbol.for) {
+ var symbolFor = Symbol.for;
+ COMPONENT_TYPE = symbolFor("selector.component");
+ HAS_PSEUDO_CLASS_TYPE = symbolFor("selector.has_pseudo_class");
+ ROLE_TYPE = symbolFor("selector.role");
+ TEST_NAME_TYPE = symbolFor("selector.test_id");
+ TEXT_TYPE = symbolFor("selector.text");
+ }
+ var commitHooks = [];
+ function onCommitRoot$1() {
+ commitHooks.forEach(function(commitHook) {
+ return commitHook();
+ });
+ }
+ var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
+ function isLegacyActEnvironment(fiber) {
+ // Legacy mode. We preserve the behavior of React 17's act. It assumes an
+ // act environment whenever `jest` is defined, but you can still turn off
+ // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly
+ // to false.
+ var isReactActEnvironmentGlobal = typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest
+ var jestIsDefined = typeof jest !== "undefined";
+ return jestIsDefined && isReactActEnvironmentGlobal !== false;
+ }
+ function isConcurrentActEnvironment() {
+ var isReactActEnvironmentGlobal = typeof IS_REACT_ACT_ENVIRONMENT !== "undefined" ? IS_REACT_ACT_ENVIRONMENT : undefined;
+ if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) // TODO: Include link to relevant documentation page.
+ error("The current testing environment is not configured to support act(...)");
+ return isReactActEnvironmentGlobal;
+ }
+ var ceil = Math.ceil;
+ var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig, ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
+ var NoContext = /* */ 0;
+ var BatchedContext = /* */ 1;
+ var RenderContext = /* */ 2;
+ var CommitContext = /* */ 4;
+ var RootInProgress = 0;
+ var RootFatalErrored = 1;
+ var RootErrored = 2;
+ var RootSuspended = 3;
+ var RootSuspendedWithDelay = 4;
+ var RootCompleted = 5;
+ var RootDidNotComplete = 6; // Describes where we are in the React execution stack
+ var executionContext = NoContext; // The root we're working on
+ var workInProgressRoot = null; // The fiber we're working on
+ var workInProgress = null; // The lanes we're rendering
+ var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
+ // This is a superset of the lanes we started working on at the root. The only
+ // case where it's different from `workInProgressRootRenderLanes` is when we
+ // enter a subtree that is hidden and needs to be unhidden: Suspense and
+ // Offscreen component.
+ //
+ // Most things in the work loop should deal with workInProgressRootRenderLanes.
+ // Most things in begin/complete phases should deal with subtreeRenderLanes.
+ var subtreeRenderLanes = NoLanes;
+ var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
+ var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
+ var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
+ // slightly different than `renderLanes` because `renderLanes` can change as you
+ // enter and exit an Offscreen tree. This value is the combination of all render
+ // lanes for the entire render phase.
+ var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
+ // includes unprocessed updates, not work in bailed out children.
+ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
+ var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
+ var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase.
+ var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
+ // We will log them once the tree commits.
+ var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train
+ // model where we don't commit new loading states in too quick succession.
+ var globalMostRecentFallbackTime = 0;
+ var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
+ // more and prefer CPU suspense heuristics instead.
+ var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
+ // suspense heuristics and opt out of rendering more content.
+ var RENDER_TIMEOUT_MS = 500;
+ var workInProgressTransitions = null;
+ function resetRenderTimer() {
+ workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
+ }
+ function getRenderTargetTime() {
+ return workInProgressRootRenderTargetTime;
+ }
+ var hasUncaughtError = false;
+ var firstUncaughtError = null;
+ var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true;
+ var rootDoesHavePassiveEffects = false;
+ var rootWithPendingPassiveEffects = null;
+ var pendingPassiveEffectsLanes = NoLanes;
+ var pendingPassiveProfilerEffects = [];
+ var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates
+ var NESTED_UPDATE_LIMIT = 50;
+ var nestedUpdateCount = 0;
+ var rootWithNestedUpdates = null;
+ var isFlushingPassiveEffects = false;
+ var didScheduleUpdateDuringPassiveEffects = false;
+ var NESTED_PASSIVE_UPDATE_LIMIT = 50;
+ var nestedPassiveUpdateCount = 0;
+ var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their
+ // event times as simultaneous, even if the actual clock time has advanced
+ // between the first and second call.
+ var currentEventTime = NoTimestamp;
+ var currentEventTransitionLane = NoLanes;
+ var isRunningInsertionEffect = false;
+ function getWorkInProgressRoot() {
+ return workInProgressRoot;
+ }
+ function requestEventTime() {
+ if ((executionContext & (RenderContext | CommitContext)) !== NoContext) // We're inside React, so it's fine to read the actual time.
+ return now();
+ // We're not inside React, so we may be in the middle of a browser event.
+ if (currentEventTime !== NoTimestamp) // Use the same start time for all updates until we enter React again.
+ return currentEventTime;
+ // This is the first update since React yielded. Compute a new start time.
+ currentEventTime = now();
+ return currentEventTime;
+ }
+ function requestUpdateLane(fiber) {
+ // Special cases
+ var mode = fiber.mode;
+ if ((mode & ConcurrentMode) === NoMode) return SyncLane;
+ else if ((executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) // This is a render phase update. These are not officially supported. The
+ // old behavior is to give this the same "thread" (lanes) as
+ // whatever is currently rendering. So if you call `setState` on a component
+ // that happens later in the same render, it will flush. Ideally, we want to
+ // remove the special case and treat them as if they came from an
+ // interleaved event. Regardless, this pattern is not officially supported.
+ // This behavior is only a fallback. The flag only exists until we can roll
+ // out the setState warning, since existing code might accidentally rely on
+ // the current behavior.
+ return pickArbitraryLane(workInProgressRootRenderLanes);
+ var isTransition = requestCurrentTransition() !== NoTransition;
+ if (isTransition) {
+ if (ReactCurrentBatchConfig$3.transition !== null) {
+ var transition = ReactCurrentBatchConfig$3.transition;
+ if (!transition._updatedFibers) transition._updatedFibers = new Set();
+ transition._updatedFibers.add(fiber);
+ } // The algorithm for assigning an update to a lane should be stable for all
+ // updates at the same priority within the same event. To do this, the
+ // inputs to the algorithm must be the same.
+ //
+ // The trick we use is to cache the first of each of these inputs within an
+ // event. Then reset the cached values once we can be sure the event is
+ // over. Our heuristic for that is whenever we enter a concurrent work loop.
+ if (currentEventTransitionLane === NoLane) // All transitions within the same event are assigned the same lane.
+ currentEventTransitionLane = claimNextTransitionLane();
+ return currentEventTransitionLane;
+ } // Updates originating inside certain React methods, like flushSync, have
+ // their priority set by tracking it with a context variable.
+ //
+ // The opaque type returned by the host config is internally a lane, so we can
+ // use that directly.
+ // TODO: Move this type conversion to the event priority module.
+ var updateLane = getCurrentUpdatePriority();
+ if (updateLane !== NoLane) return updateLane;
+ // This update originated outside React. Ask the host environment for an
+ // appropriate priority, based on the type of event.
+ //
+ // The opaque type returned by the host config is internally a lane, so we can
+ // use that directly.
+ // TODO: Move this type conversion to the event priority module.
+ var eventLane = getCurrentEventPriority();
+ return eventLane;
+ }
+ function requestRetryLane(fiber) {
+ // This is a fork of `requestUpdateLane` designed specifically for Suspense
+ // "retries" \u2014 a special update that attempts to flip a Suspense boundary
+ // from its placeholder state to its primary/resolved state.
+ // Special cases
+ var mode = fiber.mode;
+ if ((mode & ConcurrentMode) === NoMode) return SyncLane;
+ return claimNextRetryLane();
+ }
+ function scheduleUpdateOnFiber(root, fiber, lane, eventTime) {
+ checkForNestedUpdates();
+ if (isRunningInsertionEffect) error("useInsertionEffect must not schedule updates.");
+ if (isFlushingPassiveEffects) didScheduleUpdateDuringPassiveEffects = true;
+ markRootUpdated(root, lane, eventTime);
+ if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) // This update was dispatched during the render phase. This is a mistake
+ // if the update originates from user space (with the exception of local
+ // hook updates, which are handled differently and don't reach this
+ // function), but there are some internal React features that use this as
+ // an implementation detail, like selective hydration.
+ warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
+ else {
+ if (isDevToolsPresent) addFiberToLanesMap(root, fiber, lane);
+ warnIfUpdatesNotWrappedWithActDEV(fiber);
+ if (root === workInProgressRoot) {
+ // Received an update to a tree that's in the middle of rendering. Mark
+ // that there was an interleaved update work on this root. Unless the
+ // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
+ // phase update. In that case, we don't treat render phase updates as if
+ // they were interleaved, for backwards compat reasons.
+ if ((executionContext & RenderContext) === NoContext) workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
+ if (workInProgressRootExitStatus === RootSuspendedWithDelay) // The root already suspended with a delay, which means this render
+ // definitely won't finish. Since we have a new update, let's mark it as
+ // suspended now, right before marking the incoming update. This has the
+ // effect of interrupting the current render and switching to the update.
+ // TODO: Make sure this doesn't override pings that happen while we've
+ // already started rendering.
+ markRootSuspended$1(root, workInProgressRootRenderLanes);
+ }
+ ensureRootIsScheduled(root, eventTime);
+ if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
+ !ReactCurrentActQueue$1.isBatchingLegacy) {
+ // Flush the synchronous work now, unless we're already working or inside
+ // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
+ // scheduleCallbackForFiber to preserve the ability to schedule a callback
+ // without immediately flushing it. We only do this for user-initiated
+ // updates, to preserve historical behavior of legacy mode.
+ resetRenderTimer();
+ flushSyncCallbacksOnlyInLegacyMode();
+ }
+ }
+ }
+ function scheduleInitialHydrationOnRoot(root, lane, eventTime) {
+ // This is a special fork of scheduleUpdateOnFiber that is only used to
+ // schedule the initial hydration of a root that has just been created. Most
+ // of the stuff in scheduleUpdateOnFiber can be skipped.
+ //
+ // The main reason for this separate path, though, is to distinguish the
+ // initial children from subsequent updates. In fully client-rendered roots
+ // (createRoot instead of hydrateRoot), all top-level renders are modeled as
+ // updates, but hydration roots are special because the initial render must
+ // match what was rendered on the server.
+ var current = root.current;
+ current.lanes = lane;
+ markRootUpdated(root, lane, eventTime);
+ ensureRootIsScheduled(root, eventTime);
+ }
+ function isUnsafeClassRenderPhaseUpdate(fiber) {
+ // Check if this is a render phase update. Only called by class components,
+ // which special (deprecated) behavior for UNSAFE_componentWillReceive props.
+ return(// decided not to enable it.
+ (executionContext & RenderContext) !== NoContext);
+ } // Use this function to schedule a task for a root. There's only one task per
+ // root; if a task was already scheduled, we'll check to make sure the priority
+ // of the existing task is the same as the priority of the next level that the
+ // root has work on. This function is called on every update, and right before
+ // exiting a task.
+ function ensureRootIsScheduled(root, currentTime) {
+ var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
+ // expired so we know to work on those next.
+ markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
+ var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
+ if (nextLanes === NoLanes) {
+ // Special case: There's nothing to work on.
+ if (existingCallbackNode !== null) cancelCallback$1(existingCallbackNode);
+ root.callbackNode = null;
+ root.callbackPriority = NoLane;
+ return;
+ } // We use the highest priority lane to represent the priority of the callback.
+ var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it.
+ var existingCallbackPriority = root.callbackPriority;
+ if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
+ // Scheduler task, rather than an `act` task, cancel it and re-scheduled
+ // on the `act` queue.
+ !(ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
+ // If we're going to re-use an existing task, it needs to exist.
+ // Assume that discrete update microtasks are non-cancellable and null.
+ // TODO: Temporary until we confirm this warning is not fired.
+ if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) error("Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.");
+ return;
+ }
+ if (existingCallbackNode != null) // Cancel the existing callback. We'll schedule a new one below.
+ cancelCallback$1(existingCallbackNode);
+ // Schedule a new callback.
+ var newCallbackNode;
+ if (newCallbackPriority === SyncLane) {
+ // Special case: Sync React callbacks are scheduled on a special
+ // internal queue
+ if (root.tag === LegacyRoot) {
+ if (ReactCurrentActQueue$1.isBatchingLegacy !== null) ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
+ scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
+ } else scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
+ // Flush the queue in a microtask.
+ if (ReactCurrentActQueue$1.current !== null) // Inside `act`, use our internal `act` queue so that these get flushed
+ // at the end of the current scope even when using the sync version
+ // of `act`.
+ ReactCurrentActQueue$1.current.push(flushSyncCallbacks);
+ else scheduleMicrotask(function() {
+ // In Safari, appending an iframe forces microtasks to run.
+ // https://github.com/facebook/react/issues/22459
+ // We don't support running callbacks in the middle of render
+ // or commit so we need to check against that.
+ if ((executionContext & (RenderContext | CommitContext)) === NoContext) // Note that this would still prematurely flush the callbacks
+ // if this happens outside render or commit phase (e.g. in an event).
+ flushSyncCallbacks();
+ });
+ newCallbackNode = null;
+ } else {
+ var schedulerPriorityLevel;
+ switch(lanesToEventPriority(nextLanes)){
+ case DiscreteEventPriority:
+ schedulerPriorityLevel = ImmediatePriority;
+ break;
+ case ContinuousEventPriority:
+ schedulerPriorityLevel = UserBlockingPriority;
+ break;
+ case DefaultEventPriority:
+ schedulerPriorityLevel = NormalPriority;
+ break;
+ case IdleEventPriority:
+ schedulerPriorityLevel = IdlePriority;
+ break;
+ default:
+ schedulerPriorityLevel = NormalPriority;
+ break;
+ }
+ newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
+ }
+ root.callbackPriority = newCallbackPriority;
+ root.callbackNode = newCallbackNode;
+ } // This is the entry point for every concurrent task, i.e. anything that
+ // goes through Scheduler.
+ function performConcurrentWorkOnRoot(root, didTimeout) {
+ resetNestedUpdateFlag();
+ // event time. The next update will compute a new event time.
+ currentEventTime = NoTimestamp;
+ currentEventTransitionLane = NoLanes;
+ if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Should not already be working.");
+ // Flush any pending passive effects before deciding which lanes to work on,
+ // in case they schedule additional work.
+ var originalCallbackNode = root.callbackNode;
+ var didFlushPassiveEffects = flushPassiveEffects();
+ if (didFlushPassiveEffects) {
+ // Something in the passive effect phase may have canceled the current task.
+ // Check if the task node for this root was changed.
+ if (root.callbackNode !== originalCallbackNode) // The current task was canceled. Exit. We don't need to call
+ // `ensureRootIsScheduled` because the check above implies either that
+ // there's a new task, or that there's no remaining work on this root.
+ return null;
+ } // Determine the next lanes to work on, using the fields stored
+ // on the root.
+ var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
+ if (lanes === NoLanes) // Defensive coding. This is never expected to happen.
+ return null;
+ // We disable time-slicing in some cases: if the work has been CPU-bound
+ // for too long ("expired" work, to prevent starvation), or we're in
+ // sync-updates-by-default mode.
+ // TODO: We only check `didTimeout` defensively, to account for a Scheduler
+ // bug we're still investigating. Once the bug in Scheduler is fixed,
+ // we can remove this, since we track expiration ourselves.
+ var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && !didTimeout;
+ var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
+ if (exitStatus !== RootInProgress) {
+ if (exitStatus === RootErrored) {
+ // If something threw an error, try rendering one more time. We'll
+ // render synchronously to block concurrent data mutations, and we'll
+ // includes all pending updates are included. If it still fails after
+ // the second attempt, we'll give up and commit the resulting tree.
+ var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
+ if (errorRetryLanes !== NoLanes) {
+ lanes = errorRetryLanes;
+ exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
+ }
+ }
+ if (exitStatus === RootFatalErrored) {
+ var fatalError = workInProgressRootFatalError;
+ prepareFreshStack(root, NoLanes);
+ markRootSuspended$1(root, lanes);
+ ensureRootIsScheduled(root, now());
+ throw fatalError;
+ }
+ if (exitStatus === RootDidNotComplete) // The render unwound without completing the tree. This happens in special
+ // cases where need to exit the current render without producing a
+ // consistent tree or committing.
+ //
+ // This should only happen during a concurrent render, not a discrete or
+ // synchronous update. We should have already checked for this when we
+ // unwound the stack.
+ markRootSuspended$1(root, lanes);
+ else {
+ // The render completed.
+ // Check if this render may have yielded to a concurrent event, and if so,
+ // confirm that any newly rendered stores are consistent.
+ // TODO: It's possible that even a concurrent render may never have yielded
+ // to the main thread, if it was fast enough, or if it expired. We could
+ // skip the consistency check in that case, too.
+ var renderWasConcurrent = !includesBlockingLane(root, lanes);
+ var finishedWork = root.current.alternate;
+ if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
+ // A store was mutated in an interleaved event. Render again,
+ // synchronously, to block further mutations.
+ exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
+ if (exitStatus === RootErrored) {
+ var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
+ if (_errorRetryLanes !== NoLanes) {
+ lanes = _errorRetryLanes;
+ exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
+ // concurrent events.
+ }
+ }
+ if (exitStatus === RootFatalErrored) {
+ var _fatalError = workInProgressRootFatalError;
+ prepareFreshStack(root, NoLanes);
+ markRootSuspended$1(root, lanes);
+ ensureRootIsScheduled(root, now());
+ throw _fatalError;
+ }
+ } // We now have a consistent tree. The next step is either to commit it,
+ // or, if something suspended, wait to commit it after a timeout.
+ root.finishedWork = finishedWork;
+ root.finishedLanes = lanes;
+ finishConcurrentRender(root, exitStatus, lanes);
+ }
+ }
+ ensureRootIsScheduled(root, now());
+ if (root.callbackNode === originalCallbackNode) // The task node scheduled for this root is the same one that's
+ // currently executed. Need to return a continuation.
+ return performConcurrentWorkOnRoot.bind(null, root);
+ return null;
+ }
+ function recoverFromConcurrentError(root, errorRetryLanes) {
+ // If an error occurred during hydration, discard server response and fall
+ // back to client side render.
+ // Before rendering again, save the errors from the previous attempt.
+ var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
+ if (isRootDehydrated(root)) {
+ // The shell failed to hydrate. Set a flag to force a client rendering
+ // during the next attempt. To do this, we call prepareFreshStack now
+ // to create the root work-in-progress fiber. This is a bit weird in terms
+ // of factoring, because it relies on renderRootSync not calling
+ // prepareFreshStack again in the call below, which happens because the
+ // root and lanes haven't changed.
+ //
+ // TODO: I think what we should do is set ForceClientRender inside
+ // throwException, like we do for nested Suspense boundaries. The reason
+ // it's here instead is so we can switch to the synchronous work loop, too.
+ // Something to consider for a future refactor.
+ var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
+ rootWorkInProgress.flags |= ForceClientRender;
+ errorHydratingContainer(root.containerInfo);
+ }
+ var exitStatus = renderRootSync(root, errorRetryLanes);
+ if (exitStatus !== RootErrored) {
+ // Successfully finished rendering on retry
+ // The errors from the failed first attempt have been recovered. Add
+ // them to the collection of recoverable errors. We'll log them in the
+ // commit phase.
+ var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
+ workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
+ // from the first attempt, to preserve the causal sequence.
+ if (errorsFromSecondAttempt !== null) queueRecoverableErrors(errorsFromSecondAttempt);
+ }
+ return exitStatus;
+ }
+ function queueRecoverableErrors(errors) {
+ if (workInProgressRootRecoverableErrors === null) workInProgressRootRecoverableErrors = errors;
+ else workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
+ }
+ function finishConcurrentRender(root, exitStatus, lanes) {
+ switch(exitStatus){
+ case RootInProgress:
+ case RootFatalErrored:
+ throw new Error("Root did not complete. This is a bug in React.");
+ // Flow knows about invariant, so it complains if I add a break
+ // statement, but eslint doesn't know about invariant, so it complains
+ // if I do. eslint-disable-next-line no-fallthrough
+ case RootErrored:
+ // We should have already attempted to retry this tree. If we reached
+ // this point, it errored again. Commit it.
+ commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
+ break;
+ case RootSuspended:
+ markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
+ // should immediately commit it or wait a bit.
+ if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
+ !shouldForceFlushFallbacksInDEV()) {
+ // This render only included retries, no updates. Throttle committing
+ // retries so that we don't show too many loading states too quickly.
+ var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
+ if (msUntilTimeout > 10) {
+ var nextLanes = getNextLanes(root, NoLanes);
+ if (nextLanes !== NoLanes) break;
+ var suspendedLanes = root.suspendedLanes;
+ if (!isSubsetOfLanes(suspendedLanes, lanes)) {
+ // We should prefer to render the fallback of at the last
+ // suspended level. Ping the last suspended level to try
+ // rendering it again.
+ // FIXME: What if the suspended lanes are Idle? Should not restart.
+ var eventTime = requestEventTime();
+ markRootPinged(root, suspendedLanes);
+ break;
+ } // The render is suspended, it hasn't timed out, and there's no
+ // lower priority work to do. Instead of committing the fallback
+ // immediately, wait for more data to arrive.
+ root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout);
+ break;
+ }
+ } // The work expired. Commit immediately.
+ commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
+ break;
+ case RootSuspendedWithDelay:
+ markRootSuspended$1(root, lanes);
+ if (includesOnlyTransitions(lanes)) break;
+ if (!shouldForceFlushFallbacksInDEV()) {
+ // This is not a transition, but we did trigger an avoided state.
+ // Schedule a placeholder to display after a short delay, using the Just
+ // Noticeable Difference.
+ // TODO: Is the JND optimization worth the added complexity? If this is
+ // the only reason we track the event time, then probably not.
+ // Consider removing.
+ var mostRecentEventTime = getMostRecentEventTime(root, lanes);
+ var eventTimeMs = mostRecentEventTime;
+ var timeElapsedMs = now() - eventTimeMs;
+ var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
+ if (_msUntilTimeout > 10) {
+ // Instead of committing the fallback immediately, wait for more data
+ // to arrive.
+ root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout);
+ break;
+ }
+ } // Commit the placeholder.
+ commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
+ break;
+ case RootCompleted:
+ // The work completed. Ready to commit.
+ commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
+ break;
+ default:
+ throw new Error("Unknown root exit status.");
+ }
+ }
+ function isRenderConsistentWithExternalStores(finishedWork) {
+ // Search the rendered tree for external store reads, and check whether the
+ // stores were mutated in a concurrent event. Intentionally using an iterative
+ // loop instead of recursion so we can exit early.
+ var node = finishedWork;
+ while(true){
+ if (node.flags & StoreConsistency) {
+ var updateQueue = node.updateQueue;
+ if (updateQueue !== null) {
+ var checks = updateQueue.stores;
+ if (checks !== null) for(var i = 0; i < checks.length; i++){
+ var check = checks[i];
+ var getSnapshot = check.getSnapshot;
+ var renderedValue = check.value;
+ try {
+ if (!objectIs(getSnapshot(), renderedValue)) // Found an inconsistent store.
+ return false;
+ } catch (error) {
+ // If `getSnapshot` throws, return `false`. This will schedule
+ // a re-render, and the error will be rethrown during render.
+ return false;
+ }
+ }
+ }
+ }
+ var child = node.child;
+ if (node.subtreeFlags & StoreConsistency && child !== null) {
+ child.return = node;
+ node = child;
+ continue;
+ }
+ if (node === finishedWork) return true;
+ while(node.sibling === null){
+ if (node.return === null || node.return === finishedWork) return true;
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ } // Flow doesn't know this is unreachable, but eslint does
+ // eslint-disable-next-line no-unreachable
+ return true;
+ }
+ function markRootSuspended$1(root, suspendedLanes) {
+ // When suspending, we should always exclude lanes that were pinged or (more
+ // rarely, since we try to avoid it) updated during the render phase.
+ // TODO: Lol maybe there's a better way to factor this besides this
+ // obnoxiously named function :)
+ suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
+ suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
+ markRootSuspended(root, suspendedLanes);
+ } // This is the entry point for synchronous tasks that don't go
+ // through Scheduler
+ function performSyncWorkOnRoot(root) {
+ syncNestedUpdateFlag();
+ if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Should not already be working.");
+ flushPassiveEffects();
+ var lanes = getNextLanes(root, NoLanes);
+ if (!includesSomeLane(lanes, SyncLane)) {
+ // There's no remaining sync work left.
+ ensureRootIsScheduled(root, now());
+ return null;
+ }
+ var exitStatus = renderRootSync(root, lanes);
+ if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
+ // If something threw an error, try rendering one more time. We'll render
+ // synchronously to block concurrent data mutations, and we'll includes
+ // all pending updates are included. If it still fails after the second
+ // attempt, we'll give up and commit the resulting tree.
+ var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
+ if (errorRetryLanes !== NoLanes) {
+ lanes = errorRetryLanes;
+ exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
+ }
+ }
+ if (exitStatus === RootFatalErrored) {
+ var fatalError = workInProgressRootFatalError;
+ prepareFreshStack(root, NoLanes);
+ markRootSuspended$1(root, lanes);
+ ensureRootIsScheduled(root, now());
+ throw fatalError;
+ }
+ if (exitStatus === RootDidNotComplete) throw new Error("Root did not complete. This is a bug in React.");
+ // We now have a consistent tree. Because this is a sync render, we
+ // will commit it even if something suspended.
+ var finishedWork = root.current.alternate;
+ root.finishedWork = finishedWork;
+ root.finishedLanes = lanes;
+ commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); // Before exiting, make sure there's a callback scheduled for the next
+ // pending level.
+ ensureRootIsScheduled(root, now());
+ return null;
+ }
+ function flushRoot(root, lanes) {
+ if (lanes !== NoLanes) {
+ markRootEntangled(root, mergeLanes(lanes, SyncLane));
+ ensureRootIsScheduled(root, now());
+ if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
+ resetRenderTimer();
+ flushSyncCallbacks();
+ }
+ }
+ }
+ function batchedUpdates$1(fn, a) {
+ var prevExecutionContext = executionContext;
+ executionContext |= BatchedContext;
+ try {
+ return fn(a);
+ } finally{
+ executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer
+ // most batchedUpdates-like method.
+ if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
+ !ReactCurrentActQueue$1.isBatchingLegacy) {
+ resetRenderTimer();
+ flushSyncCallbacksOnlyInLegacyMode();
+ }
+ }
+ }
+ function discreteUpdates(fn, a, b, c, d) {
+ var previousPriority = getCurrentUpdatePriority();
+ var prevTransition = ReactCurrentBatchConfig$3.transition;
+ try {
+ ReactCurrentBatchConfig$3.transition = null;
+ setCurrentUpdatePriority(DiscreteEventPriority);
+ return fn(a, b, c, d);
+ } finally{
+ setCurrentUpdatePriority(previousPriority);
+ ReactCurrentBatchConfig$3.transition = prevTransition;
+ if (executionContext === NoContext) resetRenderTimer();
+ }
+ } // Overload the definition to the two valid signatures.
+ // Warning, this opts-out of checking the function body.
+ // eslint-disable-next-line no-redeclare
+ function flushSync(fn) {
+ // In legacy mode, we flush pending passive effects at the beginning of the
+ // next event, not at the end of the previous one.
+ if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) flushPassiveEffects();
+ var prevExecutionContext = executionContext;
+ executionContext |= BatchedContext;
+ var prevTransition = ReactCurrentBatchConfig$3.transition;
+ var previousPriority = getCurrentUpdatePriority();
+ try {
+ ReactCurrentBatchConfig$3.transition = null;
+ setCurrentUpdatePriority(DiscreteEventPriority);
+ if (fn) return fn();
+ else return undefined;
+ } finally{
+ setCurrentUpdatePriority(previousPriority);
+ ReactCurrentBatchConfig$3.transition = prevTransition;
+ executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
+ // Note that this will happen even if batchedUpdates is higher up
+ // the stack.
+ if ((executionContext & (RenderContext | CommitContext)) === NoContext) flushSyncCallbacks();
+ }
+ }
+ function isAlreadyRendering() {
+ // Used by the renderer to print a warning if certain APIs are called from
+ // the wrong context.
+ return (executionContext & (RenderContext | CommitContext)) !== NoContext;
+ }
+ function pushRenderLanes(fiber, lanes) {
+ push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
+ subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
+ workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
+ }
+ function popRenderLanes(fiber) {
+ subtreeRenderLanes = subtreeRenderLanesCursor.current;
+ pop(subtreeRenderLanesCursor, fiber);
+ }
+ function prepareFreshStack(root, lanes) {
+ root.finishedWork = null;
+ root.finishedLanes = NoLanes;
+ var timeoutHandle = root.timeoutHandle;
+ if (timeoutHandle !== noTimeout) {
+ // The root previous suspended and scheduled a timeout to commit a fallback
+ // state. Now that we have additional work, cancel the timeout.
+ root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
+ cancelTimeout(timeoutHandle);
+ }
+ if (workInProgress !== null) {
+ var interruptedWork = workInProgress.return;
+ while(interruptedWork !== null){
+ var current = interruptedWork.alternate;
+ unwindInterruptedWork(current, interruptedWork);
+ interruptedWork = interruptedWork.return;
+ }
+ }
+ workInProgressRoot = root;
+ var rootWorkInProgress = createWorkInProgress(root.current, null);
+ workInProgress = rootWorkInProgress;
+ workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
+ workInProgressRootExitStatus = RootInProgress;
+ workInProgressRootFatalError = null;
+ workInProgressRootSkippedLanes = NoLanes;
+ workInProgressRootInterleavedUpdatedLanes = NoLanes;
+ workInProgressRootPingedLanes = NoLanes;
+ workInProgressRootConcurrentErrors = null;
+ workInProgressRootRecoverableErrors = null;
+ finishQueueingConcurrentUpdates();
+ ReactStrictModeWarnings.discardPendingWarnings();
+ return rootWorkInProgress;
+ }
+ function handleError(root, thrownValue) {
+ do {
+ var erroredWork = workInProgress;
+ try {
+ // Reset module-level state that was set during the render phase.
+ resetContextDependencies();
+ resetHooksAfterThrow();
+ resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
+ // separate issue. Write a regression test using string refs.
+ ReactCurrentOwner$2.current = null;
+ if (erroredWork === null || erroredWork.return === null) {
+ // Expected to be working on a non-root fiber. This is a fatal error
+ // because there's no ancestor that can handle it; the root is
+ // supposed to capture all errors that weren't caught by an error
+ // boundary.
+ workInProgressRootExitStatus = RootFatalErrored;
+ workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
+ // sibling, or the parent if there are no siblings. But since the root
+ // has no siblings nor a parent, we set it to null. Usually this is
+ // handled by `completeUnitOfWork` or `unwindWork`, but since we're
+ // intentionally not calling those, we need set it here.
+ // TODO: Consider calling `unwindWork` to pop the contexts.
+ workInProgress = null;
+ return;
+ }
+ if (enableProfilerTimer && erroredWork.mode & ProfileMode) // Record the time spent rendering before an error was thrown. This
+ // avoids inaccurate Profiler durations in the case of a
+ // suspended render.
+ stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
+ if (enableSchedulingProfiler) {
+ markComponentRenderStopped();
+ if (thrownValue !== null && typeof thrownValue === "object" && typeof thrownValue.then === "function") {
+ var wakeable = thrownValue;
+ markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
+ } else markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
+ }
+ throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
+ completeUnitOfWork(erroredWork);
+ } catch (yetAnotherThrownValue) {
+ // Something in the return path also threw.
+ thrownValue = yetAnotherThrownValue;
+ if (workInProgress === erroredWork && erroredWork !== null) {
+ // If this boundary has already errored, then we had trouble processing
+ // the error. Bubble it to the next boundary.
+ erroredWork = erroredWork.return;
+ workInProgress = erroredWork;
+ } else erroredWork = workInProgress;
+ continue;
+ } // Return to the normal work loop.
+ return;
+ }while (true);
+ }
+ function pushDispatcher() {
+ var prevDispatcher = ReactCurrentDispatcher$2.current;
+ ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
+ if (prevDispatcher === null) // The React isomorphic package does not include a default dispatcher.
+ // Instead the first renderer will lazily attach one, in order to give
+ // nicer error messages.
+ return ContextOnlyDispatcher;
+ else return prevDispatcher;
+ }
+ function popDispatcher(prevDispatcher) {
+ ReactCurrentDispatcher$2.current = prevDispatcher;
+ }
+ function markCommitTimeOfFallback() {
+ globalMostRecentFallbackTime = now();
+ }
+ function markSkippedUpdateLanes(lane) {
+ workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
+ }
+ function renderDidSuspend() {
+ if (workInProgressRootExitStatus === RootInProgress) workInProgressRootExitStatus = RootSuspended;
+ }
+ function renderDidSuspendDelayIfPossible() {
+ if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) workInProgressRootExitStatus = RootSuspendedWithDelay;
+ // Check if there are updates that we skipped tree that might have unblocked
+ // this render.
+ if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) // Mark the current render as suspended so that we switch to working on
+ // the updates that were skipped. Usually we only suspend at the end of
+ // the render phase.
+ // TODO: We should probably always mark the root as suspended immediately
+ // (inside this function), since by suspending at the end of the render
+ // phase introduces a potential mistake where we suspend lanes that were
+ // pinged or updated while we were rendering.
+ markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
+ }
+ function renderDidError(error) {
+ if (workInProgressRootExitStatus !== RootSuspendedWithDelay) workInProgressRootExitStatus = RootErrored;
+ if (workInProgressRootConcurrentErrors === null) workInProgressRootConcurrentErrors = [
+ error
+ ];
+ else workInProgressRootConcurrentErrors.push(error);
+ } // Called during render to determine if anything has suspended.
+ // Returns false if we're not sure.
+ function renderHasNotSuspendedYet() {
+ // If something errored or completed, we can't really be sure,
+ // so those are false.
+ return workInProgressRootExitStatus === RootInProgress;
+ }
+ function renderRootSync(root, lanes) {
+ var prevExecutionContext = executionContext;
+ executionContext |= RenderContext;
+ var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
+ // and prepare a fresh one. Otherwise we'll continue where we left off.
+ if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
+ if (isDevToolsPresent) {
+ var memoizedUpdaters = root.memoizedUpdaters;
+ if (memoizedUpdaters.size > 0) {
+ restorePendingUpdaters(root, workInProgressRootRenderLanes);
+ memoizedUpdaters.clear();
+ } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
+ // If we bailout on this work, we'll move them back (like above).
+ // It's important to move them now in case the work spawns more work at the same priority with different updaters.
+ // That way we can keep the current update and future updates separate.
+ movePendingFibersToMemoized(root, lanes);
+ }
+ workInProgressTransitions = getTransitionsForLanes();
+ prepareFreshStack(root, lanes);
+ }
+ markRenderStarted(lanes);
+ for(;;)try {
+ workLoopSync();
+ break;
+ } catch (thrownValue) {
+ handleError(root, thrownValue);
+ }
+ resetContextDependencies();
+ executionContext = prevExecutionContext;
+ popDispatcher(prevDispatcher);
+ if (workInProgress !== null) // This is a sync render, so we should have finished the whole tree.
+ throw new Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.");
+ markRenderStopped();
+ workInProgressRoot = null;
+ workInProgressRootRenderLanes = NoLanes;
+ return workInProgressRootExitStatus;
+ } // The work loop is an extremely hot path. Tell Closure not to inline it.
+ /** @noinline */ function workLoopSync() {
+ // Already timed out, so perform work without checking if we need to yield.
+ while(workInProgress !== null)performUnitOfWork(workInProgress);
+ }
+ function renderRootConcurrent(root, lanes) {
+ var prevExecutionContext = executionContext;
+ executionContext |= RenderContext;
+ var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
+ // and prepare a fresh one. Otherwise we'll continue where we left off.
+ if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
+ if (isDevToolsPresent) {
+ var memoizedUpdaters = root.memoizedUpdaters;
+ if (memoizedUpdaters.size > 0) {
+ restorePendingUpdaters(root, workInProgressRootRenderLanes);
+ memoizedUpdaters.clear();
+ } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
+ // If we bailout on this work, we'll move them back (like above).
+ // It's important to move them now in case the work spawns more work at the same priority with different updaters.
+ // That way we can keep the current update and future updates separate.
+ movePendingFibersToMemoized(root, lanes);
+ }
+ workInProgressTransitions = getTransitionsForLanes();
+ resetRenderTimer();
+ prepareFreshStack(root, lanes);
+ }
+ markRenderStarted(lanes);
+ for(;;)try {
+ workLoopConcurrent();
+ break;
+ } catch (thrownValue) {
+ handleError(root, thrownValue);
+ }
+ resetContextDependencies();
+ popDispatcher(prevDispatcher);
+ executionContext = prevExecutionContext;
+ if (workInProgress !== null) {
+ markRenderYielded();
+ return RootInProgress;
+ } else {
+ markRenderStopped();
+ workInProgressRoot = null;
+ workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
+ return workInProgressRootExitStatus;
+ }
+ }
+ /** @noinline */ function workLoopConcurrent() {
+ // Perform work until Scheduler asks us to yield
+ while(workInProgress !== null && !shouldYield())performUnitOfWork(workInProgress);
+ }
+ function performUnitOfWork(unitOfWork) {
+ // The current, flushed, state of this fiber is the alternate. Ideally
+ // nothing should rely on this, but relying on it here means that we don't
+ // need an additional field on the work in progress.
+ var current = unitOfWork.alternate;
+ setCurrentFiber(unitOfWork);
+ var next;
+ if ((unitOfWork.mode & ProfileMode) !== NoMode) {
+ startProfilerTimer(unitOfWork);
+ next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
+ stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
+ } else next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
+ resetCurrentFiber();
+ unitOfWork.memoizedProps = unitOfWork.pendingProps;
+ if (next === null) // If this doesn't spawn new work, complete the current work.
+ completeUnitOfWork(unitOfWork);
+ else workInProgress = next;
+ ReactCurrentOwner$2.current = null;
+ }
+ function completeUnitOfWork(unitOfWork) {
+ // Attempt to complete the current unit of work, then move to the next
+ // sibling. If there are no more siblings, return to the parent fiber.
+ var completedWork = unitOfWork;
+ do {
+ // The current, flushed, state of this fiber is the alternate. Ideally
+ // nothing should rely on this, but relying on it here means that we don't
+ // need an additional field on the work in progress.
+ var current = completedWork.alternate;
+ var returnFiber = completedWork.return; // Check if the work completed or if something threw.
+ if ((completedWork.flags & Incomplete) === NoFlags) {
+ setCurrentFiber(completedWork);
+ var next = void 0;
+ if ((completedWork.mode & ProfileMode) === NoMode) next = completeWork(current, completedWork, subtreeRenderLanes);
+ else {
+ startProfilerTimer(completedWork);
+ next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
+ stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
+ }
+ resetCurrentFiber();
+ if (next !== null) {
+ // Completing this fiber spawned new work. Work on that next.
+ workInProgress = next;
+ return;
+ }
+ } else {
+ // This fiber did not complete because something threw. Pop values off
+ // the stack without entering the complete phase. If this is a boundary,
+ // capture values if possible.
+ var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes.
+ if (_next !== null) {
+ // If completing this work spawned new work, do that next. We'll come
+ // back here again.
+ // Since we're restarting, remove anything that is not a host effect
+ // from the effect tag.
+ _next.flags &= HostEffectMask;
+ workInProgress = _next;
+ return;
+ }
+ if ((completedWork.mode & ProfileMode) !== NoMode) {
+ // Record the render duration for the fiber that errored.
+ stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
+ var actualDuration = completedWork.actualDuration;
+ var child = completedWork.child;
+ while(child !== null){
+ actualDuration += child.actualDuration;
+ child = child.sibling;
+ }
+ completedWork.actualDuration = actualDuration;
+ }
+ if (returnFiber !== null) {
+ // Mark the parent fiber as incomplete and clear its subtree flags.
+ returnFiber.flags |= Incomplete;
+ returnFiber.subtreeFlags = NoFlags;
+ returnFiber.deletions = null;
+ } else {
+ // We've unwound all the way to the root.
+ workInProgressRootExitStatus = RootDidNotComplete;
+ workInProgress = null;
+ return;
+ }
+ }
+ var siblingFiber = completedWork.sibling;
+ if (siblingFiber !== null) {
+ // If there is more work to do in this returnFiber, do that next.
+ workInProgress = siblingFiber;
+ return;
+ } // Otherwise, return to the parent
+ completedWork = returnFiber; // Update the next thing we're working on in case something throws.
+ workInProgress = completedWork;
+ }while (completedWork !== null); // We've reached the root.
+ if (workInProgressRootExitStatus === RootInProgress) workInProgressRootExitStatus = RootCompleted;
+ }
+ function commitRoot(root, recoverableErrors, transitions) {
+ // TODO: This no longer makes any sense. We already wrap the mutation and
+ // layout phases. Should be able to remove.
+ var previousUpdateLanePriority = getCurrentUpdatePriority();
+ var prevTransition = ReactCurrentBatchConfig$3.transition;
+ try {
+ ReactCurrentBatchConfig$3.transition = null;
+ setCurrentUpdatePriority(DiscreteEventPriority);
+ commitRootImpl(root, recoverableErrors, transitions, previousUpdateLanePriority);
+ } finally{
+ ReactCurrentBatchConfig$3.transition = prevTransition;
+ setCurrentUpdatePriority(previousUpdateLanePriority);
+ }
+ return null;
+ }
+ function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) {
+ do // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
+ // means `flushPassiveEffects` will sometimes result in additional
+ // passive effects. So we need to keep flushing in a loop until there are
+ // no more pending effects.
+ // TODO: Might be better if `flushPassiveEffects` did not automatically
+ // flush synchronous work at the end, to avoid factoring hazards like this.
+ flushPassiveEffects();
+ while (rootWithPendingPassiveEffects !== null);
+ flushRenderPhaseStrictModeWarningsInDEV();
+ if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Should not already be working.");
+ var finishedWork = root.finishedWork;
+ var lanes = root.finishedLanes;
+ markCommitStarted(lanes);
+ if (finishedWork === null) {
+ markCommitStopped();
+ return null;
+ } else if (lanes === NoLanes) error("root.finishedLanes should not be empty during a commit. This is a bug in React.");
+ root.finishedWork = null;
+ root.finishedLanes = NoLanes;
+ if (finishedWork === root.current) throw new Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.");
+ // commitRoot never returns a continuation; it always finishes synchronously.
+ // So we can clear these now to allow a new callback to be scheduled.
+ root.callbackNode = null;
+ root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first
+ // pending time is whatever is left on the root fiber.
+ var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
+ markRootFinished(root, remainingLanes);
+ if (root === workInProgressRoot) {
+ // We can reset these now that they are finished.
+ workInProgressRoot = null;
+ workInProgress = null;
+ workInProgressRootRenderLanes = NoLanes;
+ } // If there are pending passive effects, schedule a callback to process them.
+ // Do this as early as possible, so it is queued before anything else that
+ // might get scheduled in the commit phase. (See #16714.)
+ // TODO: Delete all other places that schedule the passive effect callback
+ // They're redundant.
+ if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
+ if (!rootDoesHavePassiveEffects) {
+ rootDoesHavePassiveEffects = true;
+ // to store it in pendingPassiveTransitions until they get processed
+ // We need to pass this through as an argument to commitRoot
+ // because workInProgressTransitions might have changed between
+ // the previous render and commit if we throttle the commit
+ // with setTimeout
+ pendingPassiveTransitions = transitions;
+ scheduleCallback$1(NormalPriority, function() {
+ flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
+ // *after* passive effects fire to avoid freeing a cache pool that may
+ // be referenced by a node in the tree (HostRoot, Cache boundary etc)
+ return null;
+ });
+ }
+ } // Check if there are any effects in the whole tree.
+ // TODO: This is left over from the effect list implementation, where we had
+ // to check for the existence of `firstEffect` to satisfy Flow. I think the
+ // only other reason this optimization exists is because it affects profiling.
+ // Reconsider whether this is necessary.
+ var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
+ var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
+ if (subtreeHasEffects || rootHasEffect) {
+ var prevTransition = ReactCurrentBatchConfig$3.transition;
+ ReactCurrentBatchConfig$3.transition = null;
+ var previousPriority = getCurrentUpdatePriority();
+ setCurrentUpdatePriority(DiscreteEventPriority);
+ var prevExecutionContext = executionContext;
+ executionContext |= CommitContext; // Reset this to null before calling lifecycles
+ ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
+ // of the effect list for each phase: all mutation effects come before all
+ // layout effects, and so on.
+ // The first phase a "before mutation" phase. We use this phase to read the
+ // state of the host tree right before we mutate it. This is where
+ // getSnapshotBeforeUpdate is called.
+ var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork);
+ // Mark the current commit time to be shared by all Profilers in this
+ // batch. This enables them to be grouped later.
+ recordCommitTime();
+ commitMutationEffects(root, finishedWork, lanes);
+ resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
+ // the mutation phase, so that the previous tree is still current during
+ // componentWillUnmount, but before the layout phase, so that the finished
+ // work is current during componentDidMount/Update.
+ root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
+ markLayoutEffectsStarted(lanes);
+ commitLayoutEffects(finishedWork, root, lanes);
+ markLayoutEffectsStopped();
+ // opportunity to paint.
+ requestPaint();
+ executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
+ setCurrentUpdatePriority(previousPriority);
+ ReactCurrentBatchConfig$3.transition = prevTransition;
+ } else {
+ // No effects.
+ root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
+ recordCommitTime();
+ }
+ var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
+ if (rootDoesHavePassiveEffects) {
+ // This commit has passive effects. Stash a reference to them. But don't
+ // schedule a callback until after flushing layout work.
+ rootDoesHavePassiveEffects = false;
+ rootWithPendingPassiveEffects = root;
+ pendingPassiveEffectsLanes = lanes;
+ } else {
+ nestedPassiveUpdateCount = 0;
+ rootWithPassiveNestedUpdates = null;
+ } // Read this again, since an effect might have updated it
+ remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
+ // TODO: This is part of the `componentDidCatch` implementation. Its purpose
+ // is to detect whether something might have called setState inside
+ // `componentDidCatch`. The mechanism is known to be flawed because `setState`
+ // inside `componentDidCatch` is itself flawed \u2014 that's why we recommend
+ // `getDerivedStateFromError` instead. However, it could be improved by
+ // checking if remainingLanes includes Sync work, instead of whether there's
+ // any work remaining at all (which would also include stuff like Suspense
+ // retries or transitions). It's been like this for a while, though, so fixing
+ // it probably isn't that urgent.
+ if (remainingLanes === NoLanes) // If there's no remaining work, we can clear the set of already failed
+ // error boundaries.
+ legacyErrorBoundariesThatAlreadyFailed = null;
+ if (!rootDidHavePassiveEffects) commitDoubleInvokeEffectsInDEV(root.current, false);
+ onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
+ if (isDevToolsPresent) root.memoizedUpdaters.clear();
+ onCommitRoot$1();
+ // additional work on this root is scheduled.
+ ensureRootIsScheduled(root, now());
+ if (recoverableErrors !== null) {
+ // There were errors during this render, but recovered from them without
+ // needing to surface it to the UI. We log them here.
+ var onRecoverableError = root.onRecoverableError;
+ for(var i = 0; i < recoverableErrors.length; i++){
+ var recoverableError = recoverableErrors[i];
+ var componentStack = recoverableError.stack;
+ var digest = recoverableError.digest;
+ onRecoverableError(recoverableError.value, {
+ componentStack: componentStack,
+ digest: digest
+ });
+ }
+ }
+ if (hasUncaughtError) {
+ hasUncaughtError = false;
+ var error$1 = firstUncaughtError;
+ firstUncaughtError = null;
+ throw error$1;
+ } // If the passive effects are the result of a discrete render, flush them
+ // synchronously at the end of the current task so that the result is
+ // immediately observable. Otherwise, we assume that they are not
+ // order-dependent and do not need to be observed by external systems, so we
+ // can wait until after paint.
+ // TODO: We can optimize this by not scheduling the callback earlier. Since we
+ // currently schedule the callback in multiple places, will wait until those
+ // are consolidated.
+ if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) flushPassiveEffects();
+ // Read this again, since a passive effect might have updated it
+ remainingLanes = root.pendingLanes;
+ if (includesSomeLane(remainingLanes, SyncLane)) {
+ markNestedUpdateScheduled();
+ // finishing. If there are too many, it indicates an infinite update loop.
+ if (root === rootWithNestedUpdates) nestedUpdateCount++;
+ else {
+ nestedUpdateCount = 0;
+ rootWithNestedUpdates = root;
+ }
+ } else nestedUpdateCount = 0;
+ // If layout work was scheduled, flush it now.
+ flushSyncCallbacks();
+ markCommitStopped();
+ return null;
+ }
+ function flushPassiveEffects() {
+ // Returns whether passive effects were flushed.
+ // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
+ // probably just combine the two functions. I believe they were only separate
+ // in the first place because we used to wrap it with
+ // `Scheduler.runWithPriority`, which accepts a function. But now we track the
+ // priority within React itself, so we can mutate the variable directly.
+ if (rootWithPendingPassiveEffects !== null) {
+ var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
+ var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
+ var prevTransition = ReactCurrentBatchConfig$3.transition;
+ var previousPriority = getCurrentUpdatePriority();
+ try {
+ ReactCurrentBatchConfig$3.transition = null;
+ setCurrentUpdatePriority(priority);
+ return flushPassiveEffectsImpl();
+ } finally{
+ setCurrentUpdatePriority(previousPriority);
+ ReactCurrentBatchConfig$3.transition = prevTransition; // Once passive effects have run for the tree - giving components a
+ }
+ }
+ return false;
+ }
+ function enqueuePendingPassiveProfilerEffect(fiber) {
+ pendingPassiveProfilerEffects.push(fiber);
+ if (!rootDoesHavePassiveEffects) {
+ rootDoesHavePassiveEffects = true;
+ scheduleCallback$1(NormalPriority, function() {
+ flushPassiveEffects();
+ return null;
+ });
+ }
+ }
+ function flushPassiveEffectsImpl() {
+ if (rootWithPendingPassiveEffects === null) return false;
+ // Cache and clear the transitions flag
+ var transitions = pendingPassiveTransitions;
+ pendingPassiveTransitions = null;
+ var root = rootWithPendingPassiveEffects;
+ var lanes = pendingPassiveEffectsLanes;
+ rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
+ // Figure out why and fix it. It's not causing any known issues (probably
+ // because it's only used for profiling), but it's a refactor hazard.
+ pendingPassiveEffectsLanes = NoLanes;
+ if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw new Error("Cannot flush passive effects while already rendering.");
+ isFlushingPassiveEffects = true;
+ didScheduleUpdateDuringPassiveEffects = false;
+ markPassiveEffectsStarted(lanes);
+ var prevExecutionContext = executionContext;
+ executionContext |= CommitContext;
+ commitPassiveUnmountEffects(root.current);
+ commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects
+ var profilerEffects = pendingPassiveProfilerEffects;
+ pendingPassiveProfilerEffects = [];
+ for(var i = 0; i < profilerEffects.length; i++){
+ var _fiber = profilerEffects[i];
+ commitPassiveEffectDurations(root, _fiber);
+ }
+ markPassiveEffectsStopped();
+ commitDoubleInvokeEffectsInDEV(root.current, true);
+ executionContext = prevExecutionContext;
+ flushSyncCallbacks();
+ // If additional passive effects were scheduled, increment a counter. If this
+ // exceeds the limit, we'll fire a warning.
+ if (didScheduleUpdateDuringPassiveEffects) {
+ if (root === rootWithPassiveNestedUpdates) nestedPassiveUpdateCount++;
+ else {
+ nestedPassiveUpdateCount = 0;
+ rootWithPassiveNestedUpdates = root;
+ }
+ } else nestedPassiveUpdateCount = 0;
+ isFlushingPassiveEffects = false;
+ didScheduleUpdateDuringPassiveEffects = false;
+ onPostCommitRoot(root);
+ var stateNode = root.current.stateNode;
+ stateNode.effectDuration = 0;
+ stateNode.passiveEffectDuration = 0;
+ return true;
+ }
+ function isAlreadyFailedLegacyErrorBoundary(instance) {
+ return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
+ }
+ function markLegacyErrorBoundaryAsFailed(instance) {
+ if (legacyErrorBoundariesThatAlreadyFailed === null) legacyErrorBoundariesThatAlreadyFailed = new Set([
+ instance
+ ]);
+ else legacyErrorBoundariesThatAlreadyFailed.add(instance);
+ }
+ function prepareToThrowUncaughtError(error) {
+ if (!hasUncaughtError) {
+ hasUncaughtError = true;
+ firstUncaughtError = error;
+ }
+ }
+ var onUncaughtError = prepareToThrowUncaughtError;
+ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
+ var errorInfo = createCapturedValueAtFiber(error, sourceFiber);
+ var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
+ var root = enqueueUpdate(rootFiber, update, SyncLane);
+ var eventTime = requestEventTime();
+ if (root !== null) {
+ markRootUpdated(root, SyncLane, eventTime);
+ ensureRootIsScheduled(root, eventTime);
+ }
+ }
+ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
+ reportUncaughtErrorInDEV(error$1);
+ setIsRunningInsertionEffect(false);
+ if (sourceFiber.tag === HostRoot) {
+ // Error was thrown at the root. There is no parent, so the root
+ // itself should capture it.
+ captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
+ return;
+ }
+ var fiber = null;
+ fiber = nearestMountedAncestor;
+ while(fiber !== null){
+ if (fiber.tag === HostRoot) {
+ captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
+ return;
+ } else if (fiber.tag === ClassComponent) {
+ var ctor = fiber.type;
+ var instance = fiber.stateNode;
+ if (typeof ctor.getDerivedStateFromError === "function" || typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) {
+ var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber);
+ var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
+ var root = enqueueUpdate(fiber, update, SyncLane);
+ var eventTime = requestEventTime();
+ if (root !== null) {
+ markRootUpdated(root, SyncLane, eventTime);
+ ensureRootIsScheduled(root, eventTime);
+ }
+ return;
+ }
+ }
+ fiber = fiber.return;
+ }
+ // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning
+ // will fire for errors that are thrown by destroy functions inside deleted
+ // trees. What it should instead do is propagate the error to the parent of
+ // the deleted tree. In the meantime, do not add this warning to the
+ // allowlist; this is only for our internal use.
+ error("Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.\n\nError message:\n\n%s", error$1);
+ }
+ function pingSuspendedRoot(root, wakeable, pingedLanes) {
+ var pingCache = root.pingCache;
+ if (pingCache !== null) // The wakeable resolved, so we no longer need to memoize, because it will
+ // never be thrown again.
+ pingCache.delete(wakeable);
+ var eventTime = requestEventTime();
+ markRootPinged(root, pingedLanes);
+ warnIfSuspenseResolutionNotWrappedWithActDEV(root);
+ if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
+ // Received a ping at the same priority level at which we're currently
+ // rendering. We might want to restart this render. This should mirror
+ // the logic of whether or not a root suspends once it completes.
+ // TODO: If we're rendering sync either due to Sync, Batched or expired,
+ // we should probably never restart.
+ // If we're suspended with delay, or if it's a retry, we'll always suspend
+ // so we can always restart.
+ if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) // Restart from the root.
+ prepareFreshStack(root, NoLanes);
+ else // Even though we can't restart right now, we might get an
+ // opportunity later. So we mark this render as having a ping.
+ workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
+ }
+ ensureRootIsScheduled(root, eventTime);
+ }
+ function retryTimedOutBoundary(boundaryFiber, retryLane) {
+ // The boundary fiber (a Suspense component or SuspenseList component)
+ // previously was rendered in its fallback state. One of the promises that
+ // suspended it has resolved, which means at least part of the tree was
+ // likely unblocked. Try rendering again, at a new lanes.
+ if (retryLane === NoLane) // TODO: Assign this to `suspenseState.retryLane`? to avoid
+ // unnecessary entanglement?
+ retryLane = requestRetryLane(boundaryFiber);
+ // TODO: Special case idle priority?
+ var eventTime = requestEventTime();
+ var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
+ if (root !== null) {
+ markRootUpdated(root, retryLane, eventTime);
+ ensureRootIsScheduled(root, eventTime);
+ }
+ }
+ function retryDehydratedSuspenseBoundary(boundaryFiber) {
+ var suspenseState = boundaryFiber.memoizedState;
+ var retryLane = NoLane;
+ if (suspenseState !== null) retryLane = suspenseState.retryLane;
+ retryTimedOutBoundary(boundaryFiber, retryLane);
+ }
+ function resolveRetryWakeable(boundaryFiber, wakeable) {
+ var retryLane = NoLane; // Default
+ var retryCache;
+ switch(boundaryFiber.tag){
+ case SuspenseComponent:
+ retryCache = boundaryFiber.stateNode;
+ var suspenseState = boundaryFiber.memoizedState;
+ if (suspenseState !== null) retryLane = suspenseState.retryLane;
+ break;
+ case SuspenseListComponent:
+ retryCache = boundaryFiber.stateNode;
+ break;
+ default:
+ throw new Error("Pinged unknown suspense boundary type. This is probably a bug in React.");
+ }
+ if (retryCache !== null) // The wakeable resolved, so we no longer need to memoize, because it will
+ // never be thrown again.
+ retryCache.delete(wakeable);
+ retryTimedOutBoundary(boundaryFiber, retryLane);
+ } // Computes the next Just Noticeable Difference (JND) boundary.
+ // The theory is that a person can't tell the difference between small differences in time.
+ // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
+ // difference in the experience. However, waiting for longer might mean that we can avoid
+ // showing an intermediate loading state. The longer we have already waited, the harder it
+ // is to tell small differences in time. Therefore, the longer we've already waited,
+ // the longer we can wait additionally. At some point we have to give up though.
+ // We pick a train model where the next boundary commits at a consistent schedule.
+ // These particular numbers are vague estimates. We expect to adjust them based on research.
+ function jnd(timeElapsed) {
+ return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
+ }
+ function checkForNestedUpdates() {
+ if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
+ nestedUpdateCount = 0;
+ rootWithNestedUpdates = null;
+ throw new Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.");
+ }
+ if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
+ nestedPassiveUpdateCount = 0;
+ rootWithPassiveNestedUpdates = null;
+ error("Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.");
+ }
+ }
+ function flushRenderPhaseStrictModeWarningsInDEV() {
+ ReactStrictModeWarnings.flushLegacyContextWarning();
+ ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
+ }
+ function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) {
+ // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects
+ // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level.
+ // Maybe not a big deal since this is DEV only behavior.
+ setCurrentFiber(fiber);
+ invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV);
+ if (hasPassiveEffects) invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV);
+ invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV);
+ if (hasPassiveEffects) invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV);
+ resetCurrentFiber();
+ }
+ function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) {
+ // We don't need to re-check StrictEffectsMode here.
+ // This function is only called if that check has already passed.
+ var current = firstChild;
+ var subtreeRoot = null;
+ while(current !== null){
+ var primarySubtreeFlag = current.subtreeFlags & fiberFlags;
+ if (current !== subtreeRoot && current.child !== null && primarySubtreeFlag !== NoFlags) current = current.child;
+ else {
+ if ((current.flags & fiberFlags) !== NoFlags) invokeEffectFn(current);
+ if (current.sibling !== null) current = current.sibling;
+ else current = subtreeRoot = current.return;
+ }
+ }
+ }
+ var didWarnStateUpdateForNotYetMountedComponent = null;
+ function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
+ if ((executionContext & RenderContext) !== NoContext) // We let the other warning about render phase updates deal with this one.
+ return;
+ if (!(fiber.mode & ConcurrentMode)) return;
+ var tag = fiber.tag;
+ if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) // Only warn for user-defined components, not internal ones like Suspense.
+ return;
+ // We show the whole stack but dedupe on the top component's name because
+ // the problematic code almost always lies inside that component.
+ var componentName = getComponentNameFromFiber(fiber) || "ReactComponent";
+ if (didWarnStateUpdateForNotYetMountedComponent !== null) {
+ if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) return;
+ didWarnStateUpdateForNotYetMountedComponent.add(componentName);
+ } else didWarnStateUpdateForNotYetMountedComponent = new Set([
+ componentName
+ ]);
+ var previousFiber = current;
+ try {
+ setCurrentFiber(fiber);
+ error("Can't perform a React state update on a component that hasn't mounted yet. This indicates that you have a side-effect in your render function that asynchronously later calls tries to update the component. Move this work to useEffect instead.");
+ } finally{
+ if (previousFiber) setCurrentFiber(fiber);
+ else resetCurrentFiber();
+ }
+ }
+ var beginWork$1;
+ var dummyFiber = null;
+ beginWork$1 = function(current, unitOfWork, lanes) {
+ // If a component throws an error, we replay it again in a synchronously
+ // dispatched event, so that the debugger will treat it as an uncaught
+ // error See ReactErrorUtils for more information.
+ // Before entering the begin phase, copy the work-in-progress onto a dummy
+ // fiber. If beginWork throws, we'll use this to reset the state.
+ var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
+ try {
+ return beginWork(current, unitOfWork, lanes);
+ } catch (originalError) {
+ if (didSuspendOrErrorWhileHydratingDEV() || originalError !== null && typeof originalError === "object" && typeof originalError.then === "function") // Don't replay promises.
+ // Don't replay errors if we are hydrating and have already suspended or handled an error
+ throw originalError;
+ // Keep this code in sync with handleError; any changes here must have
+ // corresponding changes there.
+ resetContextDependencies();
+ resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
+ // same fiber again.
+ // Unwind the failed stack frame
+ unwindInterruptedWork(current, unitOfWork); // Restore the original properties of the fiber.
+ assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
+ if (unitOfWork.mode & ProfileMode) // Reset the profiler timer.
+ startProfilerTimer(unitOfWork);
+ // Run beginWork again.
+ invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);
+ if (hasCaughtError()) {
+ var replayError = clearCaughtError();
+ if (typeof replayError === "object" && replayError !== null && replayError._suppressLogging && typeof originalError === "object" && originalError !== null && !originalError._suppressLogging) // If suppressed, let the flag carry over to the original error which is the one we'll rethrow.
+ originalError._suppressLogging = true;
+ } // We always throw the original error in case the second render pass is not idempotent.
+ // This can happen if a memoized function or CommonJS module doesn't throw after first invocation.
+ throw originalError;
+ }
+ };
+ var didWarnAboutUpdateInRender = false;
+ var didWarnAboutUpdateInRenderForAnotherComponent;
+ didWarnAboutUpdateInRenderForAnotherComponent = new Set();
+ function warnAboutRenderPhaseUpdatesInDEV(fiber) {
+ if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) switch(fiber.tag){
+ case FunctionComponent:
+ case ForwardRef:
+ case SimpleMemoComponent:
+ var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || "Unknown"; // Dedupe by the rendering component because it's the one that needs to be fixed.
+ var dedupeKey = renderingComponentName;
+ if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
+ didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
+ var setStateComponentName = getComponentNameFromFiber(fiber) || "Unknown";
+ error("Cannot update a component (`%s`) while rendering a different component (`%s`). To locate the bad setState() call inside `%s`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render", setStateComponentName, renderingComponentName, renderingComponentName);
+ }
+ break;
+ case ClassComponent:
+ if (!didWarnAboutUpdateInRender) {
+ error("Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.");
+ didWarnAboutUpdateInRender = true;
+ }
+ break;
+ }
+ }
+ function restorePendingUpdaters(root, lanes) {
+ if (isDevToolsPresent) {
+ var memoizedUpdaters = root.memoizedUpdaters;
+ memoizedUpdaters.forEach(function(schedulingFiber) {
+ addFiberToLanesMap(root, schedulingFiber, lanes);
+ }); // This function intentionally does not clear memoized updaters.
+ // Those may still be relevant to the current commit
+ // and a future one (e.g. Suspense).
+ }
+ }
+ var fakeActCallbackNode = {};
+ function scheduleCallback$1(priorityLevel, callback) {
+ // If we're currently inside an `act` scope, bypass Scheduler and push to
+ // the `act` queue instead.
+ var actQueue = ReactCurrentActQueue$1.current;
+ if (actQueue !== null) {
+ actQueue.push(callback);
+ return fakeActCallbackNode;
+ } else return scheduleCallback(priorityLevel, callback);
+ }
+ function cancelCallback$1(callbackNode) {
+ if (callbackNode === fakeActCallbackNode) return;
+ // In production, always call Scheduler. This function will be stripped out.
+ return cancelCallback(callbackNode);
+ }
+ function shouldForceFlushFallbacksInDEV() {
+ // Never force flush in production. This function should get stripped out.
+ return ReactCurrentActQueue$1.current !== null;
+ }
+ function warnIfUpdatesNotWrappedWithActDEV(fiber) {
+ if (fiber.mode & ConcurrentMode) {
+ if (!isConcurrentActEnvironment()) // Not in an act environment. No need to warn.
+ return;
+ } else {
+ // Legacy mode has additional cases where we suppress a warning.
+ if (!isLegacyActEnvironment()) // Not in an act environment. No need to warn.
+ return;
+ if (executionContext !== NoContext) // Legacy mode doesn't warn if the update is batched, i.e.
+ // batchedUpdates or flushSync.
+ return;
+ if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) // For backwards compatibility with pre-hooks code, legacy mode only
+ // warns for updates that originate from a hook.
+ return;
+ }
+ if (ReactCurrentActQueue$1.current === null) {
+ var previousFiber = current;
+ try {
+ setCurrentFiber(fiber);
+ error("An update to %s inside a test was not wrapped in act(...).\n\nWhen testing, code that causes React state updates should be wrapped into act(...):\n\nact(() => {\n /* fire events that update state */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act", getComponentNameFromFiber(fiber));
+ } finally{
+ if (previousFiber) setCurrentFiber(fiber);
+ else resetCurrentFiber();
+ }
+ }
+ }
+ function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
+ if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) error("A suspended resource finished loading inside a test, but the event was not wrapped in act(...).\n\nWhen testing, code that resolves suspended data should be wrapped into act(...):\n\nact(() => {\n /* finish loading suspended data */\n});\n/* assert on the output */\n\nThis ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act");
+ }
+ function setIsRunningInsertionEffect(isRunning) {
+ isRunningInsertionEffect = isRunning;
+ }
+ /* eslint-disable react-internal/prod-error-codes */ var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
+ var failedBoundaries = null;
+ var setRefreshHandler = function(handler) {
+ resolveFamily = handler;
+ };
+ function resolveFunctionForHotReloading(type) {
+ if (resolveFamily === null) // Hot reloading is disabled.
+ return type;
+ var family = resolveFamily(type);
+ if (family === undefined) return type;
+ // Use the latest known implementation.
+ return family.current;
+ }
+ function resolveClassForHotReloading(type) {
+ // No implementation differences.
+ return resolveFunctionForHotReloading(type);
+ }
+ function resolveForwardRefForHotReloading(type) {
+ if (resolveFamily === null) // Hot reloading is disabled.
+ return type;
+ var family = resolveFamily(type);
+ if (family === undefined) {
+ // Check if we're dealing with a real forwardRef. Don't want to crash early.
+ if (type !== null && type !== undefined && typeof type.render === "function") {
+ // ForwardRef is special because its resolved .type is an object,
+ // but it's possible that we only have its inner render function in the map.
+ // If that inner render function is different, we'll build a new forwardRef type.
+ var currentRender = resolveFunctionForHotReloading(type.render);
+ if (type.render !== currentRender) {
+ var syntheticType = {
+ $$typeof: REACT_FORWARD_REF_TYPE,
+ render: currentRender
+ };
+ if (type.displayName !== undefined) syntheticType.displayName = type.displayName;
+ return syntheticType;
+ }
+ }
+ return type;
+ } // Use the latest known implementation.
+ return family.current;
+ }
+ function isCompatibleFamilyForHotReloading(fiber, element) {
+ if (resolveFamily === null) // Hot reloading is disabled.
+ return false;
+ var prevType = fiber.elementType;
+ var nextType = element.type; // If we got here, we know types aren't === equal.
+ var needsCompareFamilies = false;
+ var $$typeofNextType = typeof nextType === "object" && nextType !== null ? nextType.$$typeof : null;
+ switch(fiber.tag){
+ case ClassComponent:
+ if (typeof nextType === "function") needsCompareFamilies = true;
+ break;
+ case FunctionComponent:
+ if (typeof nextType === "function") needsCompareFamilies = true;
+ else if ($$typeofNextType === REACT_LAZY_TYPE) // We don't know the inner type yet.
+ // We're going to assume that the lazy inner type is stable,
+ // and so it is sufficient to avoid reconciling it away.
+ // We're not going to unwrap or actually use the new lazy type.
+ needsCompareFamilies = true;
+ break;
+ case ForwardRef:
+ if ($$typeofNextType === REACT_FORWARD_REF_TYPE) needsCompareFamilies = true;
+ else if ($$typeofNextType === REACT_LAZY_TYPE) needsCompareFamilies = true;
+ break;
+ case MemoComponent:
+ case SimpleMemoComponent:
+ if ($$typeofNextType === REACT_MEMO_TYPE) // TODO: if it was but can no longer be simple,
+ // we shouldn't set this.
+ needsCompareFamilies = true;
+ else if ($$typeofNextType === REACT_LAZY_TYPE) needsCompareFamilies = true;
+ break;
+ default:
+ return false;
+ } // Check if both types have a family and it's the same one.
+ if (needsCompareFamilies) {
+ // Note: memo() and forwardRef() we'll compare outer rather than inner type.
+ // This means both of them need to be registered to preserve state.
+ // If we unwrapped and compared the inner types for wrappers instead,
+ // then we would risk falsely saying two separate memo(Foo)
+ // calls are equivalent because they wrap the same Foo function.
+ var prevFamily = resolveFamily(prevType);
+ if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) return true;
+ }
+ return false;
+ }
+ function markFailedErrorBoundaryForHotReloading(fiber) {
+ if (resolveFamily === null) // Hot reloading is disabled.
+ return;
+ if (typeof WeakSet !== "function") return;
+ if (failedBoundaries === null) failedBoundaries = new WeakSet();
+ failedBoundaries.add(fiber);
+ }
+ var scheduleRefresh = function(root, update) {
+ if (resolveFamily === null) // Hot reloading is disabled.
+ return;
+ var staleFamilies = update.staleFamilies, updatedFamilies = update.updatedFamilies;
+ flushPassiveEffects();
+ flushSync(function() {
+ scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
+ });
+ };
+ var scheduleRoot = function(root, element) {
+ if (root.context !== emptyContextObject) // Super edge case: root has a legacy _renderSubtree context
+ // but we don't know the parentComponent so we can't pass it.
+ // Just ignore. We'll delete this with _renderSubtree code path later.
+ return;
+ flushPassiveEffects();
+ flushSync(function() {
+ updateContainer(element, root, null, null);
+ });
+ };
+ function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
+ var alternate = fiber.alternate, child = fiber.child, sibling = fiber.sibling, tag = fiber.tag, type = fiber.type;
+ var candidateType = null;
+ switch(tag){
+ case FunctionComponent:
+ case SimpleMemoComponent:
+ case ClassComponent:
+ candidateType = type;
+ break;
+ case ForwardRef:
+ candidateType = type.render;
+ break;
+ }
+ if (resolveFamily === null) throw new Error("Expected resolveFamily to be set during hot reload.");
+ var needsRender = false;
+ var needsRemount = false;
+ if (candidateType !== null) {
+ var family = resolveFamily(candidateType);
+ if (family !== undefined) {
+ if (staleFamilies.has(family)) needsRemount = true;
+ else if (updatedFamilies.has(family)) {
+ if (tag === ClassComponent) needsRemount = true;
+ else needsRender = true;
+ }
+ }
+ }
+ if (failedBoundaries !== null) {
+ if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) needsRemount = true;
+ }
+ if (needsRemount) fiber._debugNeedsRemount = true;
+ if (needsRemount || needsRender) {
+ var _root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (_root !== null) scheduleUpdateOnFiber(_root, fiber, SyncLane, NoTimestamp);
+ }
+ if (child !== null && !needsRemount) scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
+ if (sibling !== null) scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
+ }
+ var findHostInstancesForRefresh = function(root, families) {
+ var hostInstances = new Set();
+ var types = new Set(families.map(function(family) {
+ return family.current;
+ }));
+ findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
+ return hostInstances;
+ };
+ function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
+ var child = fiber.child, sibling = fiber.sibling, tag = fiber.tag, type = fiber.type;
+ var candidateType = null;
+ switch(tag){
+ case FunctionComponent:
+ case SimpleMemoComponent:
+ case ClassComponent:
+ candidateType = type;
+ break;
+ case ForwardRef:
+ candidateType = type.render;
+ break;
+ }
+ var didMatch = false;
+ if (candidateType !== null) {
+ if (types.has(candidateType)) didMatch = true;
+ }
+ if (didMatch) // We have a match. This only drills down to the closest host components.
+ // There's no need to search deeper because for the purpose of giving
+ // visual feedback, "flashing" outermost parent rectangles is sufficient.
+ findHostInstancesForFiberShallowly(fiber, hostInstances);
+ else // If there's no match, maybe there will be one further down in the child tree.
+ if (child !== null) findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
+ if (sibling !== null) findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
+ }
+ function findHostInstancesForFiberShallowly(fiber, hostInstances) {
+ var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
+ if (foundHostInstances) return;
+ // If we didn't find any host children, fallback to closest host parent.
+ var node = fiber;
+ while(true){
+ switch(node.tag){
+ case HostComponent:
+ hostInstances.add(node.stateNode);
+ return;
+ case HostPortal:
+ hostInstances.add(node.stateNode.containerInfo);
+ return;
+ case HostRoot:
+ hostInstances.add(node.stateNode.containerInfo);
+ return;
+ }
+ if (node.return === null) throw new Error("Expected to reach root first.");
+ node = node.return;
+ }
+ }
+ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
+ var node = fiber;
+ var foundHostInstances = false;
+ while(true){
+ if (node.tag === HostComponent) {
+ // We got a match.
+ foundHostInstances = true;
+ hostInstances.add(node.stateNode); // There may still be more, so keep searching.
+ } else if (node.child !== null) {
+ node.child.return = node;
+ node = node.child;
+ continue;
+ }
+ if (node === fiber) return foundHostInstances;
+ while(node.sibling === null){
+ if (node.return === null || node.return === fiber) return foundHostInstances;
+ node = node.return;
+ }
+ node.sibling.return = node.return;
+ node = node.sibling;
+ }
+ return false;
+ }
+ var hasBadMapPolyfill;
+ hasBadMapPolyfill = false;
+ try {
+ var nonExtensibleObject = Object.preventExtensions({});
+ /* eslint-disable no-new */ new Map([
+ [
+ nonExtensibleObject,
+ null
+ ]
+ ]);
+ new Set([
+ nonExtensibleObject
+ ]);
+ /* eslint-enable no-new */ } catch (e) {
+ // TODO: Consider warning about bad polyfills
+ hasBadMapPolyfill = true;
+ }
+ function FiberNode(tag, pendingProps, key, mode) {
+ // Instance
+ this.tag = tag;
+ this.key = key;
+ this.elementType = null;
+ this.type = null;
+ this.stateNode = null; // Fiber
+ this.return = null;
+ this.child = null;
+ this.sibling = null;
+ this.index = 0;
+ this.ref = null;
+ this.pendingProps = pendingProps;
+ this.memoizedProps = null;
+ this.updateQueue = null;
+ this.memoizedState = null;
+ this.dependencies = null;
+ this.mode = mode; // Effects
+ this.flags = NoFlags;
+ this.subtreeFlags = NoFlags;
+ this.deletions = null;
+ this.lanes = NoLanes;
+ this.childLanes = NoLanes;
+ this.alternate = null;
+ // Note: The following is done to avoid a v8 performance cliff.
+ //
+ // Initializing the fields below to smis and later updating them with
+ // double values will cause Fibers to end up having separate shapes.
+ // This behavior/bug has something to do with Object.preventExtension().
+ // Fortunately this only impacts DEV builds.
+ // Unfortunately it makes React unusably slow for some applications.
+ // To work around this, initialize the fields below with doubles.
+ //
+ // Learn more about this here:
+ // https://github.com/facebook/react/issues/14365
+ // https://bugs.chromium.org/p/v8/issues/detail?id=8538
+ this.actualDuration = Number.NaN;
+ this.actualStartTime = Number.NaN;
+ this.selfBaseDuration = Number.NaN;
+ this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
+ // This won't trigger the performance cliff mentioned above,
+ // and it simplifies other profiler code (including DevTools).
+ this.actualDuration = 0;
+ this.actualStartTime = -1;
+ this.selfBaseDuration = 0;
+ this.treeBaseDuration = 0;
+ // This isn't directly used but is handy for debugging internals:
+ this._debugSource = null;
+ this._debugOwner = null;
+ this._debugNeedsRemount = false;
+ this._debugHookTypes = null;
+ if (!hasBadMapPolyfill && typeof Object.preventExtensions === "function") Object.preventExtensions(this);
+ } // This is a constructor function, rather than a POJO constructor, still
+ // please ensure we do the following:
+ // 1) Nobody should add any instance methods on this. Instance methods can be
+ // more difficult to predict when they get optimized and they are almost
+ // never inlined properly in static compilers.
+ // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
+ // always know when it is a fiber.
+ // 3) We might want to experiment with using numeric keys since they are easier
+ // to optimize in a non-JIT environment.
+ // 4) We can easily go from a constructor to a createFiber object literal if that
+ // is faster.
+ // 5) It should be easy to port this to a C struct and keep a C implementation
+ // compatible.
+ var createFiber = function(tag, pendingProps, key, mode) {
+ // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
+ return new FiberNode(tag, pendingProps, key, mode);
+ };
+ function shouldConstruct$1(Component) {
+ var prototype = Component.prototype;
+ return !!(prototype && prototype.isReactComponent);
+ }
+ function isSimpleFunctionComponent(type) {
+ return typeof type === "function" && !shouldConstruct$1(type) && type.defaultProps === undefined;
+ }
+ function resolveLazyComponentTag(Component) {
+ if (typeof Component === "function") return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
+ else if (Component !== undefined && Component !== null) {
+ var $$typeof = Component.$$typeof;
+ if ($$typeof === REACT_FORWARD_REF_TYPE) return ForwardRef;
+ if ($$typeof === REACT_MEMO_TYPE) return MemoComponent;
+ }
+ return IndeterminateComponent;
+ } // This is used to create an alternate fiber to do work on.
+ function createWorkInProgress(current, pendingProps) {
+ var workInProgress = current.alternate;
+ if (workInProgress === null) {
+ // We use a double buffering pooling technique because we know that we'll
+ // only ever need at most two versions of a tree. We pool the "other" unused
+ // node that we're free to reuse. This is lazily created to avoid allocating
+ // extra objects for things that are never updated. It also allow us to
+ // reclaim the extra memory if needed.
+ workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
+ workInProgress.elementType = current.elementType;
+ workInProgress.type = current.type;
+ workInProgress.stateNode = current.stateNode;
+ // DEV-only fields
+ workInProgress._debugSource = current._debugSource;
+ workInProgress._debugOwner = current._debugOwner;
+ workInProgress._debugHookTypes = current._debugHookTypes;
+ workInProgress.alternate = current;
+ current.alternate = workInProgress;
+ } else {
+ workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
+ workInProgress.type = current.type; // We already have an alternate.
+ // Reset the effect tag.
+ workInProgress.flags = NoFlags; // The effects are no longer valid.
+ workInProgress.subtreeFlags = NoFlags;
+ workInProgress.deletions = null;
+ // We intentionally reset, rather than copy, actualDuration & actualStartTime.
+ // This prevents time from endlessly accumulating in new commits.
+ // This has the downside of resetting values for different priority renders,
+ // But works for yielding (the common case) and should support resuming.
+ workInProgress.actualDuration = 0;
+ workInProgress.actualStartTime = -1;
+ } // Reset all effects except static ones.
+ // Static effects are not specific to a render.
+ workInProgress.flags = current.flags & StaticMask;
+ workInProgress.childLanes = current.childLanes;
+ workInProgress.lanes = current.lanes;
+ workInProgress.child = current.child;
+ workInProgress.memoizedProps = current.memoizedProps;
+ workInProgress.memoizedState = current.memoizedState;
+ workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
+ // it cannot be shared with the current fiber.
+ var currentDependencies = current.dependencies;
+ workInProgress.dependencies = currentDependencies === null ? null : {
+ lanes: currentDependencies.lanes,
+ firstContext: currentDependencies.firstContext
+ }; // These will be overridden during the parent's reconciliation
+ workInProgress.sibling = current.sibling;
+ workInProgress.index = current.index;
+ workInProgress.ref = current.ref;
+ workInProgress.selfBaseDuration = current.selfBaseDuration;
+ workInProgress.treeBaseDuration = current.treeBaseDuration;
+ workInProgress._debugNeedsRemount = current._debugNeedsRemount;
+ switch(workInProgress.tag){
+ case IndeterminateComponent:
+ case FunctionComponent:
+ case SimpleMemoComponent:
+ workInProgress.type = resolveFunctionForHotReloading(current.type);
+ break;
+ case ClassComponent:
+ workInProgress.type = resolveClassForHotReloading(current.type);
+ break;
+ case ForwardRef:
+ workInProgress.type = resolveForwardRefForHotReloading(current.type);
+ break;
+ }
+ return workInProgress;
+ } // Used to reuse a Fiber for a second pass.
+ function resetWorkInProgress(workInProgress, renderLanes) {
+ // This resets the Fiber to what createFiber or createWorkInProgress would
+ // have set the values to before during the first pass. Ideally this wouldn't
+ // be necessary but unfortunately many code paths reads from the workInProgress
+ // when they should be reading from current and writing to workInProgress.
+ // We assume pendingProps, index, key, ref, return are still untouched to
+ // avoid doing another reconciliation.
+ // Reset the effect flags but keep any Placement tags, since that's something
+ // that child fiber is setting, not the reconciliation.
+ workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
+ var current = workInProgress.alternate;
+ if (current === null) {
+ // Reset to createFiber's initial values.
+ workInProgress.childLanes = NoLanes;
+ workInProgress.lanes = renderLanes;
+ workInProgress.child = null;
+ workInProgress.subtreeFlags = NoFlags;
+ workInProgress.memoizedProps = null;
+ workInProgress.memoizedState = null;
+ workInProgress.updateQueue = null;
+ workInProgress.dependencies = null;
+ workInProgress.stateNode = null;
+ // Note: We don't reset the actualTime counts. It's useful to accumulate
+ // actual time across multiple render passes.
+ workInProgress.selfBaseDuration = 0;
+ workInProgress.treeBaseDuration = 0;
+ } else {
+ // Reset to the cloned values that createWorkInProgress would've.
+ workInProgress.childLanes = current.childLanes;
+ workInProgress.lanes = current.lanes;
+ workInProgress.child = current.child;
+ workInProgress.subtreeFlags = NoFlags;
+ workInProgress.deletions = null;
+ workInProgress.memoizedProps = current.memoizedProps;
+ workInProgress.memoizedState = current.memoizedState;
+ workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
+ workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
+ // it cannot be shared with the current fiber.
+ var currentDependencies = current.dependencies;
+ workInProgress.dependencies = currentDependencies === null ? null : {
+ lanes: currentDependencies.lanes,
+ firstContext: currentDependencies.firstContext
+ };
+ // Note: We don't reset the actualTime counts. It's useful to accumulate
+ // actual time across multiple render passes.
+ workInProgress.selfBaseDuration = current.selfBaseDuration;
+ workInProgress.treeBaseDuration = current.treeBaseDuration;
+ }
+ return workInProgress;
+ }
+ function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
+ var mode;
+ if (tag === ConcurrentRoot) {
+ mode = ConcurrentMode;
+ if (isStrictMode === true) {
+ mode |= StrictLegacyMode;
+ mode |= StrictEffectsMode;
+ }
+ } else mode = NoMode;
+ if (isDevToolsPresent) // Always collect profile timings when DevTools are present.
+ // This enables DevTools to start capturing timing at any point\u2013
+ // Without some nodes in the tree having empty base times.
+ mode |= ProfileMode;
+ return createFiber(HostRoot, null, null, mode);
+ }
+ function createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes) {
+ var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
+ var resolvedType = type;
+ if (typeof type === "function") {
+ if (shouldConstruct$1(type)) {
+ fiberTag = ClassComponent;
+ resolvedType = resolveClassForHotReloading(resolvedType);
+ } else resolvedType = resolveFunctionForHotReloading(resolvedType);
+ } else if (typeof type === "string") fiberTag = HostComponent;
+ else getTag: switch(type){
+ case REACT_FRAGMENT_TYPE:
+ return createFiberFromFragment(pendingProps.children, mode, lanes, key);
+ case REACT_STRICT_MODE_TYPE:
+ fiberTag = Mode;
+ mode |= StrictLegacyMode;
+ if ((mode & ConcurrentMode) !== NoMode) // Strict effects should never run on legacy roots
+ mode |= StrictEffectsMode;
+ break;
+ case REACT_PROFILER_TYPE:
+ return createFiberFromProfiler(pendingProps, mode, lanes, key);
+ case REACT_SUSPENSE_TYPE:
+ return createFiberFromSuspense(pendingProps, mode, lanes, key);
+ case REACT_SUSPENSE_LIST_TYPE:
+ return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
+ case REACT_OFFSCREEN_TYPE:
+ return createFiberFromOffscreen(pendingProps, mode, lanes, key);
+ case REACT_LEGACY_HIDDEN_TYPE:
+ // eslint-disable-next-line no-fallthrough
+ case REACT_SCOPE_TYPE:
+ // eslint-disable-next-line no-fallthrough
+ case REACT_CACHE_TYPE:
+ // eslint-disable-next-line no-fallthrough
+ case REACT_TRACING_MARKER_TYPE:
+ // eslint-disable-next-line no-fallthrough
+ case REACT_DEBUG_TRACING_MODE_TYPE:
+ // eslint-disable-next-line no-fallthrough
+ default:
+ if (typeof type === "object" && type !== null) switch(type.$$typeof){
+ case REACT_PROVIDER_TYPE:
+ fiberTag = ContextProvider;
+ break getTag;
+ case REACT_CONTEXT_TYPE:
+ // This is a consumer
+ fiberTag = ContextConsumer;
+ break getTag;
+ case REACT_FORWARD_REF_TYPE:
+ fiberTag = ForwardRef;
+ resolvedType = resolveForwardRefForHotReloading(resolvedType);
+ break getTag;
+ case REACT_MEMO_TYPE:
+ fiberTag = MemoComponent;
+ break getTag;
+ case REACT_LAZY_TYPE:
+ fiberTag = LazyComponent;
+ resolvedType = null;
+ break getTag;
+ }
+ var info = "";
+ if (type === undefined || typeof type === "object" && type !== null && Object.keys(type).length === 0) info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.";
+ var ownerName = owner ? getComponentNameFromFiber(owner) : null;
+ if (ownerName) info += "\n\nCheck the render method of `" + ownerName + "`.";
+ throw new Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) " + ("but got: " + (type == null ? type : typeof type) + "." + info));
+ }
+ var fiber = createFiber(fiberTag, pendingProps, key, mode);
+ fiber.elementType = type;
+ fiber.type = resolvedType;
+ fiber.lanes = lanes;
+ fiber._debugOwner = owner;
+ return fiber;
+ }
+ function createFiberFromElement(element, mode, lanes) {
+ var owner = null;
+ owner = element._owner;
+ var type = element.type;
+ var key = element.key;
+ var pendingProps = element.props;
+ var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
+ fiber._debugSource = element._source;
+ fiber._debugOwner = element._owner;
+ return fiber;
+ }
+ function createFiberFromFragment(elements, mode, lanes, key) {
+ var fiber = createFiber(Fragment, elements, key, mode);
+ fiber.lanes = lanes;
+ return fiber;
+ }
+ function createFiberFromProfiler(pendingProps, mode, lanes, key) {
+ if (typeof pendingProps.id !== "string") error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
+ var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
+ fiber.elementType = REACT_PROFILER_TYPE;
+ fiber.lanes = lanes;
+ fiber.stateNode = {
+ effectDuration: 0,
+ passiveEffectDuration: 0
+ };
+ return fiber;
+ }
+ function createFiberFromSuspense(pendingProps, mode, lanes, key) {
+ var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
+ fiber.elementType = REACT_SUSPENSE_TYPE;
+ fiber.lanes = lanes;
+ return fiber;
+ }
+ function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
+ var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
+ fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
+ fiber.lanes = lanes;
+ return fiber;
+ }
+ function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
+ var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
+ fiber.elementType = REACT_OFFSCREEN_TYPE;
+ fiber.lanes = lanes;
+ var primaryChildInstance = {
+ isHidden: false
+ };
+ fiber.stateNode = primaryChildInstance;
+ return fiber;
+ }
+ function createFiberFromText(content, mode, lanes) {
+ var fiber = createFiber(HostText, content, null, mode);
+ fiber.lanes = lanes;
+ return fiber;
+ }
+ function createFiberFromHostInstanceForDeletion() {
+ var fiber = createFiber(HostComponent, null, null, NoMode);
+ fiber.elementType = "DELETED";
+ return fiber;
+ }
+ function createFiberFromDehydratedFragment(dehydratedNode) {
+ var fiber = createFiber(DehydratedFragment, null, null, NoMode);
+ fiber.stateNode = dehydratedNode;
+ return fiber;
+ }
+ function createFiberFromPortal(portal, mode, lanes) {
+ var pendingProps = portal.children !== null ? portal.children : [];
+ var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
+ fiber.lanes = lanes;
+ fiber.stateNode = {
+ containerInfo: portal.containerInfo,
+ pendingChildren: null,
+ // Used by persistent updates
+ implementation: portal.implementation
+ };
+ return fiber;
+ } // Used for stashing WIP properties to replay failed work in DEV.
+ function assignFiberPropertiesInDEV(target, source) {
+ if (target === null) // This Fiber's initial properties will always be overwritten.
+ // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
+ target = createFiber(IndeterminateComponent, null, null, NoMode);
+ // This is intentionally written as a list of all properties.
+ // We tried to use Object.assign() instead but this is called in
+ // the hottest path, and Object.assign() was too slow:
+ // https://github.com/facebook/react/issues/12502
+ // This code is DEV-only so size is not a concern.
+ target.tag = source.tag;
+ target.key = source.key;
+ target.elementType = source.elementType;
+ target.type = source.type;
+ target.stateNode = source.stateNode;
+ target.return = source.return;
+ target.child = source.child;
+ target.sibling = source.sibling;
+ target.index = source.index;
+ target.ref = source.ref;
+ target.pendingProps = source.pendingProps;
+ target.memoizedProps = source.memoizedProps;
+ target.updateQueue = source.updateQueue;
+ target.memoizedState = source.memoizedState;
+ target.dependencies = source.dependencies;
+ target.mode = source.mode;
+ target.flags = source.flags;
+ target.subtreeFlags = source.subtreeFlags;
+ target.deletions = source.deletions;
+ target.lanes = source.lanes;
+ target.childLanes = source.childLanes;
+ target.alternate = source.alternate;
+ target.actualDuration = source.actualDuration;
+ target.actualStartTime = source.actualStartTime;
+ target.selfBaseDuration = source.selfBaseDuration;
+ target.treeBaseDuration = source.treeBaseDuration;
+ target._debugSource = source._debugSource;
+ target._debugOwner = source._debugOwner;
+ target._debugNeedsRemount = source._debugNeedsRemount;
+ target._debugHookTypes = source._debugHookTypes;
+ return target;
+ }
+ function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) {
+ this.tag = tag;
+ this.containerInfo = containerInfo;
+ this.pendingChildren = null;
+ this.current = null;
+ this.pingCache = null;
+ this.finishedWork = null;
+ this.timeoutHandle = noTimeout;
+ this.context = null;
+ this.pendingContext = null;
+ this.callbackNode = null;
+ this.callbackPriority = NoLane;
+ this.eventTimes = createLaneMap(NoLanes);
+ this.expirationTimes = createLaneMap(NoTimestamp);
+ this.pendingLanes = NoLanes;
+ this.suspendedLanes = NoLanes;
+ this.pingedLanes = NoLanes;
+ this.expiredLanes = NoLanes;
+ this.mutableReadLanes = NoLanes;
+ this.finishedLanes = NoLanes;
+ this.entangledLanes = NoLanes;
+ this.entanglements = createLaneMap(NoLanes);
+ this.identifierPrefix = identifierPrefix;
+ this.onRecoverableError = onRecoverableError;
+ this.mutableSourceEagerHydrationData = null;
+ this.effectDuration = 0;
+ this.passiveEffectDuration = 0;
+ this.memoizedUpdaters = new Set();
+ var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = [];
+ for(var _i = 0; _i < TotalLanes; _i++)pendingUpdatersLaneMap.push(new Set());
+ switch(tag){
+ case ConcurrentRoot:
+ this._debugRootType = hydrate ? "hydrateRoot()" : "createRoot()";
+ break;
+ case LegacyRoot:
+ this._debugRootType = hydrate ? "hydrate()" : "render()";
+ break;
+ }
+ }
+ function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // host config, but because they are passed in at runtime, we have to thread
+ // them through the root constructor. Perhaps we should put them all into a
+ // single type, like a DynamicHostConfig that is defined by the renderer.
+ identifierPrefix, onRecoverableError, transitionCallbacks) {
+ var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);
+ // stateNode is any.
+ var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
+ root.current = uninitializedFiber;
+ uninitializedFiber.stateNode = root;
+ var _initialState = {
+ element: initialChildren,
+ isDehydrated: hydrate,
+ cache: null,
+ // not enabled yet
+ transitions: null,
+ pendingSuspenseBoundaries: null
+ };
+ uninitializedFiber.memoizedState = _initialState;
+ initializeUpdateQueue(uninitializedFiber);
+ return root;
+ }
+ var ReactVersion = "18.2.0";
+ function createPortal(children, containerInfo, implementation) {
+ var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
+ checkKeyStringCoercion(key);
+ return {
+ // This tag allow us to uniquely identify this as a React Portal
+ $$typeof: REACT_PORTAL_TYPE,
+ key: key == null ? null : "" + key,
+ children: children,
+ containerInfo: containerInfo,
+ implementation: implementation
+ };
+ }
+ var didWarnAboutNestedUpdates;
+ var didWarnAboutFindNodeInStrictMode;
+ didWarnAboutNestedUpdates = false;
+ didWarnAboutFindNodeInStrictMode = {};
+ function getContextForSubtree(parentComponent) {
+ if (!parentComponent) return emptyContextObject;
+ var fiber = get(parentComponent);
+ var parentContext = findCurrentUnmaskedContext(fiber);
+ if (fiber.tag === ClassComponent) {
+ var Component = fiber.type;
+ if (isContextProvider(Component)) return processChildContext(fiber, Component, parentContext);
+ }
+ return parentContext;
+ }
+ function findHostInstanceWithWarning(component, methodName) {
+ var fiber = get(component);
+ if (fiber === undefined) {
+ if (typeof component.render === "function") throw new Error("Unable to find node on an unmounted component.");
+ else {
+ var keys = Object.keys(component).join(",");
+ throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys);
+ }
+ }
+ var hostFiber = findCurrentHostFiber(fiber);
+ if (hostFiber === null) return null;
+ if (hostFiber.mode & StrictLegacyMode) {
+ var componentName = getComponentNameFromFiber(fiber) || "Component";
+ if (!didWarnAboutFindNodeInStrictMode[componentName]) {
+ didWarnAboutFindNodeInStrictMode[componentName] = true;
+ var previousFiber = current;
+ try {
+ setCurrentFiber(hostFiber);
+ if (fiber.mode & StrictLegacyMode) error("%s is deprecated in StrictMode. %s was passed an instance of %s which is inside StrictMode. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node", methodName, methodName, componentName);
+ else error("%s is deprecated in StrictMode. %s was passed an instance of %s which renders StrictMode children. Instead, add a ref directly to the element you want to reference. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-find-node", methodName, methodName, componentName);
+ } finally{
+ // Ideally this should reset to previous but this shouldn't be called in
+ // render and there's another warning for that anyway.
+ if (previousFiber) setCurrentFiber(previousFiber);
+ else resetCurrentFiber();
+ }
+ }
+ }
+ return hostFiber.stateNode;
+ }
+ function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
+ var hydrate = false;
+ var initialChildren = null;
+ return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
+ }
+ function createHydrationContainer(initialChildren, callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
+ var hydrate = true;
+ var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); // TODO: Move this to FiberRoot constructor
+ root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from
+ // a regular update because the initial render must match was was rendered
+ // on the server.
+ // NOTE: This update intentionally doesn't have a payload. We're only using
+ // the update to schedule work on the root fiber (and, for legacy roots, to
+ // enqueue the callback if one is provided).
+ var current = root.current;
+ var eventTime = requestEventTime();
+ var lane = requestUpdateLane(current);
+ var update = createUpdate(eventTime, lane);
+ update.callback = callback !== undefined && callback !== null ? callback : null;
+ enqueueUpdate(current, update, lane);
+ scheduleInitialHydrationOnRoot(root, lane, eventTime);
+ return root;
+ }
+ function updateContainer(element, container, parentComponent, callback) {
+ onScheduleRoot(container, element);
+ var current$1 = container.current;
+ var eventTime = requestEventTime();
+ var lane = requestUpdateLane(current$1);
+ markRenderScheduled(lane);
+ var context = getContextForSubtree(parentComponent);
+ if (container.context === null) container.context = context;
+ else container.pendingContext = context;
+ if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
+ didWarnAboutNestedUpdates = true;
+ error("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.\n\nCheck the render method of %s.", getComponentNameFromFiber(current) || "Unknown");
+ }
+ var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
+ // being called "element".
+ update.payload = {
+ element: element
+ };
+ callback = callback === undefined ? null : callback;
+ if (callback !== null) {
+ if (typeof callback !== "function") error("render(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callback);
+ update.callback = callback;
+ }
+ var root = enqueueUpdate(current$1, update, lane);
+ if (root !== null) {
+ scheduleUpdateOnFiber(root, current$1, lane, eventTime);
+ entangleTransitions(root, current$1, lane);
+ }
+ return lane;
+ }
+ function getPublicRootInstance(container) {
+ var containerFiber = container.current;
+ if (!containerFiber.child) return null;
+ switch(containerFiber.child.tag){
+ case HostComponent:
+ return getPublicInstance(containerFiber.child.stateNode);
+ default:
+ return containerFiber.child.stateNode;
+ }
+ }
+ function attemptSynchronousHydration$1(fiber) {
+ switch(fiber.tag){
+ case HostRoot:
+ var root = fiber.stateNode;
+ if (isRootDehydrated(root)) {
+ // Flush the first scheduled "update".
+ var lanes = getHighestPriorityPendingLanes(root);
+ flushRoot(root, lanes);
+ }
+ break;
+ case SuspenseComponent:
+ flushSync(function() {
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) {
+ var eventTime = requestEventTime();
+ scheduleUpdateOnFiber(root, fiber, SyncLane, eventTime);
+ }
+ }); // If we're still blocked after this, we need to increase
+ // the priority of any promises resolving within this
+ // boundary so that they next attempt also has higher pri.
+ var retryLane = SyncLane;
+ markRetryLaneIfNotHydrated(fiber, retryLane);
+ break;
+ }
+ }
+ function markRetryLaneImpl(fiber, retryLane) {
+ var suspenseState = fiber.memoizedState;
+ if (suspenseState !== null && suspenseState.dehydrated !== null) suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
+ } // Increases the priority of thenables when they resolve within this boundary.
+ function markRetryLaneIfNotHydrated(fiber, retryLane) {
+ markRetryLaneImpl(fiber, retryLane);
+ var alternate = fiber.alternate;
+ if (alternate) markRetryLaneImpl(alternate, retryLane);
+ }
+ function attemptContinuousHydration$1(fiber) {
+ if (fiber.tag !== SuspenseComponent) // We ignore HostRoots here because we can't increase
+ // their priority and they should not suspend on I/O,
+ // since you have to wrap anything that might suspend in
+ // Suspense.
+ return;
+ var lane = SelectiveHydrationLane;
+ var root = enqueueConcurrentRenderForLane(fiber, lane);
+ if (root !== null) {
+ var eventTime = requestEventTime();
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ }
+ markRetryLaneIfNotHydrated(fiber, lane);
+ }
+ function attemptHydrationAtCurrentPriority$1(fiber) {
+ if (fiber.tag !== SuspenseComponent) // We ignore HostRoots here because we can't increase
+ // their priority other than synchronously flush it.
+ return;
+ var lane = requestUpdateLane(fiber);
+ var root = enqueueConcurrentRenderForLane(fiber, lane);
+ if (root !== null) {
+ var eventTime = requestEventTime();
+ scheduleUpdateOnFiber(root, fiber, lane, eventTime);
+ }
+ markRetryLaneIfNotHydrated(fiber, lane);
+ }
+ function findHostInstanceWithNoPortals(fiber) {
+ var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
+ if (hostFiber === null) return null;
+ return hostFiber.stateNode;
+ }
+ var shouldErrorImpl = function(fiber) {
+ return null;
+ };
+ function shouldError(fiber) {
+ return shouldErrorImpl(fiber);
+ }
+ var shouldSuspendImpl = function(fiber) {
+ return false;
+ };
+ function shouldSuspend(fiber) {
+ return shouldSuspendImpl(fiber);
+ }
+ var overrideHookState = null;
+ var overrideHookStateDeletePath = null;
+ var overrideHookStateRenamePath = null;
+ var overrideProps = null;
+ var overridePropsDeletePath = null;
+ var overridePropsRenamePath = null;
+ var scheduleUpdate = null;
+ var setErrorHandler = null;
+ var setSuspenseHandler = null;
+ var copyWithDeleteImpl = function(obj, path, index) {
+ var key = path[index];
+ var updated = isArray(obj) ? obj.slice() : assign({}, obj);
+ if (index + 1 === path.length) {
+ if (isArray(updated)) updated.splice(key, 1);
+ else delete updated[key];
+ return updated;
+ } // $FlowFixMe number or string is fine here
+ updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
+ return updated;
+ };
+ var copyWithDelete = function(obj, path) {
+ return copyWithDeleteImpl(obj, path, 0);
+ };
+ var copyWithRenameImpl = function(obj, oldPath, newPath, index) {
+ var oldKey = oldPath[index];
+ var updated = isArray(obj) ? obj.slice() : assign({}, obj);
+ if (index + 1 === oldPath.length) {
+ var newKey = newPath[index]; // $FlowFixMe number or string is fine here
+ updated[newKey] = updated[oldKey];
+ if (isArray(updated)) updated.splice(oldKey, 1);
+ else delete updated[oldKey];
+ } else // $FlowFixMe number or string is fine here
+ updated[oldKey] = copyWithRenameImpl(obj[oldKey], oldPath, newPath, index + 1);
+ return updated;
+ };
+ var copyWithRename = function(obj, oldPath, newPath) {
+ if (oldPath.length !== newPath.length) {
+ warn("copyWithRename() expects paths of the same length");
+ return;
+ } else {
+ for(var i = 0; i < newPath.length - 1; i++)if (oldPath[i] !== newPath[i]) {
+ warn("copyWithRename() expects paths to be the same except for the deepest key");
+ return;
+ }
+ }
+ return copyWithRenameImpl(obj, oldPath, newPath, 0);
+ };
+ var copyWithSetImpl = function(obj, path, index, value) {
+ if (index >= path.length) return value;
+ var key = path[index];
+ var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here
+ updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
+ return updated;
+ };
+ var copyWithSet = function(obj, path, value) {
+ return copyWithSetImpl(obj, path, 0, value);
+ };
+ var findHook = function(fiber, id) {
+ // For now, the "id" of stateful hooks is just the stateful hook index.
+ // This may change in the future with e.g. nested hooks.
+ var currentHook = fiber.memoizedState;
+ while(currentHook !== null && id > 0){
+ currentHook = currentHook.next;
+ id--;
+ }
+ return currentHook;
+ }; // Support DevTools editable values for useState and useReducer.
+ overrideHookState = function(fiber, id, path, value) {
+ var hook = findHook(fiber, id);
+ if (hook !== null) {
+ var newState = copyWithSet(hook.memoizedState, path, value);
+ hook.memoizedState = newState;
+ hook.baseState = newState; // We aren't actually adding an update to the queue,
+ // because there is no update we can add for useReducer hooks that won't trigger an error.
+ // (There's no appropriate action type for DevTools overrides.)
+ // As a result though, React will see the scheduled update as a noop and bailout.
+ // Shallow cloning props works as a workaround for now to bypass the bailout check.
+ fiber.memoizedProps = assign({}, fiber.memoizedProps);
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ }
+ };
+ overrideHookStateDeletePath = function(fiber, id, path) {
+ var hook = findHook(fiber, id);
+ if (hook !== null) {
+ var newState = copyWithDelete(hook.memoizedState, path);
+ hook.memoizedState = newState;
+ hook.baseState = newState; // We aren't actually adding an update to the queue,
+ // because there is no update we can add for useReducer hooks that won't trigger an error.
+ // (There's no appropriate action type for DevTools overrides.)
+ // As a result though, React will see the scheduled update as a noop and bailout.
+ // Shallow cloning props works as a workaround for now to bypass the bailout check.
+ fiber.memoizedProps = assign({}, fiber.memoizedProps);
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ }
+ };
+ overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
+ var hook = findHook(fiber, id);
+ if (hook !== null) {
+ var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
+ hook.memoizedState = newState;
+ hook.baseState = newState; // We aren't actually adding an update to the queue,
+ // because there is no update we can add for useReducer hooks that won't trigger an error.
+ // (There's no appropriate action type for DevTools overrides.)
+ // As a result though, React will see the scheduled update as a noop and bailout.
+ // Shallow cloning props works as a workaround for now to bypass the bailout check.
+ fiber.memoizedProps = assign({}, fiber.memoizedProps);
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ }
+ }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
+ overrideProps = function(fiber, path, value) {
+ fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
+ if (fiber.alternate) fiber.alternate.pendingProps = fiber.pendingProps;
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ };
+ overridePropsDeletePath = function(fiber, path) {
+ fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
+ if (fiber.alternate) fiber.alternate.pendingProps = fiber.pendingProps;
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ };
+ overridePropsRenamePath = function(fiber, oldPath, newPath) {
+ fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
+ if (fiber.alternate) fiber.alternate.pendingProps = fiber.pendingProps;
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ };
+ scheduleUpdate = function(fiber) {
+ var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
+ if (root !== null) scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
+ };
+ setErrorHandler = function(newShouldErrorImpl) {
+ shouldErrorImpl = newShouldErrorImpl;
+ };
+ setSuspenseHandler = function(newShouldSuspendImpl) {
+ shouldSuspendImpl = newShouldSuspendImpl;
+ };
+ function findHostInstanceByFiber(fiber) {
+ var hostFiber = findCurrentHostFiber(fiber);
+ if (hostFiber === null) return null;
+ return hostFiber.stateNode;
+ }
+ function emptyFindFiberByHostInstance(instance) {
+ return null;
+ }
+ function getCurrentFiberForDevTools() {
+ return current;
+ }
+ function injectIntoDevTools(devToolsConfig) {
+ var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
+ var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
+ return injectInternals({
+ bundleType: devToolsConfig.bundleType,
+ version: devToolsConfig.version,
+ rendererPackageName: devToolsConfig.rendererPackageName,
+ rendererConfig: devToolsConfig.rendererConfig,
+ overrideHookState: overrideHookState,
+ overrideHookStateDeletePath: overrideHookStateDeletePath,
+ overrideHookStateRenamePath: overrideHookStateRenamePath,
+ overrideProps: overrideProps,
+ overridePropsDeletePath: overridePropsDeletePath,
+ overridePropsRenamePath: overridePropsRenamePath,
+ setErrorHandler: setErrorHandler,
+ setSuspenseHandler: setSuspenseHandler,
+ scheduleUpdate: scheduleUpdate,
+ currentDispatcherRef: ReactCurrentDispatcher,
+ findHostInstanceByFiber: findHostInstanceByFiber,
+ findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
+ // React Refresh
+ findHostInstancesForRefresh: findHostInstancesForRefresh,
+ scheduleRefresh: scheduleRefresh,
+ scheduleRoot: scheduleRoot,
+ setRefreshHandler: setRefreshHandler,
+ // Enables DevTools to append owner stacks to error messages in DEV mode.
+ getCurrentFiber: getCurrentFiberForDevTools,
+ // Enables DevTools to detect reconciler version rather than renderer version
+ // which may not match for third party renderers.
+ reconcilerVersion: ReactVersion
+ });
+ }
+ /* global reportError */ var defaultOnRecoverableError = typeof reportError === "function" ? // emulating an uncaught JavaScript error.
+ reportError : function(error) {
+ // In older browsers and test environments, fallback to console.error.
+ // eslint-disable-next-line react-internal/no-production-logging
+ console["error"](error);
+ };
+ function ReactDOMRoot(internalRoot) {
+ this._internalRoot = internalRoot;
+ }
+ ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function(children) {
+ var root = this._internalRoot;
+ if (root === null) throw new Error("Cannot update an unmounted root.");
+ if (typeof arguments[1] === "function") error("render(...): does not support the second callback argument. To execute a side effect after rendering, declare it in a component body with useEffect().");
+ else if (isValidContainer(arguments[1])) error("You passed a container to the second argument of root.render(...). You don't need to pass it again since you already passed it to create the root.");
+ else if (typeof arguments[1] !== "undefined") error("You passed a second argument to root.render(...) but it only accepts one argument.");
+ var container = root.containerInfo;
+ if (container.nodeType !== COMMENT_NODE) {
+ var hostInstance = findHostInstanceWithNoPortals(root.current);
+ if (hostInstance) {
+ if (hostInstance.parentNode !== container) error("render(...): It looks like the React-rendered content of the root container was removed without using React. This is not supported and will cause errors. Instead, call root.unmount() to empty a root's container.");
+ }
+ }
+ updateContainer(children, root, null, null);
+ };
+ ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function() {
+ if (typeof arguments[0] === "function") error("unmount(...): does not support a callback argument. To execute a side effect after rendering, declare it in a component body with useEffect().");
+ var root = this._internalRoot;
+ if (root !== null) {
+ this._internalRoot = null;
+ var container = root.containerInfo;
+ if (isAlreadyRendering()) error("Attempted to synchronously unmount a root while React was already rendering. React cannot finish unmounting the root until the current render has completed, which may lead to a race condition.");
+ flushSync(function() {
+ updateContainer(null, root, null, null);
+ });
+ unmarkContainerAsRoot(container);
+ }
+ };
+ function createRoot(container, options) {
+ if (!isValidContainer(container)) throw new Error("createRoot(...): Target container is not a DOM element.");
+ warnIfReactDOMContainerInDEV(container);
+ var isStrictMode = false;
+ var concurrentUpdatesByDefaultOverride = false;
+ var identifierPrefix = "";
+ var onRecoverableError = defaultOnRecoverableError;
+ var transitionCallbacks = null;
+ if (options !== null && options !== undefined) {
+ if (options.hydrate) warn("hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, ) instead.");
+ else if (typeof options === "object" && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) error("You passed a JSX element to createRoot. You probably meant to call root.render instead. Example usage:\n\n let root = createRoot(domContainer);\n root.render( );");
+ if (options.unstable_strictMode === true) isStrictMode = true;
+ if (options.identifierPrefix !== undefined) identifierPrefix = options.identifierPrefix;
+ if (options.onRecoverableError !== undefined) onRecoverableError = options.onRecoverableError;
+ if (options.transitionCallbacks !== undefined) transitionCallbacks = options.transitionCallbacks;
+ }
+ var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
+ markContainerAsRoot(root.current, container);
+ var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
+ listenToAllSupportedEvents(rootContainerElement);
+ return new ReactDOMRoot(root);
+ }
+ function ReactDOMHydrationRoot(internalRoot) {
+ this._internalRoot = internalRoot;
+ }
+ function scheduleHydration(target) {
+ if (target) queueExplicitHydrationTarget(target);
+ }
+ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
+ function hydrateRoot(container, initialChildren, options) {
+ if (!isValidContainer(container)) throw new Error("hydrateRoot(...): Target container is not a DOM element.");
+ warnIfReactDOMContainerInDEV(container);
+ if (initialChildren === undefined) error("Must provide initial children as second argument to hydrateRoot. Example usage: hydrateRoot(domContainer, )");
+ // the hydration callbacks.
+ var hydrationCallbacks = options != null ? options : null; // TODO: Delete this option
+ var mutableSources = options != null && options.hydratedSources || null;
+ var isStrictMode = false;
+ var concurrentUpdatesByDefaultOverride = false;
+ var identifierPrefix = "";
+ var onRecoverableError = defaultOnRecoverableError;
+ if (options !== null && options !== undefined) {
+ if (options.unstable_strictMode === true) isStrictMode = true;
+ if (options.identifierPrefix !== undefined) identifierPrefix = options.identifierPrefix;
+ if (options.onRecoverableError !== undefined) onRecoverableError = options.onRecoverableError;
+ }
+ var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
+ markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway.
+ listenToAllSupportedEvents(container);
+ if (mutableSources) for(var i = 0; i < mutableSources.length; i++){
+ var mutableSource = mutableSources[i];
+ registerMutableSourceForHydration(root, mutableSource);
+ }
+ return new ReactDOMHydrationRoot(root);
+ }
+ function isValidContainer(node) {
+ return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers));
+ } // TODO: Remove this function which also includes comment nodes.
+ // We only use it in places that are currently more relaxed.
+ function isValidContainerLegacy(node) {
+ return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === " react-mount-point-unstable "));
+ }
+ function warnIfReactDOMContainerInDEV(container) {
+ if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === "BODY") error("createRoot(): Creating roots directly with 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 using a container element created for your app.");
+ if (isContainerMarkedAsRoot(container)) {
+ if (container._reactRootContainer) error("You are calling ReactDOMClient.createRoot() on a container that was previously passed to ReactDOM.render(). This is not supported.");
+ else error("You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.");
+ }
+ }
+ var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
+ var topLevelUpdateWarnings;
+ topLevelUpdateWarnings = function(container) {
+ if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
+ var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current);
+ if (hostInstance) {
+ if (hostInstance.parentNode !== container) error("render(...): It looks like the React-rendered content of this container was removed without using React. This is not supported and will cause errors. Instead, call ReactDOM.unmountComponentAtNode to empty a container.");
+ }
+ }
+ var isRootRenderedBySomeReact = !!container._reactRootContainer;
+ var rootEl = getReactRootElementInContainer(container);
+ var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
+ if (hasNonRootReactChild && !isRootRenderedBySomeReact) error("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.");
+ if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === "BODY") error("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.");
+ };
+ function getReactRootElementInContainer(container) {
+ if (!container) return null;
+ if (container.nodeType === DOCUMENT_NODE) return container.documentElement;
+ else return container.firstChild;
+ }
+ function noopOnRecoverableError() {
+ // legacy API.
+ }
+ function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) {
+ if (isHydrationContainer) {
+ if (typeof callback === "function") {
+ var originalCallback = callback;
+ callback = function() {
+ var instance = getPublicRootInstance(root);
+ originalCallback.call(instance);
+ };
+ }
+ var root = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, false, false, "", noopOnRecoverableError);
+ container._reactRootContainer = root;
+ markContainerAsRoot(root.current, container);
+ var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
+ listenToAllSupportedEvents(rootContainerElement);
+ flushSync();
+ return root;
+ } else {
+ // First clear any existing content.
+ var rootSibling;
+ while(rootSibling = container.lastChild)container.removeChild(rootSibling);
+ if (typeof callback === "function") {
+ var _originalCallback = callback;
+ callback = function() {
+ var instance = getPublicRootInstance(_root);
+ _originalCallback.call(instance);
+ };
+ }
+ var _root = createContainer(container, LegacyRoot, null, false, false, "", noopOnRecoverableError);
+ container._reactRootContainer = _root;
+ markContainerAsRoot(_root.current, container);
+ var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
+ listenToAllSupportedEvents(_rootContainerElement); // Initial mount should not be batched.
+ flushSync(function() {
+ updateContainer(initialChildren, _root, parentComponent, callback);
+ });
+ return _root;
+ }
+ }
+ function warnOnInvalidCallback$1(callback, callerName) {
+ if (callback !== null && typeof callback !== "function") error("%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.", callerName, callback);
+ }
+ function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
+ topLevelUpdateWarnings(container);
+ warnOnInvalidCallback$1(callback === undefined ? null : callback, "render");
+ var maybeRoot = container._reactRootContainer;
+ var root;
+ if (!maybeRoot) // Initial mount
+ root = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate);
+ else {
+ root = maybeRoot;
+ if (typeof callback === "function") {
+ var originalCallback = callback;
+ callback = function() {
+ var instance = getPublicRootInstance(root);
+ originalCallback.call(instance);
+ };
+ } // Update
+ updateContainer(children, root, parentComponent, callback);
+ }
+ return getPublicRootInstance(root);
+ }
+ function findDOMNode(componentOrElement) {
+ var owner = ReactCurrentOwner$3.current;
+ if (owner !== null && owner.stateNode !== null) {
+ var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
+ if (!warnedAboutRefsInRender) error("%s is accessing 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.", getComponentNameFromType(owner.type) || "A component");
+ owner.stateNode._warnedAboutRefsInRender = true;
+ }
+ if (componentOrElement == null) return null;
+ if (componentOrElement.nodeType === ELEMENT_NODE) return componentOrElement;
+ return findHostInstanceWithWarning(componentOrElement, "findDOMNode");
+ }
+ function hydrate(element, container, callback) {
+ error("ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot");
+ if (!isValidContainerLegacy(container)) throw new Error("Target container is not a DOM element.");
+ var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
+ if (isModernRoot) error("You are calling ReactDOM.hydrate() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call hydrateRoot(container, element)?");
+ return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
+ }
+ function render(element, container, callback) {
+ error("ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot");
+ if (!isValidContainerLegacy(container)) throw new Error("Target container is not a DOM element.");
+ var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
+ if (isModernRoot) error("You are calling ReactDOM.render() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.render(element)?");
+ return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
+ }
+ function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
+ error("ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18. Consider using a portal instead. Until you switch to the createRoot API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot");
+ if (!isValidContainerLegacy(containerNode)) throw new Error("Target container is not a DOM element.");
+ if (parentComponent == null || !has(parentComponent)) throw new Error("parentComponent must be a valid React Component");
+ return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
+ }
+ function unmountComponentAtNode(container) {
+ if (!isValidContainerLegacy(container)) throw new Error("unmountComponentAtNode(...): Target container is not a DOM element.");
+ var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
+ if (isModernRoot) error("You are calling ReactDOM.unmountComponentAtNode() on a container that was previously passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?");
+ if (container._reactRootContainer) {
+ var rootEl = getReactRootElementInContainer(container);
+ var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
+ if (renderedByDifferentReact) error("unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React.");
+ flushSync(function() {
+ legacyRenderSubtreeIntoContainer(null, null, container, false, function() {
+ // $FlowFixMe This should probably use `delete container._reactRootContainer`
+ container._reactRootContainer = null;
+ unmarkContainerAsRoot(container);
+ });
+ }); // If you call unmountComponentAtNode twice in quick succession, you'll
+ // get `true` twice. That's probably fine?
+ return true;
+ } else {
+ var _rootEl = getReactRootElementInContainer(container);
+ var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node.
+ var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer;
+ if (hasNonRootReactChild) error("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.");
+ return false;
+ }
+ }
+ setAttemptSynchronousHydration(attemptSynchronousHydration$1);
+ setAttemptContinuousHydration(attemptContinuousHydration$1);
+ setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
+ setGetCurrentUpdatePriority(getCurrentUpdatePriority);
+ setAttemptHydrationAtPriority(runWithPriority);
+ if (typeof Map !== "function" || // $FlowIssue Flow incorrectly thinks Map has no prototype
+ Map.prototype == null || typeof Map.prototype.forEach !== "function" || typeof Set !== "function" || // $FlowIssue Flow incorrectly thinks Set has no prototype
+ Set.prototype == null || typeof Set.prototype.clear !== "function" || typeof Set.prototype.forEach !== "function") error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills");
+ setRestoreImplementation(restoreControlledState$3);
+ setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync);
+ function createPortal$1(children, container) {
+ var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
+ if (!isValidContainer(container)) throw new Error("Target container is not a DOM element.");
+ // TODO: pass ReactDOM portal implementation as third argument
+ // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
+ return createPortal(children, container, null, key);
+ }
+ function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
+ return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
+ }
+ var Internals = {
+ usingClientEntryPoint: false,
+ // Keep in sync with ReactTestUtils.js.
+ // This is an array for better minification.
+ Events: [
+ getInstanceFromNode,
+ getNodeFromInstance,
+ getFiberCurrentPropsFromNode,
+ enqueueStateRestore,
+ restoreStateIfNeeded,
+ batchedUpdates$1
+ ]
+ };
+ function createRoot$1(container, options) {
+ if (!Internals.usingClientEntryPoint && true) error('You are importing createRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client".');
+ return createRoot(container, options);
+ }
+ function hydrateRoot$1(container, initialChildren, options) {
+ if (!Internals.usingClientEntryPoint && true) error('You are importing hydrateRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client".');
+ return hydrateRoot(container, initialChildren, options);
+ } // Overload the definition to the two valid signatures.
+ // Warning, this opts-out of checking the function body.
+ // eslint-disable-next-line no-redeclare
+ function flushSync$1(fn) {
+ if (isAlreadyRendering()) error("flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.");
+ return flushSync(fn);
+ }
+ var foundDevTools = injectIntoDevTools({
+ findFiberByHostInstance: getClosestInstanceFromNode,
+ bundleType: 1,
+ version: ReactVersion,
+ rendererPackageName: "react-dom"
+ });
+ if (!foundDevTools && canUseDOM && window.top === window.self) // 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) {
+ var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
+ if (/^(https?|file):$/.test(protocol)) // eslint-disable-next-line react-internal/no-production-logging
+ console.info("%cDownload the React DevTools for a better development experience: https://reactjs.org/link/react-devtools" + (protocol === "file:" ? "\nYou might need to use a local HTTP server (instead of file://): https://reactjs.org/link/react-devtools-faq" : ""), "font-weight:bold");
+ }
+ }
+ exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
+ exports.createPortal = createPortal$1;
+ exports.createRoot = createRoot$1;
+ exports.findDOMNode = findDOMNode;
+ exports.flushSync = flushSync$1;
+ exports.hydrate = hydrate;
+ exports.hydrateRoot = hydrateRoot$1;
+ exports.render = render;
+ exports.unmountComponentAtNode = unmountComponentAtNode;
+ exports.unstable_batchedUpdates = batchedUpdates$1;
+ exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
+ exports.version = ReactVersion;
+ /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
+})();
+
+},{"6f0162e9ab224cd4":"ifaUc","8ad4ca65319d28a7":"1SbWp"}],"1SbWp":[function(require,module,exports) {
+"use strict";
+module.exports = require("ef03b89c8fe2794e");
+
+},{"ef03b89c8fe2794e":"lSn8J"}],"lSn8J":[function(require,module,exports) {
+/**
+ * @license React
+ * scheduler.development.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */ "use strict";
+(function() {
+ "use strict";
+ /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
+ var enableSchedulerDebugging = false;
+ var enableProfiling = false;
+ var frameYieldMs = 5;
+ function push(heap, node) {
+ var index = heap.length;
+ heap.push(node);
+ siftUp(heap, node, index);
+ }
+ function peek(heap) {
+ return heap.length === 0 ? null : heap[0];
+ }
+ function pop(heap) {
+ if (heap.length === 0) return null;
+ var first = heap[0];
+ var last = heap.pop();
+ if (last !== first) {
+ heap[0] = last;
+ siftDown(heap, last, 0);
+ }
+ return first;
+ }
+ function siftUp(heap, node, i) {
+ var index = i;
+ while(index > 0){
+ var parentIndex = index - 1 >>> 1;
+ var parent = heap[parentIndex];
+ if (compare(parent, node) > 0) {
+ // The parent is larger. Swap positions.
+ heap[parentIndex] = node;
+ heap[index] = parent;
+ index = parentIndex;
+ } else // The parent is smaller. Exit.
+ return;
+ }
+ }
+ function siftDown(heap, node, i) {
+ var index = i;
+ var length = heap.length;
+ var halfLength = length >>> 1;
+ while(index < halfLength){
+ var leftIndex = (index + 1) * 2 - 1;
+ var left = heap[leftIndex];
+ var rightIndex = leftIndex + 1;
+ var right = heap[rightIndex]; // If the left or right node is smaller, swap with the smaller of those.
+ if (compare(left, node) < 0) {
+ if (rightIndex < length && compare(right, left) < 0) {
+ heap[index] = right;
+ heap[rightIndex] = node;
+ index = rightIndex;
+ } else {
+ heap[index] = left;
+ heap[leftIndex] = node;
+ index = leftIndex;
+ }
+ } else if (rightIndex < length && compare(right, node) < 0) {
+ heap[index] = right;
+ heap[rightIndex] = node;
+ index = rightIndex;
+ } else // Neither child is smaller. Exit.
+ return;
+ }
+ }
+ function compare(a, b) {
+ // Compare sort index first, then task id.
+ var diff = a.sortIndex - b.sortIndex;
+ return diff !== 0 ? diff : a.id - b.id;
+ }
+ // TODO: Use symbols?
+ var ImmediatePriority = 1;
+ var UserBlockingPriority = 2;
+ var NormalPriority = 3;
+ var LowPriority = 4;
+ var IdlePriority = 5;
+ function markTaskErrored(task, ms) {}
+ /* eslint-disable no-var */ var hasPerformanceNow = typeof performance === "object" && typeof performance.now === "function";
+ if (hasPerformanceNow) {
+ var localPerformance = performance;
+ exports.unstable_now = function() {
+ return localPerformance.now();
+ };
+ } else {
+ var localDate = Date;
+ var initialTime = localDate.now();
+ exports.unstable_now = function() {
+ return localDate.now() - initialTime;
+ };
+ } // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
+ // Math.pow(2, 30) - 1
+ // 0b111111111111111111111111111111
+ var maxSigned31BitInt = 1073741823; // Times out immediately
+ var IMMEDIATE_PRIORITY_TIMEOUT = -1; // Eventually times out
+ var USER_BLOCKING_PRIORITY_TIMEOUT = 250;
+ var NORMAL_PRIORITY_TIMEOUT = 5000;
+ var LOW_PRIORITY_TIMEOUT = 10000; // Never times out
+ var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt; // Tasks are stored on a min heap
+ var taskQueue = [];
+ var timerQueue = []; // Incrementing id counter. Used to maintain insertion order.
+ var taskIdCounter = 1; // Pausing the scheduler is useful for debugging.
+ var currentTask = null;
+ var currentPriorityLevel = NormalPriority; // This is set while performing work, to prevent re-entrance.
+ var isPerformingWork = false;
+ var isHostCallbackScheduled = false;
+ var isHostTimeoutScheduled = false; // Capture local references to native APIs, in case a polyfill overrides them.
+ var localSetTimeout = typeof setTimeout === "function" ? setTimeout : null;
+ var localClearTimeout = typeof clearTimeout === "function" ? clearTimeout : null;
+ var localSetImmediate = typeof setImmediate !== "undefined" ? setImmediate : null; // IE and Node.js + jsdom
+ var isInputPending = typeof navigator !== "undefined" && navigator.scheduling !== undefined && navigator.scheduling.isInputPending !== undefined ? navigator.scheduling.isInputPending.bind(navigator.scheduling) : null;
+ function advanceTimers(currentTime) {
+ // Check for tasks that are no longer delayed and add them to the queue.
+ var timer = peek(timerQueue);
+ while(timer !== null){
+ if (timer.callback === null) // Timer was cancelled.
+ pop(timerQueue);
+ else if (timer.startTime <= currentTime) {
+ // Timer fired. Transfer to the task queue.
+ pop(timerQueue);
+ timer.sortIndex = timer.expirationTime;
+ push(taskQueue, timer);
+ } else // Remaining timers are pending.
+ return;
+ timer = peek(timerQueue);
+ }
+ }
+ function handleTimeout(currentTime) {
+ isHostTimeoutScheduled = false;
+ advanceTimers(currentTime);
+ if (!isHostCallbackScheduled) {
+ if (peek(taskQueue) !== null) {
+ isHostCallbackScheduled = true;
+ requestHostCallback(flushWork);
+ } else {
+ var firstTimer = peek(timerQueue);
+ if (firstTimer !== null) requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
+ }
+ }
+ }
+ function flushWork(hasTimeRemaining, initialTime) {
+ isHostCallbackScheduled = false;
+ if (isHostTimeoutScheduled) {
+ // We scheduled a timeout but it's no longer needed. Cancel it.
+ isHostTimeoutScheduled = false;
+ cancelHostTimeout();
+ }
+ isPerformingWork = true;
+ var previousPriorityLevel = currentPriorityLevel;
+ try {
+ if (enableProfiling) try {
+ return workLoop(hasTimeRemaining, initialTime);
+ } catch (error) {
+ if (currentTask !== null) {
+ var currentTime = exports.unstable_now();
+ markTaskErrored(currentTask, currentTime);
+ currentTask.isQueued = false;
+ }
+ throw error;
+ }
+ else // No catch in prod code path.
+ return workLoop(hasTimeRemaining, initialTime);
+ } finally{
+ currentTask = null;
+ currentPriorityLevel = previousPriorityLevel;
+ isPerformingWork = false;
+ }
+ }
+ function workLoop(hasTimeRemaining, initialTime) {
+ var currentTime = initialTime;
+ advanceTimers(currentTime);
+ currentTask = peek(taskQueue);
+ while(currentTask !== null && !enableSchedulerDebugging){
+ if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) break;
+ var callback = currentTask.callback;
+ if (typeof callback === "function") {
+ currentTask.callback = null;
+ currentPriorityLevel = currentTask.priorityLevel;
+ var didUserCallbackTimeout = currentTask.expirationTime <= currentTime;
+ var continuationCallback = callback(didUserCallbackTimeout);
+ currentTime = exports.unstable_now();
+ if (typeof continuationCallback === "function") currentTask.callback = continuationCallback;
+ else if (currentTask === peek(taskQueue)) pop(taskQueue);
+ advanceTimers(currentTime);
+ } else pop(taskQueue);
+ currentTask = peek(taskQueue);
+ } // Return whether there's additional work
+ if (currentTask !== null) return true;
+ else {
+ var firstTimer = peek(timerQueue);
+ if (firstTimer !== null) requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime);
+ return false;
+ }
+ }
+ function unstable_runWithPriority(priorityLevel, eventHandler) {
+ switch(priorityLevel){
+ case ImmediatePriority:
+ case UserBlockingPriority:
+ case NormalPriority:
+ case LowPriority:
+ case IdlePriority:
+ break;
+ default:
+ priorityLevel = NormalPriority;
+ }
+ var previousPriorityLevel = currentPriorityLevel;
+ currentPriorityLevel = priorityLevel;
+ try {
+ return eventHandler();
+ } finally{
+ currentPriorityLevel = previousPriorityLevel;
+ }
+ }
+ function unstable_next(eventHandler) {
+ var priorityLevel;
+ switch(currentPriorityLevel){
+ case ImmediatePriority:
+ case UserBlockingPriority:
+ case NormalPriority:
+ // Shift down to normal priority
+ priorityLevel = NormalPriority;
+ break;
+ default:
+ // Anything lower than normal priority should remain at the current level.
+ priorityLevel = currentPriorityLevel;
+ break;
+ }
+ var previousPriorityLevel = currentPriorityLevel;
+ currentPriorityLevel = priorityLevel;
+ try {
+ return eventHandler();
+ } finally{
+ currentPriorityLevel = previousPriorityLevel;
+ }
+ }
+ function unstable_wrapCallback(callback) {
+ var parentPriorityLevel = currentPriorityLevel;
+ return function() {
+ // This is a fork of runWithPriority, inlined for performance.
+ var previousPriorityLevel = currentPriorityLevel;
+ currentPriorityLevel = parentPriorityLevel;
+ try {
+ return callback.apply(this, arguments);
+ } finally{
+ currentPriorityLevel = previousPriorityLevel;
+ }
+ };
+ }
+ function unstable_scheduleCallback(priorityLevel, callback, options) {
+ var currentTime = exports.unstable_now();
+ var startTime;
+ if (typeof options === "object" && options !== null) {
+ var delay = options.delay;
+ if (typeof delay === "number" && delay > 0) startTime = currentTime + delay;
+ else startTime = currentTime;
+ } else startTime = currentTime;
+ var timeout;
+ switch(priorityLevel){
+ case ImmediatePriority:
+ timeout = IMMEDIATE_PRIORITY_TIMEOUT;
+ break;
+ case UserBlockingPriority:
+ timeout = USER_BLOCKING_PRIORITY_TIMEOUT;
+ break;
+ case IdlePriority:
+ timeout = IDLE_PRIORITY_TIMEOUT;
+ break;
+ case LowPriority:
+ timeout = LOW_PRIORITY_TIMEOUT;
+ break;
+ case NormalPriority:
+ default:
+ timeout = NORMAL_PRIORITY_TIMEOUT;
+ break;
+ }
+ var expirationTime = startTime + timeout;
+ var newTask = {
+ id: taskIdCounter++,
+ callback: callback,
+ priorityLevel: priorityLevel,
+ startTime: startTime,
+ expirationTime: expirationTime,
+ sortIndex: -1
+ };
+ if (startTime > currentTime) {
+ // This is a delayed task.
+ newTask.sortIndex = startTime;
+ push(timerQueue, newTask);
+ if (peek(taskQueue) === null && newTask === peek(timerQueue)) {
+ // All tasks are delayed, and this is the task with the earliest delay.
+ if (isHostTimeoutScheduled) // Cancel an existing timeout.
+ cancelHostTimeout();
+ else isHostTimeoutScheduled = true;
+ // Schedule a timeout.
+ requestHostTimeout(handleTimeout, startTime - currentTime);
+ }
+ } else {
+ newTask.sortIndex = expirationTime;
+ push(taskQueue, newTask);
+ // wait until the next time we yield.
+ if (!isHostCallbackScheduled && !isPerformingWork) {
+ isHostCallbackScheduled = true;
+ requestHostCallback(flushWork);
+ }
+ }
+ return newTask;
+ }
+ function unstable_pauseExecution() {}
+ function unstable_continueExecution() {
+ if (!isHostCallbackScheduled && !isPerformingWork) {
+ isHostCallbackScheduled = true;
+ requestHostCallback(flushWork);
+ }
+ }
+ function unstable_getFirstCallbackNode() {
+ return peek(taskQueue);
+ }
+ function unstable_cancelCallback(task) {
+ // remove from the queue because you can't remove arbitrary nodes from an
+ // array based heap, only the first one.)
+ task.callback = null;
+ }
+ function unstable_getCurrentPriorityLevel() {
+ return currentPriorityLevel;
+ }
+ var isMessageLoopRunning = false;
+ var scheduledHostCallback = null;
+ var taskTimeoutID = -1; // Scheduler periodically yields in case there is other work on the main
+ // thread, like user events. By default, it yields multiple times per frame.
+ // It does not attempt to align with frame boundaries, since most tasks don't
+ // need to be frame aligned; for those that do, use requestAnimationFrame.
+ var frameInterval = frameYieldMs;
+ var startTime = -1;
+ function shouldYieldToHost() {
+ var timeElapsed = exports.unstable_now() - startTime;
+ if (timeElapsed < frameInterval) // The main thread has only been blocked for a really short amount of time;
+ // smaller than a single frame. Don't yield yet.
+ return false;
+ // The main thread has been blocked for a non-negligible amount of time. We
+ return true;
+ }
+ function requestPaint() {}
+ function forceFrameRate(fps) {
+ if (fps < 0 || fps > 125) {
+ // Using console['error'] to evade Babel and ESLint
+ console["error"]("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported");
+ return;
+ }
+ if (fps > 0) frameInterval = Math.floor(1000 / fps);
+ else // reset the framerate
+ frameInterval = frameYieldMs;
+ }
+ var performWorkUntilDeadline = function() {
+ if (scheduledHostCallback !== null) {
+ var currentTime = exports.unstable_now(); // Keep track of the start time so we can measure how long the main thread
+ // has been blocked.
+ startTime = currentTime;
+ var hasTimeRemaining = true; // If a scheduler task throws, exit the current browser task so the
+ // error can be observed.
+ //
+ // Intentionally not using a try-catch, since that makes some debugging
+ // techniques harder. Instead, if `scheduledHostCallback` errors, then
+ // `hasMoreWork` will remain true, and we'll continue the work loop.
+ var hasMoreWork = true;
+ try {
+ hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime);
+ } finally{
+ if (hasMoreWork) // If there's more work, schedule the next message event at the end
+ // of the preceding one.
+ schedulePerformWorkUntilDeadline();
+ else {
+ isMessageLoopRunning = false;
+ scheduledHostCallback = null;
+ }
+ }
+ } else isMessageLoopRunning = false;
+ // Yielding to the browser will give it a chance to paint, so we can
+ };
+ var schedulePerformWorkUntilDeadline;
+ if (typeof localSetImmediate === "function") // Node.js and old IE.
+ // There's a few reasons for why we prefer setImmediate.
+ //
+ // Unlike MessageChannel, it doesn't prevent a Node.js process from exiting.
+ // (Even though this is a DOM fork of the Scheduler, you could get here
+ // with a mix of Node.js 15+, which has a MessageChannel, and jsdom.)
+ // https://github.com/facebook/react/issues/20756
+ //
+ // But also, it runs earlier which is the semantic we want.
+ // If other browsers ever implement it, it's better to use it.
+ // Although both of these would be inferior to native scheduling.
+ schedulePerformWorkUntilDeadline = function() {
+ localSetImmediate(performWorkUntilDeadline);
+ };
+ else if (typeof MessageChannel !== "undefined") {
+ // DOM and Worker environments.
+ // We prefer MessageChannel because of the 4ms setTimeout clamping.
+ var channel = new MessageChannel();
+ var port = channel.port2;
+ channel.port1.onmessage = performWorkUntilDeadline;
+ schedulePerformWorkUntilDeadline = function() {
+ port.postMessage(null);
+ };
+ } else // We should only fallback here in non-browser environments.
+ schedulePerformWorkUntilDeadline = function() {
+ localSetTimeout(performWorkUntilDeadline, 0);
+ };
+ function requestHostCallback(callback) {
+ scheduledHostCallback = callback;
+ if (!isMessageLoopRunning) {
+ isMessageLoopRunning = true;
+ schedulePerformWorkUntilDeadline();
+ }
+ }
+ function requestHostTimeout(callback, ms) {
+ taskTimeoutID = localSetTimeout(function() {
+ callback(exports.unstable_now());
+ }, ms);
+ }
+ function cancelHostTimeout() {
+ localClearTimeout(taskTimeoutID);
+ taskTimeoutID = -1;
+ }
+ var unstable_requestPaint = requestPaint;
+ var unstable_Profiling = null;
+ exports.unstable_IdlePriority = IdlePriority;
+ exports.unstable_ImmediatePriority = ImmediatePriority;
+ exports.unstable_LowPriority = LowPriority;
+ exports.unstable_NormalPriority = NormalPriority;
+ exports.unstable_Profiling = unstable_Profiling;
+ exports.unstable_UserBlockingPriority = UserBlockingPriority;
+ exports.unstable_cancelCallback = unstable_cancelCallback;
+ exports.unstable_continueExecution = unstable_continueExecution;
+ exports.unstable_forceFrameRate = forceFrameRate;
+ exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
+ exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode;
+ exports.unstable_next = unstable_next;
+ exports.unstable_pauseExecution = unstable_pauseExecution;
+ exports.unstable_requestPaint = unstable_requestPaint;
+ exports.unstable_runWithPriority = unstable_runWithPriority;
+ exports.unstable_scheduleCallback = unstable_scheduleCallback;
+ exports.unstable_shouldYield = shouldYieldToHost;
+ exports.unstable_wrapCallback = unstable_wrapCallback;
+ /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */ if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
+})();
+
+},{}],"gR4js":[function(require,module,exports) {
+var $parcel$ReactRefreshHelpers$3fe9 = require("@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js");
+var prevRefreshReg = window.$RefreshReg$;
+var prevRefreshSig = window.$RefreshSig$;
+$parcel$ReactRefreshHelpers$3fe9.prelude(module);
+
+try {
+var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
+parcelHelpers.defineInteropFlag(exports);
+parcelHelpers.export(exports, "getLayout", ()=>getLayout);
+var _react = require("react");
+const getLayout = (RawImport)=>typeof RawImport.Layout === "function" ? RawImport.Layout : typeof RawImport.getGlobalProvider === "function" ? RawImport.getGlobalProvider() : (0, _react.Fragment);
+
+ $parcel$ReactRefreshHelpers$3fe9.postlude(module);
+} finally {
+ window.$RefreshReg$ = prevRefreshReg;
+ window.$RefreshSig$ = prevRefreshSig;
+}
+},{"react":"ifaUc","@parcel/transformer-js/src/esmodule-helpers.js":"boKlo","@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js":"d37mJ"}],"boKlo":[function(require,module,exports) {
+exports.interopDefault = function(a) {
+ return a && a.__esModule ? a : {
+ default: a
+ };
+};
+exports.defineInteropFlag = function(a) {
+ Object.defineProperty(a, "__esModule", {
+ value: true
+ });
+};
+exports.exportAll = function(source, dest) {
+ Object.keys(source).forEach(function(key) {
+ if (key === "default" || key === "__esModule" || dest.hasOwnProperty(key)) return;
+ Object.defineProperty(dest, key, {
+ enumerable: true,
+ get: function() {
+ return source[key];
+ }
+ });
+ });
+ return dest;
+};
+exports.export = function(dest, destName, get) {
+ Object.defineProperty(dest, destName, {
+ enumerable: true,
+ get: get
+ });
+};
+
+},{}],"d37mJ":[function(require,module,exports) {
+"use strict";
+var Refresh = require("7422ead32dcc1e6b");
+function debounce(func, delay) {
+ {
+ let timeout = undefined;
+ let lastTime = 0;
+ return function(args) {
+ // Call immediately if last call was more than the delay ago.
+ // Otherwise, set a timeout. This means the first call is fast
+ // (for the common case of a single update), and subsequent updates
+ // are batched.
+ let now = Date.now();
+ if (now - lastTime > delay) {
+ lastTime = now;
+ func.call(null, args);
+ } else {
+ clearTimeout(timeout);
+ timeout = setTimeout(function() {
+ timeout = undefined;
+ lastTime = Date.now();
+ func.call(null, args);
+ }, delay);
+ }
+ };
+ }
+}
+var enqueueUpdate = debounce(function() {
+ Refresh.performReactRefresh();
+}, 30);
+// Everthing below is either adapted or copied from
+// https://github.com/facebook/metro/blob/61de16bd1edd7e738dd0311c89555a644023ab2d/packages/metro/src/lib/polyfills/require.js
+// MIT License - Copyright (c) Facebook, Inc. and its affiliates.
+module.exports.prelude = function(module1) {
+ window.$RefreshReg$ = function(type, id) {
+ Refresh.register(type, module1.id + " " + id);
+ };
+ window.$RefreshSig$ = Refresh.createSignatureFunctionForTransform;
+};
+module.exports.postlude = function(module1) {
+ if (isReactRefreshBoundary(module1.exports)) {
+ registerExportsForReactRefresh(module1);
+ if (module1.hot) {
+ module1.hot.dispose(function(data) {
+ if (Refresh.hasUnrecoverableErrors()) window.location.reload();
+ data.prevExports = module1.exports;
+ });
+ module1.hot.accept(function(getParents) {
+ var prevExports = module1.hot.data.prevExports;
+ var nextExports = module1.exports;
+ // Since we just executed the code for it, it's possible
+ // that the new exports make it ineligible for being a boundary.
+ var isNoLongerABoundary = !isReactRefreshBoundary(nextExports);
+ // It can also become ineligible if its exports are incompatible
+ // with the previous exports.
+ // For example, if you add/remove/change exports, we'll want
+ // to re-execute the importing modules, and force those components
+ // to re-render. Similarly, if you convert a class component
+ // to a function, we want to invalidate the boundary.
+ var didInvalidate = shouldInvalidateReactRefreshBoundary(prevExports, nextExports);
+ if (isNoLongerABoundary || didInvalidate) {
+ // We'll be conservative. The only case in which we won't do a full
+ // reload is if all parent modules are also refresh boundaries.
+ // In that case we'll add them to the current queue.
+ var parents = getParents();
+ if (parents.length === 0) {
+ // Looks like we bubbled to the root. Can't recover from that.
+ window.location.reload();
+ return;
+ }
+ return parents;
+ }
+ enqueueUpdate();
+ });
+ }
+ }
+};
+function isReactRefreshBoundary(exports) {
+ if (Refresh.isLikelyComponentType(exports)) return true;
+ if (exports == null || typeof exports !== "object") // Exit if we can't iterate over exports.
+ return false;
+ var hasExports = false;
+ var areAllExportsComponents = true;
+ let isESM = "__esModule" in exports;
+ for(var key in exports){
+ hasExports = true;
+ if (key === "__esModule") continue;
+ var desc = Object.getOwnPropertyDescriptor(exports, key);
+ if (desc && desc.get && !isESM) // Don't invoke getters for CJS as they may have side effects.
+ return false;
+ var exportValue = exports[key];
+ if (!Refresh.isLikelyComponentType(exportValue)) areAllExportsComponents = false;
+ }
+ return hasExports && areAllExportsComponents;
+}
+function shouldInvalidateReactRefreshBoundary(prevExports, nextExports) {
+ var prevSignature = getRefreshBoundarySignature(prevExports);
+ var nextSignature = getRefreshBoundarySignature(nextExports);
+ if (prevSignature.length !== nextSignature.length) return true;
+ for(var i = 0; i < nextSignature.length; i++){
+ if (prevSignature[i] !== nextSignature[i]) return true;
+ }
+ return false;
+}
+// When this signature changes, it's unsafe to stop at this refresh boundary.
+function getRefreshBoundarySignature(exports) {
+ var signature = [];
+ signature.push(Refresh.getFamilyByType(exports));
+ if (exports == null || typeof exports !== "object") // Exit if we can't iterate over exports.
+ // (This is important for legacy environments.)
+ return signature;
+ let isESM = "__esModule" in exports;
+ for(var key in exports){
+ if (key === "__esModule") continue;
+ var desc = Object.getOwnPropertyDescriptor(exports, key);
+ if (desc && desc.get && !isESM) continue;
+ var exportValue = exports[key];
+ signature.push(key);
+ signature.push(Refresh.getFamilyByType(exportValue));
+ }
+ return signature;
+}
+function registerExportsForReactRefresh(module1) {
+ var exports = module1.exports, id = module1.id;
+ Refresh.register(exports, id + " %exports%");
+ if (exports == null || typeof exports !== "object") // Exit if we can't iterate over exports.
+ // (This is important for legacy environments.)
+ return;
+ let isESM = "__esModule" in exports;
+ for(var key in exports){
+ var desc = Object.getOwnPropertyDescriptor(exports, key);
+ if (desc && desc.get && !isESM) continue;
+ var exportValue = exports[key];
+ var typeID = id + " %exports% " + key;
+ Refresh.register(exportValue, typeID);
+ }
+}
+
+},{"7422ead32dcc1e6b":"iZhE1"}],"29e65":[function(require,module,exports) {
+var $parcel$ReactRefreshHelpers$e74c = require("@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js");
+var prevRefreshReg = window.$RefreshReg$;
+var prevRefreshSig = window.$RefreshSig$;
+$parcel$ReactRefreshHelpers$e74c.prelude(module);
+
+try {
+var parcelHelpers = require("@parcel/transformer-js/src/esmodule-helpers.js");
+parcelHelpers.defineInteropFlag(exports);
+var _jsxDevRuntime = require("react/jsx-dev-runtime");
+var _react = require("react");
+var _s = $RefreshSig$();
+function IndexPopup() {
+ _s();
+ const [data, setData] = (0, _react.useState)("");
+ return /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("div", {
+ style: {
+ padding: 16
+ },
+ children: [
+ /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("h2", {
+ children: [
+ "Welcome to your",
+ " ",
+ /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("a", {
+ href: "https://www.plasmo.com",
+ target: "_blank",
+ children: "Plasmo"
+ }, void 0, false, {
+ fileName: "packages/whats-ext/popup.tsx",
+ lineNumber: 13,
+ columnNumber: 9
+ }, this),
+ " ",
+ "Extension!"
+ ]
+ }, void 0, true, {
+ fileName: "packages/whats-ext/popup.tsx",
+ lineNumber: 11,
+ columnNumber: 7
+ }, this),
+ /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("input", {
+ onChange: (e)=>setData(e.target.value),
+ value: data
+ }, void 0, false, {
+ fileName: "packages/whats-ext/popup.tsx",
+ lineNumber: 18,
+ columnNumber: 7
+ }, this),
+ /*#__PURE__*/ (0, _jsxDevRuntime.jsxDEV)("a", {
+ href: "https://docs.plasmo.com",
+ target: "_blank",
+ children: "View Docs"
+ }, void 0, false, {
+ fileName: "packages/whats-ext/popup.tsx",
+ lineNumber: 19,
+ columnNumber: 7
+ }, this)
+ ]
+ }, void 0, true, {
+ fileName: "packages/whats-ext/popup.tsx",
+ lineNumber: 7,
+ columnNumber: 5
+ }, this);
+}
+_s(IndexPopup, "avaWeDctHFwWP+lC5+N1mkv/uq8=");
+_c = IndexPopup;
+exports.default = IndexPopup;
+var _c;
+$RefreshReg$(_c, "IndexPopup");
+
+ $parcel$ReactRefreshHelpers$e74c.postlude(module);
+} finally {
+ window.$RefreshReg$ = prevRefreshReg;
+ window.$RefreshSig$ = prevRefreshSig;
+}
+},{"react/jsx-dev-runtime":"g2xeO","react":"ifaUc","@parcel/transformer-js/src/esmodule-helpers.js":"boKlo","@parcel/transformer-react-refresh-wrap/lib/helpers/helpers.js":"d37mJ"}]},["gTWK1","5TpEE"], "5TpEE", "parcelRequire8cd9")
+
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUMsQUFBQyxDQUFBLE1BQUksS0FBRyxNQUFNLFFBQVEsTUFBSSxDQUFDLENBQUMsRUFBRSxTQUFPLEVBQUUsS0FBRyxDQUFBLEtBQUksRUFBRSxLQUFLO1FBQUM7UUFBRTtLQUFFO0lBQUUsT0FBTyxFQUFFLFVBQVMsQ0FBQSxJQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsUUFBTyxHQUFFLEdBQUc7QUFBQztBQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUM7SUFBRSxJQUFHLEVBQUUsR0FBRSxHQUFFLElBQUcsT0FBTSxDQUFDO0lBQUUsSUFBSSxJQUFFLEVBQUUsT0FBTyxPQUFPLE1BQUssSUFBRyxJQUFFLENBQUM7SUFBRSxNQUFLLEVBQUUsU0FBTyxHQUFHO1FBQUMsSUFBRyxDQUFDLEdBQUUsRUFBRSxHQUFDLEVBQUU7UUFBUSxJQUFHLEVBQUUsR0FBRSxHQUFFLE9BQU0sSUFBRSxDQUFDO2FBQU07WUFBQyxJQUFJLElBQUUsRUFBRSxPQUFPLE9BQU8sTUFBSztZQUFHLElBQUcsRUFBRSxXQUFTLEdBQUU7Z0JBQUMsSUFBRSxDQUFDO2dCQUFFO1lBQUs7WUFBQyxFQUFFLFFBQVE7UUFBRTtJQUFDO0lBQUMsT0FBTztBQUFDO0FBQUMsU0FBUyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQztJQUFFLElBQUcsRUFBQyxTQUFRLENBQUMsRUFBQyxHQUFDO0lBQUUsSUFBRyxDQUFDLEdBQUUsT0FBTSxDQUFDO0lBQUUsSUFBRyxLQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFDLE9BQU8sRUFBRSxTQUFPLEVBQUUsRUFBRSxRQUFPLEdBQUUsS0FBRyxDQUFDO0lBQUUsSUFBRyxFQUFFLGFBQWEsQ0FBQyxFQUFFLEVBQUMsT0FBTSxDQUFDO0lBQUUsRUFBRSxhQUFhLENBQUMsRUFBRSxHQUFDLENBQUM7SUFBRSxJQUFJLElBQUUs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QUMsRUFBRSxHQUFHLENBQUMsRUFBRTtvQkFBQyxJQUFJLElBQUksS0FBSyxFQUFFLElBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBQzt3QkFBQyxJQUFJLElBQUUsQ0FBQyxDQUFDLEVBQUU7d0JBQUMsRUFBRSxPQUFPLE9BQU8sTUFBSyxHQUFHLFdBQVMsS0FBRyxFQUFFLE9BQU8sT0FBTyxNQUFLO29CQUFFO2dCQUFDO2dCQUFDLElBQUksSUFBRSxPQUFPLGVBQWUsQ0FBQyxFQUFFLEdBQUc7Z0JBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxHQUFDO29CQUFDO29CQUFFO2lCQUFFO1lBQUEsT0FBTSxFQUFFLFVBQVEsRUFBRSxFQUFFLFFBQU87UUFBRTtJQUFDO0FBQUM7QUFBQyxTQUFTLEVBQUUsQ0FBQyxFQUFDLENBQUM7SUFBRSxJQUFJLElBQUUsRUFBRTtJQUFRLElBQUc7UUFBRSxJQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUM7WUFBQyxJQUFJLElBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUMsSUFBRSxFQUFFO1lBQUMsSUFBSSxJQUFJLEtBQUssRUFBRSxFQUFFLE9BQU8sT0FBTyxNQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsV0FBUyxLQUFHLEVBQUUsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBQyxFQUFFLFFBQVEsQ0FBQTtnQkFBSSxFQUFFLE9BQU8sT0FBTyxNQUFLO1lBQUU7UUFBRSxPQUFNLEVBQUUsVUFBUSxFQUFFLEVBQUUsUUFBTzs7QUFBRTtBQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUMsQ0FBQztJQUFFLElBQUksSUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFO0lBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxHQUFDLENBQUMsR0FBRSxLQUFHLEVBQUUsT0FBTSxDQUFBLEVBQUUsSUFBSSxPQUFLLEVBQUUs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S0FBRyxPQUFPLGdCQUFlLEtBQUcsT0FBTyxVQUFVO0FBQWUsSUFBSSxJQUFFLENBQUMsR0FBRSxJQUFJLElBQUssQ0FBQSxLQUFHLEVBQUUsQUFBQyxDQUFBLElBQUU7WUFBQyxTQUFRLENBQUM7UUFBQyxDQUFBLEVBQUcsU0FBUSxJQUFHLEVBQUUsT0FBTSxHQUFHLEtBQUcsQ0FBQyxHQUFFO0lBQUssSUFBSSxJQUFJLEtBQUssRUFBRSxFQUFFLEdBQUUsR0FBRTtRQUFDLEtBQUksQ0FBQyxDQUFDLEVBQUU7UUFBQyxZQUFXLENBQUM7SUFBQztBQUFFLEdBQUUsSUFBRSxDQUFDLEdBQUUsR0FBRSxHQUFFO0lBQUssSUFBRyxLQUFHLE9BQU8sS0FBRyxZQUFVLE9BQU8sS0FBRyxZQUFXLEtBQUksSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsS0FBSyxHQUFFLE1BQUksTUFBSSxLQUFHLEVBQUUsR0FBRSxHQUFFO1FBQUMsS0FBSSxJQUFJLENBQUMsQ0FBQyxFQUFFO1FBQUMsWUFBVyxDQUFFLENBQUEsSUFBRSxHQUFHLEdBQUUsRUFBQyxLQUFJLEVBQUU7SUFBVTtJQUFHLE9BQU87QUFBQyxHQUFFLElBQUUsQ0FBQyxHQUFFLEdBQUUsSUFBSyxDQUFBLEVBQUUsR0FBRSxHQUFFLFlBQVcsS0FBRyxFQUFFLEdBQUUsR0FBRSxVQUFTLEdBQUcsSUFBRSxDQUFDLEdBQUUsR0FBRSxJQUFLLENBQUEsSUFBRSxLQUFHLE9BQUssR0FBRyxHQUFHLE1BQUksQ0FBQyxHQUFFLEVBQUUsS0FBRyxDQUFDLEtBQUcsQ0FBQyxFQUFFLGFBQVcsRUFBRSxHQUFFLFdBQVU7UUFBQyxPQUFNO1FBQUUsWUFBVyxDQUFDO0lBQUMsS0FBRyxHQUFFLEVBQUMsR0FBRyxLQUFHLENBQUEsSUFBRyxFQUFFLEVBQUUsQ0FBQyxHQUFFLGNBQWE7UUFBQyxPQUFNLENBQUM7SUFBQyxJQUFHO0FBQUcsSUFBSSxJQUFFLEVBQUUsQ0FBQTtJQUFJO0lBQWMsQ0FBQTtRQUFXO1FBQWEsSUFBSSxJQUFFLE9BQU8sSUFBSSxzQkFBcUIsSUFBRSxPQUFPLElBQUksZUFBYyxJQUFFLE9BQU8sV0FBUyxhQUFXLFVBQVEsS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksR0FBRSxJQUFFLElBQUksR0FBRSxJQUFFLElBQUksR0FBRSxJQUFFLEVBQUUsRUFBQyxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLElBQUksS0FBSSxJQUFFLE9BQU8sV0FBUyxhQUFXLElBQUksVUFBUSxNQUFLLElBQUUsQ0FBQztRQUFFLFNBQVMsRUFBRSxDQUFDO1lBQUUsSUFBRyxFQUFFLFlBQVUsTUFBSyxPQUFPLEVBQUU7WUFBUSxJQUFJLElBQUUsRUFBRSxRQUFPO1lBQUUsSUFBRztnQkFBQyxJQUFFLEVBQUU7WUFBZ0IsRUFBQyxPQUFNLEdBQUU7Z0JBQUMsT0FBTyxFQUFFLGFBQVcsQ0FBQyxHQUFFLEVBQUUsVUFBUSxHQUFFO1lBQUM7WUFBQyxJQUFJLElBQUksSUFBRSxHQUFFLElBQUUsRUFBRSxRQUFPLElBQUk7Z0JBQUMsSUFBSSxJQUFFLENBQUMsQ0FBQyxFQUFFO2dCQUFDLElBQUcsT0FBTyxLQUFHLFlBQVcsT0FBTyxFQUFFLGFBQVcsQ0FBQyxHQUFFLEVBQUUsVUFBUSxHQUFFO2dCQUFFLElBQUksSUFBRSxFQUFFLElBQUk7Z0JBQUcsSUFBRyxNQUFJLEtBQUssR0FBRTtvQkFBQyxJQUFJLElBQUUsRUFBRTtvQkFBRyxFQUFFLGNBQWEsQ0FBQSxFQUFFLGFBQVcsQ0FBQyxDQUFBLEdBQUcsS0FBRyxDQUFDOztBQUUzdkMsQ0FBQyxHQUFDO2dCQUFDO1lBQUM7WUFBQyxPQUFPLEVBQUUsVUFBUSxHQUFFO1FBQUM7UUFBQyxTQUFTLEVBQUUsQ0FBQyxFQUFDLENBQUM7WUFBRSxJQUFJLElBQUUsRUFBRSxJQUFJLElBQUcsSUFBRSxFQUFFLElBQUk7WUFBRyxPQUFPLE1BQUksS0FBSyxLQUFHLE1BQUksS0FBSyxJQUFFLENBQUMsSUFBRSxDQUFFLENBQUEsTUFBSSxLQUFLLEtBQUcsTUFBSSxLQUFLLEtBQUcsRUFBRSxPQUFLLEVBQUUsTUFBSSxFQUFFLFVBQVM7UUFBRTtRQUFDLFNBQVMsRUFBRSxDQUFDO1lBQUUsT0FBTyxFQUFFLGFBQVcsRUFBRSxVQUFVO1FBQWdCO1FBQUMsU0FBUyxFQUFFLENBQUMsRUFBQyxDQUFDO1lBQUUsT0FBTyxFQUFFLE1BQUksRUFBRSxLQUFHLENBQUMsSUFBRSxDQUFDLENBQUMsRUFBRSxHQUFFO1FBQUU7UUFBQyxTQUFTLEVBQUUsQ0FBQztZQUFFLE9BQU8sRUFBRSxJQUFJO1FBQUU7UUFBQyxTQUFTLEVBQUUsQ0FBQztZQUFFLElBQUksSUFBRSxJQUFJO1lBQUksT0FBTyxFQUFFLFFBQVEsU0FBUyxDQUFDLEVBQUMsQ0FBQztnQkFBRSxFQUFFLElBQUksR0FBRTtZQUFFLElBQUc7UUFBQztRQUFDLFNBQVMsRUFBRSxDQUFDO1lBQUUsSUFBSSxJQUFFLElBQUk7WUFBSSxPQUFPLEVBQUUsUUFBUSxTQUFTLENBQUM7Z0JBQUUsRUFBRSxJQUFJO1lBQUUsSUFBRztRQUFDO1FBQUMsU0FBUyxFQUFFLENBQUMsRUFBQyxDQUFDO1lBQUUsSUFBRztnQkFBQyxPQUFPLENBQUMsQ0FBQyxFQUFFO1lBQUEsRUFBQyxPQUFNLEdBQUU7Z0JBQUM7WUFBTTtRQUFDO1FBQUMsU0FBUztZQUFJLElBQUcsRUFBRSxXQUFTLEtBQUcsR0FBRSxPQUFPO1lBQUssSUFBRSxDQUFDO1lBQUUsSUFBRztnQkFBQyxJQUFJLElBQUUsSUFBSSxLQUFJLElBQUUsSUFBSSxLQUFJLElBQUU7Z0JBQUUsSUFBRSxFQUFFLEVBQUMsRUFBRSxRQUFRLFNBQVMsQ0FBQztvQkFBRSxJQUFJLElBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBQyxJQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUMsSUFBRSxFQUFFO29CQUFRLEVBQUUsSUFBSSxHQUFFLElBQUcsRUFBRSxJQUFJLEdBQUUsSUFBRyxFQUFFLFVBQVEsR0FBRSxFQUFFLEdBQUUsS0FBRyxFQUFFLElBQUksS0FBRyxFQUFFLElBQUk7Z0JBQUU7Z0JBQUcsSUFB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QSxlQUFPLEVBQUU7SUFFakMscUJBQ0UsMkJBQUM7UUFDQyxPQUFPO1lBQ0wsU0FBUztRQUNYOzswQkFDQSwyQkFBQzs7b0JBQUc7b0JBQ2M7a0NBQ2hCLDJCQUFDO3dCQUFFLE1BQUs7d0JBQXlCLFFBQU87a0NBQVM7Ozs7OztvQkFFNUM7b0JBQUk7Ozs7Ozs7MEJBR1gsMkJBQUM7Z0JBQU0sVUFBVSxDQUFDLElBQU0sUUFBUSxFQUFFLE9BQU87Z0JBQVEsT0FBTzs7Ozs7OzBCQUN4RCwyQkFBQztnQkFBRSxNQUFLO2dCQUEwQixRQUFPOzBCQUFTOzs7Ozs7Ozs7Ozs7QUFLeEQ7R0FyQlM7S0FBQTtrQkF1Qk0iLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9AcGxhc21vaHEvcGFyY2VsLXJ1bnRpbWUvZGlzdC9ydW50aW1lLWE1N2E5OGM4ZThiODgwZWIuanMiLCJub2RlX21vZHVsZXMvQHBsYXNtb2hxL3BhcmNlbC1yZXNvbHZlci9kaXN0L3BvbHlmaWxscy9yZWFjdC1yZWZyZXNoL3J1bnRpbWUuanMiLCJwYWNrYWdlcy93aGF0cy1leHQvLnBsYXNtby9zdGF0aWMvcG9wdXAudHN4Iiwibm9kZV9tb2R1bGVzL3JlYWN0L2pzeC1kZXYtcnVudGltZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC9janMvcmVhY3QtanN4LWRldi1ydW50aW1lLmRldmVsb3BtZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0L2Nqcy9yZWFjdC5kZXZlbG9wbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2xpZW50LmpzIiwibm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFjdC1kb20vY2pzL3JlYWN0LWRvbS5kZXZlbG9wbWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zY2hlZHVsZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2NoZWR1bGVyL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMiLCJwYWNrYWdlcy93aGF0cy1leHQvLnBsYXNtby9zdGF0aWMvY29tbW9uL3JlYWN0LnRzIiwibm9kZV9tb2R1bGVzL0BwYXJjZWwvdHJhbnNmb3JtZXItanMvc3JjL2VzbW9kdWxlLWhlbHBlcnMuanMiLCJub2RlX21vZHVsZXMvQHBhcmNlbC90cmFuc2Zvcm1lci1yZWFjdC1yZWZyZXNoLXdyYXAvbGliL2hlbHBlcnMvaGVscGVycy5qcyIsInBhY2thZ2VzL3doYXRzLWV4dC9wb3B1cC50c3giXSwic291cmNlc0NvbnRlbnQiOlsidmFyIFc9T2JqZWN0LmNyZWF0ZTt2YXIgUD1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIFY9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjt2YXIgRz1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczt2YXIgWD1PYmplY3QuZ2V0UHJvdG90eXBlT2YsSj1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O3ZhciBxPShlLHQsbyxyKT0+e2lmKHQmJnR5cGVvZiB0PT1cIm9iamVjdFwifHx0eXBlb2YgdD09XCJmdW5jdGlvblwiKWZvcihsZXQgbiBvZiBHKHQpKSFKLmNhbGwoZSxuKSYmbiE9PW8mJlAoZSxuLHtnZXQ6KCk9PnRbbl0sZW51bWVyYWJsZTohKHI9Vih0LG4pKXx8ci5lbnVtZXJhYmxlfSk7cmV0dXJuIGV9O3ZhciB6PShlLHQsbyk9PihvPWUhPW51bGw/VyhYKGUpKTp7fSxxKHR8fCFlfHwhZS5fX2VzTW9kdWxlP1AobyxcImRlZmF1bHRcIix7dmFsdWU6ZSxlbnVtZXJhYmxlOiEwfSk6byxlKSk7dmFyIHk9dHlwZW9mIGdsb2JhbFRoaXMucHJvY2VzczxcInVcIj9nbG9iYWxUaGlzLnByb2Nlc3MuYXJndjpbXTt2YXIgSD0oKT0+dHlwZW9mIGdsb2JhbFRoaXMucHJvY2VzczxcInVcIj9nbG9iYWxUaGlzLnByb2Nlc3MuZW52Ont9O3ZhciBLPW5ldyBTZXQoeSksRD1lPT5LLmhhcyhlKSx1ZT15LmZpbHRlcihlPT5lLnN0YXJ0c1dpdGgoXCItLVwiKSYmZS5pbmNsdWRlcyhcIj1cIikpLm1hcChlPT5lLnNwbGl0KFwiPVwiKSkucmVkdWNlKChlLFt0LG9dKT0+KGVbdF09byxlKSx7fSk7dmFyIGRlPUQoXCItLWRyeS1ydW5cIiksXz0oKT0+RChcIi0tdmVyYm9zZVwiKXx8SCgpLlZFUkJPU0U9PT1cInRydWVcIixmZT1fKCk7dmFyIHg9KGU9XCJcIiwuLi50KT0+Y29uc29sZS5sb2coZS5wYWRFbmQoOSksXCJ8XCIsLi4udCk7dmFyIFQ9KC4uLmUpPT5jb25zb2xlLmVycm9yKFwiXFx1ezFGNTM0fSBFUlJPUlwiLnBhZEVuZCg5KSxcInxcIiwuLi5lKSxrPSguLi5lKT0+eChcIlxcdXsxRjUzNX0gSU5GT1wiLC4uLmUpLEE9KC4uLmUpPT54KFwiXFx1ezFGN0UwfSBXQVJOXCIsLi4uZSksUT0wLHA9KC4uLmUpPT5fKCkmJngoYFxcdXsxRjdFMX0gJHtRKyt9YCwuLi5lKTt2YXIgYz17XCJpc0NvbnRlbnRTY3JpcHRcIjpmYWxzZSxcImlzQmFja2dyb3VuZFwiOmZhbHNlLFwiaXNSZWFjdFwiOnRydWUsXCJydW50aW1lc1wiOltcInBhZ2UtcnVudGltZVwiXSxcImhvc3RcIjpcImxvY2FsaG9zdFwiLFwicG9ydFwiOjE4MTUsXCJlbnRyeUZpbGVQYXRoXCI6XCIvVXNlcnMva2VyZW4vRGVza3RvcC93aGF0cy1lbGVtZW50L3BhY2thZ2VzL3doYXRzLWV4dC8ucGxhc21vL3N0YXRpYy9wb3B1cC50c3hcIixcImJ1bmRsZUlkXCI6XCI0ODg5ODY3MzdmZjU4OGYzXCIsXCJlbnZIYXNoXCI6XCJlNzkyZmJiZGFhNzhlZTg0XCIsXCJ2ZXJib3NlXCI6XCJmYWxzZVwiLFwic2VjdXJlXCI6ZmFsc2UsXCJzZXJ2ZXJQb3J0XCI6NDk5OTR9O21vZHVsZS5idW5kbGUuSE1SX0JVTkRMRV9JRD1jLmJ1bmRsZUlkO2dsb2JhbFRoaXMucHJvY2Vzcz17YXJndjpbXSxlbnY6e1ZFUkJPU0U6Yy52ZXJib3NlfX07dmFyIFk9bW9kdWxlLmJ1bmRsZS5Nb2R1bGU7ZnVuY3Rpb24gWihlKXtZLmNhbGwodGhpcyxlKSx0aGlzLmhvdD17ZGF0YTptb2R1bGUuYnVuZGxlLmhvdERhdGFbZV0sX2FjY2VwdENhbGxiYWNrczpbXSxfZGlzcG9zZUNhbGxiYWNrczpbXSxhY2NlcHQ6ZnVuY3Rpb24odCl7dGhpcy5fYWNjZXB0Q2FsbGJhY2tzLnB1c2godHx8ZnVuY3Rpb24oKXt9KX0sZGlzcG9zZTpmdW5jdGlvbih0KXt0aGlzLl9kaXNwb3NlQ2FsbGJhY2tzLnB1c2godCl9fSxtb2R1bGUuYnVuZGxlLmhvdERhdGFbZV09dm9pZCAwfW1vZHVsZS5idW5kbGUuTW9kdWxlPVo7bW9kdWxlLmJ1bmRsZS5ob3REYXRhPXt9O3ZhciBkPWdsb2JhbFRoaXMuYnJvd3Nlcnx8Z2xvYmFsVGhpcy5jaHJvbWV8fG51bGw7YXN5bmMgZnVuY3Rpb24gbShlPSExKXtlPyhwKFwiVHJpZ2dlcmluZyBmdWxsIHJlbG9hZFwiKSxkLnJ1bnRpbWUuc2VuZE1lc3NhZ2Uoe19fcGxhc21vX2Z1bGxfcmVsb2FkX186ITB9KSk6Z2xvYmFsVGhpcy5sb2NhdGlvbj8ucmVsb2FkPy4oKX1mdW5jdGlvbiB3KCl7cmV0dXJuIWMuaG9zdHx8Yy5ob3N0PT09XCIwLjAuMC4wXCI/bG9jYXRpb24ucHJvdG9jb2wuaW5kZXhPZihcImh0dHBcIik9PT0wP2xvY2F0aW9uLmhvc3RuYW1lOlwibG9jYWxob3N0XCI6Yy5ob3N0fWZ1bmN0aW9uIEwoKXtyZXR1cm4hYy5ob3N0fHxjLmhvc3Q9PT1cIjAuMC4wLjBcIj9cImxvY2FsaG9zdFwiOmMuaG9zdH1mdW5jdGlvbiBmKCl7cmV0dXJuIGMucG9ydHx8bG9jYXRpb24ucG9ydH12YXIgUz1cIl9fcGxhc21vX3J1bnRpbWVfcGFnZV9cIjt2YXIgaT17Y2hlY2tlZEFzc2V0czp7fSxhc3NldHNUb0Rpc3Bvc2U6W10sYXNzZXRzVG9BY2NlcHQ6W119LEI9KCk9PntpLmNoZWNrZWRBc3NldHM9e30saS5hc3NldHNUb0Rpc3Bvc2U9W10saS5hc3NldHNUb0FjY2VwdD1bXX07ZnVuY3Rpb24gdShlLHQpe2xldHttb2R1bGVzOm99PWU7aWYoIW8pcmV0dXJuW107bGV0IHI9W10sbixzLGE7Zm9yKG4gaW4gbylmb3IocyBpbiBvW25dWzFdKWE9b1tuXVsxXVtzXSwoYT09PXR8fEFycmF5LmlzQXJyYXkoYSkmJmFbYS5sZW5ndGgtMV09PT10KSYmci5wdXNoKFtlLG5dKTtyZXR1cm4gZS5wYXJlbnQmJihyPXIuY29uY2F0KHUoZS5wYXJlbnQsdCkpKSxyfWZ1bmN0aW9uIFIoZSx0LG8pe2lmKEMoZSx0LG8pKXJldHVybiEwO2xldCByPXUobW9kdWxlLmJ1bmRsZS5yb290LHQpLG49ITE7Zm9yKDtyLmxlbmd0aD4wOyl7bGV0W3MsYV09ci5zaGlmdCgpO2lmKEMocyxhLG51bGwpKW49ITA7ZWxzZXtsZXQgZz11KG1vZHVsZS5idW5kbGUucm9vdCxhKTtpZihnLmxlbmd0aD09PTApe249ITE7YnJlYWt9ci5wdXNoKC4uLmcpfX1yZXR1cm4gbn1mdW5jdGlvbiBDKGUsdCxvKXtsZXR7bW9kdWxlczpyfT1lO2lmKCFyKXJldHVybiExO2lmKG8mJiFvW2UuSE1SX0JVTkRMRV9JRF0pcmV0dXJuIGUucGFyZW50P1IoZS5wYXJlbnQsdCxvKTohMDtpZihpLmNoZWNrZWRBc3NldHNbdF0pcmV0dXJuITA7aS5jaGVja2VkQXNzZXRzW3RdPSEwO2xldCBuPWUuY2FjaGVbdF07cmV0dXJuIGkuYXNzZXRzVG9EaXNwb3NlLnB1c2goW2UsdF0pLCFufHxuLmhvdCYmbi5ob3QuX2FjY2VwdENhbGxiYWNrcy5sZW5ndGg/KGkuYXNzZXRzVG9BY2NlcHQucHVzaChbZSx0XSksITApOiExfWZ1bmN0aW9uIE0oZSx0KXtsZXR7bW9kdWxlczpvfT1lO3JldHVybiBvPyEhb1t0XTohMX1mdW5jdGlvbiBlZShlKXtpZihlLnR5cGU9PT1cImpzXCImJnR5cGVvZiBkb2N1bWVudDxcInVcIilyZXR1cm4gbmV3IFByb21pc2UoKHQsbyk9PntsZXQgcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO3Iuc3JjPWAke2UudXJsfT90PSR7RGF0ZS5ub3coKX1gLGUub3V0cHV0Rm9ybWF0PT09XCJlc21vZHVsZVwiJiYoci50eXBlPVwibW9kdWxlXCIpLHIuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKT0+dChyKSksci5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIiwoKT0+byhuZXcgRXJyb3IoYEZhaWxlZCB0byBkb3dubG9hZCBhc3NldDogJHtlLmlkfWApKSksZG9jdW1lbnQuaGVhZD8uYXBwZW5kQ2hpbGQocil9KX1hc3luYyBmdW5jdGlvbiBPKGUpe2dsb2JhbC5wYXJjZWxIb3RVcGRhdGU9T2JqZWN0LmNyZWF0ZShudWxsKSxlLmZvckVhY2gobz0+e28udXJsPWQucnVudGltZS5nZXRVUkwoXCIvX19wbGFzbW9faG1yX3Byb3h5X18/dXJsPVwiK2VuY29kZVVSSUNvbXBvbmVudChgJHtvLnVybH0/dD0ke0RhdGUubm93KCl9YCkpfSk7bGV0IHQ9YXdhaXQgUHJvbWlzZS5hbGwoZS5tYXAoZWUpKTt0cnl7ZS5mb3JFYWNoKGZ1bmN0aW9uKG8peyQobW9kdWxlLmJ1bmRsZS5yb290LG8pfSl9ZmluYWxseXtkZWxldGUgZ2xvYmFsLnBhcmNlbEhvdFVwZGF0ZSx0JiZ0LmZvckVhY2gobz0+e28mJmRvY3VtZW50LmhlYWQ/LnJlbW92ZUNoaWxkKG8pfSl9fWZ1bmN0aW9uIHRlKGUpe2xldCB0PWUuY2xvbmVOb2RlKCk7dC5vbmxvYWQ9ZnVuY3Rpb24oKXtlLnBhcmVudE5vZGUhPT1udWxsJiZlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZSl9LHQuc2V0QXR0cmlidXRlKFwiaHJlZlwiLGUuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKS5zcGxpdChcIj9cIilbMF0rXCI/XCIrRGF0ZS5ub3coKSksZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0LGUubmV4dFNpYmxpbmcpfXZhciBiPW51bGw7ZnVuY3Rpb24gb2UoKXtifHwoYj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bGV0IGU9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnbGlua1tyZWw9XCJzdHlsZXNoZWV0XCJdJyk7Zm9yKHZhciB0PTA7dDxlLmxlbmd0aDt0Kyspe2xldCBvPWVbdF0uZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSxyPXcoKSxuPXI9PT1cImxvY2FsaG9zdFwiP25ldyBSZWdFeHAoXCJeKGh0dHBzPzpcXFxcL1xcXFwvKDAuMC4wLjB8MTI3LjAuMC4xKXxsb2NhbGhvc3QpOlwiK2YoKSkudGVzdChvKTpvLmluZGV4T2YocitcIjpcIitmKCkpOy9eaHR0cHM/OlxcL1xcLy9pLnRlc3QobykmJm8uaW5kZXhPZihsb2NhdGlvbi5vcmlnaW4pIT09MCYmIW58fHRlKGVbdF0pfWI9bnVsbH0sNDcpKX1mdW5jdGlvbiAkKGUsdCl7bGV0e21vZHVsZXM6b309ZTtpZihvKXtpZih0LnR5cGU9PT1cImNzc1wiKW9lKCk7ZWxzZSBpZih0LnR5cGU9PT1cImpzXCIpe2xldCByPXQuZGVwc0J5QnVuZGxlW2UuSE1SX0JVTkRMRV9JRF07aWYocil7aWYob1t0LmlkXSl7bGV0IHM9b1t0LmlkXVsxXTtmb3IobGV0IGEgaW4gcylpZighclthXXx8clthXSE9PXNbYV0pe2xldCBsPXNbYV07dShtb2R1bGUuYnVuZGxlLnJvb3QsbCkubGVuZ3RoPT09MSYmRShtb2R1bGUuYnVuZGxlLnJvb3QsbCl9fWxldCBuPWdsb2JhbC5wYXJjZWxIb3RVcGRhdGVbdC5pZF07b1t0LmlkXT1bbixyXX1lbHNlIGUucGFyZW50JiYkKGUucGFyZW50LHQpfX19ZnVuY3Rpb24gRShlLHQpe2xldCBvPWUubW9kdWxlcztpZihvKWlmKG9bdF0pe2xldCByPW9bdF1bMV0sbj1bXTtmb3IobGV0IHMgaW4gcil1KG1vZHVsZS5idW5kbGUucm9vdCxyW3NdKS5sZW5ndGg9PT0xJiZuLnB1c2gocltzXSk7ZGVsZXRlIG9bdF0sZGVsZXRlIGUuY2FjaGVbdF0sbi5mb3JFYWNoKHM9PntFKG1vZHVsZS5idW5kbGUucm9vdCxzKX0pfWVsc2UgZS5wYXJlbnQmJkUoZS5wYXJlbnQsdCl9ZnVuY3Rpb24gdihlLHQpe2xldCBvPWUuY2FjaGVbdF07ZS5ob3REYXRhW3RdPXt9LG8mJm8uaG90JiYoby5ob3QuZGF0YT1lLmhvdERhdGFbdF0pLG8mJm8uaG90JiZvLmhvdC5fZGlzcG9zZUNhbGxiYWNrcy5sZW5ndGgmJm8uaG90Ll9kaXNwb3NlQ2FsbGJhY2tzLmZvckVhY2goZnVuY3Rpb24ocil7cihlLmhvdERhdGFbdF0pfSksZGVsZXRlIGUuY2FjaGVbdF19ZnVuY3Rpb24gSShlLHQpe2UodCk7bGV0IG89ZS5jYWNoZVt0XTtpZihvJiZvLmhvdCYmby5ob3QuX2FjY2VwdENhbGxiYWNrcy5sZW5ndGgpe2xldCByPXUobW9kdWxlLmJ1bmRsZS5yb290LHQpO28uaG90Ll9hY2NlcHRDYWxsYmFja3MuZm9yRWFjaChmdW5jdGlvbihuKXtsZXQgcz1uKCgpPT5yKTtzJiZzLmxlbmd0aCYmKHMuZm9yRWFjaCgoW2EsbF0pPT57dihhLGwpfSksaS5hc3NldHNUb0FjY2VwdC5wdXNoLmFwcGx5KGkuYXNzZXRzVG9BY2NlcHQscykpfSl9fWZ1bmN0aW9uIHJlKGU9ZigpKXtsZXQgdD1MKCk7cmV0dXJuYCR7Yy5zZWN1cmV8fGxvY2F0aW9uLnByb3RvY29sPT09XCJodHRwczpcIiYmIS9sb2NhbGhvc3R8MTI3LjAuMC4xfDAuMC4wLjAvLnRlc3QodCk/XCJ3c3NcIjpcIndzXCJ9Oi8vJHt0fToke2V9L2B9ZnVuY3Rpb24gbmUoZSl7dHlwZW9mIGUubWVzc2FnZT09XCJzdHJpbmdcIiYmVChcIltwbGFzbW8vcGFyY2VsLXJ1bnRpbWVdOiBcIitlLm1lc3NhZ2UpfWZ1bmN0aW9uIE4oZSl7aWYodHlwZW9mIGdsb2JhbFRoaXMuV2ViU29ja2V0PlwidVwiKXJldHVybjtsZXQgdD1uZXcgV2ViU29ja2V0KHJlKCkpO3JldHVybiB0LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsYXN5bmMgZnVuY3Rpb24obyl7bGV0IHI9SlNPTi5wYXJzZShvLmRhdGEpO2lmKHIudHlwZT09PVwidXBkYXRlXCImJmF3YWl0IGUoci5hc3NldHMpLHIudHlwZT09PVwiZXJyb3JcIilmb3IobGV0IG4gb2Ygci5kaWFnbm9zdGljcy5hbnNpKXtsZXQgcz1uLmNvZGVmcmFtZXx8bi5zdGFjaztBKFwiW3BsYXNtby9wYXJjZWwtcnVudGltZV06IFwiK24ubWVzc2FnZStgXG5gK3MrYFxuXG5gK24uaGludHMuam9pbihgXG5gKSl9fSksdC5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIixuZSksdC5hZGRFdmVudExpc3RlbmVyKFwib3BlblwiLCgpPT57ayhgW3BsYXNtby9wYXJjZWwtcnVudGltZV06IENvbm5lY3RlZCB0byBITVIgc2VydmVyIGZvciAke2MuZW50cnlGaWxlUGF0aH1gKX0pLHQuYWRkRXZlbnRMaXN0ZW5lcihcImNsb3NlXCIsKCk9PntBKGBbcGxhc21vL3BhcmNlbC1ydW50aW1lXTogQ29ubmVjdGlvbiB0byB0aGUgSE1SIHNlcnZlciBpcyBjbG9zZWQgZm9yICR7Yy5lbnRyeUZpbGVQYXRofWApfSksdH12YXIgaj16KHJlcXVpcmUoXCJyZWFjdC1yZWZyZXNoL3J1bnRpbWVcIikpO2FzeW5jIGZ1bmN0aW9uIEYoKXtqLmRlZmF1bHQuaW5qZWN0SW50b0dsb2JhbEhvb2sod2luZG93KSx3aW5kb3cuJFJlZnJlc2hSZWckPWZ1bmN0aW9uKCl7fSx3aW5kb3cuJFJlZnJlc2hTaWckPWZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKGUpe3JldHVybiBlfX19dmFyIHNlPWAke1N9JHttb2R1bGUuaWR9X19gLGgsVT1tb2R1bGUuYnVuZGxlLnBhcmVudDtpZighVXx8IVUuaXNQYXJjZWxSZXF1aXJlKXt0cnl7aD1kPy5ydW50aW1lLmNvbm5lY3Qoe25hbWU6c2V9KSxoLm9uRGlzY29ubmVjdC5hZGRMaXN0ZW5lcigoKT0+e20oKX0pLGMuaXNSZWFjdHx8aC5vbk1lc3NhZ2UuYWRkTGlzdGVuZXIoKCk9PnttKCl9KX1jYXRjaChlKXtwKGUpfU4oYXN5bmMgZT0+e2lmKHAoXCJQYWdlIHJ1bnRpbWUgLSBPbiBITVIgVXBkYXRlXCIpLGMuaXNSZWFjdCl7QigpO2xldCB0PWUuZmlsdGVyKHI9PnIuZW52SGFzaD09PWMuZW52SGFzaCk7aWYodC5zb21lKHI9PnIudHlwZT09PVwiY3NzXCJ8fHIudHlwZT09PVwianNcIiYmUihtb2R1bGUuYnVuZGxlLnJvb3Qsci5pZCxyLmRlcHNCeUJ1bmRsZSkpKXRyeXthd2FpdCBPKHQpO2xldCByPXt9O2ZvcihsZXRbcyxhXW9mIGkuYXNzZXRzVG9EaXNwb3NlKXJbYV18fCh2KHMsYSksclthXT0hMCk7bGV0IG49e307Zm9yKGxldCBzPTA7czxpLmFzc2V0c1RvQWNjZXB0Lmxlbmd0aDtzKyspe2xldFthLGxdPWkuYXNzZXRzVG9BY2NlcHRbc107bltsXXx8KEkoYSxsKSxuW2xdPSEwKX19Y2F0Y2gocil7Yy52ZXJib3NlPT09XCJ0cnVlXCImJihjb25zb2xlLnRyYWNlKHIpLGFsZXJ0KEpTT04uc3RyaW5naWZ5KHIpKSksYXdhaXQgbSghMCl9fWVsc2V7bGV0IHQ9ZS5maWx0ZXIobz0+by5lbnZIYXNoPT09Yy5lbnZIYXNoKS5zb21lKG89Pk0obW9kdWxlLmJ1bmRsZSxvLmlkKSk7cChcIlBhZ2UgcnVudGltZSAtXCIse3NvdXJjZUNoYW5nZWQ6dH0pLHQmJmgucG9zdE1lc3NhZ2Uoe19fcGxhc21vX3BhZ2VfY2hhbmdlZF9fOiEwfSl9fSl9Yy5pc1JlYWN0JiYocChcIkluamVjdGluZyByZWFjdCByZWZyZXNoXCIpLEYoKSk7XG4iLCJ2YXIgb2U9T2JqZWN0LmNyZWF0ZTt2YXIgSD1PYmplY3QuZGVmaW5lUHJvcGVydHk7dmFyIGFlPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7dmFyIHVlPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzO3ZhciBzZT1PYmplY3QuZ2V0UHJvdG90eXBlT2YsbGU9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTt2YXIgej0obyxmKT0+KCk9PihmfHxvKChmPXtleHBvcnRzOnt9fSkuZXhwb3J0cyxmKSxmLmV4cG9ydHMpLGNlPShvLGYpPT57Zm9yKHZhciBzIGluIGYpSChvLHMse2dldDpmW3NdLGVudW1lcmFibGU6ITB9KX0sRD0obyxmLHMseSk9PntpZihmJiZ0eXBlb2YgZj09XCJvYmplY3RcInx8dHlwZW9mIGY9PVwiZnVuY3Rpb25cIilmb3IobGV0IG0gb2YgdWUoZikpIWxlLmNhbGwobyxtKSYmbSE9PXMmJkgobyxtLHtnZXQ6KCk9PmZbbV0sZW51bWVyYWJsZTohKHk9YWUoZixtKSl8fHkuZW51bWVyYWJsZX0pO3JldHVybiBvfSxTPShvLGYscyk9PihEKG8sZixcImRlZmF1bHRcIikscyYmRChzLGYsXCJkZWZhdWx0XCIpKSxHPShvLGYscyk9PihzPW8hPW51bGw/b2Uoc2UobykpOnt9LEQoZnx8IW98fCFvLl9fZXNNb2R1bGU/SChzLFwiZGVmYXVsdFwiLHt2YWx1ZTpvLGVudW1lcmFibGU6ITB9KTpzLG8pKSxkZT1vPT5EKEgoe30sXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSksbyk7dmFyIE49eihoPT57XCJ1c2Ugc3RyaWN0XCI7KGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIG89U3ltYm9sLmZvcihcInJlYWN0LmZvcndhcmRfcmVmXCIpLGY9U3ltYm9sLmZvcihcInJlYWN0Lm1lbW9cIikscz10eXBlb2YgV2Vha01hcD09XCJmdW5jdGlvblwiP1dlYWtNYXA6TWFwLHk9bmV3IE1hcCxtPW5ldyBzLGI9bmV3IHMsaj1uZXcgcyxFPVtdLEM9bmV3IE1hcCxPPW5ldyBNYXAscD1uZXcgU2V0LF89bmV3IFNldCxGPXR5cGVvZiBXZWFrTWFwPT1cImZ1bmN0aW9uXCI/bmV3IFdlYWtNYXA6bnVsbCxUPSExO2Z1bmN0aW9uIEIoZSl7aWYoZS5mdWxsS2V5IT09bnVsbClyZXR1cm4gZS5mdWxsS2V5O3ZhciByPWUub3duS2V5LG47dHJ5e249ZS5nZXRDdXN0b21Ib29rcygpfWNhdGNoKGkpe3JldHVybiBlLmZvcmNlUmVzZXQ9ITAsZS5mdWxsS2V5PXIscn1mb3IodmFyIHQ9MDt0PG4ubGVuZ3RoO3QrKyl7dmFyIGw9blt0XTtpZih0eXBlb2YgbCE9XCJmdW5jdGlvblwiKXJldHVybiBlLmZvcmNlUmVzZXQ9ITAsZS5mdWxsS2V5PXIscjt2YXIgZD1iLmdldChsKTtpZihkIT09dm9pZCAwKXt2YXIgYT1CKGQpO2QuZm9yY2VSZXNldCYmKGUuZm9yY2VSZXNldD0hMCkscis9YFxuLS0tXG5gK2F9fXJldHVybiBlLmZ1bGxLZXk9cixyfWZ1bmN0aW9uIHEoZSxyKXt2YXIgbj1iLmdldChlKSx0PWIuZ2V0KHIpO3JldHVybiBuPT09dm9pZCAwJiZ0PT09dm9pZCAwPyEwOiEobj09PXZvaWQgMHx8dD09PXZvaWQgMHx8QihuKSE9PUIodCl8fHQuZm9yY2VSZXNldCl9ZnVuY3Rpb24gJChlKXtyZXR1cm4gZS5wcm90b3R5cGUmJmUucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnR9ZnVuY3Rpb24gayhlLHIpe3JldHVybiAkKGUpfHwkKHIpPyExOiEhcShlLHIpfWZ1bmN0aW9uIFkoZSl7cmV0dXJuIGouZ2V0KGUpfWZ1bmN0aW9uIFooZSl7dmFyIHI9bmV3IE1hcDtyZXR1cm4gZS5mb3JFYWNoKGZ1bmN0aW9uKG4sdCl7ci5zZXQodCxuKX0pLHJ9ZnVuY3Rpb24gVyhlKXt2YXIgcj1uZXcgU2V0O3JldHVybiBlLmZvckVhY2goZnVuY3Rpb24obil7ci5hZGQobil9KSxyfWZ1bmN0aW9uIE0oZSxyKXt0cnl7cmV0dXJuIGVbcl19Y2F0Y2gobil7cmV0dXJufX1mdW5jdGlvbiBKKCl7aWYoRS5sZW5ndGg9PT0wfHxUKXJldHVybiBudWxsO1Q9ITA7dHJ5e3ZhciBlPW5ldyBTZXQscj1uZXcgU2V0LG49RTtFPVtdLG4uZm9yRWFjaChmdW5jdGlvbih1KXt2YXIgYz11WzBdLHY9dVsxXSxSPWMuY3VycmVudDtqLnNldChSLGMpLGouc2V0KHYsYyksYy5jdXJyZW50PXYsayhSLHYpP3IuYWRkKGMpOmUuYWRkKGMpfSk7dmFyIHQ9e3VwZGF0ZWRGYW1pbGllczpyLHN0YWxlRmFtaWxpZXM6ZX07Qy5mb3JFYWNoKGZ1bmN0aW9uKHUpe3Uuc2V0UmVmcmVzaEhhbmRsZXIoWSl9KTt2YXIgbD0hMSxkPW51bGwsYT1XKF8pLGk9VyhwKSxnPVooTyk7aWYoYS5mb3JFYWNoKGZ1bmN0aW9uKHUpe3ZhciBjPWcuZ2V0KHUpO2lmKGM9PT12b2lkIDApdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgaGVscGVycyBmb3IgYSByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0IFJlZnJlc2guXCIpO2lmKF8uaGFzKHUpLEYhPT1udWxsJiZGLmhhcyh1KSl7dmFyIHY9Ri5nZXQodSk7dHJ5e2Muc2NoZWR1bGVSb290KHUsdil9Y2F0Y2goUil7bHx8KGw9ITAsZD1SKX19fSksaS5mb3JFYWNoKGZ1bmN0aW9uKHUpe3ZhciBjPWcuZ2V0KHUpO2lmKGM9PT12b2lkIDApdGhyb3cgbmV3IEVycm9yKFwiQ291bGQgbm90IGZpbmQgaGVscGVycyBmb3IgYSByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0IFJlZnJlc2guXCIpO3AuaGFzKHUpO3RyeXtjLnNjaGVkdWxlUmVmcmVzaCh1LHQpfWNhdGNoKHYpe2x8fChsPSEwLGQ9dil9fSksbCl0aHJvdyBkO3JldHVybiB0fWZpbmFsbHl7VD0hMX19ZnVuY3Rpb24gUChlLHIpe3tpZihlPT09bnVsbHx8dHlwZW9mIGUhPVwiZnVuY3Rpb25cIiYmdHlwZW9mIGUhPVwib2JqZWN0XCJ8fG0uaGFzKGUpKXJldHVybjt2YXIgbj15LmdldChyKTtpZihuPT09dm9pZCAwPyhuPXtjdXJyZW50OmV9LHkuc2V0KHIsbikpOkUucHVzaChbbixlXSksbS5zZXQoZSxuKSx0eXBlb2YgZT09XCJvYmplY3RcIiYmZSE9PW51bGwpc3dpdGNoKE0oZSxcIiQkdHlwZW9mXCIpKXtjYXNlIG86UChlLnJlbmRlcixyK1wiJHJlbmRlclwiKTticmVhaztjYXNlIGY6UChlLnR5cGUscitcIiR0eXBlXCIpO2JyZWFrfX19ZnVuY3Rpb24gSyhlLHIpe3ZhciBuPWFyZ3VtZW50cy5sZW5ndGg+MiYmYXJndW1lbnRzWzJdIT09dm9pZCAwP2FyZ3VtZW50c1syXTohMSx0PWFyZ3VtZW50cy5sZW5ndGg+Mz9hcmd1bWVudHNbM106dm9pZCAwO2lmKGIuaGFzKGUpfHxiLnNldChlLHtmb3JjZVJlc2V0Om4sb3duS2V5OnIsZnVsbEtleTpudWxsLGdldEN1c3RvbUhvb2tzOnR8fGZ1bmN0aW9uKCl7cmV0dXJuW119fSksdHlwZW9mIGU9PVwib2JqZWN0XCImJmUhPT1udWxsKXN3aXRjaChNKGUsXCIkJHR5cGVvZlwiKSl7Y2FzZSBvOksoZS5yZW5kZXIscixuLHQpO2JyZWFrO2Nhc2UgZjpLKGUudHlwZSxyLG4sdCk7YnJlYWt9fWZ1bmN0aW9uIHgoZSl7e3ZhciByPWIuZ2V0KGUpO3IhPT12b2lkIDAmJkIocil9fWZ1bmN0aW9uIFEoZSl7cmV0dXJuIHkuZ2V0KGUpfWZ1bmN0aW9uIFgoZSl7cmV0dXJuIG0uZ2V0KGUpfWZ1bmN0aW9uIGVlKGUpe3t2YXIgcj1uZXcgU2V0O3JldHVybiBwLmZvckVhY2goZnVuY3Rpb24obil7dmFyIHQ9Ty5nZXQobik7aWYodD09PXZvaWQgMCl0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgZmluZCBoZWxwZXJzIGZvciBhIHJvb3QuIFRoaXMgaXMgYSBidWcgaW4gUmVhY3QgUmVmcmVzaC5cIik7dmFyIGw9dC5maW5kSG9zdEluc3RhbmNlc0ZvclJlZnJlc2gobixlKTtsLmZvckVhY2goZnVuY3Rpb24oZCl7ci5hZGQoZCl9KX0pLHJ9fWZ1bmN0aW9uIHJlKGUpe3t2YXIgcj1lLl9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXztpZihyPT09dm9pZCAwKXt2YXIgbj0wO2UuX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fPXI9e3JlbmRlcmVyczpuZXcgTWFwLHN1cHBvcnRzRmliZXI6ITAsaW5qZWN0OmZ1bmN0aW9uKGEpe3JldHVybiBuKyt9LG9uU2NoZWR1bGVGaWJlclJvb3Q6ZnVuY3Rpb24oYSxpLGcpe30sb25Db21taXRGaWJlclJvb3Q6ZnVuY3Rpb24oYSxpLGcsdSl7fSxvbkNvbW1pdEZpYmVyVW5tb3VudDpmdW5jdGlvbigpe319fWlmKHIuaXNEaXNhYmxlZCl7Y29uc29sZS53YXJuKFwiU29tZXRoaW5nIGhhcyBzaGltbWVkIHRoZSBSZWFjdCBEZXZUb29scyBnbG9iYWwgaG9vayAoX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fKS4gRmFzdCBSZWZyZXNoIGlzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhpcyBzaGltIGFuZCB3aWxsIGJlIGRpc2FibGVkLlwiKTtyZXR1cm59dmFyIHQ9ci5pbmplY3Q7ci5pbmplY3Q9ZnVuY3Rpb24oYSl7dmFyIGk9dC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7cmV0dXJuIHR5cGVvZiBhLnNjaGVkdWxlUmVmcmVzaD09XCJmdW5jdGlvblwiJiZ0eXBlb2YgYS5zZXRSZWZyZXNoSGFuZGxlcj09XCJmdW5jdGlvblwiJiZDLnNldChpLGEpLGl9LHIucmVuZGVyZXJzLmZvckVhY2goZnVuY3Rpb24oYSxpKXt0eXBlb2YgYS5zY2hlZHVsZVJlZnJlc2g9PVwiZnVuY3Rpb25cIiYmdHlwZW9mIGEuc2V0UmVmcmVzaEhhbmRsZXI9PVwiZnVuY3Rpb25cIiYmQy5zZXQoaSxhKX0pO3ZhciBsPXIub25Db21taXRGaWJlclJvb3QsZD1yLm9uU2NoZWR1bGVGaWJlclJvb3R8fGZ1bmN0aW9uKCl7fTtyLm9uU2NoZWR1bGVGaWJlclJvb3Q9ZnVuY3Rpb24oYSxpLGcpe3JldHVybiBUfHwoXy5kZWxldGUoaSksRiE9PW51bGwmJkYuc2V0KGksZykpLGQuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxyLm9uQ29tbWl0RmliZXJSb290PWZ1bmN0aW9uKGEsaSxnLHUpe3ZhciBjPUMuZ2V0KGEpO2lmKGMhPT12b2lkIDApe08uc2V0KGksYyk7dmFyIHY9aS5jdXJyZW50LFI9di5hbHRlcm5hdGU7aWYoUiE9PW51bGwpe3ZhciBMPVIubWVtb2l6ZWRTdGF0ZSE9bnVsbCYmUi5tZW1vaXplZFN0YXRlLmVsZW1lbnQhPW51bGwmJnAuaGFzKGkpLEE9di5tZW1vaXplZFN0YXRlIT1udWxsJiZ2Lm1lbW9pemVkU3RhdGUuZWxlbWVudCE9bnVsbDshTCYmQT8ocC5hZGQoaSksXy5kZWxldGUoaSkpOkwmJkF8fChMJiYhQT8ocC5kZWxldGUoaSksdT9fLmFkZChpKTpPLmRlbGV0ZShpKSk6IUwmJiFBJiZ1JiZfLmFkZChpKSl9ZWxzZSBwLmFkZChpKX1yZXR1cm4gbC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX1mdW5jdGlvbiBuZSgpe3JldHVybiExfWZ1bmN0aW9uIHRlKCl7cmV0dXJuIHAuc2l6ZX1mdW5jdGlvbiBmZSgpe3t2YXIgZSxyLG49ITE7cmV0dXJuIGZ1bmN0aW9uKHQsbCxkLGEpe2lmKHR5cGVvZiBsPT1cInN0cmluZ1wiKXJldHVybiBlfHwoZT10LHI9dHlwZW9mIGE9PVwiZnVuY3Rpb25cIiksdCE9bnVsbCYmKHR5cGVvZiB0PT1cImZ1bmN0aW9uXCJ8fHR5cGVvZiB0PT1cIm9iamVjdFwiKSYmSyh0LGwsZCxhKSx0OyFuJiZyJiYobj0hMCx4KGUpKX19fWZ1bmN0aW9uIGllKGUpe3N3aXRjaCh0eXBlb2YgZSl7Y2FzZVwiZnVuY3Rpb25cIjp7aWYoZS5wcm90b3R5cGUhPW51bGwpe2lmKGUucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQpcmV0dXJuITA7dmFyIHI9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZS5wcm90b3R5cGUpO2lmKHIubGVuZ3RoPjF8fHJbMF0hPT1cImNvbnN0cnVjdG9yXCJ8fGUucHJvdG90eXBlLl9fcHJvdG9fXyE9PU9iamVjdC5wcm90b3R5cGUpcmV0dXJuITF9dmFyIG49ZS5uYW1lfHxlLmRpc3BsYXlOYW1lO3JldHVybiB0eXBlb2Ygbj09XCJzdHJpbmdcIiYmL15bQS1aXS8udGVzdChuKX1jYXNlXCJvYmplY3RcIjp7aWYoZSE9bnVsbClzd2l0Y2goTShlLFwiJCR0eXBlb2ZcIikpe2Nhc2UgbzpjYXNlIGY6cmV0dXJuITA7ZGVmYXVsdDpyZXR1cm4hMX1yZXR1cm4hMX1kZWZhdWx0OnJldHVybiExfX1oLl9nZXRNb3VudGVkUm9vdENvdW50PXRlLGguY29sbGVjdEN1c3RvbUhvb2tzRm9yU2lnbmF0dXJlPXgsaC5jcmVhdGVTaWduYXR1cmVGdW5jdGlvbkZvclRyYW5zZm9ybT1mZSxoLmZpbmRBZmZlY3RlZEhvc3RJbnN0YW5jZXM9ZWUsaC5nZXRGYW1pbHlCeUlEPVEsaC5nZXRGYW1pbHlCeVR5cGU9WCxoLmhhc1VucmVjb3ZlcmFibGVFcnJvcnM9bmUsaC5pbmplY3RJbnRvR2xvYmFsSG9vaz1yZSxoLmlzTGlrZWx5Q29tcG9uZW50VHlwZT1pZSxoLnBlcmZvcm1SZWFjdFJlZnJlc2g9SixoLnJlZ2lzdGVyPVAsaC5zZXRTaWduYXR1cmU9S30pKCl9KTt2YXIgST16KChwZSxWKT0+e1widXNlIHN0cmljdFwiO1YuZXhwb3J0cz1OKCl9KTt2YXIgdz17fTtjZSh3LHtkZWZhdWx0OigpPT5oZX0pO21vZHVsZS5leHBvcnRzPWRlKHcpO3ZhciBVPUcoSSgpKTtTKHcsRyhJKCkpLG1vZHVsZS5leHBvcnRzKTt2YXIgaGU9VS5kZWZhdWx0O1xuLyohIEJ1bmRsZWQgbGljZW5zZSBpbmZvcm1hdGlvbjpcblxucmVhY3QtcmVmcmVzaC9janMvcmVhY3QtcmVmcmVzaC1ydW50aW1lLmRldmVsb3BtZW50LmpzOlxuICAoKipcbiAgICogQGxpY2Vuc2UgUmVhY3RcbiAgICogcmVhY3QtcmVmcmVzaC1ydW50aW1lLmRldmVsb3BtZW50LmpzXG4gICAqXG4gICAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICAgKlxuICAgKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAgICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICAgKilcbiovXG4iLCJpbXBvcnQgUmVhY3QgZnJvbSBcInJlYWN0XCJcbmltcG9ydCB7IGNyZWF0ZVJvb3QgfSBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiXG5cbmltcG9ydCB7IGdldExheW91dCB9IGZyb20gXCJAcGxhc21vLXN0YXRpYy1jb21tb24vcmVhY3RcIlxuXG4vLyBAdHMtaWdub3JlXG5pbXBvcnQgKiBhcyBDb21wb25lbnQgZnJvbSBcIi4uLy4uL3BvcHVwLnRzeFwiXG5cbmxldCBfX3BsYXNtb1Jvb3Q6IEhUTUxFbGVtZW50ID0gbnVsbFxuXG5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiB7XG4gIGlmICghIV9fcGxhc21vUm9vdCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgX19wbGFzbW9Sb290ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJfX3BsYXNtb1wiKVxuXG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KF9fcGxhc21vUm9vdClcblxuICBjb25zdCBMYXlvdXQgPSBnZXRMYXlvdXQoQ29tcG9uZW50KVxuXG4gIHJvb3QucmVuZGVyKFxuICAgIDxMYXlvdXQ+XG4gICAgICA8Q29tcG9uZW50LmRlZmF1bHQgLz5cbiAgICA8L0xheW91dD5cbiAgKVxufSlcbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1qc3gtZGV2LXJ1bnRpbWUucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtanN4LWRldi1ydW50aW1lLmRldmVsb3BtZW50LmpzJyk7XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC1qc3gtZGV2LXJ1bnRpbWUuZGV2ZWxvcG1lbnQuanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgKGZ1bmN0aW9uKCkge1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG4vLyBBVFRFTlRJT05cbi8vIFdoZW4gYWRkaW5nIG5ldyBzeW1ib2xzIHRvIHRoaXMgZmlsZSxcbi8vIFBsZWFzZSBjb25zaWRlciBhbHNvIGFkZGluZyB0byAncmVhY3QtZGV2dG9vbHMtc2hhcmVkL3NyYy9iYWNrZW5kL1JlYWN0U3ltYm9scydcbi8vIFRoZSBTeW1ib2wgdXNlZCB0byB0YWcgdGhlIFJlYWN0RWxlbWVudC1saWtlIHR5cGVzLlxudmFyIFJFQUNUX0VMRU1FTlRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKTtcbnZhciBSRUFDVF9QT1JUQUxfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnBvcnRhbCcpO1xudmFyIFJFQUNUX0ZSQUdNRU5UX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5mcmFnbWVudCcpO1xudmFyIFJFQUNUX1NUUklDVF9NT0RFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdHJpY3RfbW9kZScpO1xudmFyIFJFQUNUX1BST0ZJTEVSX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5wcm9maWxlcicpO1xudmFyIFJFQUNUX1BST1ZJREVSX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5wcm92aWRlcicpO1xudmFyIFJFQUNUX0NPTlRFWFRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmNvbnRleHQnKTtcbnZhciBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZm9yd2FyZF9yZWYnKTtcbnZhciBSRUFDVF9TVVNQRU5TRV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3Quc3VzcGVuc2UnKTtcbnZhciBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZV9saXN0Jyk7XG52YXIgUkVBQ1RfTUVNT19UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubWVtbycpO1xudmFyIFJFQUNUX0xBWllfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmxhenknKTtcbnZhciBSRUFDVF9PRkZTQ1JFRU5fVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0Lm9mZnNjcmVlbicpO1xudmFyIE1BWUJFX0lURVJBVE9SX1NZTUJPTCA9IFN5bWJvbC5pdGVyYXRvcjtcbnZhciBGQVVYX0lURVJBVE9SX1NZTUJPTCA9ICdAQGl0ZXJhdG9yJztcbmZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4obWF5YmVJdGVyYWJsZSkge1xuICBpZiAobWF5YmVJdGVyYWJsZSA9PT0gbnVsbCB8fCB0eXBlb2YgbWF5YmVJdGVyYWJsZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBtYXliZUl0ZXJhdG9yID0gTUFZQkVfSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbTUFZQkVfSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXTtcblxuICBpZiAodHlwZW9mIG1heWJlSXRlcmF0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbWF5YmVJdGVyYXRvcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgUmVhY3RTaGFyZWRJbnRlcm5hbHMgPSBSZWFjdC5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRDtcblxuZnVuY3Rpb24gZXJyb3IoZm9ybWF0KSB7XG4gIHtcbiAgICB7XG4gICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIgPiAxID8gX2xlbjIgLSAxIDogMCksIF9rZXkyID0gMTsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICBhcmdzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgfVxuXG4gICAgICBwcmludFdhcm5pbmcoJ2Vycm9yJywgZm9ybWF0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJpbnRXYXJuaW5nKGxldmVsLCBmb3JtYXQsIGFyZ3MpIHtcbiAgLy8gV2hlbiBjaGFuZ2luZyB0aGlzIGxvZ2ljLCB5b3UgbWlnaHQgd2FudCB0byBhbHNvXG4gIC8vIHVwZGF0ZSBjb25zb2xlV2l0aFN0YWNrRGV2Lnd3dy5qcyBhcyB3ZWxsLlxuICB7XG4gICAgdmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuICAgIHZhciBzdGFjayA9IFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0U3RhY2tBZGRlbmR1bSgpO1xuXG4gICAgaWYgKHN0YWNrICE9PSAnJykge1xuICAgICAgZm9ybWF0ICs9ICclcyc7XG4gICAgICBhcmdzID0gYXJncy5jb25jYXQoW3N0YWNrXSk7XG4gICAgfSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb25cblxuXG4gICAgdmFyIGFyZ3NXaXRoRm9ybWF0ID0gYXJncy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBTdHJpbmcoaXRlbSk7XG4gICAgfSk7IC8vIENhcmVmdWw6IFJOIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJlZml4XG5cbiAgICBhcmdzV2l0aEZvcm1hdC51bnNoaWZ0KCdXYXJuaW5nOiAnICsgZm9ybWF0KTsgLy8gV2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2Ugc3ByZWFkIChvciAuYXBwbHkpIGRpcmVjdGx5IGJlY2F1c2UgaXRcbiAgICAvLyBicmVha3MgSUU5OiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEzNjEwXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuXG4gICAgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZVtsZXZlbF0sIGNvbnNvbGUsIGFyZ3NXaXRoRm9ybWF0KTtcbiAgfVxufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgZW5hYmxlU2NvcGVBUEkgPSBmYWxzZTsgLy8gRXhwZXJpbWVudGFsIENyZWF0ZSBFdmVudCBIYW5kbGUgQVBJLlxudmFyIGVuYWJsZUNhY2hlRWxlbWVudCA9IGZhbHNlO1xudmFyIGVuYWJsZVRyYW5zaXRpb25UcmFjaW5nID0gZmFsc2U7IC8vIE5vIGtub3duIGJ1Z3MsIGJ1dCBuZWVkcyBwZXJmb3JtYW5jZSB0ZXN0aW5nXG5cbnZhciBlbmFibGVMZWdhY3lIaWRkZW4gPSBmYWxzZTsgLy8gRW5hYmxlcyB1bnN0YWJsZV9hdm9pZFRoaXNGYWxsYmFjayBmZWF0dXJlIGluIEZpYmVyXG4vLyBzdHVmZi4gSW50ZW5kZWQgdG8gZW5hYmxlIFJlYWN0IGNvcmUgbWVtYmVycyB0byBtb3JlIGVhc2lseSBkZWJ1ZyBzY2hlZHVsaW5nXG4vLyBpc3N1ZXMgaW4gREVWIGJ1aWxkcy5cblxudmFyIGVuYWJsZURlYnVnVHJhY2luZyA9IGZhbHNlOyAvLyBUcmFjayB3aGljaCBGaWJlcihzKSBzY2hlZHVsZSByZW5kZXIgd29yay5cblxudmFyIFJFQUNUX01PRFVMRV9SRUZFUkVOQ0U7XG5cbntcbiAgUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSA9IFN5bWJvbC5mb3IoJ3JlYWN0Lm1vZHVsZS5yZWZlcmVuY2UnKTtcbn1cblxuZnVuY3Rpb24gaXNWYWxpZEVsZW1lbnRUeXBlKHR5cGUpIHtcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIE5vdGU6IHR5cGVvZiBtaWdodCBiZSBvdGhlciB0aGFuICdzeW1ib2wnIG9yICdudW1iZXInIChlLmcuIGlmIGl0J3MgYSBwb2x5ZmlsbCkuXG5cblxuICBpZiAodHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9QUk9GSUxFUl9UWVBFIHx8IGVuYWJsZURlYnVnVHJhY2luZyAgfHwgdHlwZSA9PT0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9TVVNQRU5TRV9UWVBFIHx8IHR5cGUgPT09IFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSB8fCBlbmFibGVMZWdhY3lIaWRkZW4gIHx8IHR5cGUgPT09IFJFQUNUX09GRlNDUkVFTl9UWVBFIHx8IGVuYWJsZVNjb3BlQVBJICB8fCBlbmFibGVDYWNoZUVsZW1lbnQgIHx8IGVuYWJsZVRyYW5zaXRpb25UcmFjaW5nICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfUFJPVklERVJfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9DT05URVhUX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSB8fCAvLyBUaGlzIG5lZWRzIHRvIGluY2x1ZGUgYWxsIHBvc3NpYmxlIG1vZHVsZSByZWZlcmVuY2Ugb2JqZWN0XG4gICAgLy8gdHlwZXMgc3VwcG9ydGVkIGJ5IGFueSBGbGlnaHQgY29uZmlndXJhdGlvbiBhbnl3aGVyZSBzaW5jZVxuICAgIC8vIHdlIGRvbid0IGtub3cgd2hpY2ggRmxpZ2h0IGJ1aWxkIHRoaXMgd2lsbCBlbmQgdXAgYmVpbmcgdXNlZFxuICAgIC8vIHdpdGguXG4gICAgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSB8fCB0eXBlLmdldE1vZHVsZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0V3JhcHBlZE5hbWUob3V0ZXJUeXBlLCBpbm5lclR5cGUsIHdyYXBwZXJOYW1lKSB7XG4gIHZhciBkaXNwbGF5TmFtZSA9IG91dGVyVHlwZS5kaXNwbGF5TmFtZTtcblxuICBpZiAoZGlzcGxheU5hbWUpIHtcbiAgICByZXR1cm4gZGlzcGxheU5hbWU7XG4gIH1cblxuICB2YXIgZnVuY3Rpb25OYW1lID0gaW5uZXJUeXBlLmRpc3BsYXlOYW1lIHx8IGlubmVyVHlwZS5uYW1lIHx8ICcnO1xuICByZXR1cm4gZnVuY3Rpb25OYW1lICE9PSAnJyA/IHdyYXBwZXJOYW1lICsgXCIoXCIgKyBmdW5jdGlvbk5hbWUgKyBcIilcIiA6IHdyYXBwZXJOYW1lO1xufSAvLyBLZWVwIGluIHN5bmMgd2l0aCByZWFjdC1yZWNvbmNpbGVyL2dldENvbXBvbmVudE5hbWVGcm9tRmliZXJcblxuXG5mdW5jdGlvbiBnZXRDb250ZXh0TmFtZSh0eXBlKSB7XG4gIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8ICdDb250ZXh0Jztcbn0gLy8gTm90ZSB0aGF0IHRoZSByZWNvbmNpbGVyIHBhY2thZ2Ugc2hvdWxkIGdlbmVyYWxseSBwcmVmZXIgdG8gdXNlIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoKSBpbnN0ZWFkLlxuXG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKSB7XG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAvLyBIb3N0IHJvb3QsIHRleHQgbm9kZSBvciBqdXN0IGludmFsaWQgdHlwZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICBpZiAodHlwZW9mIHR5cGUudGFnID09PSAnbnVtYmVyJykge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIGFuIHVuZXhwZWN0ZWQgb2JqZWN0IGluIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSgpLiAnICsgJ1RoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCB0eXBlLm5hbWUgfHwgbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgUkVBQ1RfRlJBR01FTlRfVFlQRTpcbiAgICAgIHJldHVybiAnRnJhZ21lbnQnO1xuXG4gICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgIHJldHVybiAnUG9ydGFsJztcblxuICAgIGNhc2UgUkVBQ1RfUFJPRklMRVJfVFlQRTpcbiAgICAgIHJldHVybiAnUHJvZmlsZXInO1xuXG4gICAgY2FzZSBSRUFDVF9TVFJJQ1RfTU9ERV9UWVBFOlxuICAgICAgcmV0dXJuICdTdHJpY3RNb2RlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgIHJldHVybiAnU3VzcGVuc2UnO1xuXG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlTGlzdCc7XG5cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgIGNhc2UgUkVBQ1RfQ09OVEVYVF9UWVBFOlxuICAgICAgICB2YXIgY29udGV4dCA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShjb250ZXh0KSArICcuQ29uc3VtZXInO1xuXG4gICAgICBjYXNlIFJFQUNUX1BST1ZJREVSX1RZUEU6XG4gICAgICAgIHZhciBwcm92aWRlciA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShwcm92aWRlci5fY29udGV4dCkgKyAnLlByb3ZpZGVyJztcblxuICAgICAgY2FzZSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFOlxuICAgICAgICByZXR1cm4gZ2V0V3JhcHBlZE5hbWUodHlwZSwgdHlwZS5yZW5kZXIsICdGb3J3YXJkUmVmJyk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICB2YXIgb3V0ZXJOYW1lID0gdHlwZS5kaXNwbGF5TmFtZSB8fCBudWxsO1xuXG4gICAgICAgIGlmIChvdXRlck5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gb3V0ZXJOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlLnR5cGUpIHx8ICdNZW1vJztcblxuICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IHR5cGU7XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGluaXQocGF5bG9hZCkpO1xuICAgICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxudmFyIGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIEhlbHBlcnMgdG8gcGF0Y2ggY29uc29sZS5sb2dzIHRvIGF2b2lkIGxvZ2dpbmcgZHVyaW5nIHNpZGUtZWZmZWN0IGZyZWVcbi8vIHJlcGxheWluZyBvbiByZW5kZXIgZnVuY3Rpb24uIFRoaXMgY3VycmVudGx5IG9ubHkgcGF0Y2hlcyB0aGUgb2JqZWN0XG4vLyBsYXppbHkgd2hpY2ggd29uJ3QgY292ZXIgaWYgdGhlIGxvZyBmdW5jdGlvbiB3YXMgZXh0cmFjdGVkIGVhZ2VybHkuXG4vLyBXZSBjb3VsZCBhbHNvIGVhZ2VybHkgcGF0Y2ggdGhlIG1ldGhvZC5cbnZhciBkaXNhYmxlZERlcHRoID0gMDtcbnZhciBwcmV2TG9nO1xudmFyIHByZXZJbmZvO1xudmFyIHByZXZXYXJuO1xudmFyIHByZXZFcnJvcjtcbnZhciBwcmV2R3JvdXA7XG52YXIgcHJldkdyb3VwQ29sbGFwc2VkO1xudmFyIHByZXZHcm91cEVuZDtcblxuZnVuY3Rpb24gZGlzYWJsZWRMb2coKSB7fVxuXG5kaXNhYmxlZExvZy5fX3JlYWN0RGlzYWJsZWRMb2cgPSB0cnVlO1xuZnVuY3Rpb24gZGlzYWJsZUxvZ3MoKSB7XG4gIHtcbiAgICBpZiAoZGlzYWJsZWREZXB0aCA9PT0gMCkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgICBwcmV2TG9nID0gY29uc29sZS5sb2c7XG4gICAgICBwcmV2SW5mbyA9IGNvbnNvbGUuaW5mbztcbiAgICAgIHByZXZXYXJuID0gY29uc29sZS53YXJuO1xuICAgICAgcHJldkVycm9yID0gY29uc29sZS5lcnJvcjtcbiAgICAgIHByZXZHcm91cCA9IGNvbnNvbGUuZ3JvdXA7XG4gICAgICBwcmV2R3JvdXBDb2xsYXBzZWQgPSBjb25zb2xlLmdyb3VwQ29sbGFwc2VkO1xuICAgICAgcHJldkdyb3VwRW5kID0gY29uc29sZS5ncm91cEVuZDsgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xOTA5OVxuXG4gICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGRpc2FibGVkTG9nLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgfTsgLy8gJEZsb3dGaXhNZSBGbG93IHRoaW5rcyBjb25zb2xlIGlzIGltbXV0YWJsZS5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc29sZSwge1xuICAgICAgICBpbmZvOiBwcm9wcyxcbiAgICAgICAgbG9nOiBwcm9wcyxcbiAgICAgICAgd2FybjogcHJvcHMsXG4gICAgICAgIGVycm9yOiBwcm9wcyxcbiAgICAgICAgZ3JvdXA6IHByb3BzLFxuICAgICAgICBncm91cENvbGxhcHNlZDogcHJvcHMsXG4gICAgICAgIGdyb3VwRW5kOiBwcm9wc1xuICAgICAgfSk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgIH1cblxuICAgIGRpc2FibGVkRGVwdGgrKztcbiAgfVxufVxuZnVuY3Rpb24gcmVlbmFibGVMb2dzKCkge1xuICB7XG4gICAgZGlzYWJsZWREZXB0aC0tO1xuXG4gICAgaWYgKGRpc2FibGVkRGVwdGggPT09IDApIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgICAgdmFyIHByb3BzID0ge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lIEZsb3cgdGhpbmtzIGNvbnNvbGUgaXMgaW1tdXRhYmxlLlxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zb2xlLCB7XG4gICAgICAgIGxvZzogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2TG9nXG4gICAgICAgIH0pLFxuICAgICAgICBpbmZvOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZJbmZvXG4gICAgICAgIH0pLFxuICAgICAgICB3YXJuOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZXYXJuXG4gICAgICAgIH0pLFxuICAgICAgICBlcnJvcjogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2RXJyb3JcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cFxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXBDb2xsYXBzZWQ6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwQ29sbGFwc2VkXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cEVuZDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBFbmRcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgICAgLyogZXNsaW50LWVuYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICB9XG5cbiAgICBpZiAoZGlzYWJsZWREZXB0aCA8IDApIHtcbiAgICAgIGVycm9yKCdkaXNhYmxlZERlcHRoIGZlbGwgYmVsb3cgemVyby4gJyArICdUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnREaXNwYXRjaGVyO1xudmFyIHByZWZpeDtcbmZ1bmN0aW9uIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKG5hbWUsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBWTSBzcGVjaWZpYyBwcmVmaXggdXNlZCBieSBlYWNoIGxpbmUuXG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICB2YXIgbWF0Y2ggPSB4LnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO1xuICAgICAgICBwcmVmaXggPSBtYXRjaCAmJiBtYXRjaFsxXSB8fCAnJztcbiAgICAgIH1cbiAgICB9IC8vIFdlIHVzZSB0aGUgcHJlZml4IHRvIGVuc3VyZSBvdXIgc3RhY2tzIGxpbmUgdXAgd2l0aCBuYXRpdmUgc3RhY2sgZnJhbWVzLlxuXG5cbiAgICByZXR1cm4gJ1xcbicgKyBwcmVmaXggKyBuYW1lO1xuICB9XG59XG52YXIgcmVlbnRyeSA9IGZhbHNlO1xudmFyIGNvbXBvbmVudEZyYW1lQ2FjaGU7XG5cbntcbiAgdmFyIFBvc3NpYmx5V2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcbiAgY29tcG9uZW50RnJhbWVDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAoKTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgY29uc3RydWN0KSB7XG4gIC8vIElmIHNvbWV0aGluZyBhc2tlZCBmb3IgYSBzdGFjayBpbnNpZGUgYSBmYWtlIHJlbmRlciwgaXQgc2hvdWxkIGdldCBpZ25vcmVkLlxuICBpZiAoICFmbiB8fCByZWVudHJ5KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAge1xuICAgIHZhciBmcmFtZSA9IGNvbXBvbmVudEZyYW1lQ2FjaGUuZ2V0KGZuKTtcblxuICAgIGlmIChmcmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZnJhbWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbnRyb2w7XG4gIHJlZW50cnkgPSB0cnVlO1xuICB2YXIgcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZSA9IEVycm9yLnByZXBhcmVTdGFja1RyYWNlOyAvLyAkRmxvd0ZpeE1lIEl0IGRvZXMgYWNjZXB0IHVuZGVmaW5lZC5cblxuICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IHVuZGVmaW5lZDtcbiAgdmFyIHByZXZpb3VzRGlzcGF0Y2hlcjtcblxuICB7XG4gICAgcHJldmlvdXNEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlci5jdXJyZW50OyAvLyBTZXQgdGhlIGRpc3BhdGNoZXIgaW4gREVWIGJlY2F1c2UgdGhpcyBtaWdodCBiZSBjYWxsIGluIHRoZSByZW5kZXIgZnVuY3Rpb25cbiAgICAvLyBmb3Igd2FybmluZ3MuXG5cbiAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLmN1cnJlbnQgPSBudWxsO1xuICAgIGRpc2FibGVMb2dzKCk7XG4gIH1cblxuICB0cnkge1xuICAgIC8vIFRoaXMgc2hvdWxkIHRocm93LlxuICAgIGlmIChjb25zdHJ1Y3QpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBzaG91bGQgYmUgc2V0dGluZyB0aGUgcHJvcHMgaW4gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAgdmFyIEZha2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lXG5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEZha2UucHJvdG90eXBlLCAncHJvcHMnLCB7XG4gICAgICAgIHNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIFdlIHVzZSBhIHRocm93aW5nIHNldHRlciBpbnN0ZWFkIG9mIGZyb3plbiBvciBub24td3JpdGFibGUgcHJvcHNcbiAgICAgICAgICAvLyBiZWNhdXNlIHRoYXQgd29uJ3QgdGhyb3cgaW4gYSBub24tc3RyaWN0IG1vZGUgZnVuY3Rpb24uXG4gICAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gJ29iamVjdCcgJiYgUmVmbGVjdC5jb25zdHJ1Y3QpIHtcbiAgICAgICAgLy8gV2UgY29uc3RydWN0IGEgZGlmZmVyZW50IGNvbnRyb2wgZm9yIHRoaXMgY2FzZSB0byBpbmNsdWRlIGFueSBleHRyYVxuICAgICAgICAvLyBmcmFtZXMgYWRkZWQgYnkgdGhlIGNvbnN0cnVjdCBjYWxsLlxuICAgICAgICB0cnkge1xuICAgICAgICAgIFJlZmxlY3QuY29uc3RydWN0KEZha2UsIFtdKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgICB9XG5cbiAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoZm4sIFtdLCBGYWtlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgRmFrZS5jYWxsKCk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBjb250cm9sID0geDtcbiAgICAgICAgfVxuXG4gICAgICAgIGZuLmNhbGwoRmFrZS5wcm90b3R5cGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICBjb250cm9sID0geDtcbiAgICAgIH1cblxuICAgICAgZm4oKTtcbiAgICB9XG4gIH0gY2F0Y2ggKHNhbXBsZSkge1xuICAgIC8vIFRoaXMgaXMgaW5saW5lZCBtYW51YWxseSBiZWNhdXNlIGNsb3N1cmUgZG9lc24ndCBkbyBpdCBmb3IgdXMuXG4gICAgaWYgKHNhbXBsZSAmJiBjb250cm9sICYmIHR5cGVvZiBzYW1wbGUuc3RhY2sgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBUaGlzIGV4dHJhY3RzIHRoZSBmaXJzdCBmcmFtZSBmcm9tIHRoZSBzYW1wbGUgdGhhdCBpc24ndCBhbHNvIGluIHRoZSBjb250cm9sLlxuICAgICAgLy8gU2tpcHBpbmcgb25lIGZyYW1lIHRoYXQgd2UgYXNzdW1lIGlzIHRoZSBmcmFtZSB0aGF0IGNhbGxzIHRoZSB0d28uXG4gICAgICB2YXIgc2FtcGxlTGluZXMgPSBzYW1wbGUuc3RhY2suc3BsaXQoJ1xcbicpO1xuICAgICAgdmFyIGNvbnRyb2xMaW5lcyA9IGNvbnRyb2wuc3RhY2suc3BsaXQoJ1xcbicpO1xuICAgICAgdmFyIHMgPSBzYW1wbGVMaW5lcy5sZW5ndGggLSAxO1xuICAgICAgdmFyIGMgPSBjb250cm9sTGluZXMubGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKHMgPj0gMSAmJiBjID49IDAgJiYgc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAvLyBXZSBleHBlY3QgYXQgbGVhc3Qgb25lIHN0YWNrIGZyYW1lIHRvIGJlIHNoYXJlZC5cbiAgICAgICAgLy8gVHlwaWNhbGx5IHRoaXMgd2lsbCBiZSB0aGUgcm9vdCBtb3N0IG9uZS4gSG93ZXZlciwgc3RhY2sgZnJhbWVzIG1heSBiZVxuICAgICAgICAvLyBjdXQgb2ZmIGR1ZSB0byBtYXhpbXVtIHN0YWNrIGxpbWl0cy4gSW4gdGhpcyBjYXNlLCBvbmUgbWF5YmUgY3V0IG9mZlxuICAgICAgICAvLyBlYXJsaWVyIHRoYW4gdGhlIG90aGVyLiBXZSBhc3N1bWUgdGhhdCB0aGUgc2FtcGxlIGlzIGxvbmdlciBvciB0aGUgc2FtZVxuICAgICAgICAvLyBhbmQgdGhlcmUgZm9yIGN1dCBvZmYgZWFybGllci4gU28gd2Ugc2hvdWxkIGZpbmQgdGhlIHJvb3QgbW9zdCBmcmFtZSBpblxuICAgICAgICAvLyB0aGUgc2FtcGxlIHNvbWV3aGVyZSBpbiB0aGUgY29udHJvbC5cbiAgICAgICAgYy0tO1xuICAgICAgfVxuXG4gICAgICBmb3IgKDsgcyA+PSAxICYmIGMgPj0gMDsgcy0tLCBjLS0pIHtcbiAgICAgICAgLy8gTmV4dCB3ZSBmaW5kIHRoZSBmaXJzdCBvbmUgdGhhdCBpc24ndCB0aGUgc2FtZSB3aGljaCBzaG91bGQgYmUgdGhlXG4gICAgICAgIC8vIGZyYW1lIHRoYXQgY2FsbGVkIG91ciBzYW1wbGUgZnVuY3Rpb24gYW5kIHRoZSBjb250cm9sLlxuICAgICAgICBpZiAoc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAgIC8vIEluIFY4LCB0aGUgZmlyc3QgbGluZSBpcyBkZXNjcmliaW5nIHRoZSBtZXNzYWdlIGJ1dCBvdGhlciBWTXMgZG9uJ3QuXG4gICAgICAgICAgLy8gSWYgd2UncmUgYWJvdXQgdG8gcmV0dXJuIHRoZSBmaXJzdCBsaW5lLCBhbmQgdGhlIGNvbnRyb2wgaXMgYWxzbyBvbiB0aGUgc2FtZVxuICAgICAgICAgIC8vIGxpbmUsIHRoYXQncyBhIHByZXR0eSBnb29kIGluZGljYXRvciB0aGF0IG91ciBzYW1wbGUgdGhyZXcgYXQgc2FtZSBsaW5lIGFzXG4gICAgICAgICAgLy8gdGhlIGNvbnRyb2wuIEkuZS4gYmVmb3JlIHdlIGVudGVyZWQgdGhlIHNhbXBsZSBmcmFtZS4gU28gd2UgaWdub3JlIHRoaXMgcmVzdWx0LlxuICAgICAgICAgIC8vIFRoaXMgY2FuIGhhcHBlbiBpZiB5b3UgcGFzc2VkIGEgY2xhc3MgdG8gZnVuY3Rpb24gY29tcG9uZW50LCBvciBub24tZnVuY3Rpb24uXG4gICAgICAgICAgaWYgKHMgIT09IDEgfHwgYyAhPT0gMSkge1xuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICBzLS07XG4gICAgICAgICAgICAgIGMtLTsgLy8gV2UgbWF5IHN0aWxsIGhhdmUgc2ltaWxhciBpbnRlcm1lZGlhdGUgZnJhbWVzIGZyb20gdGhlIGNvbnN0cnVjdCBjYWxsLlxuICAgICAgICAgICAgICAvLyBUaGUgbmV4dCBvbmUgdGhhdCBpc24ndCB0aGUgc2FtZSBzaG91bGQgYmUgb3VyIG1hdGNoIHRob3VnaC5cblxuICAgICAgICAgICAgICBpZiAoYyA8IDAgfHwgc2FtcGxlTGluZXNbc10gIT09IGNvbnRyb2xMaW5lc1tjXSkge1xuICAgICAgICAgICAgICAgIC8vIFY4IGFkZHMgYSBcIm5ld1wiIHByZWZpeCBmb3IgbmF0aXZlIGNsYXNzZXMuIExldCdzIHJlbW92ZSBpdCB0byBtYWtlIGl0IHByZXR0aWVyLlxuICAgICAgICAgICAgICAgIHZhciBfZnJhbWUgPSAnXFxuJyArIHNhbXBsZUxpbmVzW3NdLnJlcGxhY2UoJyBhdCBuZXcgJywgJyBhdCAnKTsgLy8gSWYgb3VyIGNvbXBvbmVudCBmcmFtZSBpcyBsYWJlbGVkIFwiPGFub255bW91cz5cIlxuICAgICAgICAgICAgICAgIC8vIGJ1dCB3ZSBoYXZlIGEgdXNlci1wcm92aWRlZCBcImRpc3BsYXlOYW1lXCJcbiAgICAgICAgICAgICAgICAvLyBzcGxpY2UgaXQgaW4gdG8gbWFrZSB0aGUgc3RhY2sgbW9yZSByZWFkYWJsZS5cblxuXG4gICAgICAgICAgICAgICAgaWYgKGZuLmRpc3BsYXlOYW1lICYmIF9mcmFtZS5pbmNsdWRlcygnPGFub255bW91cz4nKSkge1xuICAgICAgICAgICAgICAgICAgX2ZyYW1lID0gX2ZyYW1lLnJlcGxhY2UoJzxhbm9ueW1vdXM+JywgZm4uZGlzcGxheU5hbWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIF9mcmFtZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSAvLyBSZXR1cm4gdGhlIGxpbmUgd2UgZm91bmQuXG5cblxuICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gd2hpbGUgKHMgPj0gMSAmJiBjID49IDApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIHJlZW50cnkgPSBmYWxzZTtcblxuICAgIHtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudCA9IHByZXZpb3VzRGlzcGF0Y2hlcjtcbiAgICAgIHJlZW5hYmxlTG9ncygpO1xuICAgIH1cblxuICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZTtcbiAgfSAvLyBGYWxsYmFjayB0byBqdXN0IHVzaW5nIHRoZSBuYW1lIGlmIHdlIGNvdWxkbid0IG1ha2UgaXQgdGhyb3cuXG5cblxuICB2YXIgbmFtZSA9IGZuID8gZm4uZGlzcGxheU5hbWUgfHwgZm4ubmFtZSA6ICcnO1xuICB2YXIgc3ludGhldGljRnJhbWUgPSBuYW1lID8gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSkgOiAnJztcblxuICB7XG4gICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIHN5bnRoZXRpY0ZyYW1lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3ludGhldGljRnJhbWU7XG59XG5mdW5jdGlvbiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUoZm4sIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoZm4sIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QoQ29tcG9uZW50KSB7XG4gIHZhciBwcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuICByZXR1cm4gISEocHJvdG90eXBlICYmIHByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50KTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUsIHNvdXJjZSwgb3duZXJGbikge1xuXG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB7XG4gICAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZSh0eXBlLCBzaG91bGRDb25zdHJ1Y3QodHlwZSkpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUodHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEU6XG4gICAgICAgIHJldHVybiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUodHlwZS5yZW5kZXIpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgLy8gTWVtbyBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVih0eXBlLnR5cGUsIHNvdXJjZSwgb3duZXJGbik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTGF6eSBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoaW5pdChwYXlsb2FkKSwgc291cmNlLCBvd25lckZuKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7fVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgbG9nZ2VkVHlwZUZhaWx1cmVzID0ge307XG52YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpIHtcbiAge1xuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgICAgIHZhciBzdGFjayA9IGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihlbGVtZW50LnR5cGUsIGVsZW1lbnQuX3NvdXJjZSwgb3duZXIgPyBvd25lci50eXBlIDogbnVsbCk7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLnNldEV4dHJhU3RhY2tGcmFtZShzdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuc2V0RXh0cmFTdGFja0ZyYW1lKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja1Byb3BUeXBlcyh0eXBlU3BlY3MsIHZhbHVlcywgbG9jYXRpb24sIGNvbXBvbmVudE5hbWUsIGVsZW1lbnQpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWUgVGhpcyBpcyBva2F5IGJ1dCBGbG93IGRvZXNuJ3Qga25vdyBpdC5cbiAgICB2YXIgaGFzID0gRnVuY3Rpb24uY2FsbC5iaW5kKGhhc093blByb3BlcnR5KTtcblxuICAgIGZvciAodmFyIHR5cGVTcGVjTmFtZSBpbiB0eXBlU3BlY3MpIHtcbiAgICAgIGlmIChoYXModHlwZVNwZWNzLCB0eXBlU3BlY05hbWUpKSB7XG4gICAgICAgIHZhciBlcnJvciQxID0gdm9pZCAwOyAvLyBQcm9wIHR5cGUgdmFsaWRhdGlvbiBtYXkgdGhyb3cuIEluIGNhc2UgdGhleSBkbywgd2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgICAvLyBmYWlsIHRoZSByZW5kZXIgcGhhc2Ugd2hlcmUgaXQgZGlkbid0IGZhaWwgYmVmb3JlLiBTbyB3ZSBsb2cgaXQuXG4gICAgICAgIC8vIEFmdGVyIHRoZXNlIGhhdmUgYmVlbiBjbGVhbmVkIHVwLCB3ZSdsbCBsZXQgdGhlbSB0aHJvdy5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBhbiBpbnZhcmlhbnQgdGhhdCBnZXRzIGNhdWdodC4gSXQncyB0aGUgc2FtZVxuICAgICAgICAgIC8vIGJlaGF2aW9yIGFzIHdpdGhvdXQgdGhpcyBzdGF0ZW1lbnQgZXhjZXB0IHdpdGggYSBiZXR0ZXIgbWVzc2FnZS5cbiAgICAgICAgICBpZiAodHlwZW9mIHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKChjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycpICsgJzogJyArIGxvY2F0aW9uICsgJyB0eXBlIGAnICsgdHlwZVNwZWNOYW1lICsgJ2AgaXMgaW52YWxpZDsgJyArICdpdCBtdXN0IGJlIGEgZnVuY3Rpb24sIHVzdWFsbHkgZnJvbSB0aGUgYHByb3AtdHlwZXNgIHBhY2thZ2UsIGJ1dCByZWNlaXZlZCBgJyArIHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSArICdgLicgKyAnVGhpcyBvZnRlbiBoYXBwZW5zIGJlY2F1c2Ugb2YgdHlwb3Mgc3VjaCBhcyBgUHJvcFR5cGVzLmZ1bmN0aW9uYCBpbnN0ZWFkIG9mIGBQcm9wVHlwZXMuZnVuY2AuJyk7XG4gICAgICAgICAgICBlcnIubmFtZSA9ICdJbnZhcmlhbnQgVmlvbGF0aW9uJztcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlcnJvciQxID0gdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0odmFsdWVzLCB0eXBlU3BlY05hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBudWxsLCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICBlcnJvciQxID0gZXg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSAmJiAhKGVycm9yJDEgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCclczogdHlwZSBzcGVjaWZpY2F0aW9uIG9mICVzJyArICcgYCVzYCBpcyBpbnZhbGlkOyB0aGUgdHlwZSBjaGVja2VyICcgKyAnZnVuY3Rpb24gbXVzdCByZXR1cm4gYG51bGxgIG9yIGFuIGBFcnJvcmAgYnV0IHJldHVybmVkIGEgJXMuICcgKyAnWW91IG1heSBoYXZlIGZvcmdvdHRlbiB0byBwYXNzIGFuIGFyZ3VtZW50IHRvIHRoZSB0eXBlIGNoZWNrZXIgJyArICdjcmVhdG9yIChhcnJheU9mLCBpbnN0YW5jZU9mLCBvYmplY3RPZiwgb25lT2YsIG9uZU9mVHlwZSwgYW5kICcgKyAnc2hhcGUgYWxsIHJlcXVpcmUgYW4gYXJndW1lbnQpLicsIGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJywgbG9jYXRpb24sIHR5cGVTcGVjTmFtZSwgdHlwZW9mIGVycm9yJDEpO1xuXG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IkMS5tZXNzYWdlIGluIGxvZ2dlZFR5cGVGYWlsdXJlcykpIHtcbiAgICAgICAgICAvLyBPbmx5IG1vbml0b3IgdGhpcyBmYWlsdXJlIG9uY2UgYmVjYXVzZSB0aGVyZSB0ZW5kcyB0byBiZSBhIGxvdCBvZiB0aGVcbiAgICAgICAgICAvLyBzYW1lIGVycm9yLlxuICAgICAgICAgIGxvZ2dlZFR5cGVGYWlsdXJlc1tlcnJvciQxLm1lc3NhZ2VdID0gdHJ1ZTtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCdGYWlsZWQgJXMgdHlwZTogJXMnLCBsb2NhdGlvbiwgZXJyb3IkMS5tZXNzYWdlKTtcblxuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KG51bGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBpc0FycmF5SW1wbCA9IEFycmF5LmlzQXJyYXk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1yZWRlY2xhcmVcblxuZnVuY3Rpb24gaXNBcnJheShhKSB7XG4gIHJldHVybiBpc0FycmF5SW1wbChhKTtcbn1cblxuLypcbiAqIFRoZSBgJycgKyB2YWx1ZWAgcGF0dGVybiAodXNlZCBpbiBpbiBwZXJmLXNlbnNpdGl2ZSBjb2RlKSB0aHJvd3MgZm9yIFN5bWJvbFxuICogYW5kIFRlbXBvcmFsLiogdHlwZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8yMjA2NC5cbiAqXG4gKiBUaGUgZnVuY3Rpb25zIGluIHRoaXMgbW9kdWxlIHdpbGwgdGhyb3cgYW4gZWFzaWVyLXRvLXVuZGVyc3RhbmQsXG4gKiBlYXNpZXItdG8tZGVidWcgZXhjZXB0aW9uIHdpdGggYSBjbGVhciBlcnJvcnMgbWVzc2FnZSBtZXNzYWdlIGV4cGxhaW5pbmcgdGhlXG4gKiBwcm9ibGVtLiAoSW5zdGVhZCBvZiBhIGNvbmZ1c2luZyBleGNlcHRpb24gdGhyb3duIGluc2lkZSB0aGUgaW1wbGVtZW50YXRpb25cbiAqIG9mIHRoZSBgdmFsdWVgIG9iamVjdCkuXG4gKi9cbi8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5mdW5jdGlvbiB0eXBlTmFtZSh2YWx1ZSkge1xuICB7XG4gICAgLy8gdG9TdHJpbmdUYWcgaXMgbmVlZGVkIGZvciBuYW1lc3BhY2VkIHR5cGVzIGxpa2UgVGVtcG9yYWwuSW5zdGFudFxuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLnRvU3RyaW5nVGFnO1xuICAgIHZhciB0eXBlID0gaGFzVG9TdHJpbmdUYWcgJiYgdmFsdWVbU3ltYm9sLnRvU3RyaW5nVGFnXSB8fCB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdPYmplY3QnO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG59IC8vICRGbG93Rml4TWUgb25seSBjYWxsZWQgaW4gREVWLCBzbyB2b2lkIHJldHVybiBpcyBub3QgcG9zc2libGUuXG5cblxuZnVuY3Rpb24gd2lsbENvZXJjaW9uVGhyb3codmFsdWUpIHtcbiAge1xuICAgIHRyeSB7XG4gICAgICB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAgLy8gSWYgeW91IGVuZGVkIHVwIGhlcmUgYnkgZm9sbG93aW5nIGFuIGV4Y2VwdGlvbiBjYWxsIHN0YWNrLCBoZXJlJ3Mgd2hhdCdzXG4gIC8vIGhhcHBlbmVkOiB5b3Ugc3VwcGxpZWQgYW4gb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBSZWFjdCAoYXMgYSBwcm9wLCBrZXksXG4gIC8vIERPTSBhdHRyaWJ1dGUsIENTUyBwcm9wZXJ0eSwgc3RyaW5nIHJlZiwgZXRjLikgYW5kIHdoZW4gUmVhY3QgdHJpZWQgdG9cbiAgLy8gY29lcmNlIGl0IHRvIGEgc3RyaW5nIHVzaW5nIGAnJyArIHZhbHVlYCwgYW4gZXhjZXB0aW9uIHdhcyB0aHJvd24uXG4gIC8vXG4gIC8vIFRoZSBtb3N0IGNvbW1vbiB0eXBlcyB0aGF0IHdpbGwgY2F1c2UgdGhpcyBleGNlcHRpb24gYXJlIGBTeW1ib2xgIGluc3RhbmNlc1xuICAvLyBhbmQgVGVtcG9yYWwgb2JqZWN0cyBsaWtlIGBUZW1wb3JhbC5JbnN0YW50YC4gQnV0IGFueSBvYmplY3QgdGhhdCBoYXMgYVxuICAvLyBgdmFsdWVPZmAgb3IgYFtTeW1ib2wudG9QcmltaXRpdmVdYCBtZXRob2QgdGhhdCB0aHJvd3Mgd2lsbCBhbHNvIGNhdXNlIHRoaXNcbiAgLy8gZXhjZXB0aW9uLiAoTGlicmFyeSBhdXRob3JzIGRvIHRoaXMgdG8gcHJldmVudCB1c2VycyBmcm9tIHVzaW5nIGJ1aWx0LWluXG4gIC8vIG51bWVyaWMgb3BlcmF0b3JzIGxpa2UgYCtgIG9yIGNvbXBhcmlzb24gb3BlcmF0b3JzIGxpa2UgYD49YCBiZWNhdXNlIGN1c3RvbVxuICAvLyBtZXRob2RzIGFyZSBuZWVkZWQgdG8gcGVyZm9ybSBhY2N1cmF0ZSBhcml0aG1ldGljIG9yIGNvbXBhcmlzb24uKVxuICAvL1xuICAvLyBUbyBmaXggdGhlIHByb2JsZW0sIGNvZXJjZSB0aGlzIG9iamVjdCBvciBzeW1ib2wgdmFsdWUgdG8gYSBzdHJpbmcgYmVmb3JlXG4gIC8vIHBhc3NpbmcgaXQgdG8gUmVhY3QuIFRoZSBtb3N0IHJlbGlhYmxlIHdheSBpcyB1c3VhbGx5IGBTdHJpbmcodmFsdWUpYC5cbiAgLy9cbiAgLy8gVG8gZmluZCB3aGljaCB2YWx1ZSBpcyB0aHJvd2luZywgY2hlY2sgdGhlIGJyb3dzZXIgb3IgZGVidWdnZXIgY29uc29sZS5cbiAgLy8gQmVmb3JlIHRoaXMgZXhjZXB0aW9uIHdhcyB0aHJvd24sIHRoZXJlIHNob3VsZCBiZSBgY29uc29sZS5lcnJvcmAgb3V0cHV0XG4gIC8vIHRoYXQgc2hvd3MgdGhlIHR5cGUgKFN5bWJvbCwgVGVtcG9yYWwuUGxhaW5EYXRlLCBldGMuKSB0aGF0IGNhdXNlZCB0aGVcbiAgLy8gcHJvYmxlbSBhbmQgaG93IHRoYXQgdHlwZSB3YXMgdXNlZDoga2V5LCBhdHJyaWJ1dGUsIGlucHV0IHZhbHVlIHByb3AsIGV0Yy5cbiAgLy8gSW4gbW9zdCBjYXNlcywgdGhpcyBjb25zb2xlIG91dHB1dCBhbHNvIHNob3dzIHRoZSBjb21wb25lbnQgYW5kIGl0c1xuICAvLyBhbmNlc3RvciBjb21wb25lbnRzIHdoZXJlIHRoZSBleGNlcHRpb24gaGFwcGVuZWQuXG4gIC8vXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICByZXR1cm4gJycgKyB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQga2V5IGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50T3duZXIgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciBSRVNFUlZFRF9QUk9QUyA9IHtcbiAga2V5OiB0cnVlLFxuICByZWY6IHRydWUsXG4gIF9fc2VsZjogdHJ1ZSxcbiAgX19zb3VyY2U6IHRydWVcbn07XG52YXIgc3BlY2lhbFByb3BLZXlXYXJuaW5nU2hvd247XG52YXIgc3BlY2lhbFByb3BSZWZXYXJuaW5nU2hvd247XG52YXIgZGlkV2FybkFib3V0U3RyaW5nUmVmcztcblxue1xuICBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzID0ge307XG59XG5cbmZ1bmN0aW9uIGhhc1ZhbGlkUmVmKGNvbmZpZykge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCAncmVmJykpIHtcbiAgICAgIHZhciBnZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGNvbmZpZywgJ3JlZicpLmdldDtcblxuICAgICAgaWYgKGdldHRlciAmJiBnZXR0ZXIuaXNSZWFjdFdhcm5pbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25maWcucmVmICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGhhc1ZhbGlkS2V5KGNvbmZpZykge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCAna2V5JykpIHtcbiAgICAgIHZhciBnZXR0ZXIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGNvbmZpZywgJ2tleScpLmdldDtcblxuICAgICAgaWYgKGdldHRlciAmJiBnZXR0ZXIuaXNSZWFjdFdhcm5pbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjb25maWcua2V5ICE9PSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZlN0cmluZ1JlZkNhbm5vdEJlQXV0b0NvbnZlcnRlZChjb25maWcsIHNlbGYpIHtcbiAge1xuICAgIGlmICh0eXBlb2YgY29uZmlnLnJlZiA9PT0gJ3N0cmluZycgJiYgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCAmJiBzZWxmICYmIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQuc3RhdGVOb2RlICE9PSBzZWxmKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnR5cGUpO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZXJyb3IoJ0NvbXBvbmVudCBcIiVzXCIgY29udGFpbnMgdGhlIHN0cmluZyByZWYgXCIlc1wiLiAnICsgJ1N1cHBvcnQgZm9yIHN0cmluZyByZWZzIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiAnICsgJ1RoaXMgY2FzZSBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gYW4gYXJyb3cgZnVuY3Rpb24uICcgKyAnV2UgYXNrIHlvdSB0byBtYW51YWxseSBmaXggdGhpcyBjYXNlIGJ5IHVzaW5nIHVzZVJlZigpIG9yIGNyZWF0ZVJlZigpIGluc3RlYWQuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1zdHJpbmctcmVmJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQudHlwZSksIGNvbmZpZy5yZWYpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkZWZpbmVLZXlQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpIHtcbiAge1xuICAgIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIXNwZWNpYWxQcm9wS2V5V2FybmluZ1Nob3duKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wS2V5V2FybmluZ1Nob3duID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXM6IGBrZXlgIGlzIG5vdCBhIHByb3AuIFRyeWluZyB0byBhY2Nlc3MgaXQgd2lsbCByZXN1bHQgJyArICdpbiBgdW5kZWZpbmVkYCBiZWluZyByZXR1cm5lZC4gSWYgeW91IG5lZWQgdG8gYWNjZXNzIHRoZSBzYW1lICcgKyAndmFsdWUgd2l0aGluIHRoZSBjaGlsZCBjb21wb25lbnQsIHlvdSBzaG91bGQgcGFzcyBpdCBhcyBhIGRpZmZlcmVudCAnICsgJ3Byb3AuIChodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3BlY2lhbC1wcm9wcyknLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHdhcm5BYm91dEFjY2Vzc2luZ0tleS5pc1JlYWN0V2FybmluZyA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3BzLCAna2V5Jywge1xuICAgICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdLZXksXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZWZpbmVSZWZQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpIHtcbiAge1xuICAgIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIXNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXM6IGByZWZgIGlzIG5vdCBhIHByb3AuIFRyeWluZyB0byBhY2Nlc3MgaXQgd2lsbCByZXN1bHQgJyArICdpbiBgdW5kZWZpbmVkYCBiZWluZyByZXR1cm5lZC4gSWYgeW91IG5lZWQgdG8gYWNjZXNzIHRoZSBzYW1lICcgKyAndmFsdWUgd2l0aGluIHRoZSBjaGlsZCBjb21wb25lbnQsIHlvdSBzaG91bGQgcGFzcyBpdCBhcyBhIGRpZmZlcmVudCAnICsgJ3Byb3AuIChodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3BlY2lhbC1wcm9wcyknLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHdhcm5BYm91dEFjY2Vzc2luZ1JlZi5pc1JlYWN0V2FybmluZyA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3BzLCAncmVmJywge1xuICAgICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdSZWYsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuLyoqXG4gKiBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgYSBuZXcgUmVhY3QgZWxlbWVudC4gVGhpcyBubyBsb25nZXIgYWRoZXJlcyB0b1xuICogdGhlIGNsYXNzIHBhdHRlcm4sIHNvIGRvIG5vdCB1c2UgbmV3IHRvIGNhbGwgaXQuIEFsc28sIGluc3RhbmNlb2YgY2hlY2tcbiAqIHdpbGwgbm90IHdvcmsuIEluc3RlYWQgdGVzdCAkJHR5cGVvZiBmaWVsZCBhZ2FpbnN0IFN5bWJvbC5mb3IoJ3JlYWN0LmVsZW1lbnQnKSB0byBjaGVja1xuICogaWYgc29tZXRoaW5nIGlzIGEgUmVhY3QgRWxlbWVudC5cbiAqXG4gKiBAcGFyYW0geyp9IHR5cGVcbiAqIEBwYXJhbSB7Kn0gcHJvcHNcbiAqIEBwYXJhbSB7Kn0ga2V5XG4gKiBAcGFyYW0ge3N0cmluZ3xvYmplY3R9IHJlZlxuICogQHBhcmFtIHsqfSBvd25lclxuICogQHBhcmFtIHsqfSBzZWxmIEEgKnRlbXBvcmFyeSogaGVscGVyIHRvIGRldGVjdCBwbGFjZXMgd2hlcmUgYHRoaXNgIGlzXG4gKiBkaWZmZXJlbnQgZnJvbSB0aGUgYG93bmVyYCB3aGVuIFJlYWN0LmNyZWF0ZUVsZW1lbnQgaXMgY2FsbGVkLCBzbyB0aGF0IHdlXG4gKiBjYW4gd2Fybi4gV2Ugd2FudCB0byBnZXQgcmlkIG9mIG93bmVyIGFuZCByZXBsYWNlIHN0cmluZyBgcmVmYHMgd2l0aCBhcnJvd1xuICogZnVuY3Rpb25zLCBhbmQgYXMgbG9uZyBhcyBgdGhpc2AgYW5kIG93bmVyIGFyZSB0aGUgc2FtZSwgdGhlcmUgd2lsbCBiZSBub1xuICogY2hhbmdlIGluIGJlaGF2aW9yLlxuICogQHBhcmFtIHsqfSBzb3VyY2UgQW4gYW5ub3RhdGlvbiBvYmplY3QgKGFkZGVkIGJ5IGEgdHJhbnNwaWxlciBvciBvdGhlcndpc2UpXG4gKiBpbmRpY2F0aW5nIGZpbGVuYW1lLCBsaW5lIG51bWJlciwgYW5kL29yIG90aGVyIGluZm9ybWF0aW9uLlxuICogQGludGVybmFsXG4gKi9cblxuXG52YXIgUmVhY3RFbGVtZW50ID0gZnVuY3Rpb24gKHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIG93bmVyLCBwcm9wcykge1xuICB2YXIgZWxlbWVudCA9IHtcbiAgICAvLyBUaGlzIHRhZyBhbGxvd3MgdXMgdG8gdW5pcXVlbHkgaWRlbnRpZnkgdGhpcyBhcyBhIFJlYWN0IEVsZW1lbnRcbiAgICAkJHR5cGVvZjogUkVBQ1RfRUxFTUVOVF9UWVBFLFxuICAgIC8vIEJ1aWx0LWluIHByb3BlcnRpZXMgdGhhdCBiZWxvbmcgb24gdGhlIGVsZW1lbnRcbiAgICB0eXBlOiB0eXBlLFxuICAgIGtleToga2V5LFxuICAgIHJlZjogcmVmLFxuICAgIHByb3BzOiBwcm9wcyxcbiAgICAvLyBSZWNvcmQgdGhlIGNvbXBvbmVudCByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgdGhpcyBlbGVtZW50LlxuICAgIF9vd25lcjogb3duZXJcbiAgfTtcblxuICB7XG4gICAgLy8gVGhlIHZhbGlkYXRpb24gZmxhZyBpcyBjdXJyZW50bHkgbXV0YXRpdmUuIFdlIHB1dCBpdCBvblxuICAgIC8vIGFuIGV4dGVybmFsIGJhY2tpbmcgc3RvcmUgc28gdGhhdCB3ZSBjYW4gZnJlZXplIHRoZSB3aG9sZSBvYmplY3QuXG4gICAgLy8gVGhpcyBjYW4gYmUgcmVwbGFjZWQgd2l0aCBhIFdlYWtNYXAgb25jZSB0aGV5IGFyZSBpbXBsZW1lbnRlZCBpblxuICAgIC8vIGNvbW1vbmx5IHVzZWQgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnRzLlxuICAgIGVsZW1lbnQuX3N0b3JlID0ge307IC8vIFRvIG1ha2UgY29tcGFyaW5nIFJlYWN0RWxlbWVudHMgZWFzaWVyIGZvciB0ZXN0aW5nIHB1cnBvc2VzLCB3ZSBtYWtlXG4gICAgLy8gdGhlIHZhbGlkYXRpb24gZmxhZyBub24tZW51bWVyYWJsZSAod2hlcmUgcG9zc2libGUsIHdoaWNoIHNob3VsZFxuICAgIC8vIGluY2x1ZGUgZXZlcnkgZW52aXJvbm1lbnQgd2UgcnVuIHRlc3RzIGluKSwgc28gdGhlIHRlc3QgZnJhbWV3b3JrXG4gICAgLy8gaWdub3JlcyBpdC5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50Ll9zdG9yZSwgJ3ZhbGlkYXRlZCcsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IGZhbHNlXG4gICAgfSk7IC8vIHNlbGYgYW5kIHNvdXJjZSBhcmUgREVWIG9ubHkgcHJvcGVydGllcy5cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50LCAnX3NlbGYnLCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogc2VsZlxuICAgIH0pOyAvLyBUd28gZWxlbWVudHMgY3JlYXRlZCBpbiB0d28gZGlmZmVyZW50IHBsYWNlcyBzaG91bGQgYmUgY29uc2lkZXJlZFxuICAgIC8vIGVxdWFsIGZvciB0ZXN0aW5nIHB1cnBvc2VzIGFuZCB0aGVyZWZvcmUgd2UgaGlkZSBpdCBmcm9tIGVudW1lcmF0aW9uLlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc291cmNlJywge1xuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgdmFsdWU6IHNvdXJjZVxuICAgIH0pO1xuXG4gICAgaWYgKE9iamVjdC5mcmVlemUpIHtcbiAgICAgIE9iamVjdC5mcmVlemUoZWxlbWVudC5wcm9wcyk7XG4gICAgICBPYmplY3QuZnJlZXplKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufTtcbi8qKlxuICogaHR0cHM6Ly9naXRodWIuY29tL3JlYWN0anMvcmZjcy9wdWxsLzEwN1xuICogQHBhcmFtIHsqfSB0eXBlXG4gKiBAcGFyYW0ge29iamVjdH0gcHJvcHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqL1xuXG5mdW5jdGlvbiBqc3hERVYodHlwZSwgY29uZmlnLCBtYXliZUtleSwgc291cmNlLCBzZWxmKSB7XG4gIHtcbiAgICB2YXIgcHJvcE5hbWU7IC8vIFJlc2VydmVkIG5hbWVzIGFyZSBleHRyYWN0ZWRcblxuICAgIHZhciBwcm9wcyA9IHt9O1xuICAgIHZhciBrZXkgPSBudWxsO1xuICAgIHZhciByZWYgPSBudWxsOyAvLyBDdXJyZW50bHksIGtleSBjYW4gYmUgc3ByZWFkIGluIGFzIGEgcHJvcC4gVGhpcyBjYXVzZXMgYSBwb3RlbnRpYWxcbiAgICAvLyBpc3N1ZSBpZiBrZXkgaXMgYWxzbyBleHBsaWNpdGx5IGRlY2xhcmVkIChpZS4gPGRpdiB7Li4ucHJvcHN9IGtleT1cIkhpXCIgLz5cbiAgICAvLyBvciA8ZGl2IGtleT1cIkhpXCIgey4uLnByb3BzfSAvPiApLiBXZSB3YW50IHRvIGRlcHJlY2F0ZSBrZXkgc3ByZWFkLFxuICAgIC8vIGJ1dCBhcyBhbiBpbnRlcm1lZGlhcnkgc3RlcCwgd2Ugd2lsbCB1c2UganN4REVWIGZvciBldmVyeXRoaW5nIGV4Y2VwdFxuICAgIC8vIDxkaXYgey4uLnByb3BzfSBrZXk9XCJIaVwiIC8+LCBiZWNhdXNlIHdlIGFyZW4ndCBjdXJyZW50bHkgYWJsZSB0byB0ZWxsIGlmXG4gICAgLy8ga2V5IGlzIGV4cGxpY2l0bHkgZGVjbGFyZWQgdG8gYmUgdW5kZWZpbmVkIG9yIG5vdC5cblxuICAgIGlmIChtYXliZUtleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24obWF5YmVLZXkpO1xuICAgICAgfVxuXG4gICAgICBrZXkgPSAnJyArIG1heWJlS2V5O1xuICAgIH1cblxuICAgIGlmIChoYXNWYWxpZEtleShjb25maWcpKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24oY29uZmlnLmtleSk7XG4gICAgICB9XG5cbiAgICAgIGtleSA9ICcnICsgY29uZmlnLmtleTtcbiAgICB9XG5cbiAgICBpZiAoaGFzVmFsaWRSZWYoY29uZmlnKSkge1xuICAgICAgcmVmID0gY29uZmlnLnJlZjtcbiAgICAgIHdhcm5JZlN0cmluZ1JlZkNhbm5vdEJlQXV0b0NvbnZlcnRlZChjb25maWcsIHNlbGYpO1xuICAgIH0gLy8gUmVtYWluaW5nIHByb3BlcnRpZXMgYXJlIGFkZGVkIHRvIGEgbmV3IHByb3BzIG9iamVjdFxuXG5cbiAgICBmb3IgKHByb3BOYW1lIGluIGNvbmZpZykge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoY29uZmlnLCBwcm9wTmFtZSkgJiYgIVJFU0VSVkVEX1BST1BTLmhhc093blByb3BlcnR5KHByb3BOYW1lKSkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBjb25maWdbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH0gLy8gUmVzb2x2ZSBkZWZhdWx0IHByb3BzXG5cblxuICAgIGlmICh0eXBlICYmIHR5cGUuZGVmYXVsdFByb3BzKSB7XG4gICAgICB2YXIgZGVmYXVsdFByb3BzID0gdHlwZS5kZWZhdWx0UHJvcHM7XG5cbiAgICAgIGZvciAocHJvcE5hbWUgaW4gZGVmYXVsdFByb3BzKSB7XG4gICAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGRlZmF1bHRQcm9wc1twcm9wTmFtZV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoa2V5IHx8IHJlZikge1xuICAgICAgdmFyIGRpc3BsYXlOYW1lID0gdHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicgPyB0eXBlLmRpc3BsYXlOYW1lIHx8IHR5cGUubmFtZSB8fCAnVW5rbm93bicgOiB0eXBlO1xuXG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGRlZmluZUtleVByb3BXYXJuaW5nR2V0dGVyKHByb3BzLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWYpIHtcbiAgICAgICAgZGVmaW5lUmVmUHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUmVhY3RFbGVtZW50KHR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQsIHByb3BzKTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50T3duZXIkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudE93bmVyO1xudmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZWxlbWVudCkge1xuICB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIHN0YWNrID0gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGVsZW1lbnQudHlwZSwgZWxlbWVudC5fc291cmNlLCBvd25lciA/IG93bmVyLnR5cGUgOiBudWxsKTtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMS5zZXRFeHRyYVN0YWNrRnJhbWUoc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEuc2V0RXh0cmFTdGFja0ZyYW1lKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd247XG5cbntcbiAgcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd24gPSBmYWxzZTtcbn1cbi8qKlxuICogVmVyaWZpZXMgdGhlIG9iamVjdCBpcyBhIFJlYWN0RWxlbWVudC5cbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjaXN2YWxpZGVsZW1lbnRcbiAqIEBwYXJhbSB7P29iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIGBvYmplY3RgIGlzIGEgUmVhY3RFbGVtZW50LlxuICogQGZpbmFsXG4gKi9cblxuXG5mdW5jdGlvbiBpc1ZhbGlkRWxlbWVudChvYmplY3QpIHtcbiAge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0ID09PSAnb2JqZWN0JyAmJiBvYmplY3QgIT09IG51bGwgJiYgb2JqZWN0LiQkdHlwZW9mID09PSBSRUFDVF9FTEVNRU5UX1RZUEU7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCkge1xuICB7XG4gICAgaWYgKFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCkge1xuICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50LnR5cGUpO1xuXG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICByZXR1cm4gJ1xcblxcbkNoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgbmFtZSArICdgLic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtKHNvdXJjZSkge1xuICB7XG4gICAgaWYgKHNvdXJjZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgZmlsZU5hbWUgPSBzb3VyY2UuZmlsZU5hbWUucmVwbGFjZSgvXi4qW1xcXFxcXC9dLywgJycpO1xuICAgICAgdmFyIGxpbmVOdW1iZXIgPSBzb3VyY2UubGluZU51bWJlcjtcbiAgICAgIHJldHVybiAnXFxuXFxuQ2hlY2sgeW91ciBjb2RlIGF0ICcgKyBmaWxlTmFtZSArICc6JyArIGxpbmVOdW1iZXIgKyAnLic7XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9XG59XG4vKipcbiAqIFdhcm4gaWYgdGhlcmUncyBubyBrZXkgZXhwbGljaXRseSBzZXQgb24gZHluYW1pYyBhcnJheXMgb2YgY2hpbGRyZW4gb3JcbiAqIG9iamVjdCBrZXlzIGFyZSBub3QgdmFsaWQuIFRoaXMgYWxsb3dzIHVzIHRvIGtlZXAgdHJhY2sgb2YgY2hpbGRyZW4gYmV0d2VlblxuICogdXBkYXRlcy5cbiAqL1xuXG5cbnZhciBvd25lckhhc0tleVVzZVdhcm5pbmcgPSB7fTtcblxuZnVuY3Rpb24gZ2V0Q3VycmVudENvbXBvbmVudEVycm9ySW5mbyhwYXJlbnRUeXBlKSB7XG4gIHtcbiAgICB2YXIgaW5mbyA9IGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpO1xuXG4gICAgaWYgKCFpbmZvKSB7XG4gICAgICB2YXIgcGFyZW50TmFtZSA9IHR5cGVvZiBwYXJlbnRUeXBlID09PSAnc3RyaW5nJyA/IHBhcmVudFR5cGUgOiBwYXJlbnRUeXBlLmRpc3BsYXlOYW1lIHx8IHBhcmVudFR5cGUubmFtZTtcblxuICAgICAgaWYgKHBhcmVudE5hbWUpIHtcbiAgICAgICAgaW5mbyA9IFwiXFxuXFxuQ2hlY2sgdGhlIHRvcC1sZXZlbCByZW5kZXIgY2FsbCB1c2luZyA8XCIgKyBwYXJlbnROYW1lICsgXCI+LlwiO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpbmZvO1xuICB9XG59XG4vKipcbiAqIFdhcm4gaWYgdGhlIGVsZW1lbnQgZG9lc24ndCBoYXZlIGFuIGV4cGxpY2l0IGtleSBhc3NpZ25lZCB0byBpdC5cbiAqIFRoaXMgZWxlbWVudCBpcyBpbiBhbiBhcnJheS4gVGhlIGFycmF5IGNvdWxkIGdyb3cgYW5kIHNocmluayBvciBiZVxuICogcmVvcmRlcmVkLiBBbGwgY2hpbGRyZW4gdGhhdCBoYXZlbid0IGFscmVhZHkgYmVlbiB2YWxpZGF0ZWQgYXJlIHJlcXVpcmVkIHRvXG4gKiBoYXZlIGEgXCJrZXlcIiBwcm9wZXJ0eSBhc3NpZ25lZCB0byBpdC4gRXJyb3Igc3RhdHVzZXMgYXJlIGNhY2hlZCBzbyBhIHdhcm5pbmdcbiAqIHdpbGwgb25seSBiZSBzaG93biBvbmNlLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHtSZWFjdEVsZW1lbnR9IGVsZW1lbnQgRWxlbWVudCB0aGF0IHJlcXVpcmVzIGEga2V5LlxuICogQHBhcmFtIHsqfSBwYXJlbnRUeXBlIGVsZW1lbnQncyBwYXJlbnQncyB0eXBlLlxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVFeHBsaWNpdEtleShlbGVtZW50LCBwYXJlbnRUeXBlKSB7XG4gIHtcbiAgICBpZiAoIWVsZW1lbnQuX3N0b3JlIHx8IGVsZW1lbnQuX3N0b3JlLnZhbGlkYXRlZCB8fCBlbGVtZW50LmtleSAhPSBudWxsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZWxlbWVudC5fc3RvcmUudmFsaWRhdGVkID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudENvbXBvbmVudEVycm9ySW5mbyA9IGdldEN1cnJlbnRDb21wb25lbnRFcnJvckluZm8ocGFyZW50VHlwZSk7XG5cbiAgICBpZiAob3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgb3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dID0gdHJ1ZTsgLy8gVXN1YWxseSB0aGUgY3VycmVudCBvd25lciBpcyB0aGUgb2ZmZW5kZXIsIGJ1dCBpZiBpdCBhY2NlcHRzIGNoaWxkcmVuIGFzIGFcbiAgICAvLyBwcm9wZXJ0eSwgaXQgbWF5IGJlIHRoZSBjcmVhdG9yIG9mIHRoZSBjaGlsZCB0aGF0J3MgcmVzcG9uc2libGUgZm9yXG4gICAgLy8gYXNzaWduaW5nIGl0IGEga2V5LlxuXG4gICAgdmFyIGNoaWxkT3duZXIgPSAnJztcblxuICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQuX293bmVyICYmIGVsZW1lbnQuX293bmVyICE9PSBSZWFjdEN1cnJlbnRPd25lciQxLmN1cnJlbnQpIHtcbiAgICAgIC8vIEdpdmUgdGhlIGNvbXBvbmVudCB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGlzIGNoaWxkLlxuICAgICAgY2hpbGRPd25lciA9IFwiIEl0IHdhcyBwYXNzZWQgYSBjaGlsZCBmcm9tIFwiICsgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGVsZW1lbnQuX293bmVyLnR5cGUpICsgXCIuXCI7XG4gICAgfVxuXG4gICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShlbGVtZW50KTtcblxuICAgIGVycm9yKCdFYWNoIGNoaWxkIGluIGEgbGlzdCBzaG91bGQgaGF2ZSBhIHVuaXF1ZSBcImtleVwiIHByb3AuJyArICclcyVzIFNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvd2FybmluZy1rZXlzIGZvciBtb3JlIGluZm9ybWF0aW9uLicsIGN1cnJlbnRDb21wb25lbnRFcnJvckluZm8sIGNoaWxkT3duZXIpO1xuXG4gICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShudWxsKTtcbiAgfVxufVxuLyoqXG4gKiBFbnN1cmUgdGhhdCBldmVyeSBlbGVtZW50IGVpdGhlciBpcyBwYXNzZWQgaW4gYSBzdGF0aWMgbG9jYXRpb24sIGluIGFuXG4gKiBhcnJheSB3aXRoIGFuIGV4cGxpY2l0IGtleXMgcHJvcGVydHkgZGVmaW5lZCwgb3IgaW4gYW4gb2JqZWN0IGxpdGVyYWxcbiAqIHdpdGggdmFsaWQga2V5IHByb3BlcnR5LlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIHtSZWFjdE5vZGV9IG5vZGUgU3RhdGljYWxseSBwYXNzZWQgY2hpbGQgb2YgYW55IHR5cGUuXG4gKiBAcGFyYW0geyp9IHBhcmVudFR5cGUgbm9kZSdzIHBhcmVudCdzIHR5cGUuXG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZUNoaWxkS2V5cyhub2RlLCBwYXJlbnRUeXBlKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkobm9kZSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBub2RlW2ldO1xuXG4gICAgICAgIGlmIChpc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgICAgICB2YWxpZGF0ZUV4cGxpY2l0S2V5KGNoaWxkLCBwYXJlbnRUeXBlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNWYWxpZEVsZW1lbnQobm9kZSkpIHtcbiAgICAgIC8vIFRoaXMgZWxlbWVudCB3YXMgcGFzc2VkIGluIGEgdmFsaWQgbG9jYXRpb24uXG4gICAgICBpZiAobm9kZS5fc3RvcmUpIHtcbiAgICAgICAgbm9kZS5fc3RvcmUudmFsaWRhdGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5vZGUpIHtcbiAgICAgIHZhciBpdGVyYXRvckZuID0gZ2V0SXRlcmF0b3JGbihub2RlKTtcblxuICAgICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIEVudHJ5IGl0ZXJhdG9ycyB1c2VkIHRvIHByb3ZpZGUgaW1wbGljaXQga2V5cyxcbiAgICAgICAgLy8gYnV0IG5vdyB3ZSBwcmludCBhIHNlcGFyYXRlIHdhcm5pbmcgZm9yIHRoZW0gbGF0ZXIuXG4gICAgICAgIGlmIChpdGVyYXRvckZuICE9PSBub2RlLmVudHJpZXMpIHtcbiAgICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwobm9kZSk7XG4gICAgICAgICAgdmFyIHN0ZXA7XG5cbiAgICAgICAgICB3aGlsZSAoIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lKSB7XG4gICAgICAgICAgICBpZiAoaXNWYWxpZEVsZW1lbnQoc3RlcC52YWx1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsaWRhdGVFeHBsaWNpdEtleShzdGVwLnZhbHVlLCBwYXJlbnRUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbi8qKlxuICogR2l2ZW4gYW4gZWxlbWVudCwgdmFsaWRhdGUgdGhhdCBpdHMgcHJvcHMgZm9sbG93IHRoZSBwcm9wVHlwZXMgZGVmaW5pdGlvbixcbiAqIHByb3ZpZGVkIGJ5IHRoZSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBlbGVtZW50XG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BUeXBlcyhlbGVtZW50KSB7XG4gIHtcbiAgICB2YXIgdHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgIGlmICh0eXBlID09PSBudWxsIHx8IHR5cGUgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcHJvcFR5cGVzO1xuXG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9wVHlwZXMgPSB0eXBlLnByb3BUeXBlcztcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiAodHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSB8fCAvLyBOb3RlOiBNZW1vIG9ubHkgY2hlY2tzIG91dGVyIHByb3BzIGhlcmUuXG4gICAgLy8gSW5uZXIgcHJvcHMgYXJlIGNoZWNrZWQgaW4gdGhlIHJlY29uY2lsZXIuXG4gICAgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTUVNT19UWVBFKSkge1xuICAgICAgcHJvcFR5cGVzID0gdHlwZS5wcm9wVHlwZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocHJvcFR5cGVzKSB7XG4gICAgICAvLyBJbnRlbnRpb25hbGx5IGluc2lkZSB0byBhdm9pZCB0cmlnZ2VyaW5nIGxhenkgaW5pdGlhbGl6ZXJzOlxuICAgICAgdmFyIG5hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSk7XG4gICAgICBjaGVja1Byb3BUeXBlcyhwcm9wVHlwZXMsIGVsZW1lbnQucHJvcHMsICdwcm9wJywgbmFtZSwgZWxlbWVudCk7XG4gICAgfSBlbHNlIGlmICh0eXBlLlByb3BUeXBlcyAhPT0gdW5kZWZpbmVkICYmICFwcm9wVHlwZXNNaXNzcGVsbFdhcm5pbmdTaG93bikge1xuICAgICAgcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd24gPSB0cnVlOyAvLyBJbnRlbnRpb25hbGx5IGluc2lkZSB0byBhdm9pZCB0cmlnZ2VyaW5nIGxhenkgaW5pdGlhbGl6ZXJzOlxuXG4gICAgICB2YXIgX25hbWUgPSBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSk7XG5cbiAgICAgIGVycm9yKCdDb21wb25lbnQgJXMgZGVjbGFyZWQgYFByb3BUeXBlc2AgaW5zdGVhZCBvZiBgcHJvcFR5cGVzYC4gRGlkIHlvdSBtaXNzcGVsbCB0aGUgcHJvcGVydHkgYXNzaWdubWVudD8nLCBfbmFtZSB8fCAnVW5rbm93bicpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdHlwZS5nZXREZWZhdWx0UHJvcHMgPT09ICdmdW5jdGlvbicgJiYgIXR5cGUuZ2V0RGVmYXVsdFByb3BzLmlzUmVhY3RDbGFzc0FwcHJvdmVkKSB7XG4gICAgICBlcnJvcignZ2V0RGVmYXVsdFByb3BzIGlzIG9ubHkgdXNlZCBvbiBjbGFzc2ljIFJlYWN0LmNyZWF0ZUNsYXNzICcgKyAnZGVmaW5pdGlvbnMuIFVzZSBhIHN0YXRpYyBwcm9wZXJ0eSBuYW1lZCBgZGVmYXVsdFByb3BzYCBpbnN0ZWFkLicpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBHaXZlbiBhIGZyYWdtZW50LCB2YWxpZGF0ZSB0aGF0IGl0IGNhbiBvbmx5IGJlIHByb3ZpZGVkIHdpdGggZnJhZ21lbnQgcHJvcHNcbiAqIEBwYXJhbSB7UmVhY3RFbGVtZW50fSBmcmFnbWVudFxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVGcmFnbWVudFByb3BzKGZyYWdtZW50KSB7XG4gIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGZyYWdtZW50LnByb3BzKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGtleSA9IGtleXNbaV07XG5cbiAgICAgIGlmIChrZXkgIT09ICdjaGlsZHJlbicgJiYga2V5ICE9PSAna2V5Jykge1xuICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKGZyYWdtZW50KTtcblxuICAgICAgICBlcnJvcignSW52YWxpZCBwcm9wIGAlc2Agc3VwcGxpZWQgdG8gYFJlYWN0LkZyYWdtZW50YC4gJyArICdSZWFjdC5GcmFnbWVudCBjYW4gb25seSBoYXZlIGBrZXlgIGFuZCBgY2hpbGRyZW5gIHByb3BzLicsIGtleSk7XG5cbiAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShudWxsKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZyYWdtZW50LnJlZiAhPT0gbnVsbCkge1xuICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShmcmFnbWVudCk7XG5cbiAgICAgIGVycm9yKCdJbnZhbGlkIGF0dHJpYnV0ZSBgcmVmYCBzdXBwbGllZCB0byBgUmVhY3QuRnJhZ21lbnRgLicpO1xuXG4gICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudCQxKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBqc3hXaXRoVmFsaWRhdGlvbih0eXBlLCBwcm9wcywga2V5LCBpc1N0YXRpY0NoaWxkcmVuLCBzb3VyY2UsIHNlbGYpIHtcbiAge1xuICAgIHZhciB2YWxpZFR5cGUgPSBpc1ZhbGlkRWxlbWVudFR5cGUodHlwZSk7IC8vIFdlIHdhcm4gaW4gdGhpcyBjYXNlIGJ1dCBkb24ndCB0aHJvdy4gV2UgZXhwZWN0IHRoZSBlbGVtZW50IGNyZWF0aW9uIHRvXG4gICAgLy8gc3VjY2VlZCBhbmQgdGhlcmUgd2lsbCBsaWtlbHkgYmUgZXJyb3JzIGluIHJlbmRlci5cblxuICAgIGlmICghdmFsaWRUeXBlKSB7XG4gICAgICB2YXIgaW5mbyA9ICcnO1xuXG4gICAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsICYmIE9iamVjdC5rZXlzKHR5cGUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBpbmZvICs9ICcgWW91IGxpa2VseSBmb3Jnb3QgdG8gZXhwb3J0IHlvdXIgY29tcG9uZW50IGZyb20gdGhlIGZpbGUgJyArIFwiaXQncyBkZWZpbmVkIGluLCBvciB5b3UgbWlnaHQgaGF2ZSBtaXhlZCB1cCBkZWZhdWx0IGFuZCBuYW1lZCBpbXBvcnRzLlwiO1xuICAgICAgfVxuXG4gICAgICB2YXIgc291cmNlSW5mbyA9IGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtKHNvdXJjZSk7XG5cbiAgICAgIGlmIChzb3VyY2VJbmZvKSB7XG4gICAgICAgIGluZm8gKz0gc291cmNlSW5mbztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZm8gKz0gZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCk7XG4gICAgICB9XG5cbiAgICAgIHZhciB0eXBlU3RyaW5nO1xuXG4gICAgICBpZiAodHlwZSA9PT0gbnVsbCkge1xuICAgICAgICB0eXBlU3RyaW5nID0gJ251bGwnO1xuICAgICAgfSBlbHNlIGlmIChpc0FycmF5KHR5cGUpKSB7XG4gICAgICAgIHR5cGVTdHJpbmcgPSAnYXJyYXknO1xuICAgICAgfSBlbHNlIGlmICh0eXBlICE9PSB1bmRlZmluZWQgJiYgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRUxFTUVOVF9UWVBFKSB7XG4gICAgICAgIHR5cGVTdHJpbmcgPSBcIjxcIiArIChnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZS50eXBlKSB8fCAnVW5rbm93bicpICsgXCIgLz5cIjtcbiAgICAgICAgaW5mbyA9ICcgRGlkIHlvdSBhY2NpZGVudGFsbHkgZXhwb3J0IGEgSlNYIGxpdGVyYWwgaW5zdGVhZCBvZiBhIGNvbXBvbmVudD8nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZVN0cmluZyA9IHR5cGVvZiB0eXBlO1xuICAgICAgfVxuXG4gICAgICBlcnJvcignUmVhY3QuanN4OiB0eXBlIGlzIGludmFsaWQgLS0gZXhwZWN0ZWQgYSBzdHJpbmcgKGZvciAnICsgJ2J1aWx0LWluIGNvbXBvbmVudHMpIG9yIGEgY2xhc3MvZnVuY3Rpb24gKGZvciBjb21wb3NpdGUgJyArICdjb21wb25lbnRzKSBidXQgZ290OiAlcy4lcycsIHR5cGVTdHJpbmcsIGluZm8pO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50ID0ganN4REVWKHR5cGUsIHByb3BzLCBrZXksIHNvdXJjZSwgc2VsZik7IC8vIFRoZSByZXN1bHQgY2FuIGJlIG51bGxpc2ggaWYgYSBtb2NrIG9yIGEgY3VzdG9tIGZ1bmN0aW9uIGlzIHVzZWQuXG4gICAgLy8gVE9ETzogRHJvcCB0aGlzIHdoZW4gdGhlc2UgYXJlIG5vIGxvbmdlciBhbGxvd2VkIGFzIHRoZSB0eXBlIGFyZ3VtZW50LlxuXG4gICAgaWYgKGVsZW1lbnQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfSAvLyBTa2lwIGtleSB3YXJuaW5nIGlmIHRoZSB0eXBlIGlzbid0IHZhbGlkIHNpbmNlIG91ciBrZXkgdmFsaWRhdGlvbiBsb2dpY1xuICAgIC8vIGRvZXNuJ3QgZXhwZWN0IGEgbm9uLXN0cmluZy9mdW5jdGlvbiB0eXBlIGFuZCBjYW4gdGhyb3cgY29uZnVzaW5nIGVycm9ycy5cbiAgICAvLyBXZSBkb24ndCB3YW50IGV4Y2VwdGlvbiBiZWhhdmlvciB0byBkaWZmZXIgYmV0d2VlbiBkZXYgYW5kIHByb2QuXG4gICAgLy8gKFJlbmRlcmluZyB3aWxsIHRocm93IHdpdGggYSBoZWxwZnVsIG1lc3NhZ2UgYW5kIGFzIHNvb24gYXMgdGhlIHR5cGUgaXNcbiAgICAvLyBmaXhlZCwgdGhlIGtleSB3YXJuaW5ncyB3aWxsIGFwcGVhci4pXG5cblxuICAgIGlmICh2YWxpZFR5cGUpIHtcbiAgICAgIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuO1xuXG4gICAgICBpZiAoY2hpbGRyZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoaXNTdGF0aWNDaGlsZHJlbikge1xuICAgICAgICAgIGlmIChpc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICB2YWxpZGF0ZUNoaWxkS2V5cyhjaGlsZHJlbltpXSwgdHlwZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChPYmplY3QuZnJlZXplKSB7XG4gICAgICAgICAgICAgIE9iamVjdC5mcmVlemUoY2hpbGRyZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnJvcignUmVhY3QuanN4OiBTdGF0aWMgY2hpbGRyZW4gc2hvdWxkIGFsd2F5cyBiZSBhbiBhcnJheS4gJyArICdZb3UgYXJlIGxpa2VseSBleHBsaWNpdGx5IGNhbGxpbmcgUmVhY3QuanN4cyBvciBSZWFjdC5qc3hERVYuICcgKyAnVXNlIHRoZSBCYWJlbCB0cmFuc2Zvcm0gaW5zdGVhZC4nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsaWRhdGVDaGlsZEtleXMoY2hpbGRyZW4sIHR5cGUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUpIHtcbiAgICAgIHZhbGlkYXRlRnJhZ21lbnRQcm9wcyhlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsaWRhdGVQcm9wVHlwZXMoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cbn0gLy8gVGhlc2UgdHdvIGZ1bmN0aW9ucyBleGlzdCB0byBzdGlsbCBnZXQgY2hpbGQgd2FybmluZ3MgaW4gZGV2XG5cbnZhciBqc3hERVYkMSA9ICBqc3hXaXRoVmFsaWRhdGlvbiA7XG5cbmV4cG9ydHMuRnJhZ21lbnQgPSBSRUFDVF9GUkFHTUVOVF9UWVBFO1xuZXhwb3J0cy5qc3hERVYgPSBqc3hERVYkMTtcbiAgfSkoKTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC5kZXZlbG9wbWVudC5qcycpO1xufVxuIiwiLyoqXG4gKiBAbGljZW5zZSBSZWFjdFxuICogcmVhY3QuZGV2ZWxvcG1lbnQuanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJwcm9kdWN0aW9uXCIpIHtcbiAgKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgICAgJ3VzZSBzdHJpY3QnO1xuXG4vKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0YXJ0ID09PVxuICAgICdmdW5jdGlvbidcbikge1xuICBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0YXJ0KG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgICB2YXIgUmVhY3RWZXJzaW9uID0gJzE4LjIuMCc7XG5cbi8vIEFUVEVOVElPTlxuLy8gV2hlbiBhZGRpbmcgbmV3IHN5bWJvbHMgdG8gdGhpcyBmaWxlLFxuLy8gUGxlYXNlIGNvbnNpZGVyIGFsc28gYWRkaW5nIHRvICdyZWFjdC1kZXZ0b29scy1zaGFyZWQvc3JjL2JhY2tlbmQvUmVhY3RTeW1ib2xzJ1xuLy8gVGhlIFN5bWJvbCB1c2VkIHRvIHRhZyB0aGUgUmVhY3RFbGVtZW50LWxpa2UgdHlwZXMuXG52YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpO1xudmFyIFJFQUNUX1BPUlRBTF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QucG9ydGFsJyk7XG52YXIgUkVBQ1RfRlJBR01FTlRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmZyYWdtZW50Jyk7XG52YXIgUkVBQ1RfU1RSSUNUX01PREVfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN0cmljdF9tb2RlJyk7XG52YXIgUkVBQ1RfUFJPRklMRVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb2ZpbGVyJyk7XG52YXIgUkVBQ1RfUFJPVklERVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb3ZpZGVyJyk7XG52YXIgUkVBQ1RfQ09OVEVYVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuY29udGV4dCcpO1xudmFyIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5mb3J3YXJkX3JlZicpO1xudmFyIFJFQUNUX1NVU1BFTlNFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZScpO1xudmFyIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN1c3BlbnNlX2xpc3QnKTtcbnZhciBSRUFDVF9NRU1PX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5tZW1vJyk7XG52YXIgUkVBQ1RfTEFaWV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubGF6eScpO1xudmFyIFJFQUNUX09GRlNDUkVFTl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3Qub2Zmc2NyZWVuJyk7XG52YXIgTUFZQkVfSVRFUkFUT1JfU1lNQk9MID0gU3ltYm9sLml0ZXJhdG9yO1xudmFyIEZBVVhfSVRFUkFUT1JfU1lNQk9MID0gJ0BAaXRlcmF0b3InO1xuZnVuY3Rpb24gZ2V0SXRlcmF0b3JGbihtYXliZUl0ZXJhYmxlKSB7XG4gIGlmIChtYXliZUl0ZXJhYmxlID09PSBudWxsIHx8IHR5cGVvZiBtYXliZUl0ZXJhYmxlICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIG1heWJlSXRlcmF0b3IgPSBNQVlCRV9JVEVSQVRPUl9TWU1CT0wgJiYgbWF5YmVJdGVyYWJsZVtNQVlCRV9JVEVSQVRPUl9TWU1CT0xdIHx8IG1heWJlSXRlcmFibGVbRkFVWF9JVEVSQVRPUl9TWU1CT0xdO1xuXG4gIGlmICh0eXBlb2YgbWF5YmVJdGVyYXRvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBtYXliZUl0ZXJhdG9yO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgZGlzcGF0Y2hlci5cbiAqL1xudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIgPSB7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHR5cGUge1JlYWN0Q29tcG9uZW50fVxuICAgKi9cbiAgY3VycmVudDogbnVsbFxufTtcblxuLyoqXG4gKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBiYXRjaCdzIGNvbmZpZ3VyYXRpb24gc3VjaCBhcyBob3cgbG9uZyBhbiB1cGRhdGVcbiAqIHNob3VsZCBzdXNwZW5kIGZvciBpZiBpdCBuZWVkcyB0by5cbiAqL1xudmFyIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnID0ge1xuICB0cmFuc2l0aW9uOiBudWxsXG59O1xuXG52YXIgUmVhY3RDdXJyZW50QWN0UXVldWUgPSB7XG4gIGN1cnJlbnQ6IG51bGwsXG4gIC8vIFVzZWQgdG8gcmVwcm9kdWNlIGJlaGF2aW9yIG9mIGBiYXRjaGVkVXBkYXRlc2AgaW4gbGVnYWN5IG1vZGUuXG4gIGlzQmF0Y2hpbmdMZWdhY3k6IGZhbHNlLFxuICBkaWRTY2hlZHVsZUxlZ2FjeVVwZGF0ZTogZmFsc2Vcbn07XG5cbi8qKlxuICogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgb3duZXIuXG4gKlxuICogVGhlIGN1cnJlbnQgb3duZXIgaXMgdGhlIGNvbXBvbmVudCB3aG8gc2hvdWxkIG93biBhbnkgY29tcG9uZW50cyB0aGF0IGFyZVxuICogY3VycmVudGx5IGJlaW5nIGNvbnN0cnVjdGVkLlxuICovXG52YXIgUmVhY3RDdXJyZW50T3duZXIgPSB7XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICogQHR5cGUge1JlYWN0Q29tcG9uZW50fVxuICAgKi9cbiAgY3VycmVudDogbnVsbFxufTtcblxudmFyIFJlYWN0RGVidWdDdXJyZW50RnJhbWUgPSB7fTtcbnZhciBjdXJyZW50RXh0cmFTdGFja0ZyYW1lID0gbnVsbDtcbmZ1bmN0aW9uIHNldEV4dHJhU3RhY2tGcmFtZShzdGFjaykge1xuICB7XG4gICAgY3VycmVudEV4dHJhU3RhY2tGcmFtZSA9IHN0YWNrO1xuICB9XG59XG5cbntcbiAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5zZXRFeHRyYVN0YWNrRnJhbWUgPSBmdW5jdGlvbiAoc3RhY2spIHtcbiAgICB7XG4gICAgICBjdXJyZW50RXh0cmFTdGFja0ZyYW1lID0gc3RhY2s7XG4gICAgfVxuICB9OyAvLyBTdGFjayBpbXBsZW1lbnRhdGlvbiBpbmplY3RlZCBieSB0aGUgY3VycmVudCByZW5kZXJlci5cblxuXG4gIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0Q3VycmVudFN0YWNrID0gbnVsbDtcblxuICBSZWFjdERlYnVnQ3VycmVudEZyYW1lLmdldFN0YWNrQWRkZW5kdW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YWNrID0gJyc7IC8vIEFkZCBhbiBleHRyYSB0b3AgZnJhbWUgd2hpbGUgYW4gZWxlbWVudCBpcyBiZWluZyB2YWxpZGF0ZWRcblxuICAgIGlmIChjdXJyZW50RXh0cmFTdGFja0ZyYW1lKSB7XG4gICAgICBzdGFjayArPSBjdXJyZW50RXh0cmFTdGFja0ZyYW1lO1xuICAgIH0gLy8gRGVsZWdhdGUgdG8gdGhlIGluamVjdGVkIHJlbmRlcmVyLXNwZWNpZmljIGltcGxlbWVudGF0aW9uXG5cblxuICAgIHZhciBpbXBsID0gUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRDdXJyZW50U3RhY2s7XG5cbiAgICBpZiAoaW1wbCkge1xuICAgICAgc3RhY2sgKz0gaW1wbCgpIHx8ICcnO1xuICAgIH1cblxuICAgIHJldHVybiBzdGFjaztcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIGVuYWJsZVNjb3BlQVBJID0gZmFsc2U7IC8vIEV4cGVyaW1lbnRhbCBDcmVhdGUgRXZlbnQgSGFuZGxlIEFQSS5cbnZhciBlbmFibGVDYWNoZUVsZW1lbnQgPSBmYWxzZTtcbnZhciBlbmFibGVUcmFuc2l0aW9uVHJhY2luZyA9IGZhbHNlOyAvLyBObyBrbm93biBidWdzLCBidXQgbmVlZHMgcGVyZm9ybWFuY2UgdGVzdGluZ1xuXG52YXIgZW5hYmxlTGVnYWN5SGlkZGVuID0gZmFsc2U7IC8vIEVuYWJsZXMgdW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgZmVhdHVyZSBpbiBGaWJlclxuLy8gc3R1ZmYuIEludGVuZGVkIHRvIGVuYWJsZSBSZWFjdCBjb3JlIG1lbWJlcnMgdG8gbW9yZSBlYXNpbHkgZGVidWcgc2NoZWR1bGluZ1xuLy8gaXNzdWVzIGluIERFViBidWlsZHMuXG5cbnZhciBlbmFibGVEZWJ1Z1RyYWNpbmcgPSBmYWxzZTsgLy8gVHJhY2sgd2hpY2ggRmliZXIocykgc2NoZWR1bGUgcmVuZGVyIHdvcmsuXG5cbnZhciBSZWFjdFNoYXJlZEludGVybmFscyA9IHtcbiAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlcjogUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixcbiAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWc6IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFxuICBSZWFjdEN1cnJlbnRPd25lcjogUmVhY3RDdXJyZW50T3duZXJcbn07XG5cbntcbiAgUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG4gIFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEFjdFF1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWU7XG59XG5cbi8vIGJ5IGNhbGxzIHRvIHRoZXNlIG1ldGhvZHMgYnkgYSBCYWJlbCBwbHVnaW4uXG4vL1xuLy8gSW4gUFJPRCAob3IgaW4gcGFja2FnZXMgd2l0aG91dCBhY2Nlc3MgdG8gUmVhY3QgaW50ZXJuYWxzKSxcbi8vIHRoZXkgYXJlIGxlZnQgYXMgdGhleSBhcmUgaW5zdGVhZC5cblxuZnVuY3Rpb24gd2Fybihmb3JtYXQpIHtcbiAge1xuICAgIHtcbiAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnd2FybicsIGZvcm1hdCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBlcnJvcihmb3JtYXQpIHtcbiAge1xuICAgIHtcbiAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiA+IDEgPyBfbGVuMiAtIDEgOiAwKSwgX2tleTIgPSAxOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgIGFyZ3NbX2tleTIgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnZXJyb3InLCBmb3JtYXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcmludFdhcm5pbmcobGV2ZWwsIGZvcm1hdCwgYXJncykge1xuICAvLyBXaGVuIGNoYW5naW5nIHRoaXMgbG9naWMsIHlvdSBtaWdodCB3YW50IHRvIGFsc29cbiAgLy8gdXBkYXRlIGNvbnNvbGVXaXRoU3RhY2tEZXYud3d3LmpzIGFzIHdlbGwuXG4gIHtcbiAgICB2YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG4gICAgdmFyIHN0YWNrID0gUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRTdGFja0FkZGVuZHVtKCk7XG5cbiAgICBpZiAoc3RhY2sgIT09ICcnKSB7XG4gICAgICBmb3JtYXQgKz0gJyVzJztcbiAgICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbc3RhY2tdKTtcbiAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuXG5cbiAgICB2YXIgYXJnc1dpdGhGb3JtYXQgPSBhcmdzLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIFN0cmluZyhpdGVtKTtcbiAgICB9KTsgLy8gQ2FyZWZ1bDogUk4gY3VycmVudGx5IGRlcGVuZHMgb24gdGhpcyBwcmVmaXhcblxuICAgIGFyZ3NXaXRoRm9ybWF0LnVuc2hpZnQoJ1dhcm5pbmc6ICcgKyBmb3JtYXQpOyAvLyBXZSBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBzcHJlYWQgKG9yIC5hcHBseSkgZGlyZWN0bHkgYmVjYXVzZSBpdFxuICAgIC8vIGJyZWFrcyBJRTk6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTM2MTBcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG5cbiAgICBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbChjb25zb2xlW2xldmVsXSwgY29uc29sZSwgYXJnc1dpdGhGb3JtYXQpO1xuICB9XG59XG5cbnZhciBkaWRXYXJuU3RhdGVVcGRhdGVGb3JVbm1vdW50ZWRDb21wb25lbnQgPSB7fTtcblxuZnVuY3Rpb24gd2Fybk5vb3AocHVibGljSW5zdGFuY2UsIGNhbGxlck5hbWUpIHtcbiAge1xuICAgIHZhciBfY29uc3RydWN0b3IgPSBwdWJsaWNJbnN0YW5jZS5jb25zdHJ1Y3RvcjtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IF9jb25zdHJ1Y3RvciAmJiAoX2NvbnN0cnVjdG9yLmRpc3BsYXlOYW1lIHx8IF9jb25zdHJ1Y3Rvci5uYW1lKSB8fCAnUmVhY3RDbGFzcyc7XG4gICAgdmFyIHdhcm5pbmdLZXkgPSBjb21wb25lbnROYW1lICsgXCIuXCIgKyBjYWxsZXJOYW1lO1xuXG4gICAgaWYgKGRpZFdhcm5TdGF0ZVVwZGF0ZUZvclVubW91bnRlZENvbXBvbmVudFt3YXJuaW5nS2V5XSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVycm9yKFwiQ2FuJ3QgY2FsbCAlcyBvbiBhIGNvbXBvbmVudCB0aGF0IGlzIG5vdCB5ZXQgbW91bnRlZC4gXCIgKyAnVGhpcyBpcyBhIG5vLW9wLCBidXQgaXQgbWlnaHQgaW5kaWNhdGUgYSBidWcgaW4geW91ciBhcHBsaWNhdGlvbi4gJyArICdJbnN0ZWFkLCBhc3NpZ24gdG8gYHRoaXMuc3RhdGVgIGRpcmVjdGx5IG9yIGRlZmluZSBhIGBzdGF0ZSA9IHt9O2AgJyArICdjbGFzcyBwcm9wZXJ0eSB3aXRoIHRoZSBkZXNpcmVkIHN0YXRlIGluIHRoZSAlcyBjb21wb25lbnQuJywgY2FsbGVyTmFtZSwgY29tcG9uZW50TmFtZSk7XG5cbiAgICBkaWRXYXJuU3RhdGVVcGRhdGVGb3JVbm1vdW50ZWRDb21wb25lbnRbd2FybmluZ0tleV0gPSB0cnVlO1xuICB9XG59XG4vKipcbiAqIFRoaXMgaXMgdGhlIGFic3RyYWN0IEFQSSBmb3IgYW4gdXBkYXRlIHF1ZXVlLlxuICovXG5cblxudmFyIFJlYWN0Tm9vcFVwZGF0ZVF1ZXVlID0ge1xuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgb3Igbm90IHRoaXMgY29tcG9zaXRlIGNvbXBvbmVudCBpcyBtb3VudGVkLlxuICAgKiBAcGFyYW0ge1JlYWN0Q2xhc3N9IHB1YmxpY0luc3RhbmNlIFRoZSBpbnN0YW5jZSB3ZSB3YW50IHRvIHRlc3QuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgbW91bnRlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBmaW5hbFxuICAgKi9cbiAgaXNNb3VudGVkOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEZvcmNlcyBhbiB1cGRhdGUuIFRoaXMgc2hvdWxkIG9ubHkgYmUgaW52b2tlZCB3aGVuIGl0IGlzIGtub3duIHdpdGhcbiAgICogY2VydGFpbnR5IHRoYXQgd2UgYXJlICoqbm90KiogaW4gYSBET00gdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIFlvdSBtYXkgd2FudCB0byBjYWxsIHRoaXMgd2hlbiB5b3Uga25vdyB0aGF0IHNvbWUgZGVlcGVyIGFzcGVjdCBvZiB0aGVcbiAgICogY29tcG9uZW50J3Mgc3RhdGUgaGFzIGNoYW5nZWQgYnV0IGBzZXRTdGF0ZWAgd2FzIG5vdCBjYWxsZWQuXG4gICAqXG4gICAqIFRoaXMgd2lsbCBub3QgaW52b2tlIGBzaG91bGRDb21wb25lbnRVcGRhdGVgLCBidXQgaXQgd2lsbCBpbnZva2VcbiAgICogYGNvbXBvbmVudFdpbGxVcGRhdGVgIGFuZCBgY29tcG9uZW50RGlkVXBkYXRlYC5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7P2Z1bmN0aW9ufSBjYWxsYmFjayBDYWxsZWQgYWZ0ZXIgY29tcG9uZW50IGlzIHVwZGF0ZWQuXG4gICAqIEBwYXJhbSB7P3N0cmluZ30gY2FsbGVyTmFtZSBuYW1lIG9mIHRoZSBjYWxsaW5nIGZ1bmN0aW9uIGluIHRoZSBwdWJsaWMgQVBJLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGVucXVldWVGb3JjZVVwZGF0ZTogZnVuY3Rpb24gKHB1YmxpY0luc3RhbmNlLCBjYWxsYmFjaywgY2FsbGVyTmFtZSkge1xuICAgIHdhcm5Ob29wKHB1YmxpY0luc3RhbmNlLCAnZm9yY2VVcGRhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIG9mIHRoZSBzdGF0ZS4gQWx3YXlzIHVzZSB0aGlzIG9yIGBzZXRTdGF0ZWAgdG8gbXV0YXRlIHN0YXRlLlxuICAgKiBZb3Ugc2hvdWxkIHRyZWF0IGB0aGlzLnN0YXRlYCBhcyBpbW11dGFibGUuXG4gICAqXG4gICAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGB0aGlzLnN0YXRlYCB3aWxsIGJlIGltbWVkaWF0ZWx5IHVwZGF0ZWQsIHNvXG4gICAqIGFjY2Vzc2luZyBgdGhpcy5zdGF0ZWAgYWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCBtYXkgcmV0dXJuIHRoZSBvbGQgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVhY3RDbGFzc30gcHVibGljSW5zdGFuY2UgVGhlIGluc3RhbmNlIHRoYXQgc2hvdWxkIHJlcmVuZGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gY29tcGxldGVTdGF0ZSBOZXh0IHN0YXRlLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIGNvbXBvbmVudCBpcyB1cGRhdGVkLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNhbGxlck5hbWUgbmFtZSBvZiB0aGUgY2FsbGluZyBmdW5jdGlvbiBpbiB0aGUgcHVibGljIEFQSS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBlbnF1ZXVlUmVwbGFjZVN0YXRlOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UsIGNvbXBsZXRlU3RhdGUsIGNhbGxiYWNrLCBjYWxsZXJOYW1lKSB7XG4gICAgd2Fybk5vb3AocHVibGljSW5zdGFuY2UsICdyZXBsYWNlU3RhdGUnKTtcbiAgfSxcblxuICAvKipcbiAgICogU2V0cyBhIHN1YnNldCBvZiB0aGUgc3RhdGUuIFRoaXMgb25seSBleGlzdHMgYmVjYXVzZSBfcGVuZGluZ1N0YXRlIGlzXG4gICAqIGludGVybmFsLiBUaGlzIHByb3ZpZGVzIGEgbWVyZ2luZyBzdHJhdGVneSB0aGF0IGlzIG5vdCBhdmFpbGFibGUgdG8gZGVlcFxuICAgKiBwcm9wZXJ0aWVzIHdoaWNoIGlzIGNvbmZ1c2luZy4gVE9ETzogRXhwb3NlIHBlbmRpbmdTdGF0ZSBvciBkb24ndCB1c2UgaXRcbiAgICogZHVyaW5nIHRoZSBtZXJnZS5cbiAgICpcbiAgICogQHBhcmFtIHtSZWFjdENsYXNzfSBwdWJsaWNJbnN0YW5jZSBUaGUgaW5zdGFuY2UgdGhhdCBzaG91bGQgcmVyZW5kZXIuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBwYXJ0aWFsU3RhdGUgTmV4dCBwYXJ0aWFsIHN0YXRlIHRvIGJlIG1lcmdlZCB3aXRoIHN0YXRlLlxuICAgKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIGNvbXBvbmVudCBpcyB1cGRhdGVkLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IE5hbWUgb2YgdGhlIGNhbGxpbmcgZnVuY3Rpb24gaW4gdGhlIHB1YmxpYyBBUEkuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgZW5xdWV1ZVNldFN0YXRlOiBmdW5jdGlvbiAocHVibGljSW5zdGFuY2UsIHBhcnRpYWxTdGF0ZSwgY2FsbGJhY2ssIGNhbGxlck5hbWUpIHtcbiAgICB3YXJuTm9vcChwdWJsaWNJbnN0YW5jZSwgJ3NldFN0YXRlJyk7XG4gIH1cbn07XG5cbnZhciBhc3NpZ24gPSBPYmplY3QuYXNzaWduO1xuXG52YXIgZW1wdHlPYmplY3QgPSB7fTtcblxue1xuICBPYmplY3QuZnJlZXplKGVtcHR5T2JqZWN0KTtcbn1cbi8qKlxuICogQmFzZSBjbGFzcyBoZWxwZXJzIGZvciB0aGUgdXBkYXRpbmcgc3RhdGUgb2YgYSBjb21wb25lbnQuXG4gKi9cblxuXG5mdW5jdGlvbiBDb21wb25lbnQocHJvcHMsIGNvbnRleHQsIHVwZGF0ZXIpIHtcbiAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0OyAvLyBJZiBhIGNvbXBvbmVudCBoYXMgc3RyaW5nIHJlZnMsIHdlIHdpbGwgYXNzaWduIGEgZGlmZmVyZW50IG9iamVjdCBsYXRlci5cblxuICB0aGlzLnJlZnMgPSBlbXB0eU9iamVjdDsgLy8gV2UgaW5pdGlhbGl6ZSB0aGUgZGVmYXVsdCB1cGRhdGVyIGJ1dCB0aGUgcmVhbCBvbmUgZ2V0cyBpbmplY3RlZCBieSB0aGVcbiAgLy8gcmVuZGVyZXIuXG5cbiAgdGhpcy51cGRhdGVyID0gdXBkYXRlciB8fCBSZWFjdE5vb3BVcGRhdGVRdWV1ZTtcbn1cblxuQ29tcG9uZW50LnByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50ID0ge307XG4vKipcbiAqIFNldHMgYSBzdWJzZXQgb2YgdGhlIHN0YXRlLiBBbHdheXMgdXNlIHRoaXMgdG8gbXV0YXRlXG4gKiBzdGF0ZS4gWW91IHNob3VsZCB0cmVhdCBgdGhpcy5zdGF0ZWAgYXMgaW1tdXRhYmxlLlxuICpcbiAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGB0aGlzLnN0YXRlYCB3aWxsIGJlIGltbWVkaWF0ZWx5IHVwZGF0ZWQsIHNvXG4gKiBhY2Nlc3NpbmcgYHRoaXMuc3RhdGVgIGFmdGVyIGNhbGxpbmcgdGhpcyBtZXRob2QgbWF5IHJldHVybiB0aGUgb2xkIHZhbHVlLlxuICpcbiAqIFRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IGNhbGxzIHRvIGBzZXRTdGF0ZWAgd2lsbCBydW4gc3luY2hyb25vdXNseSxcbiAqIGFzIHRoZXkgbWF5IGV2ZW50dWFsbHkgYmUgYmF0Y2hlZCB0b2dldGhlci4gIFlvdSBjYW4gcHJvdmlkZSBhbiBvcHRpb25hbFxuICogY2FsbGJhY2sgdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIHdoZW4gdGhlIGNhbGwgdG8gc2V0U3RhdGUgaXMgYWN0dWFsbHlcbiAqIGNvbXBsZXRlZC5cbiAqXG4gKiBXaGVuIGEgZnVuY3Rpb24gaXMgcHJvdmlkZWQgdG8gc2V0U3RhdGUsIGl0IHdpbGwgYmUgY2FsbGVkIGF0IHNvbWUgcG9pbnQgaW5cbiAqIHRoZSBmdXR1cmUgKG5vdCBzeW5jaHJvbm91c2x5KS4gSXQgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgdXAgdG8gZGF0ZVxuICogY29tcG9uZW50IGFyZ3VtZW50cyAoc3RhdGUsIHByb3BzLCBjb250ZXh0KS4gVGhlc2UgdmFsdWVzIGNhbiBiZSBkaWZmZXJlbnRcbiAqIGZyb20gdGhpcy4qIGJlY2F1c2UgeW91ciBmdW5jdGlvbiBtYXkgYmUgY2FsbGVkIGFmdGVyIHJlY2VpdmVQcm9wcyBidXQgYmVmb3JlXG4gKiBzaG91bGRDb21wb25lbnRVcGRhdGUsIGFuZCB0aGlzIG5ldyBzdGF0ZSwgcHJvcHMsIGFuZCBjb250ZXh0IHdpbGwgbm90IHlldCBiZVxuICogYXNzaWduZWQgdG8gdGhpcy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdHxmdW5jdGlvbn0gcGFydGlhbFN0YXRlIE5leHQgcGFydGlhbCBzdGF0ZSBvciBmdW5jdGlvbiB0b1xuICogICAgICAgIHByb2R1Y2UgbmV4dCBwYXJ0aWFsIHN0YXRlIHRvIGJlIG1lcmdlZCB3aXRoIGN1cnJlbnQgc3RhdGUuXG4gKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIHN0YXRlIGlzIHVwZGF0ZWQuXG4gKiBAZmluYWxcbiAqIEBwcm90ZWN0ZWRcbiAqL1xuXG5Db21wb25lbnQucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKHBhcnRpYWxTdGF0ZSwgY2FsbGJhY2spIHtcbiAgaWYgKHR5cGVvZiBwYXJ0aWFsU3RhdGUgIT09ICdvYmplY3QnICYmIHR5cGVvZiBwYXJ0aWFsU3RhdGUgIT09ICdmdW5jdGlvbicgJiYgcGFydGlhbFN0YXRlICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFN0YXRlKC4uLik6IHRha2VzIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMgdG8gdXBkYXRlIG9yIGEgJyArICdmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMuJyk7XG4gIH1cblxuICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZVNldFN0YXRlKHRoaXMsIHBhcnRpYWxTdGF0ZSwgY2FsbGJhY2ssICdzZXRTdGF0ZScpO1xufTtcbi8qKlxuICogRm9yY2VzIGFuIHVwZGF0ZS4gVGhpcyBzaG91bGQgb25seSBiZSBpbnZva2VkIHdoZW4gaXQgaXMga25vd24gd2l0aFxuICogY2VydGFpbnR5IHRoYXQgd2UgYXJlICoqbm90KiogaW4gYSBET00gdHJhbnNhY3Rpb24uXG4gKlxuICogWW91IG1heSB3YW50IHRvIGNhbGwgdGhpcyB3aGVuIHlvdSBrbm93IHRoYXQgc29tZSBkZWVwZXIgYXNwZWN0IG9mIHRoZVxuICogY29tcG9uZW50J3Mgc3RhdGUgaGFzIGNoYW5nZWQgYnV0IGBzZXRTdGF0ZWAgd2FzIG5vdCBjYWxsZWQuXG4gKlxuICogVGhpcyB3aWxsIG5vdCBpbnZva2UgYHNob3VsZENvbXBvbmVudFVwZGF0ZWAsIGJ1dCBpdCB3aWxsIGludm9rZVxuICogYGNvbXBvbmVudFdpbGxVcGRhdGVgIGFuZCBgY29tcG9uZW50RGlkVXBkYXRlYC5cbiAqXG4gKiBAcGFyYW0gez9mdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIGFmdGVyIHVwZGF0ZSBpcyBjb21wbGV0ZS5cbiAqIEBmaW5hbFxuICogQHByb3RlY3RlZFxuICovXG5cblxuQ29tcG9uZW50LnByb3RvdHlwZS5mb3JjZVVwZGF0ZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB0aGlzLnVwZGF0ZXIuZW5xdWV1ZUZvcmNlVXBkYXRlKHRoaXMsIGNhbGxiYWNrLCAnZm9yY2VVcGRhdGUnKTtcbn07XG4vKipcbiAqIERlcHJlY2F0ZWQgQVBJcy4gVGhlc2UgQVBJcyB1c2VkIHRvIGV4aXN0IG9uIGNsYXNzaWMgUmVhY3QgY2xhc3NlcyBidXQgc2luY2VcbiAqIHdlIHdvdWxkIGxpa2UgdG8gZGVwcmVjYXRlIHRoZW0sIHdlJ3JlIG5vdCBnb2luZyB0byBtb3ZlIHRoZW0gb3ZlciB0byB0aGlzXG4gKiBtb2Rlcm4gYmFzZSBjbGFzcy4gSW5zdGVhZCwgd2UgZGVmaW5lIGEgZ2V0dGVyIHRoYXQgd2FybnMgaWYgaXQncyBhY2Nlc3NlZC5cbiAqL1xuXG5cbntcbiAgdmFyIGRlcHJlY2F0ZWRBUElzID0ge1xuICAgIGlzTW91bnRlZDogWydpc01vdW50ZWQnLCAnSW5zdGVhZCwgbWFrZSBzdXJlIHRvIGNsZWFuIHVwIHN1YnNjcmlwdGlvbnMgYW5kIHBlbmRpbmcgcmVxdWVzdHMgaW4gJyArICdjb21wb25lbnRXaWxsVW5tb3VudCB0byBwcmV2ZW50IG1lbW9yeSBsZWFrcy4nXSxcbiAgICByZXBsYWNlU3RhdGU6IFsncmVwbGFjZVN0YXRlJywgJ1JlZmFjdG9yIHlvdXIgY29kZSB0byB1c2Ugc2V0U3RhdGUgaW5zdGVhZCAoc2VlICcgKyAnaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8zMjM2KS4nXVxuICB9O1xuXG4gIHZhciBkZWZpbmVEZXByZWNhdGlvbldhcm5pbmcgPSBmdW5jdGlvbiAobWV0aG9kTmFtZSwgaW5mbykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb21wb25lbnQucHJvdG90eXBlLCBtZXRob2ROYW1lLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FybignJXMoLi4uKSBpcyBkZXByZWNhdGVkIGluIHBsYWluIEphdmFTY3JpcHQgUmVhY3QgY2xhc3Nlcy4gJXMnLCBpbmZvWzBdLCBpbmZvWzFdKTtcblxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGZvciAodmFyIGZuTmFtZSBpbiBkZXByZWNhdGVkQVBJcykge1xuICAgIGlmIChkZXByZWNhdGVkQVBJcy5oYXNPd25Qcm9wZXJ0eShmbk5hbWUpKSB7XG4gICAgICBkZWZpbmVEZXByZWNhdGlvbldhcm5pbmcoZm5OYW1lLCBkZXByZWNhdGVkQVBJc1tmbk5hbWVdKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gQ29tcG9uZW50RHVtbXkoKSB7fVxuXG5Db21wb25lbnREdW1teS5wcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuLyoqXG4gKiBDb252ZW5pZW5jZSBjb21wb25lbnQgd2l0aCBkZWZhdWx0IHNoYWxsb3cgZXF1YWxpdHkgY2hlY2sgZm9yIHNDVS5cbiAqL1xuXG5mdW5jdGlvbiBQdXJlQ29tcG9uZW50KHByb3BzLCBjb250ZXh0LCB1cGRhdGVyKSB7XG4gIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dDsgLy8gSWYgYSBjb21wb25lbnQgaGFzIHN0cmluZyByZWZzLCB3ZSB3aWxsIGFzc2lnbiBhIGRpZmZlcmVudCBvYmplY3QgbGF0ZXIuXG5cbiAgdGhpcy5yZWZzID0gZW1wdHlPYmplY3Q7XG4gIHRoaXMudXBkYXRlciA9IHVwZGF0ZXIgfHwgUmVhY3ROb29wVXBkYXRlUXVldWU7XG59XG5cbnZhciBwdXJlQ29tcG9uZW50UHJvdG90eXBlID0gUHVyZUNvbXBvbmVudC5wcm90b3R5cGUgPSBuZXcgQ29tcG9uZW50RHVtbXkoKTtcbnB1cmVDb21wb25lbnRQcm90b3R5cGUuY29uc3RydWN0b3IgPSBQdXJlQ29tcG9uZW50OyAvLyBBdm9pZCBhbiBleHRyYSBwcm90b3R5cGUganVtcCBmb3IgdGhlc2UgbWV0aG9kcy5cblxuYXNzaWduKHB1cmVDb21wb25lbnRQcm90b3R5cGUsIENvbXBvbmVudC5wcm90b3R5cGUpO1xucHVyZUNvbXBvbmVudFByb3RvdHlwZS5pc1B1cmVSZWFjdENvbXBvbmVudCA9IHRydWU7XG5cbi8vIGFuIGltbXV0YWJsZSBvYmplY3Qgd2l0aCBhIHNpbmdsZSBtdXRhYmxlIHZhbHVlXG5mdW5jdGlvbiBjcmVhdGVSZWYoKSB7XG4gIHZhciByZWZPYmplY3QgPSB7XG4gICAgY3VycmVudDogbnVsbFxuICB9O1xuXG4gIHtcbiAgICBPYmplY3Quc2VhbChyZWZPYmplY3QpO1xuICB9XG5cbiAgcmV0dXJuIHJlZk9iamVjdDtcbn1cblxudmFyIGlzQXJyYXlJbXBsID0gQXJyYXkuaXNBcnJheTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuXG5mdW5jdGlvbiBpc0FycmF5KGEpIHtcbiAgcmV0dXJuIGlzQXJyYXlJbXBsKGEpO1xufVxuXG4vKlxuICogVGhlIGAnJyArIHZhbHVlYCBwYXR0ZXJuICh1c2VkIGluIGluIHBlcmYtc2Vuc2l0aXZlIGNvZGUpIHRocm93cyBmb3IgU3ltYm9sXG4gKiBhbmQgVGVtcG9yYWwuKiB0eXBlcy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIyMDY0LlxuICpcbiAqIFRoZSBmdW5jdGlvbnMgaW4gdGhpcyBtb2R1bGUgd2lsbCB0aHJvdyBhbiBlYXNpZXItdG8tdW5kZXJzdGFuZCxcbiAqIGVhc2llci10by1kZWJ1ZyBleGNlcHRpb24gd2l0aCBhIGNsZWFyIGVycm9ycyBtZXNzYWdlIG1lc3NhZ2UgZXhwbGFpbmluZyB0aGVcbiAqIHByb2JsZW0uIChJbnN0ZWFkIG9mIGEgY29uZnVzaW5nIGV4Y2VwdGlvbiB0aHJvd24gaW5zaWRlIHRoZSBpbXBsZW1lbnRhdGlvblxuICogb2YgdGhlIGB2YWx1ZWAgb2JqZWN0KS5cbiAqL1xuLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cbmZ1bmN0aW9uIHR5cGVOYW1lKHZhbHVlKSB7XG4gIHtcbiAgICAvLyB0b1N0cmluZ1RhZyBpcyBuZWVkZWQgZm9yIG5hbWVzcGFjZWQgdHlwZXMgbGlrZSBUZW1wb3JhbC5JbnN0YW50XG4gICAgdmFyIGhhc1RvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wudG9TdHJpbmdUYWc7XG4gICAgdmFyIHR5cGUgPSBoYXNUb1N0cmluZ1RhZyAmJiB2YWx1ZVtTeW1ib2wudG9TdHJpbmdUYWddIHx8IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUgfHwgJ09iamVjdCc7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cbn0gLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cblxuXG5mdW5jdGlvbiB3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkge1xuICB7XG4gICAgdHJ5IHtcbiAgICAgIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICAvLyBJZiB5b3UgZW5kZWQgdXAgaGVyZSBieSBmb2xsb3dpbmcgYW4gZXhjZXB0aW9uIGNhbGwgc3RhY2ssIGhlcmUncyB3aGF0J3NcbiAgLy8gaGFwcGVuZWQ6IHlvdSBzdXBwbGllZCBhbiBvYmplY3Qgb3Igc3ltYm9sIHZhbHVlIHRvIFJlYWN0IChhcyBhIHByb3AsIGtleSxcbiAgLy8gRE9NIGF0dHJpYnV0ZSwgQ1NTIHByb3BlcnR5LCBzdHJpbmcgcmVmLCBldGMuKSBhbmQgd2hlbiBSZWFjdCB0cmllZCB0b1xuICAvLyBjb2VyY2UgaXQgdG8gYSBzdHJpbmcgdXNpbmcgYCcnICsgdmFsdWVgLCBhbiBleGNlcHRpb24gd2FzIHRocm93bi5cbiAgLy9cbiAgLy8gVGhlIG1vc3QgY29tbW9uIHR5cGVzIHRoYXQgd2lsbCBjYXVzZSB0aGlzIGV4Y2VwdGlvbiBhcmUgYFN5bWJvbGAgaW5zdGFuY2VzXG4gIC8vIGFuZCBUZW1wb3JhbCBvYmplY3RzIGxpa2UgYFRlbXBvcmFsLkluc3RhbnRgLiBCdXQgYW55IG9iamVjdCB0aGF0IGhhcyBhXG4gIC8vIGB2YWx1ZU9mYCBvciBgW1N5bWJvbC50b1ByaW1pdGl2ZV1gIG1ldGhvZCB0aGF0IHRocm93cyB3aWxsIGFsc28gY2F1c2UgdGhpc1xuICAvLyBleGNlcHRpb24uIChMaWJyYXJ5IGF1dGhvcnMgZG8gdGhpcyB0byBwcmV2ZW50IHVzZXJzIGZyb20gdXNpbmcgYnVpbHQtaW5cbiAgLy8gbnVtZXJpYyBvcGVyYXRvcnMgbGlrZSBgK2Agb3IgY29tcGFyaXNvbiBvcGVyYXRvcnMgbGlrZSBgPj1gIGJlY2F1c2UgY3VzdG9tXG4gIC8vIG1ldGhvZHMgYXJlIG5lZWRlZCB0byBwZXJmb3JtIGFjY3VyYXRlIGFyaXRobWV0aWMgb3IgY29tcGFyaXNvbi4pXG4gIC8vXG4gIC8vIFRvIGZpeCB0aGUgcHJvYmxlbSwgY29lcmNlIHRoaXMgb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBhIHN0cmluZyBiZWZvcmVcbiAgLy8gcGFzc2luZyBpdCB0byBSZWFjdC4gVGhlIG1vc3QgcmVsaWFibGUgd2F5IGlzIHVzdWFsbHkgYFN0cmluZyh2YWx1ZSlgLlxuICAvL1xuICAvLyBUbyBmaW5kIHdoaWNoIHZhbHVlIGlzIHRocm93aW5nLCBjaGVjayB0aGUgYnJvd3NlciBvciBkZWJ1Z2dlciBjb25zb2xlLlxuICAvLyBCZWZvcmUgdGhpcyBleGNlcHRpb24gd2FzIHRocm93biwgdGhlcmUgc2hvdWxkIGJlIGBjb25zb2xlLmVycm9yYCBvdXRwdXRcbiAgLy8gdGhhdCBzaG93cyB0aGUgdHlwZSAoU3ltYm9sLCBUZW1wb3JhbC5QbGFpbkRhdGUsIGV0Yy4pIHRoYXQgY2F1c2VkIHRoZVxuICAvLyBwcm9ibGVtIGFuZCBob3cgdGhhdCB0eXBlIHdhcyB1c2VkOiBrZXksIGF0cnJpYnV0ZSwgaW5wdXQgdmFsdWUgcHJvcCwgZXRjLlxuICAvLyBJbiBtb3N0IGNhc2VzLCB0aGlzIGNvbnNvbGUgb3V0cHV0IGFsc28gc2hvd3MgdGhlIGNvbXBvbmVudCBhbmQgaXRzXG4gIC8vIGFuY2VzdG9yIGNvbXBvbmVudHMgd2hlcmUgdGhlIGV4Y2VwdGlvbiBoYXBwZW5lZC5cbiAgLy9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gIHJldHVybiAnJyArIHZhbHVlO1xufVxuZnVuY3Rpb24gY2hlY2tLZXlTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICB7XG4gICAgaWYgKHdpbGxDb2VyY2lvblRocm93KHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1RoZSBwcm92aWRlZCBrZXkgaXMgYW4gdW5zdXBwb3J0ZWQgdHlwZSAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgdHlwZU5hbWUodmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7IC8vIHRocm93ICh0byBoZWxwIGNhbGxlcnMgZmluZCB0cm91Ymxlc2hvb3RpbmcgY29tbWVudHMpXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldFdyYXBwZWROYW1lKG91dGVyVHlwZSwgaW5uZXJUeXBlLCB3cmFwcGVyTmFtZSkge1xuICB2YXIgZGlzcGxheU5hbWUgPSBvdXRlclR5cGUuZGlzcGxheU5hbWU7XG5cbiAgaWYgKGRpc3BsYXlOYW1lKSB7XG4gICAgcmV0dXJuIGRpc3BsYXlOYW1lO1xuICB9XG5cbiAgdmFyIGZ1bmN0aW9uTmFtZSA9IGlubmVyVHlwZS5kaXNwbGF5TmFtZSB8fCBpbm5lclR5cGUubmFtZSB8fCAnJztcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZSAhPT0gJycgPyB3cmFwcGVyTmFtZSArIFwiKFwiICsgZnVuY3Rpb25OYW1lICsgXCIpXCIgOiB3cmFwcGVyTmFtZTtcbn0gLy8gS2VlcCBpbiBzeW5jIHdpdGggcmVhY3QtcmVjb25jaWxlci9nZXRDb21wb25lbnROYW1lRnJvbUZpYmVyXG5cblxuZnVuY3Rpb24gZ2V0Q29udGV4dE5hbWUodHlwZSkge1xuICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCAnQ29udGV4dCc7XG59IC8vIE5vdGUgdGhhdCB0aGUgcmVjb25jaWxlciBwYWNrYWdlIHNob3VsZCBnZW5lcmFsbHkgcHJlZmVyIHRvIHVzZSBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKCkgaW5zdGVhZC5cblxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSkge1xuICBpZiAodHlwZSA9PSBudWxsKSB7XG4gICAgLy8gSG9zdCByb290LCB0ZXh0IG5vZGUgb3IganVzdCBpbnZhbGlkIHR5cGUuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB7XG4gICAgaWYgKHR5cGVvZiB0eXBlLnRhZyA9PT0gJ251bWJlcicpIHtcbiAgICAgIGVycm9yKCdSZWNlaXZlZCBhbiB1bmV4cGVjdGVkIG9iamVjdCBpbiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoKS4gJyArICdUaGlzIGlzIGxpa2VseSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHR5cGUuZGlzcGxheU5hbWUgfHwgdHlwZS5uYW1lIHx8IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX0ZSQUdNRU5UX1RZUEU6XG4gICAgICByZXR1cm4gJ0ZyYWdtZW50JztcblxuICAgIGNhc2UgUkVBQ1RfUE9SVEFMX1RZUEU6XG4gICAgICByZXR1cm4gJ1BvcnRhbCc7XG5cbiAgICBjYXNlIFJFQUNUX1BST0ZJTEVSX1RZUEU6XG4gICAgICByZXR1cm4gJ1Byb2ZpbGVyJztcblxuICAgIGNhc2UgUkVBQ1RfU1RSSUNUX01PREVfVFlQRTpcbiAgICAgIHJldHVybiAnU3RyaWN0TW9kZSc7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgcmV0dXJuICdTdXNwZW5zZUxpc3QnO1xuXG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0NPTlRFWFRfVFlQRTpcbiAgICAgICAgdmFyIGNvbnRleHQgPSB0eXBlO1xuICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUoY29udGV4dCkgKyAnLkNvbnN1bWVyJztcblxuICAgICAgY2FzZSBSRUFDVF9QUk9WSURFUl9UWVBFOlxuICAgICAgICB2YXIgcHJvdmlkZXIgPSB0eXBlO1xuICAgICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUocHJvdmlkZXIuX2NvbnRleHQpICsgJy5Qcm92aWRlcic7XG5cbiAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgcmV0dXJuIGdldFdyYXBwZWROYW1lKHR5cGUsIHR5cGUucmVuZGVyLCAnRm9yd2FyZFJlZicpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgdmFyIG91dGVyTmFtZSA9IHR5cGUuZGlzcGxheU5hbWUgfHwgbnVsbDtcblxuICAgICAgICBpZiAob3V0ZXJOYW1lICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG91dGVyTmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZS50eXBlKSB8fCAnTWVtbyc7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShpbml0KHBheWxvYWQpKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBSRVNFUlZFRF9QUk9QUyA9IHtcbiAga2V5OiB0cnVlLFxuICByZWY6IHRydWUsXG4gIF9fc2VsZjogdHJ1ZSxcbiAgX19zb3VyY2U6IHRydWVcbn07XG52YXIgc3BlY2lhbFByb3BLZXlXYXJuaW5nU2hvd24sIHNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duLCBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzO1xuXG57XG4gIGRpZFdhcm5BYm91dFN0cmluZ1JlZnMgPSB7fTtcbn1cblxuZnVuY3Rpb24gaGFzVmFsaWRSZWYoY29uZmlnKSB7XG4gIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChjb25maWcsICdyZWYnKSkge1xuICAgICAgdmFyIGdldHRlciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY29uZmlnLCAncmVmJykuZ2V0O1xuXG4gICAgICBpZiAoZ2V0dGVyICYmIGdldHRlci5pc1JlYWN0V2FybmluZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmZpZy5yZWYgIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaGFzVmFsaWRLZXkoY29uZmlnKSB7XG4gIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChjb25maWcsICdrZXknKSkge1xuICAgICAgdmFyIGdldHRlciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoY29uZmlnLCAna2V5JykuZ2V0O1xuXG4gICAgICBpZiAoZ2V0dGVyICYmIGdldHRlci5pc1JlYWN0V2FybmluZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmZpZy5rZXkgIT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gZGVmaW5lS2V5UHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKSB7XG4gIHZhciB3YXJuQWJvdXRBY2Nlc3NpbmdLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAge1xuICAgICAgaWYgKCFzcGVjaWFsUHJvcEtleVdhcm5pbmdTaG93bikge1xuICAgICAgICBzcGVjaWFsUHJvcEtleVdhcm5pbmdTaG93biA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJyVzOiBga2V5YCBpcyBub3QgYSBwcm9wLiBUcnlpbmcgdG8gYWNjZXNzIGl0IHdpbGwgcmVzdWx0ICcgKyAnaW4gYHVuZGVmaW5lZGAgYmVpbmcgcmV0dXJuZWQuIElmIHlvdSBuZWVkIHRvIGFjY2VzcyB0aGUgc2FtZSAnICsgJ3ZhbHVlIHdpdGhpbiB0aGUgY2hpbGQgY29tcG9uZW50LCB5b3Ugc2hvdWxkIHBhc3MgaXQgYXMgYSBkaWZmZXJlbnQgJyArICdwcm9wLiAoaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3NwZWNpYWwtcHJvcHMpJywgZGlzcGxheU5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB3YXJuQWJvdXRBY2Nlc3NpbmdLZXkuaXNSZWFjdFdhcm5pbmcgPSB0cnVlO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvcHMsICdrZXknLCB7XG4gICAgZ2V0OiB3YXJuQWJvdXRBY2Nlc3NpbmdLZXksXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVSZWZQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpIHtcbiAgdmFyIHdhcm5BYm91dEFjY2Vzc2luZ1JlZiA9IGZ1bmN0aW9uICgpIHtcbiAgICB7XG4gICAgICBpZiAoIXNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duKSB7XG4gICAgICAgIHNwZWNpYWxQcm9wUmVmV2FybmluZ1Nob3duID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXM6IGByZWZgIGlzIG5vdCBhIHByb3AuIFRyeWluZyB0byBhY2Nlc3MgaXQgd2lsbCByZXN1bHQgJyArICdpbiBgdW5kZWZpbmVkYCBiZWluZyByZXR1cm5lZC4gSWYgeW91IG5lZWQgdG8gYWNjZXNzIHRoZSBzYW1lICcgKyAndmFsdWUgd2l0aGluIHRoZSBjaGlsZCBjb21wb25lbnQsIHlvdSBzaG91bGQgcGFzcyBpdCBhcyBhIGRpZmZlcmVudCAnICsgJ3Byb3AuIChodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3BlY2lhbC1wcm9wcyknLCBkaXNwbGF5TmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHdhcm5BYm91dEFjY2Vzc2luZ1JlZi5pc1JlYWN0V2FybmluZyA9IHRydWU7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9wcywgJ3JlZicsIHtcbiAgICBnZXQ6IHdhcm5BYm91dEFjY2Vzc2luZ1JlZixcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZlN0cmluZ1JlZkNhbm5vdEJlQXV0b0NvbnZlcnRlZChjb25maWcpIHtcbiAge1xuICAgIGlmICh0eXBlb2YgY29uZmlnLnJlZiA9PT0gJ3N0cmluZycgJiYgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCAmJiBjb25maWcuX19zZWxmICYmIFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQuc3RhdGVOb2RlICE9PSBjb25maWcuX19zZWxmKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnR5cGUpO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFN0cmluZ1JlZnNbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZXJyb3IoJ0NvbXBvbmVudCBcIiVzXCIgY29udGFpbnMgdGhlIHN0cmluZyByZWYgXCIlc1wiLiAnICsgJ1N1cHBvcnQgZm9yIHN0cmluZyByZWZzIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiAnICsgJ1RoaXMgY2FzZSBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gYW4gYXJyb3cgZnVuY3Rpb24uICcgKyAnV2UgYXNrIHlvdSB0byBtYW51YWxseSBmaXggdGhpcyBjYXNlIGJ5IHVzaW5nIHVzZVJlZigpIG9yIGNyZWF0ZVJlZigpIGluc3RlYWQuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1zdHJpbmctcmVmJywgY29tcG9uZW50TmFtZSwgY29uZmlnLnJlZik7XG5cbiAgICAgICAgZGlkV2FybkFib3V0U3RyaW5nUmVmc1tjb21wb25lbnROYW1lXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEZhY3RvcnkgbWV0aG9kIHRvIGNyZWF0ZSBhIG5ldyBSZWFjdCBlbGVtZW50LiBUaGlzIG5vIGxvbmdlciBhZGhlcmVzIHRvXG4gKiB0aGUgY2xhc3MgcGF0dGVybiwgc28gZG8gbm90IHVzZSBuZXcgdG8gY2FsbCBpdC4gQWxzbywgaW5zdGFuY2VvZiBjaGVja1xuICogd2lsbCBub3Qgd29yay4gSW5zdGVhZCB0ZXN0ICQkdHlwZW9mIGZpZWxkIGFnYWluc3QgU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpIHRvIGNoZWNrXG4gKiBpZiBzb21ldGhpbmcgaXMgYSBSZWFjdCBFbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7Kn0gdHlwZVxuICogQHBhcmFtIHsqfSBwcm9wc1xuICogQHBhcmFtIHsqfSBrZXlcbiAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdH0gcmVmXG4gKiBAcGFyYW0geyp9IG93bmVyXG4gKiBAcGFyYW0geyp9IHNlbGYgQSAqdGVtcG9yYXJ5KiBoZWxwZXIgdG8gZGV0ZWN0IHBsYWNlcyB3aGVyZSBgdGhpc2AgaXNcbiAqIGRpZmZlcmVudCBmcm9tIHRoZSBgb3duZXJgIHdoZW4gUmVhY3QuY3JlYXRlRWxlbWVudCBpcyBjYWxsZWQsIHNvIHRoYXQgd2VcbiAqIGNhbiB3YXJuLiBXZSB3YW50IHRvIGdldCByaWQgb2Ygb3duZXIgYW5kIHJlcGxhY2Ugc3RyaW5nIGByZWZgcyB3aXRoIGFycm93XG4gKiBmdW5jdGlvbnMsIGFuZCBhcyBsb25nIGFzIGB0aGlzYCBhbmQgb3duZXIgYXJlIHRoZSBzYW1lLCB0aGVyZSB3aWxsIGJlIG5vXG4gKiBjaGFuZ2UgaW4gYmVoYXZpb3IuXG4gKiBAcGFyYW0geyp9IHNvdXJjZSBBbiBhbm5vdGF0aW9uIG9iamVjdCAoYWRkZWQgYnkgYSB0cmFuc3BpbGVyIG9yIG90aGVyd2lzZSlcbiAqIGluZGljYXRpbmcgZmlsZW5hbWUsIGxpbmUgbnVtYmVyLCBhbmQvb3Igb3RoZXIgaW5mb3JtYXRpb24uXG4gKiBAaW50ZXJuYWxcbiAqL1xuXG5cbnZhciBSZWFjdEVsZW1lbnQgPSBmdW5jdGlvbiAodHlwZSwga2V5LCByZWYsIHNlbGYsIHNvdXJjZSwgb3duZXIsIHByb3BzKSB7XG4gIHZhciBlbGVtZW50ID0ge1xuICAgIC8vIFRoaXMgdGFnIGFsbG93cyB1cyB0byB1bmlxdWVseSBpZGVudGlmeSB0aGlzIGFzIGEgUmVhY3QgRWxlbWVudFxuICAgICQkdHlwZW9mOiBSRUFDVF9FTEVNRU5UX1RZUEUsXG4gICAgLy8gQnVpbHQtaW4gcHJvcGVydGllcyB0aGF0IGJlbG9uZyBvbiB0aGUgZWxlbWVudFxuICAgIHR5cGU6IHR5cGUsXG4gICAga2V5OiBrZXksXG4gICAgcmVmOiByZWYsXG4gICAgcHJvcHM6IHByb3BzLFxuICAgIC8vIFJlY29yZCB0aGUgY29tcG9uZW50IHJlc3BvbnNpYmxlIGZvciBjcmVhdGluZyB0aGlzIGVsZW1lbnQuXG4gICAgX293bmVyOiBvd25lclxuICB9O1xuXG4gIHtcbiAgICAvLyBUaGUgdmFsaWRhdGlvbiBmbGFnIGlzIGN1cnJlbnRseSBtdXRhdGl2ZS4gV2UgcHV0IGl0IG9uXG4gICAgLy8gYW4gZXh0ZXJuYWwgYmFja2luZyBzdG9yZSBzbyB0aGF0IHdlIGNhbiBmcmVlemUgdGhlIHdob2xlIG9iamVjdC5cbiAgICAvLyBUaGlzIGNhbiBiZSByZXBsYWNlZCB3aXRoIGEgV2Vha01hcCBvbmNlIHRoZXkgYXJlIGltcGxlbWVudGVkIGluXG4gICAgLy8gY29tbW9ubHkgdXNlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudHMuXG4gICAgZWxlbWVudC5fc3RvcmUgPSB7fTsgLy8gVG8gbWFrZSBjb21wYXJpbmcgUmVhY3RFbGVtZW50cyBlYXNpZXIgZm9yIHRlc3RpbmcgcHVycG9zZXMsIHdlIG1ha2VcbiAgICAvLyB0aGUgdmFsaWRhdGlvbiBmbGFnIG5vbi1lbnVtZXJhYmxlICh3aGVyZSBwb3NzaWJsZSwgd2hpY2ggc2hvdWxkXG4gICAgLy8gaW5jbHVkZSBldmVyeSBlbnZpcm9ubWVudCB3ZSBydW4gdGVzdHMgaW4pLCBzbyB0aGUgdGVzdCBmcmFtZXdvcmtcbiAgICAvLyBpZ25vcmVzIGl0LlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQuX3N0b3JlLCAndmFsaWRhdGVkJywge1xuICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICB2YWx1ZTogZmFsc2VcbiAgICB9KTsgLy8gc2VsZiBhbmQgc291cmNlIGFyZSBERVYgb25seSBwcm9wZXJ0aWVzLlxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsZW1lbnQsICdfc2VsZicsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIHZhbHVlOiBzZWxmXG4gICAgfSk7IC8vIFR3byBlbGVtZW50cyBjcmVhdGVkIGluIHR3byBkaWZmZXJlbnQgcGxhY2VzIHNob3VsZCBiZSBjb25zaWRlcmVkXG4gICAgLy8gZXF1YWwgZm9yIHRlc3RpbmcgcHVycG9zZXMgYW5kIHRoZXJlZm9yZSB3ZSBoaWRlIGl0IGZyb20gZW51bWVyYXRpb24uXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZWxlbWVudCwgJ19zb3VyY2UnLCB7XG4gICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogc291cmNlXG4gICAgfSk7XG5cbiAgICBpZiAoT2JqZWN0LmZyZWV6ZSkge1xuICAgICAgT2JqZWN0LmZyZWV6ZShlbGVtZW50LnByb3BzKTtcbiAgICAgIE9iamVjdC5mcmVlemUoZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBhIG5ldyBSZWFjdEVsZW1lbnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI2NyZWF0ZWVsZW1lbnRcbiAqL1xuXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIGNvbmZpZywgY2hpbGRyZW4pIHtcbiAgdmFyIHByb3BOYW1lOyAvLyBSZXNlcnZlZCBuYW1lcyBhcmUgZXh0cmFjdGVkXG5cbiAgdmFyIHByb3BzID0ge307XG4gIHZhciBrZXkgPSBudWxsO1xuICB2YXIgcmVmID0gbnVsbDtcbiAgdmFyIHNlbGYgPSBudWxsO1xuICB2YXIgc291cmNlID0gbnVsbDtcblxuICBpZiAoY29uZmlnICE9IG51bGwpIHtcbiAgICBpZiAoaGFzVmFsaWRSZWYoY29uZmlnKSkge1xuICAgICAgcmVmID0gY29uZmlnLnJlZjtcblxuICAgICAge1xuICAgICAgICB3YXJuSWZTdHJpbmdSZWZDYW5ub3RCZUF1dG9Db252ZXJ0ZWQoY29uZmlnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzVmFsaWRLZXkoY29uZmlnKSkge1xuICAgICAge1xuICAgICAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKGNvbmZpZy5rZXkpO1xuICAgICAgfVxuXG4gICAgICBrZXkgPSAnJyArIGNvbmZpZy5rZXk7XG4gICAgfVxuXG4gICAgc2VsZiA9IGNvbmZpZy5fX3NlbGYgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb25maWcuX19zZWxmO1xuICAgIHNvdXJjZSA9IGNvbmZpZy5fX3NvdXJjZSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGNvbmZpZy5fX3NvdXJjZTsgLy8gUmVtYWluaW5nIHByb3BlcnRpZXMgYXJlIGFkZGVkIHRvIGEgbmV3IHByb3BzIG9iamVjdFxuXG4gICAgZm9yIChwcm9wTmFtZSBpbiBjb25maWcpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZywgcHJvcE5hbWUpICYmICFSRVNFUlZFRF9QUk9QUy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgcHJvcHNbcHJvcE5hbWVdID0gY29uZmlnW3Byb3BOYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gQ2hpbGRyZW4gY2FuIGJlIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQsIGFuZCB0aG9zZSBhcmUgdHJhbnNmZXJyZWQgb250b1xuICAvLyB0aGUgbmV3bHkgYWxsb2NhdGVkIHByb3BzIG9iamVjdC5cblxuXG4gIHZhciBjaGlsZHJlbkxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGggLSAyO1xuXG4gIGlmIChjaGlsZHJlbkxlbmd0aCA9PT0gMSkge1xuICAgIHByb3BzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gIH0gZWxzZSBpZiAoY2hpbGRyZW5MZW5ndGggPiAxKSB7XG4gICAgdmFyIGNoaWxkQXJyYXkgPSBBcnJheShjaGlsZHJlbkxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuTGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoaWxkQXJyYXlbaV0gPSBhcmd1bWVudHNbaSArIDJdO1xuICAgIH1cblxuICAgIHtcbiAgICAgIGlmIChPYmplY3QuZnJlZXplKSB7XG4gICAgICAgIE9iamVjdC5mcmVlemUoY2hpbGRBcnJheSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZEFycmF5O1xuICB9IC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wc1xuXG5cbiAgaWYgKHR5cGUgJiYgdHlwZS5kZWZhdWx0UHJvcHMpIHtcbiAgICB2YXIgZGVmYXVsdFByb3BzID0gdHlwZS5kZWZhdWx0UHJvcHM7XG5cbiAgICBmb3IgKHByb3BOYW1lIGluIGRlZmF1bHRQcm9wcykge1xuICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGRlZmF1bHRQcm9wc1twcm9wTmFtZV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAge1xuICAgIGlmIChrZXkgfHwgcmVmKSB7XG4gICAgICB2YXIgZGlzcGxheU5hbWUgPSB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJyA/IHR5cGUuZGlzcGxheU5hbWUgfHwgdHlwZS5uYW1lIHx8ICdVbmtub3duJyA6IHR5cGU7XG5cbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgZGVmaW5lS2V5UHJvcFdhcm5pbmdHZXR0ZXIocHJvcHMsIGRpc3BsYXlOYW1lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlZikge1xuICAgICAgICBkZWZpbmVSZWZQcm9wV2FybmluZ0dldHRlcihwcm9wcywgZGlzcGxheU5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBSZWFjdEVsZW1lbnQodHlwZSwga2V5LCByZWYsIHNlbGYsIHNvdXJjZSwgUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCwgcHJvcHMpO1xufVxuZnVuY3Rpb24gY2xvbmVBbmRSZXBsYWNlS2V5KG9sZEVsZW1lbnQsIG5ld0tleSkge1xuICB2YXIgbmV3RWxlbWVudCA9IFJlYWN0RWxlbWVudChvbGRFbGVtZW50LnR5cGUsIG5ld0tleSwgb2xkRWxlbWVudC5yZWYsIG9sZEVsZW1lbnQuX3NlbGYsIG9sZEVsZW1lbnQuX3NvdXJjZSwgb2xkRWxlbWVudC5fb3duZXIsIG9sZEVsZW1lbnQucHJvcHMpO1xuICByZXR1cm4gbmV3RWxlbWVudDtcbn1cbi8qKlxuICogQ2xvbmUgYW5kIHJldHVybiBhIG5ldyBSZWFjdEVsZW1lbnQgdXNpbmcgZWxlbWVudCBhcyB0aGUgc3RhcnRpbmcgcG9pbnQuXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI2Nsb25lZWxlbWVudFxuICovXG5cbmZ1bmN0aW9uIGNsb25lRWxlbWVudChlbGVtZW50LCBjb25maWcsIGNoaWxkcmVuKSB7XG4gIGlmIChlbGVtZW50ID09PSBudWxsIHx8IGVsZW1lbnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlJlYWN0LmNsb25lRWxlbWVudCguLi4pOiBUaGUgYXJndW1lbnQgbXVzdCBiZSBhIFJlYWN0IGVsZW1lbnQsIGJ1dCB5b3UgcGFzc2VkIFwiICsgZWxlbWVudCArIFwiLlwiKTtcbiAgfVxuXG4gIHZhciBwcm9wTmFtZTsgLy8gT3JpZ2luYWwgcHJvcHMgYXJlIGNvcGllZFxuXG4gIHZhciBwcm9wcyA9IGFzc2lnbih7fSwgZWxlbWVudC5wcm9wcyk7IC8vIFJlc2VydmVkIG5hbWVzIGFyZSBleHRyYWN0ZWRcblxuICB2YXIga2V5ID0gZWxlbWVudC5rZXk7XG4gIHZhciByZWYgPSBlbGVtZW50LnJlZjsgLy8gU2VsZiBpcyBwcmVzZXJ2ZWQgc2luY2UgdGhlIG93bmVyIGlzIHByZXNlcnZlZC5cblxuICB2YXIgc2VsZiA9IGVsZW1lbnQuX3NlbGY7IC8vIFNvdXJjZSBpcyBwcmVzZXJ2ZWQgc2luY2UgY2xvbmVFbGVtZW50IGlzIHVubGlrZWx5IHRvIGJlIHRhcmdldGVkIGJ5IGFcbiAgLy8gdHJhbnNwaWxlciwgYW5kIHRoZSBvcmlnaW5hbCBzb3VyY2UgaXMgcHJvYmFibHkgYSBiZXR0ZXIgaW5kaWNhdG9yIG9mIHRoZVxuICAvLyB0cnVlIG93bmVyLlxuXG4gIHZhciBzb3VyY2UgPSBlbGVtZW50Ll9zb3VyY2U7IC8vIE93bmVyIHdpbGwgYmUgcHJlc2VydmVkLCB1bmxlc3MgcmVmIGlzIG92ZXJyaWRkZW5cblxuICB2YXIgb3duZXIgPSBlbGVtZW50Ll9vd25lcjtcblxuICBpZiAoY29uZmlnICE9IG51bGwpIHtcbiAgICBpZiAoaGFzVmFsaWRSZWYoY29uZmlnKSkge1xuICAgICAgLy8gU2lsZW50bHkgc3RlYWwgdGhlIHJlZiBmcm9tIHRoZSBwYXJlbnQuXG4gICAgICByZWYgPSBjb25maWcucmVmO1xuICAgICAgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50O1xuICAgIH1cblxuICAgIGlmIChoYXNWYWxpZEtleShjb25maWcpKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24oY29uZmlnLmtleSk7XG4gICAgICB9XG5cbiAgICAgIGtleSA9ICcnICsgY29uZmlnLmtleTtcbiAgICB9IC8vIFJlbWFpbmluZyBwcm9wZXJ0aWVzIG92ZXJyaWRlIGV4aXN0aW5nIHByb3BzXG5cblxuICAgIHZhciBkZWZhdWx0UHJvcHM7XG5cbiAgICBpZiAoZWxlbWVudC50eXBlICYmIGVsZW1lbnQudHlwZS5kZWZhdWx0UHJvcHMpIHtcbiAgICAgIGRlZmF1bHRQcm9wcyA9IGVsZW1lbnQudHlwZS5kZWZhdWx0UHJvcHM7XG4gICAgfVxuXG4gICAgZm9yIChwcm9wTmFtZSBpbiBjb25maWcpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGNvbmZpZywgcHJvcE5hbWUpICYmICFSRVNFUlZFRF9QUk9QUy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkpIHtcbiAgICAgICAgaWYgKGNvbmZpZ1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCAmJiBkZWZhdWx0UHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wc1xuICAgICAgICAgIHByb3BzW3Byb3BOYW1lXSA9IGRlZmF1bHRQcm9wc1twcm9wTmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJvcHNbcHJvcE5hbWVdID0gY29uZmlnW3Byb3BOYW1lXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSAvLyBDaGlsZHJlbiBjYW4gYmUgbW9yZSB0aGFuIG9uZSBhcmd1bWVudCwgYW5kIHRob3NlIGFyZSB0cmFuc2ZlcnJlZCBvbnRvXG4gIC8vIHRoZSBuZXdseSBhbGxvY2F0ZWQgcHJvcHMgb2JqZWN0LlxuXG5cbiAgdmFyIGNoaWxkcmVuTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCAtIDI7XG5cbiAgaWYgKGNoaWxkcmVuTGVuZ3RoID09PSAxKSB7XG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgfSBlbHNlIGlmIChjaGlsZHJlbkxlbmd0aCA+IDEpIHtcbiAgICB2YXIgY2hpbGRBcnJheSA9IEFycmF5KGNoaWxkcmVuTGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW5MZW5ndGg7IGkrKykge1xuICAgICAgY2hpbGRBcnJheVtpXSA9IGFyZ3VtZW50c1tpICsgMl07XG4gICAgfVxuXG4gICAgcHJvcHMuY2hpbGRyZW4gPSBjaGlsZEFycmF5O1xuICB9XG5cbiAgcmV0dXJuIFJlYWN0RWxlbWVudChlbGVtZW50LnR5cGUsIGtleSwgcmVmLCBzZWxmLCBzb3VyY2UsIG93bmVyLCBwcm9wcyk7XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoZSBvYmplY3QgaXMgYSBSZWFjdEVsZW1lbnQuXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI2lzdmFsaWRlbGVtZW50XG4gKiBAcGFyYW0gez9vYmplY3R9IG9iamVjdFxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBgb2JqZWN0YCBpcyBhIFJlYWN0RWxlbWVudC5cbiAqIEBmaW5hbFxuICovXG5cbmZ1bmN0aW9uIGlzVmFsaWRFbGVtZW50KG9iamVjdCkge1xuICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0ICE9PSBudWxsICYmIG9iamVjdC4kJHR5cGVvZiA9PT0gUkVBQ1RfRUxFTUVOVF9UWVBFO1xufVxuXG52YXIgU0VQQVJBVE9SID0gJy4nO1xudmFyIFNVQlNFUEFSQVRPUiA9ICc6Jztcbi8qKlxuICogRXNjYXBlIGFuZCB3cmFwIGtleSBzbyBpdCBpcyBzYWZlIHRvIHVzZSBhcyBhIHJlYWN0aWRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IHRvIGJlIGVzY2FwZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBlc2NhcGVkIGtleS5cbiAqL1xuXG5mdW5jdGlvbiBlc2NhcGUoa2V5KSB7XG4gIHZhciBlc2NhcGVSZWdleCA9IC9bPTpdL2c7XG4gIHZhciBlc2NhcGVyTG9va3VwID0ge1xuICAgICc9JzogJz0wJyxcbiAgICAnOic6ICc9MidcbiAgfTtcbiAgdmFyIGVzY2FwZWRTdHJpbmcgPSBrZXkucmVwbGFjZShlc2NhcGVSZWdleCwgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgcmV0dXJuIGVzY2FwZXJMb29rdXBbbWF0Y2hdO1xuICB9KTtcbiAgcmV0dXJuICckJyArIGVzY2FwZWRTdHJpbmc7XG59XG4vKipcbiAqIFRPRE86IFRlc3QgdGhhdCBhIHNpbmdsZSBjaGlsZCBhbmQgYW4gYXJyYXkgd2l0aCBvbmUgaXRlbSBoYXZlIHRoZSBzYW1lIGtleVxuICogcGF0dGVybi5cbiAqL1xuXG5cbnZhciBkaWRXYXJuQWJvdXRNYXBzID0gZmFsc2U7XG52YXIgdXNlclByb3ZpZGVkS2V5RXNjYXBlUmVnZXggPSAvXFwvKy9nO1xuXG5mdW5jdGlvbiBlc2NhcGVVc2VyUHJvdmlkZWRLZXkodGV4dCkge1xuICByZXR1cm4gdGV4dC5yZXBsYWNlKHVzZXJQcm92aWRlZEtleUVzY2FwZVJlZ2V4LCAnJCYvJyk7XG59XG4vKipcbiAqIEdlbmVyYXRlIGEga2V5IHN0cmluZyB0aGF0IGlkZW50aWZpZXMgYSBlbGVtZW50IHdpdGhpbiBhIHNldC5cbiAqXG4gKiBAcGFyYW0geyp9IGVsZW1lbnQgQSBlbGVtZW50IHRoYXQgY291bGQgY29udGFpbiBhIG1hbnVhbCBrZXkuXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXggdGhhdCBpcyB1c2VkIGlmIGEgbWFudWFsIGtleSBpcyBub3QgcHJvdmlkZWQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXRFbGVtZW50S2V5KGVsZW1lbnQsIGluZGV4KSB7XG4gIC8vIERvIHNvbWUgdHlwZWNoZWNraW5nIGhlcmUgc2luY2Ugd2UgY2FsbCB0aGlzIGJsaW5kbHkuIFdlIHdhbnQgdG8gZW5zdXJlXG4gIC8vIHRoYXQgd2UgZG9uJ3QgYmxvY2sgcG90ZW50aWFsIGZ1dHVyZSBFUyBBUElzLlxuICBpZiAodHlwZW9mIGVsZW1lbnQgPT09ICdvYmplY3QnICYmIGVsZW1lbnQgIT09IG51bGwgJiYgZWxlbWVudC5rZXkgIT0gbnVsbCkge1xuICAgIC8vIEV4cGxpY2l0IGtleVxuICAgIHtcbiAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24oZWxlbWVudC5rZXkpO1xuICAgIH1cblxuICAgIHJldHVybiBlc2NhcGUoJycgKyBlbGVtZW50LmtleSk7XG4gIH0gLy8gSW1wbGljaXQga2V5IGRldGVybWluZWQgYnkgdGhlIGluZGV4IGluIHRoZSBzZXRcblxuXG4gIHJldHVybiBpbmRleC50b1N0cmluZygzNik7XG59XG5cbmZ1bmN0aW9uIG1hcEludG9BcnJheShjaGlsZHJlbiwgYXJyYXksIGVzY2FwZWRQcmVmaXgsIG5hbWVTb0ZhciwgY2FsbGJhY2spIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgY2hpbGRyZW47XG5cbiAgaWYgKHR5cGUgPT09ICd1bmRlZmluZWQnIHx8IHR5cGUgPT09ICdib29sZWFuJykge1xuICAgIC8vIEFsbCBvZiB0aGUgYWJvdmUgYXJlIHBlcmNlaXZlZCBhcyBudWxsLlxuICAgIGNoaWxkcmVuID0gbnVsbDtcbiAgfVxuXG4gIHZhciBpbnZva2VDYWxsYmFjayA9IGZhbHNlO1xuXG4gIGlmIChjaGlsZHJlbiA9PT0gbnVsbCkge1xuICAgIGludm9rZUNhbGxiYWNrID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBpbnZva2VDYWxsYmFjayA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICBzd2l0Y2ggKGNoaWxkcmVuLiQkdHlwZW9mKSB7XG4gICAgICAgICAgY2FzZSBSRUFDVF9FTEVNRU5UX1RZUEU6XG4gICAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICAgIGludm9rZUNhbGxiYWNrID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgfVxuICB9XG5cbiAgaWYgKGludm9rZUNhbGxiYWNrKSB7XG4gICAgdmFyIF9jaGlsZCA9IGNoaWxkcmVuO1xuICAgIHZhciBtYXBwZWRDaGlsZCA9IGNhbGxiYWNrKF9jaGlsZCk7IC8vIElmIGl0J3MgdGhlIG9ubHkgY2hpbGQsIHRyZWF0IHRoZSBuYW1lIGFzIGlmIGl0IHdhcyB3cmFwcGVkIGluIGFuIGFycmF5XG4gICAgLy8gc28gdGhhdCBpdCdzIGNvbnNpc3RlbnQgaWYgdGhlIG51bWJlciBvZiBjaGlsZHJlbiBncm93czpcblxuICAgIHZhciBjaGlsZEtleSA9IG5hbWVTb0ZhciA9PT0gJycgPyBTRVBBUkFUT1IgKyBnZXRFbGVtZW50S2V5KF9jaGlsZCwgMCkgOiBuYW1lU29GYXI7XG5cbiAgICBpZiAoaXNBcnJheShtYXBwZWRDaGlsZCkpIHtcbiAgICAgIHZhciBlc2NhcGVkQ2hpbGRLZXkgPSAnJztcblxuICAgICAgaWYgKGNoaWxkS2V5ICE9IG51bGwpIHtcbiAgICAgICAgZXNjYXBlZENoaWxkS2V5ID0gZXNjYXBlVXNlclByb3ZpZGVkS2V5KGNoaWxkS2V5KSArICcvJztcbiAgICAgIH1cblxuICAgICAgbWFwSW50b0FycmF5KG1hcHBlZENoaWxkLCBhcnJheSwgZXNjYXBlZENoaWxkS2V5LCAnJywgZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgcmV0dXJuIGM7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKG1hcHBlZENoaWxkICE9IG51bGwpIHtcbiAgICAgIGlmIChpc1ZhbGlkRWxlbWVudChtYXBwZWRDaGlsZCkpIHtcbiAgICAgICAge1xuICAgICAgICAgIC8vIFRoZSBgaWZgIHN0YXRlbWVudCBoZXJlIHByZXZlbnRzIGF1dG8tZGlzYWJsaW5nIG9mIHRoZSBzYWZlXG4gICAgICAgICAgLy8gY29lcmNpb24gRVNMaW50IHJ1bGUsIHNvIHdlIG11c3QgbWFudWFsbHkgZGlzYWJsZSBpdCBiZWxvdy5cbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lIEZsb3cgaW5jb3JyZWN0bHkgdGhpbmtzIFJlYWN0LlBvcnRhbCBkb2Vzbid0IGhhdmUgYSBrZXlcbiAgICAgICAgICBpZiAobWFwcGVkQ2hpbGQua2V5ICYmICghX2NoaWxkIHx8IF9jaGlsZC5rZXkgIT09IG1hcHBlZENoaWxkLmtleSkpIHtcbiAgICAgICAgICAgIGNoZWNrS2V5U3RyaW5nQ29lcmNpb24obWFwcGVkQ2hpbGQua2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBtYXBwZWRDaGlsZCA9IGNsb25lQW5kUmVwbGFjZUtleShtYXBwZWRDaGlsZCwgLy8gS2VlcCBib3RoIHRoZSAobWFwcGVkKSBhbmQgb2xkIGtleXMgaWYgdGhleSBkaWZmZXIsIGp1c3QgYXNcbiAgICAgICAgLy8gdHJhdmVyc2VBbGxDaGlsZHJlbiB1c2VkIHRvIGRvIGZvciBvYmplY3RzIGFzIGNoaWxkcmVuXG4gICAgICAgIGVzY2FwZWRQcmVmaXggKyAoIC8vICRGbG93Rml4TWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgUmVhY3QuUG9ydGFsIGRvZXNuJ3QgaGF2ZSBhIGtleVxuICAgICAgICBtYXBwZWRDaGlsZC5rZXkgJiYgKCFfY2hpbGQgfHwgX2NoaWxkLmtleSAhPT0gbWFwcGVkQ2hpbGQua2V5KSA/IC8vICRGbG93Rml4TWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgZXhpc3RpbmcgZWxlbWVudCdzIGtleSBjYW4gYmUgYSBudW1iZXJcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gICAgICAgIGVzY2FwZVVzZXJQcm92aWRlZEtleSgnJyArIG1hcHBlZENoaWxkLmtleSkgKyAnLycgOiAnJykgKyBjaGlsZEtleSk7XG4gICAgICB9XG5cbiAgICAgIGFycmF5LnB1c2gobWFwcGVkQ2hpbGQpO1xuICAgIH1cblxuICAgIHJldHVybiAxO1xuICB9XG5cbiAgdmFyIGNoaWxkO1xuICB2YXIgbmV4dE5hbWU7XG4gIHZhciBzdWJ0cmVlQ291bnQgPSAwOyAvLyBDb3VudCBvZiBjaGlsZHJlbiBmb3VuZCBpbiB0aGUgY3VycmVudCBzdWJ0cmVlLlxuXG4gIHZhciBuZXh0TmFtZVByZWZpeCA9IG5hbWVTb0ZhciA9PT0gJycgPyBTRVBBUkFUT1IgOiBuYW1lU29GYXIgKyBTVUJTRVBBUkFUT1I7XG5cbiAgaWYgKGlzQXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTtcbiAgICAgIG5leHROYW1lID0gbmV4dE5hbWVQcmVmaXggKyBnZXRFbGVtZW50S2V5KGNoaWxkLCBpKTtcbiAgICAgIHN1YnRyZWVDb3VudCArPSBtYXBJbnRvQXJyYXkoY2hpbGQsIGFycmF5LCBlc2NhcGVkUHJlZml4LCBuZXh0TmFtZSwgY2FsbGJhY2spO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4oY2hpbGRyZW4pO1xuXG4gICAgaWYgKHR5cGVvZiBpdGVyYXRvckZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgaXRlcmFibGVDaGlsZHJlbiA9IGNoaWxkcmVuO1xuXG4gICAgICB7XG4gICAgICAgIC8vIFdhcm4gYWJvdXQgdXNpbmcgTWFwcyBhcyBjaGlsZHJlblxuICAgICAgICBpZiAoaXRlcmF0b3JGbiA9PT0gaXRlcmFibGVDaGlsZHJlbi5lbnRyaWVzKSB7XG4gICAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNYXBzKSB7XG4gICAgICAgICAgICB3YXJuKCdVc2luZyBNYXBzIGFzIGNoaWxkcmVuIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnVXNlIGFuIGFycmF5IG9mIGtleWVkIFJlYWN0RWxlbWVudHMgaW5zdGVhZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkaWRXYXJuQWJvdXRNYXBzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwoaXRlcmFibGVDaGlsZHJlbik7XG4gICAgICB2YXIgc3RlcDtcbiAgICAgIHZhciBpaSA9IDA7XG5cbiAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgY2hpbGQgPSBzdGVwLnZhbHVlO1xuICAgICAgICBuZXh0TmFtZSA9IG5leHROYW1lUHJlZml4ICsgZ2V0RWxlbWVudEtleShjaGlsZCwgaWkrKyk7XG4gICAgICAgIHN1YnRyZWVDb3VudCArPSBtYXBJbnRvQXJyYXkoY2hpbGQsIGFycmF5LCBlc2NhcGVkUHJlZml4LCBuZXh0TmFtZSwgY2FsbGJhY2spO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgdmFyIGNoaWxkcmVuU3RyaW5nID0gU3RyaW5nKGNoaWxkcmVuKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk9iamVjdHMgYXJlIG5vdCB2YWxpZCBhcyBhIFJlYWN0IGNoaWxkIChmb3VuZDogXCIgKyAoY2hpbGRyZW5TdHJpbmcgPT09ICdbb2JqZWN0IE9iamVjdF0nID8gJ29iamVjdCB3aXRoIGtleXMgeycgKyBPYmplY3Qua2V5cyhjaGlsZHJlbikuam9pbignLCAnKSArICd9JyA6IGNoaWxkcmVuU3RyaW5nKSArIFwiKS4gXCIgKyAnSWYgeW91IG1lYW50IHRvIHJlbmRlciBhIGNvbGxlY3Rpb24gb2YgY2hpbGRyZW4sIHVzZSBhbiBhcnJheSAnICsgJ2luc3RlYWQuJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN1YnRyZWVDb3VudDtcbn1cblxuLyoqXG4gKiBNYXBzIGNoaWxkcmVuIHRoYXQgYXJlIHR5cGljYWxseSBzcGVjaWZpZWQgYXMgYHByb3BzLmNoaWxkcmVuYC5cbiAqXG4gKiBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL3JlYWN0LWFwaS5odG1sI3JlYWN0Y2hpbGRyZW5tYXBcbiAqXG4gKiBUaGUgcHJvdmlkZWQgbWFwRnVuY3Rpb24oY2hpbGQsIGluZGV4KSB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaFxuICogbGVhZiBjaGlsZC5cbiAqXG4gKiBAcGFyYW0gez8qfSBjaGlsZHJlbiBDaGlsZHJlbiB0cmVlIGNvbnRhaW5lci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKiwgaW50KX0gZnVuYyBUaGUgbWFwIGZ1bmN0aW9uLlxuICogQHBhcmFtIHsqfSBjb250ZXh0IENvbnRleHQgZm9yIG1hcEZ1bmN0aW9uLlxuICogQHJldHVybiB7b2JqZWN0fSBPYmplY3QgY29udGFpbmluZyB0aGUgb3JkZXJlZCBtYXAgb2YgcmVzdWx0cy5cbiAqL1xuZnVuY3Rpb24gbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmMsIGNvbnRleHQpIHtcbiAgaWYgKGNoaWxkcmVuID09IG51bGwpIHtcbiAgICByZXR1cm4gY2hpbGRyZW47XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBjb3VudCA9IDA7XG4gIG1hcEludG9BcnJheShjaGlsZHJlbiwgcmVzdWx0LCAnJywgJycsIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIHJldHVybiBmdW5jLmNhbGwoY29udGV4dCwgY2hpbGQsIGNvdW50KyspO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogQ291bnQgdGhlIG51bWJlciBvZiBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzXG4gKiBgcHJvcHMuY2hpbGRyZW5gLlxuICpcbiAqIFNlZSBodHRwczovL3JlYWN0anMub3JnL2RvY3MvcmVhY3QtYXBpLmh0bWwjcmVhY3RjaGlsZHJlbmNvdW50XG4gKlxuICogQHBhcmFtIHs/Kn0gY2hpbGRyZW4gQ2hpbGRyZW4gdHJlZSBjb250YWluZXIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgY2hpbGRyZW4uXG4gKi9cblxuXG5mdW5jdGlvbiBjb3VudENoaWxkcmVuKGNoaWxkcmVuKSB7XG4gIHZhciBuID0gMDtcbiAgbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmN0aW9uICgpIHtcbiAgICBuKys7IC8vIERvbid0IHJldHVybiBhbnl0aGluZ1xuICB9KTtcbiAgcmV0dXJuIG47XG59XG5cbi8qKlxuICogSXRlcmF0ZXMgdGhyb3VnaCBjaGlsZHJlbiB0aGF0IGFyZSB0eXBpY2FsbHkgc3BlY2lmaWVkIGFzIGBwcm9wcy5jaGlsZHJlbmAuXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVuZm9yZWFjaFxuICpcbiAqIFRoZSBwcm92aWRlZCBmb3JFYWNoRnVuYyhjaGlsZCwgaW5kZXgpIHdpbGwgYmUgY2FsbGVkIGZvciBlYWNoXG4gKiBsZWFmIGNoaWxkLlxuICpcbiAqIEBwYXJhbSB7Pyp9IGNoaWxkcmVuIENoaWxkcmVuIHRyZWUgY29udGFpbmVyLlxuICogQHBhcmFtIHtmdW5jdGlvbigqLCBpbnQpfSBmb3JFYWNoRnVuY1xuICogQHBhcmFtIHsqfSBmb3JFYWNoQ29udGV4dCBDb250ZXh0IGZvciBmb3JFYWNoQ29udGV4dC5cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaENoaWxkcmVuKGNoaWxkcmVuLCBmb3JFYWNoRnVuYywgZm9yRWFjaENvbnRleHQpIHtcbiAgbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmN0aW9uICgpIHtcbiAgICBmb3JFYWNoRnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyAvLyBEb24ndCByZXR1cm4gYW55dGhpbmcuXG4gIH0sIGZvckVhY2hDb250ZXh0KTtcbn1cbi8qKlxuICogRmxhdHRlbiBhIGNoaWxkcmVuIG9iamVjdCAodHlwaWNhbGx5IHNwZWNpZmllZCBhcyBgcHJvcHMuY2hpbGRyZW5gKSBhbmRcbiAqIHJldHVybiBhbiBhcnJheSB3aXRoIGFwcHJvcHJpYXRlbHkgcmUta2V5ZWQgY2hpbGRyZW4uXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVudG9hcnJheVxuICovXG5cblxuZnVuY3Rpb24gdG9BcnJheShjaGlsZHJlbikge1xuICByZXR1cm4gbWFwQ2hpbGRyZW4oY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIHJldHVybiBjaGlsZDtcbiAgfSkgfHwgW107XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IGNoaWxkIGluIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiBhbmQgdmVyaWZpZXMgdGhhdCB0aGVyZVxuICogaXMgb25seSBvbmUgY2hpbGQgaW4gdGhlIGNvbGxlY3Rpb24uXG4gKlxuICogU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvZG9jcy9yZWFjdC1hcGkuaHRtbCNyZWFjdGNoaWxkcmVub25seVxuICpcbiAqIFRoZSBjdXJyZW50IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGEgc2luZ2xlIGNoaWxkIGdldHNcbiAqIHBhc3NlZCB3aXRob3V0IGEgd3JhcHBlciwgYnV0IHRoZSBwdXJwb3NlIG9mIHRoaXMgaGVscGVyIGZ1bmN0aW9uIGlzIHRvXG4gKiBhYnN0cmFjdCBhd2F5IHRoZSBwYXJ0aWN1bGFyIHN0cnVjdHVyZSBvZiBjaGlsZHJlbi5cbiAqXG4gKiBAcGFyYW0gez9vYmplY3R9IGNoaWxkcmVuIENoaWxkIGNvbGxlY3Rpb24gc3RydWN0dXJlLlxuICogQHJldHVybiB7UmVhY3RFbGVtZW50fSBUaGUgZmlyc3QgYW5kIG9ubHkgYFJlYWN0RWxlbWVudGAgY29udGFpbmVkIGluIHRoZVxuICogc3RydWN0dXJlLlxuICovXG5cblxuZnVuY3Rpb24gb25seUNoaWxkKGNoaWxkcmVuKSB7XG4gIGlmICghaXNWYWxpZEVsZW1lbnQoY2hpbGRyZW4pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWFjdC5DaGlsZHJlbi5vbmx5IGV4cGVjdGVkIHRvIHJlY2VpdmUgYSBzaW5nbGUgUmVhY3QgZWxlbWVudCBjaGlsZC4nKTtcbiAgfVxuXG4gIHJldHVybiBjaGlsZHJlbjtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGV4dChkZWZhdWx0VmFsdWUpIHtcbiAgLy8gVE9ETzogU2Vjb25kIGFyZ3VtZW50IHVzZWQgdG8gYmUgYW4gb3B0aW9uYWwgYGNhbGN1bGF0ZUNoYW5nZWRCaXRzYFxuICAvLyBmdW5jdGlvbi4gV2FybiB0byByZXNlcnZlIGZvciBmdXR1cmUgdXNlP1xuICB2YXIgY29udGV4dCA9IHtcbiAgICAkJHR5cGVvZjogUkVBQ1RfQ09OVEVYVF9UWVBFLFxuICAgIC8vIEFzIGEgd29ya2Fyb3VuZCB0byBzdXBwb3J0IG11bHRpcGxlIGNvbmN1cnJlbnQgcmVuZGVyZXJzLCB3ZSBjYXRlZ29yaXplXG4gICAgLy8gc29tZSByZW5kZXJlcnMgYXMgcHJpbWFyeSBhbmQgb3RoZXJzIGFzIHNlY29uZGFyeS4gV2Ugb25seSBleHBlY3RcbiAgICAvLyB0aGVyZSB0byBiZSB0d28gY29uY3VycmVudCByZW5kZXJlcnMgYXQgbW9zdDogUmVhY3QgTmF0aXZlIChwcmltYXJ5KSBhbmRcbiAgICAvLyBGYWJyaWMgKHNlY29uZGFyeSk7IFJlYWN0IERPTSAocHJpbWFyeSkgYW5kIFJlYWN0IEFSVCAoc2Vjb25kYXJ5KS5cbiAgICAvLyBTZWNvbmRhcnkgcmVuZGVyZXJzIHN0b3JlIHRoZWlyIGNvbnRleHQgdmFsdWVzIG9uIHNlcGFyYXRlIGZpZWxkcy5cbiAgICBfY3VycmVudFZhbHVlOiBkZWZhdWx0VmFsdWUsXG4gICAgX2N1cnJlbnRWYWx1ZTI6IGRlZmF1bHRWYWx1ZSxcbiAgICAvLyBVc2VkIHRvIHRyYWNrIGhvdyBtYW55IGNvbmN1cnJlbnQgcmVuZGVyZXJzIHRoaXMgY29udGV4dCBjdXJyZW50bHlcbiAgICAvLyBzdXBwb3J0cyB3aXRoaW4gaW4gYSBzaW5nbGUgcmVuZGVyZXIuIFN1Y2ggYXMgcGFyYWxsZWwgc2VydmVyIHJlbmRlcmluZy5cbiAgICBfdGhyZWFkQ291bnQ6IDAsXG4gICAgLy8gVGhlc2UgYXJlIGNpcmN1bGFyXG4gICAgUHJvdmlkZXI6IG51bGwsXG4gICAgQ29uc3VtZXI6IG51bGwsXG4gICAgLy8gQWRkIHRoZXNlIHRvIHVzZSBzYW1lIGhpZGRlbiBjbGFzcyBpbiBWTSBhcyBTZXJ2ZXJDb250ZXh0XG4gICAgX2RlZmF1bHRWYWx1ZTogbnVsbCxcbiAgICBfZ2xvYmFsTmFtZTogbnVsbFxuICB9O1xuICBjb250ZXh0LlByb3ZpZGVyID0ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9QUk9WSURFUl9UWVBFLFxuICAgIF9jb250ZXh0OiBjb250ZXh0XG4gIH07XG4gIHZhciBoYXNXYXJuZWRBYm91dFVzaW5nTmVzdGVkQ29udGV4dENvbnN1bWVycyA9IGZhbHNlO1xuICB2YXIgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnN1bWVyUHJvdmlkZXIgPSBmYWxzZTtcbiAgdmFyIGhhc1dhcm5lZEFib3V0RGlzcGxheU5hbWVPbkNvbnN1bWVyID0gZmFsc2U7XG5cbiAge1xuICAgIC8vIEEgc2VwYXJhdGUgb2JqZWN0LCBidXQgcHJveGllcyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBjb250ZXh0IG9iamVjdCBmb3JcbiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS4gSXQgaGFzIGEgZGlmZmVyZW50ICQkdHlwZW9mLCBzbyB3ZSBjYW4gcHJvcGVybHlcbiAgICAvLyB3YXJuIGZvciB0aGUgaW5jb3JyZWN0IHVzYWdlIG9mIENvbnRleHQgYXMgYSBDb25zdW1lci5cbiAgICB2YXIgQ29uc3VtZXIgPSB7XG4gICAgICAkJHR5cGVvZjogUkVBQ1RfQ09OVEVYVF9UWVBFLFxuICAgICAgX2NvbnRleHQ6IGNvbnRleHRcbiAgICB9OyAvLyAkRmxvd0ZpeE1lOiBGbG93IGNvbXBsYWlucyBhYm91dCBub3Qgc2V0dGluZyBhIHZhbHVlLCB3aGljaCBpcyBpbnRlbnRpb25hbCBoZXJlXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhDb25zdW1lciwge1xuICAgICAgUHJvdmlkZXI6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nQ29uc3VtZXJQcm92aWRlcikge1xuICAgICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnN1bWVyUHJvdmlkZXIgPSB0cnVlO1xuXG4gICAgICAgICAgICBlcnJvcignUmVuZGVyaW5nIDxDb250ZXh0LkNvbnN1bWVyLlByb3ZpZGVyPiBpcyBub3Qgc3VwcG9ydGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gJyArICdhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiBEaWQgeW91IG1lYW4gdG8gcmVuZGVyIDxDb250ZXh0LlByb3ZpZGVyPiBpbnN0ZWFkPycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBjb250ZXh0LlByb3ZpZGVyO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfUHJvdmlkZXIpIHtcbiAgICAgICAgICBjb250ZXh0LlByb3ZpZGVyID0gX1Byb3ZpZGVyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgX2N1cnJlbnRWYWx1ZToge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gY29udGV4dC5fY3VycmVudFZhbHVlO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgY29udGV4dC5fY3VycmVudFZhbHVlID0gX2N1cnJlbnRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIF9jdXJyZW50VmFsdWUyOiB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBjb250ZXh0Ll9jdXJyZW50VmFsdWUyO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChfY3VycmVudFZhbHVlMikge1xuICAgICAgICAgIGNvbnRleHQuX2N1cnJlbnRWYWx1ZTIgPSBfY3VycmVudFZhbHVlMjtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIF90aHJlYWRDb3VudDoge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gY29udGV4dC5fdGhyZWFkQ291bnQ7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKF90aHJlYWRDb3VudCkge1xuICAgICAgICAgIGNvbnRleHQuX3RocmVhZENvdW50ID0gX3RocmVhZENvdW50O1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgQ29uc3VtZXI6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nTmVzdGVkQ29udGV4dENvbnN1bWVycykge1xuICAgICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ05lc3RlZENvbnRleHRDb25zdW1lcnMgPSB0cnVlO1xuXG4gICAgICAgICAgICBlcnJvcignUmVuZGVyaW5nIDxDb250ZXh0LkNvbnN1bWVyLkNvbnN1bWVyPiBpcyBub3Qgc3VwcG9ydGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gJyArICdhIGZ1dHVyZSBtYWpvciByZWxlYXNlLiBEaWQgeW91IG1lYW4gdG8gcmVuZGVyIDxDb250ZXh0LkNvbnN1bWVyPiBpbnN0ZWFkPycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBjb250ZXh0LkNvbnN1bWVyO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZGlzcGxheU5hbWU6IHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQuZGlzcGxheU5hbWU7XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKGRpc3BsYXlOYW1lKSB7XG4gICAgICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dERpc3BsYXlOYW1lT25Db25zdW1lcikge1xuICAgICAgICAgICAgd2FybignU2V0dGluZyBgZGlzcGxheU5hbWVgIG9uIENvbnRleHQuQ29uc3VtZXIgaGFzIG5vIGVmZmVjdC4gJyArIFwiWW91IHNob3VsZCBzZXQgaXQgZGlyZWN0bHkgb24gdGhlIGNvbnRleHQgd2l0aCBDb250ZXh0LmRpc3BsYXlOYW1lID0gJyVzJy5cIiwgZGlzcGxheU5hbWUpO1xuXG4gICAgICAgICAgICBoYXNXYXJuZWRBYm91dERpc3BsYXlOYW1lT25Db25zdW1lciA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7IC8vICRGbG93Rml4TWU6IEZsb3cgY29tcGxhaW5zIGFib3V0IG1pc3NpbmcgcHJvcGVydGllcyBiZWNhdXNlIGl0IGRvZXNuJ3QgdW5kZXJzdGFuZCBkZWZpbmVQcm9wZXJ0eVxuXG4gICAgY29udGV4dC5Db25zdW1lciA9IENvbnN1bWVyO1xuICB9XG5cbiAge1xuICAgIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciA9IG51bGw7XG4gICAgY29udGV4dC5fY3VycmVudFJlbmRlcmVyMiA9IG51bGw7XG4gIH1cblxuICByZXR1cm4gY29udGV4dDtcbn1cblxudmFyIFVuaW5pdGlhbGl6ZWQgPSAtMTtcbnZhciBQZW5kaW5nID0gMDtcbnZhciBSZXNvbHZlZCA9IDE7XG52YXIgUmVqZWN0ZWQgPSAyO1xuXG5mdW5jdGlvbiBsYXp5SW5pdGlhbGl6ZXIocGF5bG9hZCkge1xuICBpZiAocGF5bG9hZC5fc3RhdHVzID09PSBVbmluaXRpYWxpemVkKSB7XG4gICAgdmFyIGN0b3IgPSBwYXlsb2FkLl9yZXN1bHQ7XG4gICAgdmFyIHRoZW5hYmxlID0gY3RvcigpOyAvLyBUcmFuc2l0aW9uIHRvIHRoZSBuZXh0IHN0YXRlLlxuICAgIC8vIFRoaXMgbWlnaHQgdGhyb3cgZWl0aGVyIGJlY2F1c2UgaXQncyBtaXNzaW5nIG9yIHRocm93cy4gSWYgc28sIHdlIHRyZWF0IGl0XG4gICAgLy8gYXMgc3RpbGwgdW5pbml0aWFsaXplZCBhbmQgdHJ5IGFnYWluIG5leHQgdGltZS4gV2hpY2ggaXMgdGhlIHNhbWUgYXMgd2hhdFxuICAgIC8vIGhhcHBlbnMgaWYgdGhlIGN0b3Igb3IgYW55IHdyYXBwZXJzIHByb2Nlc3NpbmcgdGhlIGN0b3IgdGhyb3dzLiBUaGlzIG1pZ2h0XG4gICAgLy8gZW5kIHVwIGZpeGluZyBpdCBpZiB0aGUgcmVzb2x1dGlvbiB3YXMgYSBjb25jdXJyZW5jeSBidWcuXG5cbiAgICB0aGVuYWJsZS50aGVuKGZ1bmN0aW9uIChtb2R1bGVPYmplY3QpIHtcbiAgICAgIGlmIChwYXlsb2FkLl9zdGF0dXMgPT09IFBlbmRpbmcgfHwgcGF5bG9hZC5fc3RhdHVzID09PSBVbmluaXRpYWxpemVkKSB7XG4gICAgICAgIC8vIFRyYW5zaXRpb24gdG8gdGhlIG5leHQgc3RhdGUuXG4gICAgICAgIHZhciByZXNvbHZlZCA9IHBheWxvYWQ7XG4gICAgICAgIHJlc29sdmVkLl9zdGF0dXMgPSBSZXNvbHZlZDtcbiAgICAgICAgcmVzb2x2ZWQuX3Jlc3VsdCA9IG1vZHVsZU9iamVjdDtcbiAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmIChwYXlsb2FkLl9zdGF0dXMgPT09IFBlbmRpbmcgfHwgcGF5bG9hZC5fc3RhdHVzID09PSBVbmluaXRpYWxpemVkKSB7XG4gICAgICAgIC8vIFRyYW5zaXRpb24gdG8gdGhlIG5leHQgc3RhdGUuXG4gICAgICAgIHZhciByZWplY3RlZCA9IHBheWxvYWQ7XG4gICAgICAgIHJlamVjdGVkLl9zdGF0dXMgPSBSZWplY3RlZDtcbiAgICAgICAgcmVqZWN0ZWQuX3Jlc3VsdCA9IGVycm9yO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHBheWxvYWQuX3N0YXR1cyA9PT0gVW5pbml0aWFsaXplZCkge1xuICAgICAgLy8gSW4gY2FzZSwgd2UncmUgc3RpbGwgdW5pbml0aWFsaXplZCwgdGhlbiB3ZSdyZSB3YWl0aW5nIGZvciB0aGUgdGhlbmFibGVcbiAgICAgIC8vIHRvIHJlc29sdmUuIFNldCBpdCBhcyBwZW5kaW5nIGluIHRoZSBtZWFudGltZS5cbiAgICAgIHZhciBwZW5kaW5nID0gcGF5bG9hZDtcbiAgICAgIHBlbmRpbmcuX3N0YXR1cyA9IFBlbmRpbmc7XG4gICAgICBwZW5kaW5nLl9yZXN1bHQgPSB0aGVuYWJsZTtcbiAgICB9XG4gIH1cblxuICBpZiAocGF5bG9hZC5fc3RhdHVzID09PSBSZXNvbHZlZCkge1xuICAgIHZhciBtb2R1bGVPYmplY3QgPSBwYXlsb2FkLl9yZXN1bHQ7XG5cbiAgICB7XG4gICAgICBpZiAobW9kdWxlT2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXJyb3IoJ2xhenk6IEV4cGVjdGVkIHRoZSByZXN1bHQgb2YgYSBkeW5hbWljIGltcCcgKyAnb3J0KCkgY2FsbC4gJyArICdJbnN0ZWFkIHJlY2VpdmVkOiAlc1xcblxcbllvdXIgY29kZSBzaG91bGQgbG9vayBsaWtlOiBcXG4gICcgKyAvLyBCcmVhayB1cCBpbXBvcnRzIHRvIGF2b2lkIGFjY2lkZW50YWxseSBwYXJzaW5nIHRoZW0gYXMgZGVwZW5kZW5jaWVzLlxuICAgICAgICAnY29uc3QgTXlDb21wb25lbnQgPSBsYXp5KCgpID0+IGltcCcgKyBcIm9ydCgnLi9NeUNvbXBvbmVudCcpKVxcblxcblwiICsgJ0RpZCB5b3UgYWNjaWRlbnRhbGx5IHB1dCBjdXJseSBicmFjZXMgYXJvdW5kIHRoZSBpbXBvcnQ/JywgbW9kdWxlT2JqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAoISgnZGVmYXVsdCcgaW4gbW9kdWxlT2JqZWN0KSkge1xuICAgICAgICBlcnJvcignbGF6eTogRXhwZWN0ZWQgdGhlIHJlc3VsdCBvZiBhIGR5bmFtaWMgaW1wJyArICdvcnQoKSBjYWxsLiAnICsgJ0luc3RlYWQgcmVjZWl2ZWQ6ICVzXFxuXFxuWW91ciBjb2RlIHNob3VsZCBsb29rIGxpa2U6IFxcbiAgJyArIC8vIEJyZWFrIHVwIGltcG9ydHMgdG8gYXZvaWQgYWNjaWRlbnRhbGx5IHBhcnNpbmcgdGhlbSBhcyBkZXBlbmRlbmNpZXMuXG4gICAgICAgICdjb25zdCBNeUNvbXBvbmVudCA9IGxhenkoKCkgPT4gaW1wJyArIFwib3J0KCcuL015Q29tcG9uZW50JykpXCIsIG1vZHVsZU9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZHVsZU9iamVjdC5kZWZhdWx0O1xuICB9IGVsc2Uge1xuICAgIHRocm93IHBheWxvYWQuX3Jlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBsYXp5KGN0b3IpIHtcbiAgdmFyIHBheWxvYWQgPSB7XG4gICAgLy8gV2UgdXNlIHRoZXNlIGZpZWxkcyB0byBzdG9yZSB0aGUgcmVzdWx0LlxuICAgIF9zdGF0dXM6IFVuaW5pdGlhbGl6ZWQsXG4gICAgX3Jlc3VsdDogY3RvclxuICB9O1xuICB2YXIgbGF6eVR5cGUgPSB7XG4gICAgJCR0eXBlb2Y6IFJFQUNUX0xBWllfVFlQRSxcbiAgICBfcGF5bG9hZDogcGF5bG9hZCxcbiAgICBfaW5pdDogbGF6eUluaXRpYWxpemVyXG4gIH07XG5cbiAge1xuICAgIC8vIEluIHByb2R1Y3Rpb24sIHRoaXMgd291bGQganVzdCBzZXQgaXQgb24gdGhlIG9iamVjdC5cbiAgICB2YXIgZGVmYXVsdFByb3BzO1xuICAgIHZhciBwcm9wVHlwZXM7IC8vICRGbG93Rml4TWVcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGxhenlUeXBlLCB7XG4gICAgICBkZWZhdWx0UHJvcHM6IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gZGVmYXVsdFByb3BzO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdEZWZhdWx0UHJvcHMpIHtcbiAgICAgICAgICBlcnJvcignUmVhY3QubGF6eSguLi4pOiBJdCBpcyBub3Qgc3VwcG9ydGVkIHRvIGFzc2lnbiBgZGVmYXVsdFByb3BzYCB0byAnICsgJ2EgbGF6eSBjb21wb25lbnQgaW1wb3J0LiBFaXRoZXIgc3BlY2lmeSB0aGVtIHdoZXJlIHRoZSBjb21wb25lbnQgJyArICdpcyBkZWZpbmVkLCBvciBjcmVhdGUgYSB3cmFwcGluZyBjb21wb25lbnQgYXJvdW5kIGl0LicpO1xuXG4gICAgICAgICAgZGVmYXVsdFByb3BzID0gbmV3RGVmYXVsdFByb3BzOyAvLyBNYXRjaCBwcm9kdWN0aW9uIGJlaGF2aW9yIG1vcmUgY2xvc2VseTpcbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lXG5cbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eVR5cGUsICdkZWZhdWx0UHJvcHMnLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gcHJvcFR5cGVzO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdQcm9wVHlwZXMpIHtcbiAgICAgICAgICBlcnJvcignUmVhY3QubGF6eSguLi4pOiBJdCBpcyBub3Qgc3VwcG9ydGVkIHRvIGFzc2lnbiBgcHJvcFR5cGVzYCB0byAnICsgJ2EgbGF6eSBjb21wb25lbnQgaW1wb3J0LiBFaXRoZXIgc3BlY2lmeSB0aGVtIHdoZXJlIHRoZSBjb21wb25lbnQgJyArICdpcyBkZWZpbmVkLCBvciBjcmVhdGUgYSB3cmFwcGluZyBjb21wb25lbnQgYXJvdW5kIGl0LicpO1xuXG4gICAgICAgICAgcHJvcFR5cGVzID0gbmV3UHJvcFR5cGVzOyAvLyBNYXRjaCBwcm9kdWN0aW9uIGJlaGF2aW9yIG1vcmUgY2xvc2VseTpcbiAgICAgICAgICAvLyAkRmxvd0ZpeE1lXG5cbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobGF6eVR5cGUsICdwcm9wVHlwZXMnLCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBsYXp5VHlwZTtcbn1cblxuZnVuY3Rpb24gZm9yd2FyZFJlZihyZW5kZXIpIHtcbiAge1xuICAgIGlmIChyZW5kZXIgIT0gbnVsbCAmJiByZW5kZXIuJCR0eXBlb2YgPT09IFJFQUNUX01FTU9fVFlQRSkge1xuICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVxdWlyZXMgYSByZW5kZXIgZnVuY3Rpb24gYnV0IHJlY2VpdmVkIGEgYG1lbW9gICcgKyAnY29tcG9uZW50LiBJbnN0ZWFkIG9mIGZvcndhcmRSZWYobWVtbyguLi4pKSwgdXNlICcgKyAnbWVtbyhmb3J3YXJkUmVmKC4uLikpLicpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlbmRlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVxdWlyZXMgYSByZW5kZXIgZnVuY3Rpb24gYnV0IHdhcyBnaXZlbiAlcy4nLCByZW5kZXIgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2YgcmVuZGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJlbmRlci5sZW5ndGggIT09IDAgJiYgcmVuZGVyLmxlbmd0aCAhPT0gMikge1xuICAgICAgICBlcnJvcignZm9yd2FyZFJlZiByZW5kZXIgZnVuY3Rpb25zIGFjY2VwdCBleGFjdGx5IHR3byBwYXJhbWV0ZXJzOiBwcm9wcyBhbmQgcmVmLiAlcycsIHJlbmRlci5sZW5ndGggPT09IDEgPyAnRGlkIHlvdSBmb3JnZXQgdG8gdXNlIHRoZSByZWYgcGFyYW1ldGVyPycgOiAnQW55IGFkZGl0aW9uYWwgcGFyYW1ldGVyIHdpbGwgYmUgdW5kZWZpbmVkLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZW5kZXIgIT0gbnVsbCkge1xuICAgICAgaWYgKHJlbmRlci5kZWZhdWx0UHJvcHMgIT0gbnVsbCB8fCByZW5kZXIucHJvcFR5cGVzICE9IG51bGwpIHtcbiAgICAgICAgZXJyb3IoJ2ZvcndhcmRSZWYgcmVuZGVyIGZ1bmN0aW9ucyBkbyBub3Qgc3VwcG9ydCBwcm9wVHlwZXMgb3IgZGVmYXVsdFByb3BzLiAnICsgJ0RpZCB5b3UgYWNjaWRlbnRhbGx5IHBhc3MgYSBSZWFjdCBjb21wb25lbnQ/Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGVsZW1lbnRUeXBlID0ge1xuICAgICQkdHlwZW9mOiBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFLFxuICAgIHJlbmRlcjogcmVuZGVyXG4gIH07XG5cbiAge1xuICAgIHZhciBvd25OYW1lO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50VHlwZSwgJ2Rpc3BsYXlOYW1lJywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG93bk5hbWU7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICBvd25OYW1lID0gbmFtZTsgLy8gVGhlIGlubmVyIGNvbXBvbmVudCBzaG91bGRuJ3QgaW5oZXJpdCB0aGlzIGRpc3BsYXkgbmFtZSBpbiBtb3N0IGNhc2VzLFxuICAgICAgICAvLyBiZWNhdXNlIHRoZSBjb21wb25lbnQgbWF5IGJlIHVzZWQgZWxzZXdoZXJlLlxuICAgICAgICAvLyBCdXQgaXQncyBuaWNlIGZvciBhbm9ueW1vdXMgZnVuY3Rpb25zIHRvIGluaGVyaXQgdGhlIG5hbWUsXG4gICAgICAgIC8vIHNvIHRoYXQgb3VyIGNvbXBvbmVudC1zdGFjayBnZW5lcmF0aW9uIGxvZ2ljIHdpbGwgZGlzcGxheSB0aGVpciBmcmFtZXMuXG4gICAgICAgIC8vIEFuIGFub255bW91cyBmdW5jdGlvbiBnZW5lcmFsbHkgc3VnZ2VzdHMgYSBwYXR0ZXJuIGxpa2U6XG4gICAgICAgIC8vICAgUmVhY3QuZm9yd2FyZFJlZigocHJvcHMsIHJlZikgPT4gey4uLn0pO1xuICAgICAgICAvLyBUaGlzIGtpbmQgb2YgaW5uZXIgZnVuY3Rpb24gaXMgbm90IHVzZWQgZWxzZXdoZXJlIHNvIHRoZSBzaWRlIGVmZmVjdCBpcyBva2F5LlxuXG4gICAgICAgIGlmICghcmVuZGVyLm5hbWUgJiYgIXJlbmRlci5kaXNwbGF5TmFtZSkge1xuICAgICAgICAgIHJlbmRlci5kaXNwbGF5TmFtZSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50VHlwZTtcbn1cblxudmFyIFJFQUNUX01PRFVMRV9SRUZFUkVOQ0U7XG5cbntcbiAgUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSA9IFN5bWJvbC5mb3IoJ3JlYWN0Lm1vZHVsZS5yZWZlcmVuY2UnKTtcbn1cblxuZnVuY3Rpb24gaXNWYWxpZEVsZW1lbnRUeXBlKHR5cGUpIHtcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIE5vdGU6IHR5cGVvZiBtaWdodCBiZSBvdGhlciB0aGFuICdzeW1ib2wnIG9yICdudW1iZXInIChlLmcuIGlmIGl0J3MgYSBwb2x5ZmlsbCkuXG5cblxuICBpZiAodHlwZSA9PT0gUkVBQ1RfRlJBR01FTlRfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9QUk9GSUxFUl9UWVBFIHx8IGVuYWJsZURlYnVnVHJhY2luZyAgfHwgdHlwZSA9PT0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRSB8fCB0eXBlID09PSBSRUFDVF9TVVNQRU5TRV9UWVBFIHx8IHR5cGUgPT09IFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSB8fCBlbmFibGVMZWdhY3lIaWRkZW4gIHx8IHR5cGUgPT09IFJFQUNUX09GRlNDUkVFTl9UWVBFIHx8IGVuYWJsZVNjb3BlQVBJICB8fCBlbmFibGVDYWNoZUVsZW1lbnQgIHx8IGVuYWJsZVRyYW5zaXRpb25UcmFjaW5nICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfUFJPVklERVJfVFlQRSB8fCB0eXBlLiQkdHlwZW9mID09PSBSRUFDVF9DT05URVhUX1RZUEUgfHwgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSB8fCAvLyBUaGlzIG5lZWRzIHRvIGluY2x1ZGUgYWxsIHBvc3NpYmxlIG1vZHVsZSByZWZlcmVuY2Ugb2JqZWN0XG4gICAgLy8gdHlwZXMgc3VwcG9ydGVkIGJ5IGFueSBGbGlnaHQgY29uZmlndXJhdGlvbiBhbnl3aGVyZSBzaW5jZVxuICAgIC8vIHdlIGRvbid0IGtub3cgd2hpY2ggRmxpZ2h0IGJ1aWxkIHRoaXMgd2lsbCBlbmQgdXAgYmVpbmcgdXNlZFxuICAgIC8vIHdpdGguXG4gICAgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTU9EVUxFX1JFRkVSRU5DRSB8fCB0eXBlLmdldE1vZHVsZUlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gbWVtbyh0eXBlLCBjb21wYXJlKSB7XG4gIHtcbiAgICBpZiAoIWlzVmFsaWRFbGVtZW50VHlwZSh0eXBlKSkge1xuICAgICAgZXJyb3IoJ21lbW86IFRoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgY29tcG9uZW50LiBJbnN0ZWFkICcgKyAncmVjZWl2ZWQ6ICVzJywgdHlwZSA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiB0eXBlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZWxlbWVudFR5cGUgPSB7XG4gICAgJCR0eXBlb2Y6IFJFQUNUX01FTU9fVFlQRSxcbiAgICB0eXBlOiB0eXBlLFxuICAgIGNvbXBhcmU6IGNvbXBhcmUgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBjb21wYXJlXG4gIH07XG5cbiAge1xuICAgIHZhciBvd25OYW1lO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbGVtZW50VHlwZSwgJ2Rpc3BsYXlOYW1lJywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG93bk5hbWU7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICBvd25OYW1lID0gbmFtZTsgLy8gVGhlIGlubmVyIGNvbXBvbmVudCBzaG91bGRuJ3QgaW5oZXJpdCB0aGlzIGRpc3BsYXkgbmFtZSBpbiBtb3N0IGNhc2VzLFxuICAgICAgICAvLyBiZWNhdXNlIHRoZSBjb21wb25lbnQgbWF5IGJlIHVzZWQgZWxzZXdoZXJlLlxuICAgICAgICAvLyBCdXQgaXQncyBuaWNlIGZvciBhbm9ueW1vdXMgZnVuY3Rpb25zIHRvIGluaGVyaXQgdGhlIG5hbWUsXG4gICAgICAgIC8vIHNvIHRoYXQgb3VyIGNvbXBvbmVudC1zdGFjayBnZW5lcmF0aW9uIGxvZ2ljIHdpbGwgZGlzcGxheSB0aGVpciBmcmFtZXMuXG4gICAgICAgIC8vIEFuIGFub255bW91cyBmdW5jdGlvbiBnZW5lcmFsbHkgc3VnZ2VzdHMgYSBwYXR0ZXJuIGxpa2U6XG4gICAgICAgIC8vICAgUmVhY3QubWVtbygocHJvcHMpID0+IHsuLi59KTtcbiAgICAgICAgLy8gVGhpcyBraW5kIG9mIGlubmVyIGZ1bmN0aW9uIGlzIG5vdCB1c2VkIGVsc2V3aGVyZSBzbyB0aGUgc2lkZSBlZmZlY3QgaXMgb2theS5cblxuICAgICAgICBpZiAoIXR5cGUubmFtZSAmJiAhdHlwZS5kaXNwbGF5TmFtZSkge1xuICAgICAgICAgIHR5cGUuZGlzcGxheU5hbWUgPSBuYW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudFR5cGU7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVEaXNwYXRjaGVyKCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudDtcblxuICB7XG4gICAgaWYgKGRpc3BhdGNoZXIgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIGhvb2sgY2FsbC4gSG9va3MgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBvZiB0aGUgYm9keSBvZiBhIGZ1bmN0aW9uIGNvbXBvbmVudC4gVGhpcyBjb3VsZCBoYXBwZW4gZm9yJyArICcgb25lIG9mIHRoZSBmb2xsb3dpbmcgcmVhc29uczpcXG4nICsgJzEuIFlvdSBtaWdodCBoYXZlIG1pc21hdGNoaW5nIHZlcnNpb25zIG9mIFJlYWN0IGFuZCB0aGUgcmVuZGVyZXIgKHN1Y2ggYXMgUmVhY3QgRE9NKVxcbicgKyAnMi4gWW91IG1pZ2h0IGJlIGJyZWFraW5nIHRoZSBSdWxlcyBvZiBIb29rc1xcbicgKyAnMy4gWW91IG1pZ2h0IGhhdmUgbW9yZSB0aGFuIG9uZSBjb3B5IG9mIFJlYWN0IGluIHRoZSBzYW1lIGFwcFxcbicgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWhvb2stY2FsbCBmb3IgdGlwcyBhYm91dCBob3cgdG8gZGVidWcgYW5kIGZpeCB0aGlzIHByb2JsZW0uJyk7XG4gICAgfVxuICB9IC8vIFdpbGwgcmVzdWx0IGluIGEgbnVsbCBhY2Nlc3MgZXJyb3IgaWYgYWNjZXNzZWQgb3V0c2lkZSByZW5kZXIgcGhhc2UuIFdlXG4gIC8vIGludGVudGlvbmFsbHkgZG9uJ3QgdGhyb3cgb3VyIG93biBlcnJvciBiZWNhdXNlIHRoaXMgaXMgaW4gYSBob3QgcGF0aC5cbiAgLy8gQWxzbyBoZWxwcyBlbnN1cmUgdGhpcyBpcyBpbmxpbmVkLlxuXG5cbiAgcmV0dXJuIGRpc3BhdGNoZXI7XG59XG5mdW5jdGlvbiB1c2VDb250ZXh0KENvbnRleHQpIHtcbiAgdmFyIGRpc3BhdGNoZXIgPSByZXNvbHZlRGlzcGF0Y2hlcigpO1xuXG4gIHtcbiAgICAvLyBUT0RPOiBhZGQgYSBtb3JlIGdlbmVyaWMgd2FybmluZyBmb3IgaW52YWxpZCB2YWx1ZXMuXG4gICAgaWYgKENvbnRleHQuX2NvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIHJlYWxDb250ZXh0ID0gQ29udGV4dC5fY29udGV4dDsgLy8gRG9uJ3QgZGVkdXBsaWNhdGUgYmVjYXVzZSB0aGlzIGxlZ2l0aW1hdGVseSBjYXVzZXMgYnVnc1xuICAgICAgLy8gYW5kIG5vYm9keSBzaG91bGQgYmUgdXNpbmcgdGhpcyBpbiBleGlzdGluZyBjb2RlLlxuXG4gICAgICBpZiAocmVhbENvbnRleHQuQ29uc3VtZXIgPT09IENvbnRleHQpIHtcbiAgICAgICAgZXJyb3IoJ0NhbGxpbmcgdXNlQ29udGV4dChDb250ZXh0LkNvbnN1bWVyKSBpcyBub3Qgc3VwcG9ydGVkLCBtYXkgY2F1c2UgYnVncywgYW5kIHdpbGwgYmUgJyArICdyZW1vdmVkIGluIGEgZnV0dXJlIG1ham9yIHJlbGVhc2UuIERpZCB5b3UgbWVhbiB0byBjYWxsIHVzZUNvbnRleHQoQ29udGV4dCkgaW5zdGVhZD8nKTtcbiAgICAgIH0gZWxzZSBpZiAocmVhbENvbnRleHQuUHJvdmlkZXIgPT09IENvbnRleHQpIHtcbiAgICAgICAgZXJyb3IoJ0NhbGxpbmcgdXNlQ29udGV4dChDb250ZXh0LlByb3ZpZGVyKSBpcyBub3Qgc3VwcG9ydGVkLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBjYWxsIHVzZUNvbnRleHQoQ29udGV4dCkgaW5zdGVhZD8nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGlzcGF0Y2hlci51c2VDb250ZXh0KENvbnRleHQpO1xufVxuZnVuY3Rpb24gdXNlU3RhdGUoaW5pdGlhbFN0YXRlKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlU3RhdGUoaW5pdGlhbFN0YXRlKTtcbn1cbmZ1bmN0aW9uIHVzZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG59XG5mdW5jdGlvbiB1c2VSZWYoaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlUmVmKGluaXRpYWxWYWx1ZSk7XG59XG5mdW5jdGlvbiB1c2VFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG59XG5mdW5jdGlvbiB1c2VDYWxsYmFjayhjYWxsYmFjaywgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUNhbGxiYWNrKGNhbGxiYWNrLCBkZXBzKTtcbn1cbmZ1bmN0aW9uIHVzZU1lbW8oY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlTWVtbyhjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcykge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xufVxuZnVuY3Rpb24gdXNlRGVidWdWYWx1ZSh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAge1xuICAgIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgICByZXR1cm4gZGlzcGF0Y2hlci51c2VEZWJ1Z1ZhbHVlKHZhbHVlLCBmb3JtYXR0ZXJGbik7XG4gIH1cbn1cbmZ1bmN0aW9uIHVzZVRyYW5zaXRpb24oKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlVHJhbnNpdGlvbigpO1xufVxuZnVuY3Rpb24gdXNlRGVmZXJyZWRWYWx1ZSh2YWx1ZSkge1xuICB2YXIgZGlzcGF0Y2hlciA9IHJlc29sdmVEaXNwYXRjaGVyKCk7XG4gIHJldHVybiBkaXNwYXRjaGVyLnVzZURlZmVycmVkVmFsdWUodmFsdWUpO1xufVxuZnVuY3Rpb24gdXNlSWQoKSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlSWQoKTtcbn1cbmZ1bmN0aW9uIHVzZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gIHZhciBkaXNwYXRjaGVyID0gcmVzb2x2ZURpc3BhdGNoZXIoKTtcbiAgcmV0dXJuIGRpc3BhdGNoZXIudXNlU3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xufVxuXG4vLyBIZWxwZXJzIHRvIHBhdGNoIGNvbnNvbGUubG9ncyB0byBhdm9pZCBsb2dnaW5nIGR1cmluZyBzaWRlLWVmZmVjdCBmcmVlXG4vLyByZXBsYXlpbmcgb24gcmVuZGVyIGZ1bmN0aW9uLiBUaGlzIGN1cnJlbnRseSBvbmx5IHBhdGNoZXMgdGhlIG9iamVjdFxuLy8gbGF6aWx5IHdoaWNoIHdvbid0IGNvdmVyIGlmIHRoZSBsb2cgZnVuY3Rpb24gd2FzIGV4dHJhY3RlZCBlYWdlcmx5LlxuLy8gV2UgY291bGQgYWxzbyBlYWdlcmx5IHBhdGNoIHRoZSBtZXRob2QuXG52YXIgZGlzYWJsZWREZXB0aCA9IDA7XG52YXIgcHJldkxvZztcbnZhciBwcmV2SW5mbztcbnZhciBwcmV2V2FybjtcbnZhciBwcmV2RXJyb3I7XG52YXIgcHJldkdyb3VwO1xudmFyIHByZXZHcm91cENvbGxhcHNlZDtcbnZhciBwcmV2R3JvdXBFbmQ7XG5cbmZ1bmN0aW9uIGRpc2FibGVkTG9nKCkge31cblxuZGlzYWJsZWRMb2cuX19yZWFjdERpc2FibGVkTG9nID0gdHJ1ZTtcbmZ1bmN0aW9uIGRpc2FibGVMb2dzKCkge1xuICB7XG4gICAgaWYgKGRpc2FibGVkRGVwdGggPT09IDApIHtcbiAgICAgIC8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgICAgcHJldkxvZyA9IGNvbnNvbGUubG9nO1xuICAgICAgcHJldkluZm8gPSBjb25zb2xlLmluZm87XG4gICAgICBwcmV2V2FybiA9IGNvbnNvbGUud2FybjtcbiAgICAgIHByZXZFcnJvciA9IGNvbnNvbGUuZXJyb3I7XG4gICAgICBwcmV2R3JvdXAgPSBjb25zb2xlLmdyb3VwO1xuICAgICAgcHJldkdyb3VwQ29sbGFwc2VkID0gY29uc29sZS5ncm91cENvbGxhcHNlZDtcbiAgICAgIHByZXZHcm91cEVuZCA9IGNvbnNvbGUuZ3JvdXBFbmQ7IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTkwOTlcblxuICAgICAgdmFyIHByb3BzID0ge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIHZhbHVlOiBkaXNhYmxlZExvZyxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH07IC8vICRGbG93Rml4TWUgRmxvdyB0aGlua3MgY29uc29sZSBpcyBpbW11dGFibGUuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGNvbnNvbGUsIHtcbiAgICAgICAgaW5mbzogcHJvcHMsXG4gICAgICAgIGxvZzogcHJvcHMsXG4gICAgICAgIHdhcm46IHByb3BzLFxuICAgICAgICBlcnJvcjogcHJvcHMsXG4gICAgICAgIGdyb3VwOiBwcm9wcyxcbiAgICAgICAgZ3JvdXBDb2xsYXBzZWQ6IHByb3BzLFxuICAgICAgICBncm91cEVuZDogcHJvcHNcbiAgICAgIH0pO1xuICAgICAgLyogZXNsaW50LWVuYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICB9XG5cbiAgICBkaXNhYmxlZERlcHRoKys7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlZW5hYmxlTG9ncygpIHtcbiAge1xuICAgIGRpc2FibGVkRGVwdGgtLTtcblxuICAgIGlmIChkaXNhYmxlZERlcHRoID09PSAwKSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICAgIHZhciBwcm9wcyA9IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgfTsgLy8gJEZsb3dGaXhNZSBGbG93IHRoaW5rcyBjb25zb2xlIGlzIGltbXV0YWJsZS5cblxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc29sZSwge1xuICAgICAgICBsb2c6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkxvZ1xuICAgICAgICB9KSxcbiAgICAgICAgaW5mbzogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2SW5mb1xuICAgICAgICB9KSxcbiAgICAgICAgd2FybjogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2V2FyblxuICAgICAgICB9KSxcbiAgICAgICAgZXJyb3I6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkVycm9yXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwQ29sbGFwc2VkOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cENvbGxhcHNlZFxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXBFbmQ6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwRW5kXG4gICAgICAgIH0pXG4gICAgICB9KTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgfVxuXG4gICAgaWYgKGRpc2FibGVkRGVwdGggPCAwKSB7XG4gICAgICBlcnJvcignZGlzYWJsZWREZXB0aCBmZWxsIGJlbG93IHplcm8uICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG59XG5cbnZhciBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnREaXNwYXRjaGVyO1xudmFyIHByZWZpeDtcbmZ1bmN0aW9uIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKG5hbWUsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgaWYgKHByZWZpeCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBWTSBzcGVjaWZpYyBwcmVmaXggdXNlZCBieSBlYWNoIGxpbmUuXG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICB2YXIgbWF0Y2ggPSB4LnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO1xuICAgICAgICBwcmVmaXggPSBtYXRjaCAmJiBtYXRjaFsxXSB8fCAnJztcbiAgICAgIH1cbiAgICB9IC8vIFdlIHVzZSB0aGUgcHJlZml4IHRvIGVuc3VyZSBvdXIgc3RhY2tzIGxpbmUgdXAgd2l0aCBuYXRpdmUgc3RhY2sgZnJhbWVzLlxuXG5cbiAgICByZXR1cm4gJ1xcbicgKyBwcmVmaXggKyBuYW1lO1xuICB9XG59XG52YXIgcmVlbnRyeSA9IGZhbHNlO1xudmFyIGNvbXBvbmVudEZyYW1lQ2FjaGU7XG5cbntcbiAgdmFyIFBvc3NpYmx5V2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcbiAgY29tcG9uZW50RnJhbWVDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAoKTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgY29uc3RydWN0KSB7XG4gIC8vIElmIHNvbWV0aGluZyBhc2tlZCBmb3IgYSBzdGFjayBpbnNpZGUgYSBmYWtlIHJlbmRlciwgaXQgc2hvdWxkIGdldCBpZ25vcmVkLlxuICBpZiAoICFmbiB8fCByZWVudHJ5KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAge1xuICAgIHZhciBmcmFtZSA9IGNvbXBvbmVudEZyYW1lQ2FjaGUuZ2V0KGZuKTtcblxuICAgIGlmIChmcmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZnJhbWU7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbnRyb2w7XG4gIHJlZW50cnkgPSB0cnVlO1xuICB2YXIgcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZSA9IEVycm9yLnByZXBhcmVTdGFja1RyYWNlOyAvLyAkRmxvd0ZpeE1lIEl0IGRvZXMgYWNjZXB0IHVuZGVmaW5lZC5cblxuICBFcnJvci5wcmVwYXJlU3RhY2tUcmFjZSA9IHVuZGVmaW5lZDtcbiAgdmFyIHByZXZpb3VzRGlzcGF0Y2hlcjtcblxuICB7XG4gICAgcHJldmlvdXNEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7IC8vIFNldCB0aGUgZGlzcGF0Y2hlciBpbiBERVYgYmVjYXVzZSB0aGlzIG1pZ2h0IGJlIGNhbGwgaW4gdGhlIHJlbmRlciBmdW5jdGlvblxuICAgIC8vIGZvciB3YXJuaW5ncy5cblxuICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gbnVsbDtcbiAgICBkaXNhYmxlTG9ncygpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBUaGlzIHNob3VsZCB0aHJvdy5cbiAgICBpZiAoY29uc3RydWN0KSB7XG4gICAgICAvLyBTb21ldGhpbmcgc2hvdWxkIGJlIHNldHRpbmcgdGhlIHByb3BzIGluIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgIHZhciBGYWtlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgfTsgLy8gJEZsb3dGaXhNZVxuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShGYWtlLnByb3RvdHlwZSwgJ3Byb3BzJywge1xuICAgICAgICBzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAvLyBXZSB1c2UgYSB0aHJvd2luZyBzZXR0ZXIgaW5zdGVhZCBvZiBmcm96ZW4gb3Igbm9uLXdyaXRhYmxlIHByb3BzXG4gICAgICAgICAgLy8gYmVjYXVzZSB0aGF0IHdvbid0IHRocm93IGluIGEgbm9uLXN0cmljdCBtb2RlIGZ1bmN0aW9uLlxuICAgICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnICYmIFJlZmxlY3QuY29uc3RydWN0KSB7XG4gICAgICAgIC8vIFdlIGNvbnN0cnVjdCBhIGRpZmZlcmVudCBjb250cm9sIGZvciB0aGlzIGNhc2UgdG8gaW5jbHVkZSBhbnkgZXh0cmFcbiAgICAgICAgLy8gZnJhbWVzIGFkZGVkIGJ5IHRoZSBjb25zdHJ1Y3QgY2FsbC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBSZWZsZWN0LmNvbnN0cnVjdChGYWtlLCBbXSk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBjb250cm9sID0geDtcbiAgICAgICAgfVxuXG4gICAgICAgIFJlZmxlY3QuY29uc3RydWN0KGZuLCBbXSwgRmFrZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIEZha2UuY2FsbCgpO1xuICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICAgIH1cblxuICAgICAgICBmbi5jYWxsKEZha2UucHJvdG90eXBlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICB9XG5cbiAgICAgIGZuKCk7XG4gICAgfVxuICB9IGNhdGNoIChzYW1wbGUpIHtcbiAgICAvLyBUaGlzIGlzIGlubGluZWQgbWFudWFsbHkgYmVjYXVzZSBjbG9zdXJlIGRvZXNuJ3QgZG8gaXQgZm9yIHVzLlxuICAgIGlmIChzYW1wbGUgJiYgY29udHJvbCAmJiB0eXBlb2Ygc2FtcGxlLnN0YWNrID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gVGhpcyBleHRyYWN0cyB0aGUgZmlyc3QgZnJhbWUgZnJvbSB0aGUgc2FtcGxlIHRoYXQgaXNuJ3QgYWxzbyBpbiB0aGUgY29udHJvbC5cbiAgICAgIC8vIFNraXBwaW5nIG9uZSBmcmFtZSB0aGF0IHdlIGFzc3VtZSBpcyB0aGUgZnJhbWUgdGhhdCBjYWxscyB0aGUgdHdvLlxuICAgICAgdmFyIHNhbXBsZUxpbmVzID0gc2FtcGxlLnN0YWNrLnNwbGl0KCdcXG4nKTtcbiAgICAgIHZhciBjb250cm9sTGluZXMgPSBjb250cm9sLnN0YWNrLnNwbGl0KCdcXG4nKTtcbiAgICAgIHZhciBzID0gc2FtcGxlTGluZXMubGVuZ3RoIC0gMTtcbiAgICAgIHZhciBjID0gY29udHJvbExpbmVzLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChzID49IDEgJiYgYyA+PSAwICYmIHNhbXBsZUxpbmVzW3NdICE9PSBjb250cm9sTGluZXNbY10pIHtcbiAgICAgICAgLy8gV2UgZXhwZWN0IGF0IGxlYXN0IG9uZSBzdGFjayBmcmFtZSB0byBiZSBzaGFyZWQuXG4gICAgICAgIC8vIFR5cGljYWxseSB0aGlzIHdpbGwgYmUgdGhlIHJvb3QgbW9zdCBvbmUuIEhvd2V2ZXIsIHN0YWNrIGZyYW1lcyBtYXkgYmVcbiAgICAgICAgLy8gY3V0IG9mZiBkdWUgdG8gbWF4aW11bSBzdGFjayBsaW1pdHMuIEluIHRoaXMgY2FzZSwgb25lIG1heWJlIGN1dCBvZmZcbiAgICAgICAgLy8gZWFybGllciB0aGFuIHRoZSBvdGhlci4gV2UgYXNzdW1lIHRoYXQgdGhlIHNhbXBsZSBpcyBsb25nZXIgb3IgdGhlIHNhbWVcbiAgICAgICAgLy8gYW5kIHRoZXJlIGZvciBjdXQgb2ZmIGVhcmxpZXIuIFNvIHdlIHNob3VsZCBmaW5kIHRoZSByb290IG1vc3QgZnJhbWUgaW5cbiAgICAgICAgLy8gdGhlIHNhbXBsZSBzb21ld2hlcmUgaW4gdGhlIGNvbnRyb2wuXG4gICAgICAgIGMtLTtcbiAgICAgIH1cblxuICAgICAgZm9yICg7IHMgPj0gMSAmJiBjID49IDA7IHMtLSwgYy0tKSB7XG4gICAgICAgIC8vIE5leHQgd2UgZmluZCB0aGUgZmlyc3Qgb25lIHRoYXQgaXNuJ3QgdGhlIHNhbWUgd2hpY2ggc2hvdWxkIGJlIHRoZVxuICAgICAgICAvLyBmcmFtZSB0aGF0IGNhbGxlZCBvdXIgc2FtcGxlIGZ1bmN0aW9uIGFuZCB0aGUgY29udHJvbC5cbiAgICAgICAgaWYgKHNhbXBsZUxpbmVzW3NdICE9PSBjb250cm9sTGluZXNbY10pIHtcbiAgICAgICAgICAvLyBJbiBWOCwgdGhlIGZpcnN0IGxpbmUgaXMgZGVzY3JpYmluZyB0aGUgbWVzc2FnZSBidXQgb3RoZXIgVk1zIGRvbid0LlxuICAgICAgICAgIC8vIElmIHdlJ3JlIGFib3V0IHRvIHJldHVybiB0aGUgZmlyc3QgbGluZSwgYW5kIHRoZSBjb250cm9sIGlzIGFsc28gb24gdGhlIHNhbWVcbiAgICAgICAgICAvLyBsaW5lLCB0aGF0J3MgYSBwcmV0dHkgZ29vZCBpbmRpY2F0b3IgdGhhdCBvdXIgc2FtcGxlIHRocmV3IGF0IHNhbWUgbGluZSBhc1xuICAgICAgICAgIC8vIHRoZSBjb250cm9sLiBJLmUuIGJlZm9yZSB3ZSBlbnRlcmVkIHRoZSBzYW1wbGUgZnJhbWUuIFNvIHdlIGlnbm9yZSB0aGlzIHJlc3VsdC5cbiAgICAgICAgICAvLyBUaGlzIGNhbiBoYXBwZW4gaWYgeW91IHBhc3NlZCBhIGNsYXNzIHRvIGZ1bmN0aW9uIGNvbXBvbmVudCwgb3Igbm9uLWZ1bmN0aW9uLlxuICAgICAgICAgIGlmIChzICE9PSAxIHx8IGMgIT09IDEpIHtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgcy0tO1xuICAgICAgICAgICAgICBjLS07IC8vIFdlIG1heSBzdGlsbCBoYXZlIHNpbWlsYXIgaW50ZXJtZWRpYXRlIGZyYW1lcyBmcm9tIHRoZSBjb25zdHJ1Y3QgY2FsbC5cbiAgICAgICAgICAgICAgLy8gVGhlIG5leHQgb25lIHRoYXQgaXNuJ3QgdGhlIHNhbWUgc2hvdWxkIGJlIG91ciBtYXRjaCB0aG91Z2guXG5cbiAgICAgICAgICAgICAgaWYgKGMgPCAwIHx8IHNhbXBsZUxpbmVzW3NdICE9PSBjb250cm9sTGluZXNbY10pIHtcbiAgICAgICAgICAgICAgICAvLyBWOCBhZGRzIGEgXCJuZXdcIiBwcmVmaXggZm9yIG5hdGl2ZSBjbGFzc2VzLiBMZXQncyByZW1vdmUgaXQgdG8gbWFrZSBpdCBwcmV0dGllci5cbiAgICAgICAgICAgICAgICB2YXIgX2ZyYW1lID0gJ1xcbicgKyBzYW1wbGVMaW5lc1tzXS5yZXBsYWNlKCcgYXQgbmV3ICcsICcgYXQgJyk7IC8vIElmIG91ciBjb21wb25lbnQgZnJhbWUgaXMgbGFiZWxlZCBcIjxhbm9ueW1vdXM+XCJcbiAgICAgICAgICAgICAgICAvLyBidXQgd2UgaGF2ZSBhIHVzZXItcHJvdmlkZWQgXCJkaXNwbGF5TmFtZVwiXG4gICAgICAgICAgICAgICAgLy8gc3BsaWNlIGl0IGluIHRvIG1ha2UgdGhlIHN0YWNrIG1vcmUgcmVhZGFibGUuXG5cblxuICAgICAgICAgICAgICAgIGlmIChmbi5kaXNwbGF5TmFtZSAmJiBfZnJhbWUuaW5jbHVkZXMoJzxhbm9ueW1vdXM+JykpIHtcbiAgICAgICAgICAgICAgICAgIF9mcmFtZSA9IF9mcmFtZS5yZXBsYWNlKCc8YW5vbnltb3VzPicsIGZuLmRpc3BsYXlOYW1lKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudEZyYW1lQ2FjaGUuc2V0KGZuLCBfZnJhbWUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gLy8gUmV0dXJuIHRoZSBsaW5lIHdlIGZvdW5kLlxuXG5cbiAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1lO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlIChzID49IDEgJiYgYyA+PSAwKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICByZWVudHJ5ID0gZmFsc2U7XG5cbiAgICB7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZpb3VzRGlzcGF0Y2hlcjtcbiAgICAgIHJlZW5hYmxlTG9ncygpO1xuICAgIH1cblxuICAgIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gcHJldmlvdXNQcmVwYXJlU3RhY2tUcmFjZTtcbiAgfSAvLyBGYWxsYmFjayB0byBqdXN0IHVzaW5nIHRoZSBuYW1lIGlmIHdlIGNvdWxkbid0IG1ha2UgaXQgdGhyb3cuXG5cblxuICB2YXIgbmFtZSA9IGZuID8gZm4uZGlzcGxheU5hbWUgfHwgZm4ubmFtZSA6ICcnO1xuICB2YXIgc3ludGhldGljRnJhbWUgPSBuYW1lID8gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSkgOiAnJztcblxuICB7XG4gICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29tcG9uZW50RnJhbWVDYWNoZS5zZXQoZm4sIHN5bnRoZXRpY0ZyYW1lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3ludGhldGljRnJhbWU7XG59XG5mdW5jdGlvbiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUoZm4sIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoZm4sIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QoQ29tcG9uZW50KSB7XG4gIHZhciBwcm90b3R5cGUgPSBDb21wb25lbnQucHJvdG90eXBlO1xuICByZXR1cm4gISEocHJvdG90eXBlICYmIHByb3RvdHlwZS5pc1JlYWN0Q29tcG9uZW50KTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUsIHNvdXJjZSwgb3duZXJGbikge1xuXG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICB7XG4gICAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZSh0eXBlLCBzaG91bGRDb25zdHJ1Y3QodHlwZSkpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUodHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX1RZUEU6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICBjYXNlIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEU6XG4gICAgICAgIHJldHVybiBkZXNjcmliZUZ1bmN0aW9uQ29tcG9uZW50RnJhbWUodHlwZS5yZW5kZXIpO1xuXG4gICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgLy8gTWVtbyBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVih0eXBlLnR5cGUsIHNvdXJjZSwgb3duZXJGbik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGxhenlDb21wb25lbnQgPSB0eXBlO1xuICAgICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGxhenlDb21wb25lbnQuX2luaXQ7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTGF6eSBtYXkgY29udGFpbiBhbnkgY29tcG9uZW50IHR5cGUgc28gd2UgcmVjdXJzaXZlbHkgcmVzb2x2ZSBpdC5cbiAgICAgICAgICAgIHJldHVybiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoaW5pdChwYXlsb2FkKSwgc291cmNlLCBvd25lckZuKTtcbiAgICAgICAgICB9IGNhdGNoICh4KSB7fVxuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuXG52YXIgbG9nZ2VkVHlwZUZhaWx1cmVzID0ge307XG52YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSQxID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZTtcblxuZnVuY3Rpb24gc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQoZWxlbWVudCkge1xuICB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIHN0YWNrID0gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGVsZW1lbnQudHlwZSwgZWxlbWVudC5fc291cmNlLCBvd25lciA/IG93bmVyLnR5cGUgOiBudWxsKTtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMS5zZXRFeHRyYVN0YWNrRnJhbWUoc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEuc2V0RXh0cmFTdGFja0ZyYW1lKG51bGwpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja1Byb3BUeXBlcyh0eXBlU3BlY3MsIHZhbHVlcywgbG9jYXRpb24sIGNvbXBvbmVudE5hbWUsIGVsZW1lbnQpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWUgVGhpcyBpcyBva2F5IGJ1dCBGbG93IGRvZXNuJ3Qga25vdyBpdC5cbiAgICB2YXIgaGFzID0gRnVuY3Rpb24uY2FsbC5iaW5kKGhhc093blByb3BlcnR5KTtcblxuICAgIGZvciAodmFyIHR5cGVTcGVjTmFtZSBpbiB0eXBlU3BlY3MpIHtcbiAgICAgIGlmIChoYXModHlwZVNwZWNzLCB0eXBlU3BlY05hbWUpKSB7XG4gICAgICAgIHZhciBlcnJvciQxID0gdm9pZCAwOyAvLyBQcm9wIHR5cGUgdmFsaWRhdGlvbiBtYXkgdGhyb3cuIEluIGNhc2UgdGhleSBkbywgd2UgZG9uJ3Qgd2FudCB0b1xuICAgICAgICAvLyBmYWlsIHRoZSByZW5kZXIgcGhhc2Ugd2hlcmUgaXQgZGlkbid0IGZhaWwgYmVmb3JlLiBTbyB3ZSBsb2cgaXQuXG4gICAgICAgIC8vIEFmdGVyIHRoZXNlIGhhdmUgYmVlbiBjbGVhbmVkIHVwLCB3ZSdsbCBsZXQgdGhlbSB0aHJvdy5cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBhbiBpbnZhcmlhbnQgdGhhdCBnZXRzIGNhdWdodC4gSXQncyB0aGUgc2FtZVxuICAgICAgICAgIC8vIGJlaGF2aW9yIGFzIHdpdGhvdXQgdGhpcyBzdGF0ZW1lbnQgZXhjZXB0IHdpdGggYSBiZXR0ZXIgbWVzc2FnZS5cbiAgICAgICAgICBpZiAodHlwZW9mIHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgICAgdmFyIGVyciA9IEVycm9yKChjb21wb25lbnROYW1lIHx8ICdSZWFjdCBjbGFzcycpICsgJzogJyArIGxvY2F0aW9uICsgJyB0eXBlIGAnICsgdHlwZVNwZWNOYW1lICsgJ2AgaXMgaW52YWxpZDsgJyArICdpdCBtdXN0IGJlIGEgZnVuY3Rpb24sIHVzdWFsbHkgZnJvbSB0aGUgYHByb3AtdHlwZXNgIHBhY2thZ2UsIGJ1dCByZWNlaXZlZCBgJyArIHR5cGVvZiB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSArICdgLicgKyAnVGhpcyBvZnRlbiBoYXBwZW5zIGJlY2F1c2Ugb2YgdHlwb3Mgc3VjaCBhcyBgUHJvcFR5cGVzLmZ1bmN0aW9uYCBpbnN0ZWFkIG9mIGBQcm9wVHlwZXMuZnVuY2AuJyk7XG4gICAgICAgICAgICBlcnIubmFtZSA9ICdJbnZhcmlhbnQgVmlvbGF0aW9uJztcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlcnJvciQxID0gdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0odmFsdWVzLCB0eXBlU3BlY05hbWUsIGNvbXBvbmVudE5hbWUsIGxvY2F0aW9uLCBudWxsLCAnU0VDUkVUX0RPX05PVF9QQVNTX1RISVNfT1JfWU9VX1dJTExfQkVfRklSRUQnKTtcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICBlcnJvciQxID0gZXg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSAmJiAhKGVycm9yJDEgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCclczogdHlwZSBzcGVjaWZpY2F0aW9uIG9mICVzJyArICcgYCVzYCBpcyBpbnZhbGlkOyB0aGUgdHlwZSBjaGVja2VyICcgKyAnZnVuY3Rpb24gbXVzdCByZXR1cm4gYG51bGxgIG9yIGFuIGBFcnJvcmAgYnV0IHJldHVybmVkIGEgJXMuICcgKyAnWW91IG1heSBoYXZlIGZvcmdvdHRlbiB0byBwYXNzIGFuIGFyZ3VtZW50IHRvIHRoZSB0eXBlIGNoZWNrZXIgJyArICdjcmVhdG9yIChhcnJheU9mLCBpbnN0YW5jZU9mLCBvYmplY3RPZiwgb25lT2YsIG9uZU9mVHlwZSwgYW5kICcgKyAnc2hhcGUgYWxsIHJlcXVpcmUgYW4gYXJndW1lbnQpLicsIGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJywgbG9jYXRpb24sIHR5cGVTcGVjTmFtZSwgdHlwZW9mIGVycm9yJDEpO1xuXG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQobnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXJyb3IkMSBpbnN0YW5jZW9mIEVycm9yICYmICEoZXJyb3IkMS5tZXNzYWdlIGluIGxvZ2dlZFR5cGVGYWlsdXJlcykpIHtcbiAgICAgICAgICAvLyBPbmx5IG1vbml0b3IgdGhpcyBmYWlsdXJlIG9uY2UgYmVjYXVzZSB0aGVyZSB0ZW5kcyB0byBiZSBhIGxvdCBvZiB0aGVcbiAgICAgICAgICAvLyBzYW1lIGVycm9yLlxuICAgICAgICAgIGxvZ2dlZFR5cGVGYWlsdXJlc1tlcnJvciQxLm1lc3NhZ2VdID0gdHJ1ZTtcbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KTtcblxuICAgICAgICAgIGVycm9yKCdGYWlsZWQgJXMgdHlwZTogJXMnLCBsb2NhdGlvbiwgZXJyb3IkMS5tZXNzYWdlKTtcblxuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KG51bGwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZWxlbWVudCkge1xuICB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIHZhciBvd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgdmFyIHN0YWNrID0gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKGVsZW1lbnQudHlwZSwgZWxlbWVudC5fc291cmNlLCBvd25lciA/IG93bmVyLnR5cGUgOiBudWxsKTtcbiAgICAgIHNldEV4dHJhU3RhY2tGcmFtZShzdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldEV4dHJhU3RhY2tGcmFtZShudWxsKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duO1xuXG57XG4gIHByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpIHtcbiAgaWYgKFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQpIHtcbiAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShSZWFjdEN1cnJlbnRPd25lci5jdXJyZW50LnR5cGUpO1xuXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIHJldHVybiAnXFxuXFxuQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBuYW1lICsgJ2AuJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtKHNvdXJjZSkge1xuICBpZiAoc291cmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgZmlsZU5hbWUgPSBzb3VyY2UuZmlsZU5hbWUucmVwbGFjZSgvXi4qW1xcXFxcXC9dLywgJycpO1xuICAgIHZhciBsaW5lTnVtYmVyID0gc291cmNlLmxpbmVOdW1iZXI7XG4gICAgcmV0dXJuICdcXG5cXG5DaGVjayB5b3VyIGNvZGUgYXQgJyArIGZpbGVOYW1lICsgJzonICsgbGluZU51bWJlciArICcuJztcbiAgfVxuXG4gIHJldHVybiAnJztcbn1cblxuZnVuY3Rpb24gZ2V0U291cmNlSW5mb0Vycm9yQWRkZW5kdW1Gb3JQcm9wcyhlbGVtZW50UHJvcHMpIHtcbiAgaWYgKGVsZW1lbnRQcm9wcyAhPT0gbnVsbCAmJiBlbGVtZW50UHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBnZXRTb3VyY2VJbmZvRXJyb3JBZGRlbmR1bShlbGVtZW50UHJvcHMuX19zb3VyY2UpO1xuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuLyoqXG4gKiBXYXJuIGlmIHRoZXJlJ3Mgbm8ga2V5IGV4cGxpY2l0bHkgc2V0IG9uIGR5bmFtaWMgYXJyYXlzIG9mIGNoaWxkcmVuIG9yXG4gKiBvYmplY3Qga2V5cyBhcmUgbm90IHZhbGlkLiBUaGlzIGFsbG93cyB1cyB0byBrZWVwIHRyYWNrIG9mIGNoaWxkcmVuIGJldHdlZW5cbiAqIHVwZGF0ZXMuXG4gKi9cblxuXG52YXIgb3duZXJIYXNLZXlVc2VXYXJuaW5nID0ge307XG5cbmZ1bmN0aW9uIGdldEN1cnJlbnRDb21wb25lbnRFcnJvckluZm8ocGFyZW50VHlwZSkge1xuICB2YXIgaW5mbyA9IGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpO1xuXG4gIGlmICghaW5mbykge1xuICAgIHZhciBwYXJlbnROYW1lID0gdHlwZW9mIHBhcmVudFR5cGUgPT09ICdzdHJpbmcnID8gcGFyZW50VHlwZSA6IHBhcmVudFR5cGUuZGlzcGxheU5hbWUgfHwgcGFyZW50VHlwZS5uYW1lO1xuXG4gICAgaWYgKHBhcmVudE5hbWUpIHtcbiAgICAgIGluZm8gPSBcIlxcblxcbkNoZWNrIHRoZSB0b3AtbGV2ZWwgcmVuZGVyIGNhbGwgdXNpbmcgPFwiICsgcGFyZW50TmFtZSArIFwiPi5cIjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaW5mbztcbn1cbi8qKlxuICogV2FybiBpZiB0aGUgZWxlbWVudCBkb2Vzbid0IGhhdmUgYW4gZXhwbGljaXQga2V5IGFzc2lnbmVkIHRvIGl0LlxuICogVGhpcyBlbGVtZW50IGlzIGluIGFuIGFycmF5LiBUaGUgYXJyYXkgY291bGQgZ3JvdyBhbmQgc2hyaW5rIG9yIGJlXG4gKiByZW9yZGVyZWQuIEFsbCBjaGlsZHJlbiB0aGF0IGhhdmVuJ3QgYWxyZWFkeSBiZWVuIHZhbGlkYXRlZCBhcmUgcmVxdWlyZWQgdG9cbiAqIGhhdmUgYSBcImtleVwiIHByb3BlcnR5IGFzc2lnbmVkIHRvIGl0LiBFcnJvciBzdGF0dXNlcyBhcmUgY2FjaGVkIHNvIGEgd2FybmluZ1xuICogd2lsbCBvbmx5IGJlIHNob3duIG9uY2UuXG4gKlxuICogQGludGVybmFsXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZWxlbWVudCBFbGVtZW50IHRoYXQgcmVxdWlyZXMgYSBrZXkuXG4gKiBAcGFyYW0geyp9IHBhcmVudFR5cGUgZWxlbWVudCdzIHBhcmVudCdzIHR5cGUuXG4gKi9cblxuXG5mdW5jdGlvbiB2YWxpZGF0ZUV4cGxpY2l0S2V5KGVsZW1lbnQsIHBhcmVudFR5cGUpIHtcbiAgaWYgKCFlbGVtZW50Ll9zdG9yZSB8fCBlbGVtZW50Ll9zdG9yZS52YWxpZGF0ZWQgfHwgZWxlbWVudC5rZXkgIT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGVsZW1lbnQuX3N0b3JlLnZhbGlkYXRlZCA9IHRydWU7XG4gIHZhciBjdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvID0gZ2V0Q3VycmVudENvbXBvbmVudEVycm9ySW5mbyhwYXJlbnRUeXBlKTtcblxuICBpZiAob3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgb3duZXJIYXNLZXlVc2VXYXJuaW5nW2N1cnJlbnRDb21wb25lbnRFcnJvckluZm9dID0gdHJ1ZTsgLy8gVXN1YWxseSB0aGUgY3VycmVudCBvd25lciBpcyB0aGUgb2ZmZW5kZXIsIGJ1dCBpZiBpdCBhY2NlcHRzIGNoaWxkcmVuIGFzIGFcbiAgLy8gcHJvcGVydHksIGl0IG1heSBiZSB0aGUgY3JlYXRvciBvZiB0aGUgY2hpbGQgdGhhdCdzIHJlc3BvbnNpYmxlIGZvclxuICAvLyBhc3NpZ25pbmcgaXQgYSBrZXkuXG5cbiAgdmFyIGNoaWxkT3duZXIgPSAnJztcblxuICBpZiAoZWxlbWVudCAmJiBlbGVtZW50Ll9vd25lciAmJiBlbGVtZW50Ll9vd25lciAhPT0gUmVhY3RDdXJyZW50T3duZXIuY3VycmVudCkge1xuICAgIC8vIEdpdmUgdGhlIGNvbXBvbmVudCB0aGF0IG9yaWdpbmFsbHkgY3JlYXRlZCB0aGlzIGNoaWxkLlxuICAgIGNoaWxkT3duZXIgPSBcIiBJdCB3YXMgcGFzc2VkIGEgY2hpbGQgZnJvbSBcIiArIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShlbGVtZW50Ll9vd25lci50eXBlKSArIFwiLlwiO1xuICB9XG5cbiAge1xuICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZWxlbWVudCk7XG5cbiAgICBlcnJvcignRWFjaCBjaGlsZCBpbiBhIGxpc3Qgc2hvdWxkIGhhdmUgYSB1bmlxdWUgXCJrZXlcIiBwcm9wLicgKyAnJXMlcyBTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3dhcm5pbmcta2V5cyBmb3IgbW9yZSBpbmZvcm1hdGlvbi4nLCBjdXJyZW50Q29tcG9uZW50RXJyb3JJbmZvLCBjaGlsZE93bmVyKTtcblxuICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEobnVsbCk7XG4gIH1cbn1cbi8qKlxuICogRW5zdXJlIHRoYXQgZXZlcnkgZWxlbWVudCBlaXRoZXIgaXMgcGFzc2VkIGluIGEgc3RhdGljIGxvY2F0aW9uLCBpbiBhblxuICogYXJyYXkgd2l0aCBhbiBleHBsaWNpdCBrZXlzIHByb3BlcnR5IGRlZmluZWQsIG9yIGluIGFuIG9iamVjdCBsaXRlcmFsXG4gKiB3aXRoIHZhbGlkIGtleSBwcm9wZXJ0eS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSB7UmVhY3ROb2RlfSBub2RlIFN0YXRpY2FsbHkgcGFzc2VkIGNoaWxkIG9mIGFueSB0eXBlLlxuICogQHBhcmFtIHsqfSBwYXJlbnRUeXBlIG5vZGUncyBwYXJlbnQncyB0eXBlLlxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVDaGlsZEtleXMobm9kZSwgcGFyZW50VHlwZSkge1xuICBpZiAodHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkobm9kZSkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjaGlsZCA9IG5vZGVbaV07XG5cbiAgICAgIGlmIChpc1ZhbGlkRWxlbWVudChjaGlsZCkpIHtcbiAgICAgICAgdmFsaWRhdGVFeHBsaWNpdEtleShjaGlsZCwgcGFyZW50VHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzVmFsaWRFbGVtZW50KG5vZGUpKSB7XG4gICAgLy8gVGhpcyBlbGVtZW50IHdhcyBwYXNzZWQgaW4gYSB2YWxpZCBsb2NhdGlvbi5cbiAgICBpZiAobm9kZS5fc3RvcmUpIHtcbiAgICAgIG5vZGUuX3N0b3JlLnZhbGlkYXRlZCA9IHRydWU7XG4gICAgfVxuICB9IGVsc2UgaWYgKG5vZGUpIHtcbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4obm9kZSk7XG5cbiAgICBpZiAodHlwZW9mIGl0ZXJhdG9yRm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIEVudHJ5IGl0ZXJhdG9ycyB1c2VkIHRvIHByb3ZpZGUgaW1wbGljaXQga2V5cyxcbiAgICAgIC8vIGJ1dCBub3cgd2UgcHJpbnQgYSBzZXBhcmF0ZSB3YXJuaW5nIGZvciB0aGVtIGxhdGVyLlxuICAgICAgaWYgKGl0ZXJhdG9yRm4gIT09IG5vZGUuZW50cmllcykge1xuICAgICAgICB2YXIgaXRlcmF0b3IgPSBpdGVyYXRvckZuLmNhbGwobm9kZSk7XG4gICAgICAgIHZhciBzdGVwO1xuXG4gICAgICAgIHdoaWxlICghKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmUpIHtcbiAgICAgICAgICBpZiAoaXNWYWxpZEVsZW1lbnQoc3RlcC52YWx1ZSkpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlRXhwbGljaXRLZXkoc3RlcC52YWx1ZSwgcGFyZW50VHlwZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEdpdmVuIGFuIGVsZW1lbnQsIHZhbGlkYXRlIHRoYXQgaXRzIHByb3BzIGZvbGxvdyB0aGUgcHJvcFR5cGVzIGRlZmluaXRpb24sXG4gKiBwcm92aWRlZCBieSB0aGUgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZWxlbWVudFxuICovXG5cblxuZnVuY3Rpb24gdmFsaWRhdGVQcm9wVHlwZXMoZWxlbWVudCkge1xuICB7XG4gICAgdmFyIHR5cGUgPSBlbGVtZW50LnR5cGU7XG5cbiAgICBpZiAodHlwZSA9PT0gbnVsbCB8fCB0eXBlID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHByb3BUeXBlcztcblxuICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvcFR5cGVzID0gdHlwZS5wcm9wVHlwZXM7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgKHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgfHwgLy8gTm90ZTogTWVtbyBvbmx5IGNoZWNrcyBvdXRlciBwcm9wcyBoZXJlLlxuICAgIC8vIElubmVyIHByb3BzIGFyZSBjaGVja2VkIGluIHRoZSByZWNvbmNpbGVyLlxuICAgIHR5cGUuJCR0eXBlb2YgPT09IFJFQUNUX01FTU9fVFlQRSkpIHtcbiAgICAgIHByb3BUeXBlcyA9IHR5cGUucHJvcFR5cGVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHByb3BUeXBlcykge1xuICAgICAgLy8gSW50ZW50aW9uYWxseSBpbnNpZGUgdG8gYXZvaWQgdHJpZ2dlcmluZyBsYXp5IGluaXRpYWxpemVyczpcbiAgICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpO1xuICAgICAgY2hlY2tQcm9wVHlwZXMocHJvcFR5cGVzLCBlbGVtZW50LnByb3BzLCAncHJvcCcsIG5hbWUsIGVsZW1lbnQpO1xuICAgIH0gZWxzZSBpZiAodHlwZS5Qcm9wVHlwZXMgIT09IHVuZGVmaW5lZCAmJiAhcHJvcFR5cGVzTWlzc3BlbGxXYXJuaW5nU2hvd24pIHtcbiAgICAgIHByb3BUeXBlc01pc3NwZWxsV2FybmluZ1Nob3duID0gdHJ1ZTsgLy8gSW50ZW50aW9uYWxseSBpbnNpZGUgdG8gYXZvaWQgdHJpZ2dlcmluZyBsYXp5IGluaXRpYWxpemVyczpcblxuICAgICAgdmFyIF9uYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpO1xuXG4gICAgICBlcnJvcignQ29tcG9uZW50ICVzIGRlY2xhcmVkIGBQcm9wVHlwZXNgIGluc3RlYWQgb2YgYHByb3BUeXBlc2AuIERpZCB5b3UgbWlzc3BlbGwgdGhlIHByb3BlcnR5IGFzc2lnbm1lbnQ/JywgX25hbWUgfHwgJ1Vua25vd24nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHR5cGUuZ2V0RGVmYXVsdFByb3BzID09PSAnZnVuY3Rpb24nICYmICF0eXBlLmdldERlZmF1bHRQcm9wcy5pc1JlYWN0Q2xhc3NBcHByb3ZlZCkge1xuICAgICAgZXJyb3IoJ2dldERlZmF1bHRQcm9wcyBpcyBvbmx5IHVzZWQgb24gY2xhc3NpYyBSZWFjdC5jcmVhdGVDbGFzcyAnICsgJ2RlZmluaXRpb25zLiBVc2UgYSBzdGF0aWMgcHJvcGVydHkgbmFtZWQgYGRlZmF1bHRQcm9wc2AgaW5zdGVhZC4nKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogR2l2ZW4gYSBmcmFnbWVudCwgdmFsaWRhdGUgdGhhdCBpdCBjYW4gb25seSBiZSBwcm92aWRlZCB3aXRoIGZyYWdtZW50IHByb3BzXG4gKiBAcGFyYW0ge1JlYWN0RWxlbWVudH0gZnJhZ21lbnRcbiAqL1xuXG5cbmZ1bmN0aW9uIHZhbGlkYXRlRnJhZ21lbnRQcm9wcyhmcmFnbWVudCkge1xuICB7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhmcmFnbWVudC5wcm9wcyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuXG4gICAgICBpZiAoa2V5ICE9PSAnY2hpbGRyZW4nICYmIGtleSAhPT0gJ2tleScpIHtcbiAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShmcmFnbWVudCk7XG5cbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgcHJvcCBgJXNgIHN1cHBsaWVkIHRvIGBSZWFjdC5GcmFnbWVudGAuICcgKyAnUmVhY3QuRnJhZ21lbnQgY2FuIG9ubHkgaGF2ZSBga2V5YCBhbmQgYGNoaWxkcmVuYCBwcm9wcy4nLCBrZXkpO1xuXG4gICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEobnVsbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChmcmFnbWVudC5yZWYgIT09IG51bGwpIHtcbiAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50JDEoZnJhZ21lbnQpO1xuXG4gICAgICBlcnJvcignSW52YWxpZCBhdHRyaWJ1dGUgYHJlZmAgc3VwcGxpZWQgdG8gYFJlYWN0LkZyYWdtZW50YC4nKTtcblxuICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQkMShudWxsKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnRXaXRoVmFsaWRhdGlvbih0eXBlLCBwcm9wcywgY2hpbGRyZW4pIHtcbiAgdmFyIHZhbGlkVHlwZSA9IGlzVmFsaWRFbGVtZW50VHlwZSh0eXBlKTsgLy8gV2Ugd2FybiBpbiB0aGlzIGNhc2UgYnV0IGRvbid0IHRocm93LiBXZSBleHBlY3QgdGhlIGVsZW1lbnQgY3JlYXRpb24gdG9cbiAgLy8gc3VjY2VlZCBhbmQgdGhlcmUgd2lsbCBsaWtlbHkgYmUgZXJyb3JzIGluIHJlbmRlci5cblxuICBpZiAoIXZhbGlkVHlwZSkge1xuICAgIHZhciBpbmZvID0gJyc7XG5cbiAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiB0eXBlID09PSAnb2JqZWN0JyAmJiB0eXBlICE9PSBudWxsICYmIE9iamVjdC5rZXlzKHR5cGUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaW5mbyArPSAnIFlvdSBsaWtlbHkgZm9yZ290IHRvIGV4cG9ydCB5b3VyIGNvbXBvbmVudCBmcm9tIHRoZSBmaWxlICcgKyBcIml0J3MgZGVmaW5lZCBpbiwgb3IgeW91IG1pZ2h0IGhhdmUgbWl4ZWQgdXAgZGVmYXVsdCBhbmQgbmFtZWQgaW1wb3J0cy5cIjtcbiAgICB9XG5cbiAgICB2YXIgc291cmNlSW5mbyA9IGdldFNvdXJjZUluZm9FcnJvckFkZGVuZHVtRm9yUHJvcHMocHJvcHMpO1xuXG4gICAgaWYgKHNvdXJjZUluZm8pIHtcbiAgICAgIGluZm8gKz0gc291cmNlSW5mbztcbiAgICB9IGVsc2Uge1xuICAgICAgaW5mbyArPSBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKTtcbiAgICB9XG5cbiAgICB2YXIgdHlwZVN0cmluZztcblxuICAgIGlmICh0eXBlID09PSBudWxsKSB7XG4gICAgICB0eXBlU3RyaW5nID0gJ251bGwnO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheSh0eXBlKSkge1xuICAgICAgdHlwZVN0cmluZyA9ICdhcnJheSc7XG4gICAgfSBlbHNlIGlmICh0eXBlICE9PSB1bmRlZmluZWQgJiYgdHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfRUxFTUVOVF9UWVBFKSB7XG4gICAgICB0eXBlU3RyaW5nID0gXCI8XCIgKyAoZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUudHlwZSkgfHwgJ1Vua25vd24nKSArIFwiIC8+XCI7XG4gICAgICBpbmZvID0gJyBEaWQgeW91IGFjY2lkZW50YWxseSBleHBvcnQgYSBKU1ggbGl0ZXJhbCBpbnN0ZWFkIG9mIGEgY29tcG9uZW50Pyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHR5cGVTdHJpbmcgPSB0eXBlb2YgdHlwZTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBlcnJvcignUmVhY3QuY3JlYXRlRWxlbWVudDogdHlwZSBpcyBpbnZhbGlkIC0tIGV4cGVjdGVkIGEgc3RyaW5nIChmb3IgJyArICdidWlsdC1pbiBjb21wb25lbnRzKSBvciBhIGNsYXNzL2Z1bmN0aW9uIChmb3IgY29tcG9zaXRlICcgKyAnY29tcG9uZW50cykgYnV0IGdvdDogJXMuJXMnLCB0eXBlU3RyaW5nLCBpbmZvKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gVGhlIHJlc3VsdCBjYW4gYmUgbnVsbGlzaCBpZiBhIG1vY2sgb3IgYSBjdXN0b20gZnVuY3Rpb24gaXMgdXNlZC5cbiAgLy8gVE9ETzogRHJvcCB0aGlzIHdoZW4gdGhlc2UgYXJlIG5vIGxvbmdlciBhbGxvd2VkIGFzIHRoZSB0eXBlIGFyZ3VtZW50LlxuXG4gIGlmIChlbGVtZW50ID09IG51bGwpIHtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfSAvLyBTa2lwIGtleSB3YXJuaW5nIGlmIHRoZSB0eXBlIGlzbid0IHZhbGlkIHNpbmNlIG91ciBrZXkgdmFsaWRhdGlvbiBsb2dpY1xuICAvLyBkb2Vzbid0IGV4cGVjdCBhIG5vbi1zdHJpbmcvZnVuY3Rpb24gdHlwZSBhbmQgY2FuIHRocm93IGNvbmZ1c2luZyBlcnJvcnMuXG4gIC8vIFdlIGRvbid0IHdhbnQgZXhjZXB0aW9uIGJlaGF2aW9yIHRvIGRpZmZlciBiZXR3ZWVuIGRldiBhbmQgcHJvZC5cbiAgLy8gKFJlbmRlcmluZyB3aWxsIHRocm93IHdpdGggYSBoZWxwZnVsIG1lc3NhZ2UgYW5kIGFzIHNvb24gYXMgdGhlIHR5cGUgaXNcbiAgLy8gZml4ZWQsIHRoZSBrZXkgd2FybmluZ3Mgd2lsbCBhcHBlYXIuKVxuXG5cbiAgaWYgKHZhbGlkVHlwZSkge1xuICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWxpZGF0ZUNoaWxkS2V5cyhhcmd1bWVudHNbaV0sIHR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFKSB7XG4gICAgdmFsaWRhdGVGcmFnbWVudFByb3BzKGVsZW1lbnQpO1xuICB9IGVsc2Uge1xuICAgIHZhbGlkYXRlUHJvcFR5cGVzKGVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG52YXIgZGlkV2FybkFib3V0RGVwcmVjYXRlZENyZWF0ZUZhY3RvcnkgPSBmYWxzZTtcbmZ1bmN0aW9uIGNyZWF0ZUZhY3RvcnlXaXRoVmFsaWRhdGlvbih0eXBlKSB7XG4gIHZhciB2YWxpZGF0ZWRGYWN0b3J5ID0gY3JlYXRlRWxlbWVudFdpdGhWYWxpZGF0aW9uLmJpbmQobnVsbCwgdHlwZSk7XG4gIHZhbGlkYXRlZEZhY3RvcnkudHlwZSA9IHR5cGU7XG5cbiAge1xuICAgIGlmICghZGlkV2FybkFib3V0RGVwcmVjYXRlZENyZWF0ZUZhY3RvcnkpIHtcbiAgICAgIGRpZFdhcm5BYm91dERlcHJlY2F0ZWRDcmVhdGVGYWN0b3J5ID0gdHJ1ZTtcblxuICAgICAgd2FybignUmVhY3QuY3JlYXRlRmFjdG9yeSgpIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAnICsgJ2EgZnV0dXJlIG1ham9yIHJlbGVhc2UuIENvbnNpZGVyIHVzaW5nIEpTWCAnICsgJ29yIHVzZSBSZWFjdC5jcmVhdGVFbGVtZW50KCkgZGlyZWN0bHkgaW5zdGVhZC4nKTtcbiAgICB9IC8vIExlZ2FjeSBob29rOiByZW1vdmUgaXRcblxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHZhbGlkYXRlZEZhY3RvcnksICd0eXBlJywge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FybignRmFjdG9yeS50eXBlIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB0aGUgY2xhc3MgZGlyZWN0bHkgJyArICdiZWZvcmUgcGFzc2luZyBpdCB0byBjcmVhdGVGYWN0b3J5LicpO1xuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHlwZScsIHtcbiAgICAgICAgICB2YWx1ZTogdHlwZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdmFsaWRhdGVkRmFjdG9yeTtcbn1cbmZ1bmN0aW9uIGNsb25lRWxlbWVudFdpdGhWYWxpZGF0aW9uKGVsZW1lbnQsIHByb3BzLCBjaGlsZHJlbikge1xuICB2YXIgbmV3RWxlbWVudCA9IGNsb25lRWxlbWVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gIGZvciAodmFyIGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFsaWRhdGVDaGlsZEtleXMoYXJndW1lbnRzW2ldLCBuZXdFbGVtZW50LnR5cGUpO1xuICB9XG5cbiAgdmFsaWRhdGVQcm9wVHlwZXMobmV3RWxlbWVudCk7XG4gIHJldHVybiBuZXdFbGVtZW50O1xufVxuXG5mdW5jdGlvbiBzdGFydFRyYW5zaXRpb24oc2NvcGUsIG9wdGlvbnMpIHtcbiAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbjtcbiAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWcudHJhbnNpdGlvbiA9IHt9O1xuICB2YXIgY3VycmVudFRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uO1xuXG4gIHtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzID0gbmV3IFNldCgpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBzY29wZSgpO1xuICB9IGZpbmFsbHkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcblxuICAgIHtcbiAgICAgIGlmIChwcmV2VHJhbnNpdGlvbiA9PT0gbnVsbCAmJiBjdXJyZW50VHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycykge1xuICAgICAgICB2YXIgdXBkYXRlZEZpYmVyc0NvdW50ID0gY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMuc2l6ZTtcblxuICAgICAgICBpZiAodXBkYXRlZEZpYmVyc0NvdW50ID4gMTApIHtcbiAgICAgICAgICB3YXJuKCdEZXRlY3RlZCBhIGxhcmdlIG51bWJlciBvZiB1cGRhdGVzIGluc2lkZSBzdGFydFRyYW5zaXRpb24uICcgKyAnSWYgdGhpcyBpcyBkdWUgdG8gYSBzdWJzY3JpcHRpb24gcGxlYXNlIHJlLXdyaXRlIGl0IHRvIHVzZSBSZWFjdCBwcm92aWRlZCBob29rcy4gJyArICdPdGhlcndpc2UgY29uY3VycmVudCBtb2RlIGd1YXJhbnRlZXMgYXJlIG9mZiB0aGUgdGFibGUuJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50VHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycy5jbGVhcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgZGlkV2FybkFib3V0TWVzc2FnZUNoYW5uZWwgPSBmYWxzZTtcbnZhciBlbnF1ZXVlVGFza0ltcGwgPSBudWxsO1xuZnVuY3Rpb24gZW5xdWV1ZVRhc2sodGFzaykge1xuICBpZiAoZW5xdWV1ZVRhc2tJbXBsID09PSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIHJlYWQgcmVxdWlyZSBvZmYgdGhlIG1vZHVsZSBvYmplY3QgdG8gZ2V0IGFyb3VuZCB0aGUgYnVuZGxlcnMuXG4gICAgICAvLyB3ZSBkb24ndCB3YW50IHRoZW0gdG8gZGV0ZWN0IGEgcmVxdWlyZSBhbmQgYnVuZGxlIGEgTm9kZSBwb2x5ZmlsbC5cbiAgICAgIHZhciByZXF1aXJlU3RyaW5nID0gKCdyZXF1aXJlJyArIE1hdGgucmFuZG9tKCkpLnNsaWNlKDAsIDcpO1xuICAgICAgdmFyIG5vZGVSZXF1aXJlID0gbW9kdWxlICYmIG1vZHVsZVtyZXF1aXJlU3RyaW5nXTsgLy8gYXNzdW1pbmcgd2UncmUgaW4gbm9kZSwgbGV0J3MgdHJ5IHRvIGdldCBub2RlJ3NcbiAgICAgIC8vIHZlcnNpb24gb2Ygc2V0SW1tZWRpYXRlLCBieXBhc3NpbmcgZmFrZSB0aW1lcnMgaWYgYW55LlxuXG4gICAgICBlbnF1ZXVlVGFza0ltcGwgPSBub2RlUmVxdWlyZS5jYWxsKG1vZHVsZSwgJ3RpbWVycycpLnNldEltbWVkaWF0ZTtcbiAgICB9IGNhdGNoIChfZXJyKSB7XG4gICAgICAvLyB3ZSdyZSBpbiBhIGJyb3dzZXJcbiAgICAgIC8vIHdlIGNhbid0IHVzZSByZWd1bGFyIHRpbWVycyBiZWNhdXNlIHRoZXkgbWF5IHN0aWxsIGJlIGZha2VkXG4gICAgICAvLyBzbyB3ZSB0cnkgTWVzc2FnZUNoYW5uZWwrcG9zdE1lc3NhZ2UgaW5zdGVhZFxuICAgICAgZW5xdWV1ZVRhc2tJbXBsID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoZGlkV2FybkFib3V0TWVzc2FnZUNoYW5uZWwgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkaWRXYXJuQWJvdXRNZXNzYWdlQ2hhbm5lbCA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgTWVzc2FnZUNoYW5uZWwgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIGVycm9yKCdUaGlzIGJyb3dzZXIgZG9lcyBub3QgaGF2ZSBhIE1lc3NhZ2VDaGFubmVsIGltcGxlbWVudGF0aW9uLCAnICsgJ3NvIGVucXVldWluZyB0YXNrcyB2aWEgYXdhaXQgYWN0KGFzeW5jICgpID0+IC4uLikgd2lsbCBmYWlsLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMgJyArICdpZiB5b3UgZW5jb3VudGVyIHRoaXMgd2FybmluZy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGNhbGxiYWNrO1xuICAgICAgICBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKHVuZGVmaW5lZCk7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbnF1ZXVlVGFza0ltcGwodGFzayk7XG59XG5cbnZhciBhY3RTY29wZURlcHRoID0gMDtcbnZhciBkaWRXYXJuTm9Bd2FpdEFjdCA9IGZhbHNlO1xuZnVuY3Rpb24gYWN0KGNhbGxiYWNrKSB7XG4gIHtcbiAgICAvLyBgYWN0YCBjYWxscyBjYW4gYmUgbmVzdGVkLCBzbyB3ZSB0cmFjayB0aGUgZGVwdGguIFRoaXMgcmVwcmVzZW50cyB0aGVcbiAgICAvLyBudW1iZXIgb2YgYGFjdGAgc2NvcGVzIG9uIHRoZSBzdGFjay5cbiAgICB2YXIgcHJldkFjdFNjb3BlRGVwdGggPSBhY3RTY29wZURlcHRoO1xuICAgIGFjdFNjb3BlRGVwdGgrKztcblxuICAgIGlmIChSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBvdXRlcm1vc3QgYGFjdGAgc2NvcGUuIEluaXRpYWxpemUgdGhlIHF1ZXVlLiBUaGUgcmVjb25jaWxlclxuICAgICAgLy8gd2lsbCBkZXRlY3QgdGhlIHF1ZXVlIGFuZCB1c2UgaXQgaW5zdGVhZCBvZiBTY2hlZHVsZXIuXG4gICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gW107XG4gICAgfVxuXG4gICAgdmFyIHByZXZJc0JhdGNoaW5nTGVnYWN5ID0gUmVhY3RDdXJyZW50QWN0UXVldWUuaXNCYXRjaGluZ0xlZ2FjeTtcbiAgICB2YXIgcmVzdWx0O1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZWQgdG8gcmVwcm9kdWNlIGJlaGF2aW9yIG9mIGBiYXRjaGVkVXBkYXRlc2AgaW4gbGVnYWN5IG1vZGUuIE9ubHlcbiAgICAgIC8vIHNldCB0byBgdHJ1ZWAgd2hpbGUgdGhlIGdpdmVuIGNhbGxiYWNrIGlzIGV4ZWN1dGVkLCBub3QgZm9yIHVwZGF0ZXNcbiAgICAgIC8vIHRyaWdnZXJlZCBkdXJpbmcgYW4gYXN5bmMgZXZlbnQsIGJlY2F1c2UgdGhpcyBpcyBob3cgdGhlIGxlZ2FjeVxuICAgICAgLy8gaW1wbGVtZW50YXRpb24gb2YgYGFjdGAgYmVoYXZlZC5cbiAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmlzQmF0Y2hpbmdMZWdhY3kgPSB0cnVlO1xuICAgICAgcmVzdWx0ID0gY2FsbGJhY2soKTsgLy8gUmVwbGljYXRlIGJlaGF2aW9yIG9mIG9yaWdpbmFsIGBhY3RgIGltcGxlbWVudGF0aW9uIGluIGxlZ2FjeSBtb2RlLFxuICAgICAgLy8gd2hpY2ggZmx1c2hlZCB1cGRhdGVzIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBzY29wZSBmdW5jdGlvbiBleGl0cywgZXZlblxuICAgICAgLy8gaWYgaXQncyBhbiBhc3luYyBmdW5jdGlvbi5cblxuICAgICAgaWYgKCFwcmV2SXNCYXRjaGluZ0xlZ2FjeSAmJiBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5kaWRTY2hlZHVsZUxlZ2FjeVVwZGF0ZSkge1xuICAgICAgICB2YXIgcXVldWUgPSBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50O1xuXG4gICAgICAgIGlmIChxdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmRpZFNjaGVkdWxlTGVnYWN5VXBkYXRlID0gZmFsc2U7XG4gICAgICAgICAgZmx1c2hBY3RRdWV1ZShxdWV1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcG9wQWN0U2NvcGUocHJldkFjdFNjb3BlRGVwdGgpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmlzQmF0Y2hpbmdMZWdhY3kgPSBwcmV2SXNCYXRjaGluZ0xlZ2FjeTtcbiAgICB9XG5cbiAgICBpZiAocmVzdWx0ICE9PSBudWxsICYmIHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIHRoZW5hYmxlUmVzdWx0ID0gcmVzdWx0OyAvLyBUaGUgY2FsbGJhY2sgaXMgYW4gYXN5bmMgZnVuY3Rpb24gKGkuZS4gcmV0dXJuZWQgYSBwcm9taXNlKS4gV2FpdFxuICAgICAgLy8gZm9yIGl0IHRvIHJlc29sdmUgYmVmb3JlIGV4aXRpbmcgdGhlIGN1cnJlbnQgc2NvcGUuXG5cbiAgICAgIHZhciB3YXNBd2FpdGVkID0gZmFsc2U7XG4gICAgICB2YXIgdGhlbmFibGUgPSB7XG4gICAgICAgIHRoZW46IGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICB3YXNBd2FpdGVkID0gdHJ1ZTtcbiAgICAgICAgICB0aGVuYWJsZVJlc3VsdC50aGVuKGZ1bmN0aW9uIChyZXR1cm5WYWx1ZSkge1xuICAgICAgICAgICAgcG9wQWN0U2NvcGUocHJldkFjdFNjb3BlRGVwdGgpO1xuXG4gICAgICAgICAgICBpZiAoYWN0U2NvcGVEZXB0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAvLyBXZSd2ZSBleGl0ZWQgdGhlIG91dGVybW9zdCBhY3Qgc2NvcGUuIFJlY3Vyc2l2ZWx5IGZsdXNoIHRoZVxuICAgICAgICAgICAgICAvLyBxdWV1ZSB1bnRpbCB0aGVyZSdzIG5vIHJlbWFpbmluZyB3b3JrLlxuICAgICAgICAgICAgICByZWN1cnNpdmVseUZsdXNoQXN5bmNBY3RXb3JrKHJldHVyblZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShyZXR1cm5WYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgdGhyZXcgYW4gZXJyb3IuXG4gICAgICAgICAgICBwb3BBY3RTY29wZShwcmV2QWN0U2NvcGVEZXB0aCk7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB7XG4gICAgICAgIGlmICghZGlkV2Fybk5vQXdhaXRBY3QgJiYgdHlwZW9mIFByb21pc2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7fSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIXdhc0F3YWl0ZWQpIHtcbiAgICAgICAgICAgICAgZGlkV2Fybk5vQXdhaXRBY3QgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGVycm9yKCdZb3UgY2FsbGVkIGFjdChhc3luYyAoKSA9PiAuLi4pIHdpdGhvdXQgYXdhaXQuICcgKyAnVGhpcyBjb3VsZCBsZWFkIHRvIHVuZXhwZWN0ZWQgdGVzdGluZyBiZWhhdmlvdXIsICcgKyAnaW50ZXJsZWF2aW5nIG11bHRpcGxlIGFjdCBjYWxscyBhbmQgbWl4aW5nIHRoZWlyICcgKyAnc2NvcGVzLiAnICsgJ1lvdSBzaG91bGQgLSBhd2FpdCBhY3QoYXN5bmMgKCkgPT4gLi4uKTsnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhlbmFibGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciByZXR1cm5WYWx1ZSA9IHJlc3VsdDsgLy8gVGhlIGNhbGxiYWNrIGlzIG5vdCBhbiBhc3luYyBmdW5jdGlvbi4gRXhpdCB0aGUgY3VycmVudCBzY29wZVxuICAgICAgLy8gaW1tZWRpYXRlbHksIHdpdGhvdXQgYXdhaXRpbmcuXG5cbiAgICAgIHBvcEFjdFNjb3BlKHByZXZBY3RTY29wZURlcHRoKTtcblxuICAgICAgaWYgKGFjdFNjb3BlRGVwdGggPT09IDApIHtcbiAgICAgICAgLy8gRXhpdGluZyB0aGUgb3V0ZXJtb3N0IGFjdCBzY29wZS4gRmx1c2ggdGhlIHF1ZXVlLlxuICAgICAgICB2YXIgX3F1ZXVlID0gUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudDtcblxuICAgICAgICBpZiAoX3F1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgICAgZmx1c2hBY3RRdWV1ZShfcXVldWUpO1xuICAgICAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICB9IC8vIFJldHVybiBhIHRoZW5hYmxlLiBJZiB0aGUgdXNlciBhd2FpdHMgaXQsIHdlJ2xsIGZsdXNoIGFnYWluIGluXG4gICAgICAgIC8vIGNhc2UgYWRkaXRpb25hbCB3b3JrIHdhcyBzY2hlZHVsZWQgYnkgYSBtaWNyb3Rhc2suXG5cblxuICAgICAgICB2YXIgX3RoZW5hYmxlID0ge1xuICAgICAgICAgIHRoZW46IGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIC8vIENvbmZpcm0gd2UgaGF2ZW4ndCByZS1lbnRlcmVkIGFub3RoZXIgYGFjdGAgc2NvcGUsIGluIGNhc2VcbiAgICAgICAgICAgIC8vIHRoZSB1c2VyIGRvZXMgc29tZXRoaW5nIHdlaXJkIGxpa2UgYXdhaXQgdGhlIHRoZW5hYmxlXG4gICAgICAgICAgICAvLyBtdWx0aXBsZSB0aW1lcy5cbiAgICAgICAgICAgIGlmIChSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGZsdXNoIHRoZSBxdWV1ZSB1bnRpbCB0aGVyZSdzIG5vIHJlbWFpbmluZyB3b3JrLlxuICAgICAgICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gW107XG4gICAgICAgICAgICAgIHJlY3Vyc2l2ZWx5Rmx1c2hBc3luY0FjdFdvcmsocmV0dXJuVmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfdGhlbmFibGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTaW5jZSB3ZSdyZSBpbnNpZGUgYSBuZXN0ZWQgYGFjdGAgc2NvcGUsIHRoZSByZXR1cm5lZCB0aGVuYWJsZVxuICAgICAgICAvLyBpbW1lZGlhdGVseSByZXNvbHZlcy4gVGhlIG91dGVyIHNjb3BlIHdpbGwgZmx1c2ggdGhlIHF1ZXVlLlxuICAgICAgICB2YXIgX3RoZW5hYmxlMiA9IHtcbiAgICAgICAgICB0aGVuOiBmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBfdGhlbmFibGUyO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwb3BBY3RTY29wZShwcmV2QWN0U2NvcGVEZXB0aCkge1xuICB7XG4gICAgaWYgKHByZXZBY3RTY29wZURlcHRoICE9PSBhY3RTY29wZURlcHRoIC0gMSkge1xuICAgICAgZXJyb3IoJ1lvdSBzZWVtIHRvIGhhdmUgb3ZlcmxhcHBpbmcgYWN0KCkgY2FsbHMsIHRoaXMgaXMgbm90IHN1cHBvcnRlZC4gJyArICdCZSBzdXJlIHRvIGF3YWl0IHByZXZpb3VzIGFjdCgpIGNhbGxzIGJlZm9yZSBtYWtpbmcgYSBuZXcgb25lLiAnKTtcbiAgICB9XG5cbiAgICBhY3RTY29wZURlcHRoID0gcHJldkFjdFNjb3BlRGVwdGg7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVjdXJzaXZlbHlGbHVzaEFzeW5jQWN0V29yayhyZXR1cm5WYWx1ZSwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHtcbiAgICB2YXIgcXVldWUgPSBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50O1xuXG4gICAgaWYgKHF1ZXVlICE9PSBudWxsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBmbHVzaEFjdFF1ZXVlKHF1ZXVlKTtcbiAgICAgICAgZW5xdWV1ZVRhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIE5vIGFkZGl0aW9uYWwgd29yayB3YXMgc2NoZWR1bGVkLiBGaW5pc2guXG4gICAgICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZS5jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgICAgIHJlc29sdmUocmV0dXJuVmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBLZWVwIGZsdXNoaW5nIHdvcmsgdW50aWwgdGhlcmUncyBub25lIGxlZnQuXG4gICAgICAgICAgICByZWN1cnNpdmVseUZsdXNoQXN5bmNBY3RXb3JrKHJldHVyblZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHZlKHJldHVyblZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIGlzRmx1c2hpbmcgPSBmYWxzZTtcblxuZnVuY3Rpb24gZmx1c2hBY3RRdWV1ZShxdWV1ZSkge1xuICB7XG4gICAgaWYgKCFpc0ZsdXNoaW5nKSB7XG4gICAgICAvLyBQcmV2ZW50IHJlLWVudHJhbmNlLlxuICAgICAgaXNGbHVzaGluZyA9IHRydWU7XG4gICAgICB2YXIgaSA9IDA7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBxdWV1ZVtpXTtcblxuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sodHJ1ZSk7XG4gICAgICAgICAgfSB3aGlsZSAoY2FsbGJhY2sgIT09IG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgcXVldWUubGVuZ3RoID0gMDtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIElmIHNvbWV0aGluZyB0aHJvd3MsIGxlYXZlIHRoZSByZW1haW5pbmcgY2FsbGJhY2tzIG9uIHRoZSBxdWV1ZS5cbiAgICAgICAgcXVldWUgPSBxdWV1ZS5zbGljZShpICsgMSk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaXNGbHVzaGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgY3JlYXRlRWxlbWVudCQxID0gIGNyZWF0ZUVsZW1lbnRXaXRoVmFsaWRhdGlvbiA7XG52YXIgY2xvbmVFbGVtZW50JDEgPSAgY2xvbmVFbGVtZW50V2l0aFZhbGlkYXRpb24gO1xudmFyIGNyZWF0ZUZhY3RvcnkgPSAgY3JlYXRlRmFjdG9yeVdpdGhWYWxpZGF0aW9uIDtcbnZhciBDaGlsZHJlbiA9IHtcbiAgbWFwOiBtYXBDaGlsZHJlbixcbiAgZm9yRWFjaDogZm9yRWFjaENoaWxkcmVuLFxuICBjb3VudDogY291bnRDaGlsZHJlbixcbiAgdG9BcnJheTogdG9BcnJheSxcbiAgb25seTogb25seUNoaWxkXG59O1xuXG5leHBvcnRzLkNoaWxkcmVuID0gQ2hpbGRyZW47XG5leHBvcnRzLkNvbXBvbmVudCA9IENvbXBvbmVudDtcbmV4cG9ydHMuRnJhZ21lbnQgPSBSRUFDVF9GUkFHTUVOVF9UWVBFO1xuZXhwb3J0cy5Qcm9maWxlciA9IFJFQUNUX1BST0ZJTEVSX1RZUEU7XG5leHBvcnRzLlB1cmVDb21wb25lbnQgPSBQdXJlQ29tcG9uZW50O1xuZXhwb3J0cy5TdHJpY3RNb2RlID0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRTtcbmV4cG9ydHMuU3VzcGVuc2UgPSBSRUFDVF9TVVNQRU5TRV9UWVBFO1xuZXhwb3J0cy5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRCA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzO1xuZXhwb3J0cy5jbG9uZUVsZW1lbnQgPSBjbG9uZUVsZW1lbnQkMTtcbmV4cG9ydHMuY3JlYXRlQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ7XG5leHBvcnRzLmNyZWF0ZUVsZW1lbnQgPSBjcmVhdGVFbGVtZW50JDE7XG5leHBvcnRzLmNyZWF0ZUZhY3RvcnkgPSBjcmVhdGVGYWN0b3J5O1xuZXhwb3J0cy5jcmVhdGVSZWYgPSBjcmVhdGVSZWY7XG5leHBvcnRzLmZvcndhcmRSZWYgPSBmb3J3YXJkUmVmO1xuZXhwb3J0cy5pc1ZhbGlkRWxlbWVudCA9IGlzVmFsaWRFbGVtZW50O1xuZXhwb3J0cy5sYXp5ID0gbGF6eTtcbmV4cG9ydHMubWVtbyA9IG1lbW87XG5leHBvcnRzLnN0YXJ0VHJhbnNpdGlvbiA9IHN0YXJ0VHJhbnNpdGlvbjtcbmV4cG9ydHMudW5zdGFibGVfYWN0ID0gYWN0O1xuZXhwb3J0cy51c2VDYWxsYmFjayA9IHVzZUNhbGxiYWNrO1xuZXhwb3J0cy51c2VDb250ZXh0ID0gdXNlQ29udGV4dDtcbmV4cG9ydHMudXNlRGVidWdWYWx1ZSA9IHVzZURlYnVnVmFsdWU7XG5leHBvcnRzLnVzZURlZmVycmVkVmFsdWUgPSB1c2VEZWZlcnJlZFZhbHVlO1xuZXhwb3J0cy51c2VFZmZlY3QgPSB1c2VFZmZlY3Q7XG5leHBvcnRzLnVzZUlkID0gdXNlSWQ7XG5leHBvcnRzLnVzZUltcGVyYXRpdmVIYW5kbGUgPSB1c2VJbXBlcmF0aXZlSGFuZGxlO1xuZXhwb3J0cy51c2VJbnNlcnRpb25FZmZlY3QgPSB1c2VJbnNlcnRpb25FZmZlY3Q7XG5leHBvcnRzLnVzZUxheW91dEVmZmVjdCA9IHVzZUxheW91dEVmZmVjdDtcbmV4cG9ydHMudXNlTWVtbyA9IHVzZU1lbW87XG5leHBvcnRzLnVzZVJlZHVjZXIgPSB1c2VSZWR1Y2VyO1xuZXhwb3J0cy51c2VSZWYgPSB1c2VSZWY7XG5leHBvcnRzLnVzZVN0YXRlID0gdXNlU3RhdGU7XG5leHBvcnRzLnVzZVN5bmNFeHRlcm5hbFN0b3JlID0gdXNlU3luY0V4dGVybmFsU3RvcmU7XG5leHBvcnRzLnVzZVRyYW5zaXRpb24gPSB1c2VUcmFuc2l0aW9uO1xuZXhwb3J0cy52ZXJzaW9uID0gUmVhY3RWZXJzaW9uO1xuICAgICAgICAgIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcCA9PT1cbiAgICAnZnVuY3Rpb24nXG4pIHtcbiAgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fLnJlZ2lzdGVySW50ZXJuYWxNb2R1bGVTdG9wKG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgXG4gIH0pKCk7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBtID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBtLmNyZWF0ZVJvb3Q7XG4gIGV4cG9ydHMuaHlkcmF0ZVJvb3QgPSBtLmh5ZHJhdGVSb290O1xufSBlbHNlIHtcbiAgdmFyIGkgPSBtLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBmdW5jdGlvbihjLCBvKSB7XG4gICAgaS51c2luZ0NsaWVudEVudHJ5UG9pbnQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbS5jcmVhdGVSb290KGMsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbiAgZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGZ1bmN0aW9uKGMsIGgsIG8pIHtcbiAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtLmh5ZHJhdGVSb290KGMsIGgsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gY2hlY2tEQ0UoKSB7XG4gIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbiAgaWYgKFxuICAgIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gPT09ICd1bmRlZmluZWQnIHx8XG4gICAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRSAhPT0gJ2Z1bmN0aW9uJ1xuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBUaGlzIGJyYW5jaCBpcyB1bnJlYWNoYWJsZSBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWRcbiAgICAvLyBpbiBwcm9kdWN0aW9uLCBidXQgdGhlIGNvbmRpdGlvbiBpcyB0cnVlIG9ubHkgaW4gZGV2ZWxvcG1lbnQuXG4gICAgLy8gVGhlcmVmb3JlIGlmIHRoZSBicmFuY2ggaXMgc3RpbGwgaGVyZSwgZGVhZCBjb2RlIGVsaW1pbmF0aW9uIHdhc24ndFxuICAgIC8vIHByb3Blcmx5IGFwcGxpZWQuXG4gICAgLy8gRG9uJ3QgY2hhbmdlIHRoZSBtZXNzYWdlLiBSZWFjdCBEZXZUb29scyByZWxpZXMgb24gaXQuIEFsc28gbWFrZSBzdXJlXG4gICAgLy8gdGhpcyBtZXNzYWdlIGRvZXNuJ3Qgb2NjdXIgZWxzZXdoZXJlIGluIHRoaXMgZnVuY3Rpb24sIG9yIGl0IHdpbGwgY2F1c2VcbiAgICAvLyBhIGZhbHNlIHBvc2l0aXZlLlxuICAgIHRocm93IG5ldyBFcnJvcignXl9eJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29kZSBhYm92ZSBoYXMgYmVlbiBkZWFkIGNvZGUgZWxpbWluYXRlZCAoRENFJ2QpLlxuICAgIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRShjaGVja0RDRSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIERldlRvb2xzIHNob3VsZG4ndCBjcmFzaCBSZWFjdCwgbm8gbWF0dGVyIHdoYXQuXG4gICAgLy8gV2Ugc2hvdWxkIHN0aWxsIHJlcG9ydCBpbiBjYXNlIHdlIGJyZWFrIHRoaXMgY29kZS5cbiAgICBjb25zb2xlLmVycm9yKGVycik7XG4gIH1cbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgLy8gRENFIGNoZWNrIHNob3VsZCBoYXBwZW4gYmVmb3JlIFJlYWN0RE9NIGJ1bmRsZSBleGVjdXRlcyBzbyB0aGF0XG4gIC8vIERldlRvb2xzIGNhbiByZXBvcnQgYmFkIG1pbmlmaWNhdGlvbiBkdXJpbmcgaW5qZWN0aW9uLlxuICBjaGVja0RDRSgpO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3JlYWN0LWRvbS5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20uZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2UgUmVhY3RcbiAqIHJlYWN0LWRvbS5kZXZlbG9wbWVudC5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQobmV3IEVycm9yKCkpO1xufVxuICAgICAgICAgIHZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgU2NoZWR1bGVyID0gcmVxdWlyZSgnc2NoZWR1bGVyJyk7XG5cbnZhciBSZWFjdFNoYXJlZEludGVybmFscyA9IFJlYWN0Ll9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuXG52YXIgc3VwcHJlc3NXYXJuaW5nID0gZmFsc2U7XG5mdW5jdGlvbiBzZXRTdXBwcmVzc1dhcm5pbmcobmV3U3VwcHJlc3NXYXJuaW5nKSB7XG4gIHtcbiAgICBzdXBwcmVzc1dhcm5pbmcgPSBuZXdTdXBwcmVzc1dhcm5pbmc7XG4gIH1cbn0gLy8gSW4gREVWLCBjYWxscyB0byBjb25zb2xlLndhcm4gYW5kIGNvbnNvbGUuZXJyb3IgZ2V0IHJlcGxhY2VkXG4vLyBieSBjYWxscyB0byB0aGVzZSBtZXRob2RzIGJ5IGEgQmFiZWwgcGx1Z2luLlxuLy9cbi8vIEluIFBST0QgKG9yIGluIHBhY2thZ2VzIHdpdGhvdXQgYWNjZXNzIHRvIFJlYWN0IGludGVybmFscyksXG4vLyB0aGV5IGFyZSBsZWZ0IGFzIHRoZXkgYXJlIGluc3RlYWQuXG5cbmZ1bmN0aW9uIHdhcm4oZm9ybWF0KSB7XG4gIHtcbiAgICBpZiAoIXN1cHByZXNzV2FybmluZykge1xuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgICBhcmdzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgIH1cblxuICAgICAgcHJpbnRXYXJuaW5nKCd3YXJuJywgZm9ybWF0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGVycm9yKGZvcm1hdCkge1xuICB7XG4gICAgaWYgKCFzdXBwcmVzc1dhcm5pbmcpIHtcbiAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiA+IDEgPyBfbGVuMiAtIDEgOiAwKSwgX2tleTIgPSAxOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgIGFyZ3NbX2tleTIgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICB9XG5cbiAgICAgIHByaW50V2FybmluZygnZXJyb3InLCBmb3JtYXQsIGFyZ3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBwcmludFdhcm5pbmcobGV2ZWwsIGZvcm1hdCwgYXJncykge1xuICAvLyBXaGVuIGNoYW5naW5nIHRoaXMgbG9naWMsIHlvdSBtaWdodCB3YW50IHRvIGFsc29cbiAgLy8gdXBkYXRlIGNvbnNvbGVXaXRoU3RhY2tEZXYud3d3LmpzIGFzIHdlbGwuXG4gIHtcbiAgICB2YXIgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0RGVidWdDdXJyZW50RnJhbWU7XG4gICAgdmFyIHN0YWNrID0gUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZS5nZXRTdGFja0FkZGVuZHVtKCk7XG5cbiAgICBpZiAoc3RhY2sgIT09ICcnKSB7XG4gICAgICBmb3JtYXQgKz0gJyVzJztcbiAgICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbc3RhY2tdKTtcbiAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuXG5cbiAgICB2YXIgYXJnc1dpdGhGb3JtYXQgPSBhcmdzLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIFN0cmluZyhpdGVtKTtcbiAgICB9KTsgLy8gQ2FyZWZ1bDogUk4gY3VycmVudGx5IGRlcGVuZHMgb24gdGhpcyBwcmVmaXhcblxuICAgIGFyZ3NXaXRoRm9ybWF0LnVuc2hpZnQoJ1dhcm5pbmc6ICcgKyBmb3JtYXQpOyAvLyBXZSBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBzcHJlYWQgKG9yIC5hcHBseSkgZGlyZWN0bHkgYmVjYXVzZSBpdFxuICAgIC8vIGJyZWFrcyBJRTk6IGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTM2MTBcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG5cbiAgICBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbChjb25zb2xlW2xldmVsXSwgY29uc29sZSwgYXJnc1dpdGhGb3JtYXQpO1xuICB9XG59XG5cbnZhciBGdW5jdGlvbkNvbXBvbmVudCA9IDA7XG52YXIgQ2xhc3NDb21wb25lbnQgPSAxO1xudmFyIEluZGV0ZXJtaW5hdGVDb21wb25lbnQgPSAyOyAvLyBCZWZvcmUgd2Uga25vdyB3aGV0aGVyIGl0IGlzIGZ1bmN0aW9uIG9yIGNsYXNzXG5cbnZhciBIb3N0Um9vdCA9IDM7IC8vIFJvb3Qgb2YgYSBob3N0IHRyZWUuIENvdWxkIGJlIG5lc3RlZCBpbnNpZGUgYW5vdGhlciBub2RlLlxuXG52YXIgSG9zdFBvcnRhbCA9IDQ7IC8vIEEgc3VidHJlZS4gQ291bGQgYmUgYW4gZW50cnkgcG9pbnQgdG8gYSBkaWZmZXJlbnQgcmVuZGVyZXIuXG5cbnZhciBIb3N0Q29tcG9uZW50ID0gNTtcbnZhciBIb3N0VGV4dCA9IDY7XG52YXIgRnJhZ21lbnQgPSA3O1xudmFyIE1vZGUgPSA4O1xudmFyIENvbnRleHRDb25zdW1lciA9IDk7XG52YXIgQ29udGV4dFByb3ZpZGVyID0gMTA7XG52YXIgRm9yd2FyZFJlZiA9IDExO1xudmFyIFByb2ZpbGVyID0gMTI7XG52YXIgU3VzcGVuc2VDb21wb25lbnQgPSAxMztcbnZhciBNZW1vQ29tcG9uZW50ID0gMTQ7XG52YXIgU2ltcGxlTWVtb0NvbXBvbmVudCA9IDE1O1xudmFyIExhenlDb21wb25lbnQgPSAxNjtcbnZhciBJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQgPSAxNztcbnZhciBEZWh5ZHJhdGVkRnJhZ21lbnQgPSAxODtcbnZhciBTdXNwZW5zZUxpc3RDb21wb25lbnQgPSAxOTtcbnZhciBTY29wZUNvbXBvbmVudCA9IDIxO1xudmFyIE9mZnNjcmVlbkNvbXBvbmVudCA9IDIyO1xudmFyIExlZ2FjeUhpZGRlbkNvbXBvbmVudCA9IDIzO1xudmFyIENhY2hlQ29tcG9uZW50ID0gMjQ7XG52YXIgVHJhY2luZ01hcmtlckNvbXBvbmVudCA9IDI1O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgZW5hYmxlQ2xpZW50UmVuZGVyRmFsbGJhY2tPblRleHRNaXNtYXRjaCA9IHRydWU7IC8vIFRPRE86IE5lZWQgdG8gcmV2aWV3IHRoaXMgY29kZSBvbmUgbW9yZSB0aW1lIGJlZm9yZSBsYW5kaW5nXG4vLyB0aGUgcmVhY3QtcmVjb25jaWxlciBwYWNrYWdlLlxuXG52YXIgZW5hYmxlTmV3UmVjb25jaWxlciA9IGZhbHNlOyAvLyBTdXBwb3J0IGxlZ2FjeSBQcmltZXIgc3VwcG9ydCBvbiBpbnRlcm5hbCBGQiB3d3dcblxudmFyIGVuYWJsZUxhenlDb250ZXh0UHJvcGFnYXRpb24gPSBmYWxzZTsgLy8gRkItb25seSB1c2FnZS4gVGhlIG5ldyBBUEkgaGFzIGRpZmZlcmVudCBzZW1hbnRpY3MuXG5cbnZhciBlbmFibGVMZWdhY3lIaWRkZW4gPSBmYWxzZTsgLy8gRW5hYmxlcyB1bnN0YWJsZV9hdm9pZFRoaXNGYWxsYmFjayBmZWF0dXJlIGluIEZpYmVyXG5cbnZhciBlbmFibGVTdXNwZW5zZUF2b2lkVGhpc0ZhbGxiYWNrID0gZmFsc2U7IC8vIEVuYWJsZXMgdW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgZmVhdHVyZSBpbiBGaXp6XG4vLyBSZWFjdCBET00gQ2hvcHBpbmcgQmxvY2tcbi8vXG4vLyBTaW1pbGFyIHRvIG1haW4gQ2hvcHBpbmcgQmxvY2sgYnV0IG9ubHkgZmxhZ3MgcmVsYXRlZCB0byBSZWFjdCBET00uIFRoZXNlIGFyZVxuLy8gZ3JvdXBlZCBiZWNhdXNlIHdlIHdpbGwgbGlrZWx5IGJhdGNoIGFsbCBvZiB0aGVtIGludG8gYSBzaW5nbGUgbWFqb3IgcmVsZWFzZS5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBEaXNhYmxlIHN1cHBvcnQgZm9yIGNvbW1lbnQgbm9kZXMgYXMgUmVhY3QgRE9NIGNvbnRhaW5lcnMuIEFscmVhZHkgZGlzYWJsZWRcbi8vIGluIG9wZW4gc291cmNlLCBidXQgd3d3IGNvZGViYXNlIHN0aWxsIHJlbGllcyBvbiBpdC4gTmVlZCB0byByZW1vdmUuXG5cbnZhciBkaXNhYmxlQ29tbWVudHNBc0RPTUNvbnRhaW5lcnMgPSB0cnVlOyAvLyBEaXNhYmxlIGphdmFzY3JpcHQ6IFVSTCBzdHJpbmdzIGluIGhyZWYgZm9yIFhTUyBwcm90ZWN0aW9uLlxuLy8gYW5kIGNsaWVudCByZW5kZXJpbmcsIG1vc3RseSB0byBhbGxvdyBKU1ggYXR0cmlidXRlcyB0byBhcHBseSB0byB0aGUgY3VzdG9tXG4vLyBlbGVtZW50J3Mgb2JqZWN0IHByb3BlcnRpZXMgaW5zdGVhZCBvZiBvbmx5IEhUTUwgYXR0cmlidXRlcy5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTEzNDdcblxudmFyIGVuYWJsZUN1c3RvbUVsZW1lbnRQcm9wZXJ0eVN1cHBvcnQgPSBmYWxzZTsgLy8gRGlzYWJsZXMgY2hpbGRyZW4gZm9yIDx0ZXh0YXJlYT4gZWxlbWVudHNcbnZhciB3YXJuQWJvdXRTdHJpbmdSZWZzID0gZmFsc2U7IC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBEZWJ1Z2dpbmcgYW5kIERldlRvb2xzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQWRkcyB1c2VyIHRpbWluZyBtYXJrcyBmb3IgZS5nLiBzdGF0ZSB1cGRhdGVzLCBzdXNwZW5zZSwgYW5kIHdvcmsgbG9vcCBzdHVmZixcbi8vIGZvciBhbiBleHBlcmltZW50YWwgdGltZWxpbmUgdG9vbC5cblxudmFyIGVuYWJsZVNjaGVkdWxpbmdQcm9maWxlciA9IHRydWU7IC8vIEhlbHBzIGlkZW50aWZ5IHNpZGUgZWZmZWN0cyBpbiByZW5kZXItcGhhc2UgbGlmZWN5Y2xlIGhvb2tzIGFuZCBzZXRTdGF0ZVxuXG52YXIgZW5hYmxlUHJvZmlsZXJUaW1lciA9IHRydWU7IC8vIFJlY29yZCBkdXJhdGlvbnMgZm9yIGNvbW1pdCBhbmQgcGFzc2l2ZSBlZmZlY3RzIHBoYXNlcy5cblxudmFyIGVuYWJsZVByb2ZpbGVyQ29tbWl0SG9va3MgPSB0cnVlOyAvLyBQaGFzZSBwYXJhbSBwYXNzZWQgdG8gb25SZW5kZXIgY2FsbGJhY2sgZGlmZmVyZW50aWF0ZXMgYmV0d2VlbiBhbiBcInVwZGF0ZVwiIGFuZCBhIFwiY2FzY2FkaW5nLXVwZGF0ZVwiLlxuXG52YXIgYWxsTmF0aXZlRXZlbnRzID0gbmV3IFNldCgpO1xuLyoqXG4gKiBNYXBwaW5nIGZyb20gcmVnaXN0cmF0aW9uIG5hbWUgdG8gZXZlbnQgbmFtZVxuICovXG5cblxudmFyIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMgPSB7fTtcbi8qKlxuICogTWFwcGluZyBmcm9tIGxvd2VyY2FzZSByZWdpc3RyYXRpb24gbmFtZXMgdG8gdGhlIHByb3Blcmx5IGNhc2VkIHZlcnNpb24sXG4gKiB1c2VkIHRvIHdhcm4gaW4gdGhlIGNhc2Ugb2YgbWlzc2luZyBldmVudCBoYW5kbGVycy4gQXZhaWxhYmxlXG4gKiBvbmx5IGluIHRydWUuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5cbnZhciBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzID0gIHt9IDsgLy8gVHJ1c3QgdGhlIGRldmVsb3BlciB0byBvbmx5IHVzZSBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzIGluIHRydWVcblxuZnVuY3Rpb24gcmVnaXN0ZXJUd29QaGFzZUV2ZW50KHJlZ2lzdHJhdGlvbk5hbWUsIGRlcGVuZGVuY2llcykge1xuICByZWdpc3RlckRpcmVjdEV2ZW50KHJlZ2lzdHJhdGlvbk5hbWUsIGRlcGVuZGVuY2llcyk7XG4gIHJlZ2lzdGVyRGlyZWN0RXZlbnQocmVnaXN0cmF0aW9uTmFtZSArICdDYXB0dXJlJywgZGVwZW5kZW5jaWVzKTtcbn1cbmZ1bmN0aW9uIHJlZ2lzdGVyRGlyZWN0RXZlbnQocmVnaXN0cmF0aW9uTmFtZSwgZGVwZW5kZW5jaWVzKSB7XG4gIHtcbiAgICBpZiAocmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llc1tyZWdpc3RyYXRpb25OYW1lXSkge1xuICAgICAgZXJyb3IoJ0V2ZW50UmVnaXN0cnk6IE1vcmUgdGhhbiBvbmUgcGx1Z2luIGF0dGVtcHRlZCB0byBwdWJsaXNoIHRoZSBzYW1lICcgKyAncmVnaXN0cmF0aW9uIG5hbWUsIGAlc2AuJywgcmVnaXN0cmF0aW9uTmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llc1tyZWdpc3RyYXRpb25OYW1lXSA9IGRlcGVuZGVuY2llcztcblxuICB7XG4gICAgdmFyIGxvd2VyQ2FzZWROYW1lID0gcmVnaXN0cmF0aW9uTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXNbbG93ZXJDYXNlZE5hbWVdID0gcmVnaXN0cmF0aW9uTmFtZTtcblxuICAgIGlmIChyZWdpc3RyYXRpb25OYW1lID09PSAnb25Eb3VibGVDbGljaycpIHtcbiAgICAgIHBvc3NpYmxlUmVnaXN0cmF0aW9uTmFtZXMub25kYmxjbGljayA9IHJlZ2lzdHJhdGlvbk5hbWU7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZXBlbmRlbmNpZXMubGVuZ3RoOyBpKyspIHtcbiAgICBhbGxOYXRpdmVFdmVudHMuYWRkKGRlcGVuZGVuY2llc1tpXSk7XG4gIH1cbn1cblxudmFyIGNhblVzZURPTSA9ICEhKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcpO1xuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKlxuICogVGhlIGAnJyArIHZhbHVlYCBwYXR0ZXJuICh1c2VkIGluIGluIHBlcmYtc2Vuc2l0aXZlIGNvZGUpIHRocm93cyBmb3IgU3ltYm9sXG4gKiBhbmQgVGVtcG9yYWwuKiB0eXBlcy4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIyMDY0LlxuICpcbiAqIFRoZSBmdW5jdGlvbnMgaW4gdGhpcyBtb2R1bGUgd2lsbCB0aHJvdyBhbiBlYXNpZXItdG8tdW5kZXJzdGFuZCxcbiAqIGVhc2llci10by1kZWJ1ZyBleGNlcHRpb24gd2l0aCBhIGNsZWFyIGVycm9ycyBtZXNzYWdlIG1lc3NhZ2UgZXhwbGFpbmluZyB0aGVcbiAqIHByb2JsZW0uIChJbnN0ZWFkIG9mIGEgY29uZnVzaW5nIGV4Y2VwdGlvbiB0aHJvd24gaW5zaWRlIHRoZSBpbXBsZW1lbnRhdGlvblxuICogb2YgdGhlIGB2YWx1ZWAgb2JqZWN0KS5cbiAqL1xuLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cbmZ1bmN0aW9uIHR5cGVOYW1lKHZhbHVlKSB7XG4gIHtcbiAgICAvLyB0b1N0cmluZ1RhZyBpcyBuZWVkZWQgZm9yIG5hbWVzcGFjZWQgdHlwZXMgbGlrZSBUZW1wb3JhbC5JbnN0YW50XG4gICAgdmFyIGhhc1RvU3RyaW5nVGFnID0gdHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wudG9TdHJpbmdUYWc7XG4gICAgdmFyIHR5cGUgPSBoYXNUb1N0cmluZ1RhZyAmJiB2YWx1ZVtTeW1ib2wudG9TdHJpbmdUYWddIHx8IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUgfHwgJ09iamVjdCc7XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cbn0gLy8gJEZsb3dGaXhNZSBvbmx5IGNhbGxlZCBpbiBERVYsIHNvIHZvaWQgcmV0dXJuIGlzIG5vdCBwb3NzaWJsZS5cblxuXG5mdW5jdGlvbiB3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkge1xuICB7XG4gICAgdHJ5IHtcbiAgICAgIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICAvLyBJZiB5b3UgZW5kZWQgdXAgaGVyZSBieSBmb2xsb3dpbmcgYW4gZXhjZXB0aW9uIGNhbGwgc3RhY2ssIGhlcmUncyB3aGF0J3NcbiAgLy8gaGFwcGVuZWQ6IHlvdSBzdXBwbGllZCBhbiBvYmplY3Qgb3Igc3ltYm9sIHZhbHVlIHRvIFJlYWN0IChhcyBhIHByb3AsIGtleSxcbiAgLy8gRE9NIGF0dHJpYnV0ZSwgQ1NTIHByb3BlcnR5LCBzdHJpbmcgcmVmLCBldGMuKSBhbmQgd2hlbiBSZWFjdCB0cmllZCB0b1xuICAvLyBjb2VyY2UgaXQgdG8gYSBzdHJpbmcgdXNpbmcgYCcnICsgdmFsdWVgLCBhbiBleGNlcHRpb24gd2FzIHRocm93bi5cbiAgLy9cbiAgLy8gVGhlIG1vc3QgY29tbW9uIHR5cGVzIHRoYXQgd2lsbCBjYXVzZSB0aGlzIGV4Y2VwdGlvbiBhcmUgYFN5bWJvbGAgaW5zdGFuY2VzXG4gIC8vIGFuZCBUZW1wb3JhbCBvYmplY3RzIGxpa2UgYFRlbXBvcmFsLkluc3RhbnRgLiBCdXQgYW55IG9iamVjdCB0aGF0IGhhcyBhXG4gIC8vIGB2YWx1ZU9mYCBvciBgW1N5bWJvbC50b1ByaW1pdGl2ZV1gIG1ldGhvZCB0aGF0IHRocm93cyB3aWxsIGFsc28gY2F1c2UgdGhpc1xuICAvLyBleGNlcHRpb24uIChMaWJyYXJ5IGF1dGhvcnMgZG8gdGhpcyB0byBwcmV2ZW50IHVzZXJzIGZyb20gdXNpbmcgYnVpbHQtaW5cbiAgLy8gbnVtZXJpYyBvcGVyYXRvcnMgbGlrZSBgK2Agb3IgY29tcGFyaXNvbiBvcGVyYXRvcnMgbGlrZSBgPj1gIGJlY2F1c2UgY3VzdG9tXG4gIC8vIG1ldGhvZHMgYXJlIG5lZWRlZCB0byBwZXJmb3JtIGFjY3VyYXRlIGFyaXRobWV0aWMgb3IgY29tcGFyaXNvbi4pXG4gIC8vXG4gIC8vIFRvIGZpeCB0aGUgcHJvYmxlbSwgY29lcmNlIHRoaXMgb2JqZWN0IG9yIHN5bWJvbCB2YWx1ZSB0byBhIHN0cmluZyBiZWZvcmVcbiAgLy8gcGFzc2luZyBpdCB0byBSZWFjdC4gVGhlIG1vc3QgcmVsaWFibGUgd2F5IGlzIHVzdWFsbHkgYFN0cmluZyh2YWx1ZSlgLlxuICAvL1xuICAvLyBUbyBmaW5kIHdoaWNoIHZhbHVlIGlzIHRocm93aW5nLCBjaGVjayB0aGUgYnJvd3NlciBvciBkZWJ1Z2dlciBjb25zb2xlLlxuICAvLyBCZWZvcmUgdGhpcyBleGNlcHRpb24gd2FzIHRocm93biwgdGhlcmUgc2hvdWxkIGJlIGBjb25zb2xlLmVycm9yYCBvdXRwdXRcbiAgLy8gdGhhdCBzaG93cyB0aGUgdHlwZSAoU3ltYm9sLCBUZW1wb3JhbC5QbGFpbkRhdGUsIGV0Yy4pIHRoYXQgY2F1c2VkIHRoZVxuICAvLyBwcm9ibGVtIGFuZCBob3cgdGhhdCB0eXBlIHdhcyB1c2VkOiBrZXksIGF0cnJpYnV0ZSwgaW5wdXQgdmFsdWUgcHJvcCwgZXRjLlxuICAvLyBJbiBtb3N0IGNhc2VzLCB0aGlzIGNvbnNvbGUgb3V0cHV0IGFsc28gc2hvd3MgdGhlIGNvbXBvbmVudCBhbmQgaXRzXG4gIC8vIGFuY2VzdG9yIGNvbXBvbmVudHMgd2hlcmUgdGhlIGV4Y2VwdGlvbiBoYXBwZW5lZC5cbiAgLy9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3NhZmUtc3RyaW5nLWNvZXJjaW9uXG4gIHJldHVybiAnJyArIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBhdHRyaWJ1dGVOYW1lKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignVGhlIHByb3ZpZGVkIGAlc2AgYXR0cmlidXRlIGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIGF0dHJpYnV0ZU5hbWUsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tLZXlTdHJpbmdDb2VyY2lvbih2YWx1ZSkge1xuICB7XG4gICAgaWYgKHdpbGxDb2VyY2lvblRocm93KHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1RoZSBwcm92aWRlZCBrZXkgaXMgYW4gdW5zdXBwb3J0ZWQgdHlwZSAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgdHlwZU5hbWUodmFsdWUpKTtcblxuICAgICAgcmV0dXJuIHRlc3RTdHJpbmdDb2VyY2lvbih2YWx1ZSk7IC8vIHRocm93ICh0byBoZWxwIGNhbGxlcnMgZmluZCB0cm91Ymxlc2hvb3RpbmcgY29tbWVudHMpXG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBjaGVja1Byb3BTdHJpbmdDb2VyY2lvbih2YWx1ZSwgcHJvcE5hbWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQgYCVzYCBwcm9wIGlzIGFuIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHByb3BOYW1lLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGNoZWNrQ1NTUHJvcGVydHlTdHJpbmdDb2VyY2lvbih2YWx1ZSwgcHJvcE5hbWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQgYCVzYCBDU1MgcHJvcGVydHkgaXMgYW4gdW5zdXBwb3J0ZWQgdHlwZSAlcy4nICsgJyBUaGlzIHZhbHVlIG11c3QgYmUgY29lcmNlZCB0byBhIHN0cmluZyBiZWZvcmUgYmVmb3JlIHVzaW5nIGl0IGhlcmUuJywgcHJvcE5hbWUsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tIdG1sU3RyaW5nQ29lcmNpb24odmFsdWUpIHtcbiAge1xuICAgIGlmICh3aWxsQ29lcmNpb25UaHJvdyh2YWx1ZSkpIHtcbiAgICAgIGVycm9yKCdUaGUgcHJvdmlkZWQgSFRNTCBtYXJrdXAgdXNlcyBhIHZhbHVlIG9mIHVuc3VwcG9ydGVkIHR5cGUgJXMuJyArICcgVGhpcyB2YWx1ZSBtdXN0IGJlIGNvZXJjZWQgdG8gYSBzdHJpbmcgYmVmb3JlIGJlZm9yZSB1c2luZyBpdCBoZXJlLicsIHR5cGVOYW1lKHZhbHVlKSk7XG5cbiAgICAgIHJldHVybiB0ZXN0U3RyaW5nQ29lcmNpb24odmFsdWUpOyAvLyB0aHJvdyAodG8gaGVscCBjYWxsZXJzIGZpbmQgdHJvdWJsZXNob290aW5nIGNvbW1lbnRzKVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY2hlY2tGb3JtRmllbGRWYWx1ZVN0cmluZ0NvZXJjaW9uKHZhbHVlKSB7XG4gIHtcbiAgICBpZiAod2lsbENvZXJjaW9uVGhyb3codmFsdWUpKSB7XG4gICAgICBlcnJvcignRm9ybSBmaWVsZCB2YWx1ZXMgKHZhbHVlLCBjaGVja2VkLCBkZWZhdWx0VmFsdWUsIG9yIGRlZmF1bHRDaGVja2VkIHByb3BzKScgKyAnIG11c3QgYmUgc3RyaW5ncywgbm90ICVzLicgKyAnIFRoaXMgdmFsdWUgbXVzdCBiZSBjb2VyY2VkIHRvIGEgc3RyaW5nIGJlZm9yZSBiZWZvcmUgdXNpbmcgaXQgaGVyZS4nLCB0eXBlTmFtZSh2YWx1ZSkpO1xuXG4gICAgICByZXR1cm4gdGVzdFN0cmluZ0NvZXJjaW9uKHZhbHVlKTsgLy8gdGhyb3cgKHRvIGhlbHAgY2FsbGVycyBmaW5kIHRyb3VibGVzaG9vdGluZyBjb21tZW50cylcbiAgICB9XG4gIH1cbn1cblxuLy8gQSByZXNlcnZlZCBhdHRyaWJ1dGUuXG4vLyBJdCBpcyBoYW5kbGVkIGJ5IFJlYWN0IHNlcGFyYXRlbHkgYW5kIHNob3VsZG4ndCBiZSB3cml0dGVuIHRvIHRoZSBET00uXG52YXIgUkVTRVJWRUQgPSAwOyAvLyBBIHNpbXBsZSBzdHJpbmcgYXR0cmlidXRlLlxuLy8gQXR0cmlidXRlcyB0aGF0IGFyZW4ndCBpbiB0aGUgZmlsdGVyIGFyZSBwcmVzdW1lZCB0byBoYXZlIHRoaXMgdHlwZS5cblxudmFyIFNUUklORyA9IDE7IC8vIEEgc3RyaW5nIGF0dHJpYnV0ZSB0aGF0IGFjY2VwdHMgYm9vbGVhbnMgaW4gUmVhY3QuIEluIEhUTUwsIHRoZXNlIGFyZSBjYWxsZWRcbi8vIFwiZW51bWVyYXRlZFwiIGF0dHJpYnV0ZXMgd2l0aCBcInRydWVcIiBhbmQgXCJmYWxzZVwiIGFzIHBvc3NpYmxlIHZhbHVlcy5cbi8vIFdoZW4gdHJ1ZSwgaXQgc2hvdWxkIGJlIHNldCB0byBhIFwidHJ1ZVwiIHN0cmluZy5cbi8vIFdoZW4gZmFsc2UsIGl0IHNob3VsZCBiZSBzZXQgdG8gYSBcImZhbHNlXCIgc3RyaW5nLlxuXG52YXIgQk9PTEVBTklTSF9TVFJJTkcgPSAyOyAvLyBBIHJlYWwgYm9vbGVhbiBhdHRyaWJ1dGUuXG4vLyBXaGVuIHRydWUsIGl0IHNob3VsZCBiZSBwcmVzZW50IChzZXQgZWl0aGVyIHRvIGFuIGVtcHR5IHN0cmluZyBvciBpdHMgbmFtZSkuXG4vLyBXaGVuIGZhbHNlLCBpdCBzaG91bGQgYmUgb21pdHRlZC5cblxudmFyIEJPT0xFQU4gPSAzOyAvLyBBbiBhdHRyaWJ1dGUgdGhhdCBjYW4gYmUgdXNlZCBhcyBhIGZsYWcgYXMgd2VsbCBhcyB3aXRoIGEgdmFsdWUuXG4vLyBXaGVuIHRydWUsIGl0IHNob3VsZCBiZSBwcmVzZW50IChzZXQgZWl0aGVyIHRvIGFuIGVtcHR5IHN0cmluZyBvciBpdHMgbmFtZSkuXG4vLyBXaGVuIGZhbHNlLCBpdCBzaG91bGQgYmUgb21pdHRlZC5cbi8vIEZvciBhbnkgb3RoZXIgdmFsdWUsIHNob3VsZCBiZSBwcmVzZW50IHdpdGggdGhhdCB2YWx1ZS5cblxudmFyIE9WRVJMT0FERURfQk9PTEVBTiA9IDQ7IC8vIEFuIGF0dHJpYnV0ZSB0aGF0IG11c3QgYmUgbnVtZXJpYyBvciBwYXJzZSBhcyBhIG51bWVyaWMuXG4vLyBXaGVuIGZhbHN5LCBpdCBzaG91bGQgYmUgcmVtb3ZlZC5cblxudmFyIE5VTUVSSUMgPSA1OyAvLyBBbiBhdHRyaWJ1dGUgdGhhdCBtdXN0IGJlIHBvc2l0aXZlIG51bWVyaWMgb3IgcGFyc2UgYXMgYSBwb3NpdGl2ZSBudW1lcmljLlxuLy8gV2hlbiBmYWxzeSwgaXQgc2hvdWxkIGJlIHJlbW92ZWQuXG5cbnZhciBQT1NJVElWRV9OVU1FUklDID0gNjtcblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xudmFyIEFUVFJJQlVURV9OQU1FX1NUQVJUX0NIQVIgPSBcIjpBLVpfYS16XFxcXHUwMEMwLVxcXFx1MDBENlxcXFx1MDBEOC1cXFxcdTAwRjZcXFxcdTAwRjgtXFxcXHUwMkZGXFxcXHUwMzcwLVxcXFx1MDM3RFxcXFx1MDM3Ri1cXFxcdTFGRkZcXFxcdTIwMEMtXFxcXHUyMDBEXFxcXHUyMDcwLVxcXFx1MjE4RlxcXFx1MkMwMC1cXFxcdTJGRUZcXFxcdTMwMDEtXFxcXHVEN0ZGXFxcXHVGOTAwLVxcXFx1RkRDRlxcXFx1RkRGMC1cXFxcdUZGRkRcIjtcbi8qIGVzbGludC1lbmFibGUgbWF4LWxlbiAqL1xuXG52YXIgQVRUUklCVVRFX05BTUVfQ0hBUiA9IEFUVFJJQlVURV9OQU1FX1NUQVJUX0NIQVIgKyBcIlxcXFwtLjAtOVxcXFx1MDBCN1xcXFx1MDMwMC1cXFxcdTAzNkZcXFxcdTIwM0YtXFxcXHUyMDQwXCI7XG52YXIgVkFMSURfQVRUUklCVVRFX05BTUVfUkVHRVggPSBuZXcgUmVnRXhwKCdeWycgKyBBVFRSSUJVVEVfTkFNRV9TVEFSVF9DSEFSICsgJ11bJyArIEFUVFJJQlVURV9OQU1FX0NIQVIgKyAnXSokJyk7XG52YXIgaWxsZWdhbEF0dHJpYnV0ZU5hbWVDYWNoZSA9IHt9O1xudmFyIHZhbGlkYXRlZEF0dHJpYnV0ZU5hbWVDYWNoZSA9IHt9O1xuZnVuY3Rpb24gaXNBdHRyaWJ1dGVOYW1lU2FmZShhdHRyaWJ1dGVOYW1lKSB7XG4gIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbGlkYXRlZEF0dHJpYnV0ZU5hbWVDYWNoZSwgYXR0cmlidXRlTmFtZSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGlsbGVnYWxBdHRyaWJ1dGVOYW1lQ2FjaGUsIGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKFZBTElEX0FUVFJJQlVURV9OQU1FX1JFR0VYLnRlc3QoYXR0cmlidXRlTmFtZSkpIHtcbiAgICB2YWxpZGF0ZWRBdHRyaWJ1dGVOYW1lQ2FjaGVbYXR0cmlidXRlTmFtZV0gPSB0cnVlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWxsZWdhbEF0dHJpYnV0ZU5hbWVDYWNoZVthdHRyaWJ1dGVOYW1lXSA9IHRydWU7XG5cbiAge1xuICAgIGVycm9yKCdJbnZhbGlkIGF0dHJpYnV0ZSBuYW1lOiBgJXNgJywgYXR0cmlidXRlTmFtZSk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBzaG91bGRJZ25vcmVBdHRyaWJ1dGUobmFtZSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICBpZiAocHJvcGVydHlJbmZvICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SW5mby50eXBlID09PSBSRVNFUlZFRDtcbiAgfVxuXG4gIGlmIChpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChuYW1lLmxlbmd0aCA+IDIgJiYgKG5hbWVbMF0gPT09ICdvJyB8fCBuYW1lWzBdID09PSAnTycpICYmIChuYW1lWzFdID09PSAnbicgfHwgbmFtZVsxXSA9PT0gJ04nKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gc2hvdWxkUmVtb3ZlQXR0cmlidXRlV2l0aFdhcm5pbmcobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgaWYgKHByb3BlcnR5SW5mbyAhPT0gbnVsbCAmJiBwcm9wZXJ0eUluZm8udHlwZSA9PT0gUkVTRVJWRUQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzd2l0Y2ggKHR5cGVvZiB2YWx1ZSkge1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzogLy8gJEZsb3dJc3N1ZSBzeW1ib2wgaXMgcGVyZmVjdGx5IHZhbGlkIGhlcmVcblxuICAgIGNhc2UgJ3N5bWJvbCc6XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAge1xuICAgICAgICBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcGVydHlJbmZvICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuICFwcm9wZXJ0eUluZm8uYWNjZXB0c0Jvb2xlYW5zO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBwcmVmaXggPSBuYW1lLnRvTG93ZXJDYXNlKCkuc2xpY2UoMCwgNSk7XG4gICAgICAgICAgcmV0dXJuIHByZWZpeCAhPT0gJ2RhdGEtJyAmJiBwcmVmaXggIT09ICdhcmlhLSc7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCB2YWx1ZSwgcHJvcGVydHlJbmZvLCBpc0N1c3RvbUNvbXBvbmVudFRhZykge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZVdpdGhXYXJuaW5nKG5hbWUsIHZhbHVlLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAocHJvcGVydHlJbmZvICE9PSBudWxsKSB7XG5cbiAgICBzd2l0Y2ggKHByb3BlcnR5SW5mby50eXBlKSB7XG4gICAgICBjYXNlIEJPT0xFQU46XG4gICAgICAgIHJldHVybiAhdmFsdWU7XG5cbiAgICAgIGNhc2UgT1ZFUkxPQURFRF9CT09MRUFOOlxuICAgICAgICByZXR1cm4gdmFsdWUgPT09IGZhbHNlO1xuXG4gICAgICBjYXNlIE5VTUVSSUM6XG4gICAgICAgIHJldHVybiBpc05hTih2YWx1ZSk7XG5cbiAgICAgIGNhc2UgUE9TSVRJVkVfTlVNRVJJQzpcbiAgICAgICAgcmV0dXJuIGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA8IDE7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gZ2V0UHJvcGVydHlJbmZvKG5hbWUpIHtcbiAgcmV0dXJuIHByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkobmFtZSkgPyBwcm9wZXJ0aWVzW25hbWVdIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIHR5cGUsIG11c3RVc2VQcm9wZXJ0eSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlTmFtZXNwYWNlLCBzYW5pdGl6ZVVSTCwgcmVtb3ZlRW1wdHlTdHJpbmcpIHtcbiAgdGhpcy5hY2NlcHRzQm9vbGVhbnMgPSB0eXBlID09PSBCT09MRUFOSVNIX1NUUklORyB8fCB0eXBlID09PSBCT09MRUFOIHx8IHR5cGUgPT09IE9WRVJMT0FERURfQk9PTEVBTjtcbiAgdGhpcy5hdHRyaWJ1dGVOYW1lID0gYXR0cmlidXRlTmFtZTtcbiAgdGhpcy5hdHRyaWJ1dGVOYW1lc3BhY2UgPSBhdHRyaWJ1dGVOYW1lc3BhY2U7XG4gIHRoaXMubXVzdFVzZVByb3BlcnR5ID0gbXVzdFVzZVByb3BlcnR5O1xuICB0aGlzLnByb3BlcnR5TmFtZSA9IG5hbWU7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMuc2FuaXRpemVVUkwgPSBzYW5pdGl6ZVVSTDtcbiAgdGhpcy5yZW1vdmVFbXB0eVN0cmluZyA9IHJlbW92ZUVtcHR5U3RyaW5nO1xufSAvLyBXaGVuIGFkZGluZyBhdHRyaWJ1dGVzIHRvIHRoaXMgbGlzdCwgYmUgc3VyZSB0byBhbHNvIGFkZCB0aGVtIHRvXG4vLyB0aGUgYHBvc3NpYmxlU3RhbmRhcmROYW1lc2AgbW9kdWxlIHRvIGVuc3VyZSBjYXNpbmcgYW5kIGluY29ycmVjdFxuLy8gbmFtZSB3YXJuaW5ncy5cblxuXG52YXIgcHJvcGVydGllcyA9IHt9OyAvLyBUaGVzZSBwcm9wcyBhcmUgcmVzZXJ2ZWQgYnkgUmVhY3QuIFRoZXkgc2hvdWxkbid0IGJlIHdyaXR0ZW4gdG8gdGhlIERPTS5cblxudmFyIHJlc2VydmVkUHJvcHMgPSBbJ2NoaWxkcmVuJywgJ2Rhbmdlcm91c2x5U2V0SW5uZXJIVE1MJywgLy8gVE9ETzogVGhpcyBwcmV2ZW50cyB0aGUgYXNzaWdubWVudCBvZiBkZWZhdWx0VmFsdWUgdG8gcmVndWxhclxuLy8gZWxlbWVudHMgKG5vdCBqdXN0IGlucHV0cykuIE5vdyB0aGF0IFJlYWN0RE9NSW5wdXQgYXNzaWducyB0byB0aGVcbi8vIGRlZmF1bHRWYWx1ZSBwcm9wZXJ0eSAtLSBkbyB3ZSBuZWVkIHRoaXM/XG4nZGVmYXVsdFZhbHVlJywgJ2RlZmF1bHRDaGVja2VkJywgJ2lubmVySFRNTCcsICdzdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmcnLCAnc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nJywgJ3N0eWxlJ107XG5cbnJlc2VydmVkUHJvcHMuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBSRVNFUlZFRCwgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIEEgZmV3IFJlYWN0IHN0cmluZyBhdHRyaWJ1dGVzIGhhdmUgYSBkaWZmZXJlbnQgbmFtZS5cbi8vIFRoaXMgaXMgYSBtYXBwaW5nIGZyb20gUmVhY3QgcHJvcCBuYW1lcyB0byB0aGUgYXR0cmlidXRlIG5hbWVzLlxuXG5bWydhY2NlcHRDaGFyc2V0JywgJ2FjY2VwdC1jaGFyc2V0J10sIFsnY2xhc3NOYW1lJywgJ2NsYXNzJ10sIFsnaHRtbEZvcicsICdmb3InXSwgWydodHRwRXF1aXYnLCAnaHR0cC1lcXVpdiddXS5mb3JFYWNoKGZ1bmN0aW9uIChfcmVmKSB7XG4gIHZhciBuYW1lID0gX3JlZlswXSxcbiAgICAgIGF0dHJpYnV0ZU5hbWUgPSBfcmVmWzFdO1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgXCJlbnVtZXJhdGVkXCIgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgYWNjZXB0IFwidHJ1ZVwiIGFuZCBcImZhbHNlXCIuXG4vLyBJbiBSZWFjdCwgd2UgbGV0IHVzZXJzIHBhc3MgYHRydWVgIGFuZCBgZmFsc2VgIGV2ZW4gdGhvdWdoIHRlY2huaWNhbGx5XG4vLyB0aGVzZSBhcmVuJ3QgYm9vbGVhbiBhdHRyaWJ1dGVzICh0aGV5IGFyZSBjb2VyY2VkIHRvIHN0cmluZ3MpLlxuXG5bJ2NvbnRlbnRFZGl0YWJsZScsICdkcmFnZ2FibGUnLCAnc3BlbGxDaGVjaycsICd2YWx1ZSddLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgcHJvcGVydGllc1tuYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQobmFtZSwgQk9PTEVBTklTSF9TVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBcImVudW1lcmF0ZWRcIiBTVkcgYXR0cmlidXRlcyB0aGF0IGFjY2VwdCBcInRydWVcIiBhbmQgXCJmYWxzZVwiLlxuLy8gSW4gUmVhY3QsIHdlIGxldCB1c2VycyBwYXNzIGB0cnVlYCBhbmQgYGZhbHNlYCBldmVuIHRob3VnaCB0ZWNobmljYWxseVxuLy8gdGhlc2UgYXJlbid0IGJvb2xlYW4gYXR0cmlidXRlcyAodGhleSBhcmUgY29lcmNlZCB0byBzdHJpbmdzKS5cbi8vIFNpbmNlIHRoZXNlIGFyZSBTVkcgYXR0cmlidXRlcywgdGhlaXIgYXR0cmlidXRlIG5hbWVzIGFyZSBjYXNlLXNlbnNpdGl2ZS5cblxuWydhdXRvUmV2ZXJzZScsICdleHRlcm5hbFJlc291cmNlc1JlcXVpcmVkJywgJ2ZvY3VzYWJsZScsICdwcmVzZXJ2ZUFscGhhJ10uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBCT09MRUFOSVNIX1NUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBuYW1lLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSBIVE1MIGJvb2xlYW4gYXR0cmlidXRlcy5cblxuWydhbGxvd0Z1bGxTY3JlZW4nLCAnYXN5bmMnLCAvLyBOb3RlOiB0aGVyZSBpcyBhIHNwZWNpYWwgY2FzZSB0aGF0IHByZXZlbnRzIGl0IGZyb20gYmVpbmcgd3JpdHRlbiB0byB0aGUgRE9NXG4vLyBvbiB0aGUgY2xpZW50IHNpZGUgYmVjYXVzZSB0aGUgYnJvd3NlcnMgYXJlIGluY29uc2lzdGVudC4gSW5zdGVhZCB3ZSBjYWxsIGZvY3VzKCkuXG4nYXV0b0ZvY3VzJywgJ2F1dG9QbGF5JywgJ2NvbnRyb2xzJywgJ2RlZmF1bHQnLCAnZGVmZXInLCAnZGlzYWJsZWQnLCAnZGlzYWJsZVBpY3R1cmVJblBpY3R1cmUnLCAnZGlzYWJsZVJlbW90ZVBsYXliYWNrJywgJ2Zvcm1Ob1ZhbGlkYXRlJywgJ2hpZGRlbicsICdsb29wJywgJ25vTW9kdWxlJywgJ25vVmFsaWRhdGUnLCAnb3BlbicsICdwbGF5c0lubGluZScsICdyZWFkT25seScsICdyZXF1aXJlZCcsICdyZXZlcnNlZCcsICdzY29wZWQnLCAnc2VhbWxlc3MnLCAvLyBNaWNyb2RhdGFcbidpdGVtU2NvcGUnXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIEJPT0xFQU4sIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFRoZXNlIGFyZSB0aGUgZmV3IFJlYWN0IHByb3BzIHRoYXQgd2Ugc2V0IGFzIERPTSBwcm9wZXJ0aWVzXG4vLyByYXRoZXIgdGhhbiBhdHRyaWJ1dGVzLiBUaGVzZSBhcmUgYWxsIGJvb2xlYW5zLlxuXG5bJ2NoZWNrZWQnLCAvLyBOb3RlOiBgb3B0aW9uLnNlbGVjdGVkYCBpcyBub3QgdXBkYXRlZCBpZiBgc2VsZWN0Lm11bHRpcGxlYCBpc1xuLy8gZGlzYWJsZWQgd2l0aCBgcmVtb3ZlQXR0cmlidXRlYC4gV2UgaGF2ZSBzcGVjaWFsIGxvZ2ljIGZvciBoYW5kbGluZyB0aGlzLlxuJ211bHRpcGxlJywgJ211dGVkJywgJ3NlbGVjdGVkJyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBCT09MRUFOLCB0cnVlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgYXJlIFwib3ZlcmxvYWRlZCBib29sZWFuc1wiOiB0aGV5IGJlaGF2ZSBsaWtlXG4vLyBib29sZWFucywgYnV0IGNhbiBhbHNvIGFjY2VwdCBhIHN0cmluZyB2YWx1ZS5cblxuWydjYXB0dXJlJywgJ2Rvd25sb2FkJyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBPVkVSTE9BREVEX0JPT0xFQU4sIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgbXVzdCBiZSBwb3NpdGl2ZSBudW1iZXJzLlxuXG5bJ2NvbHMnLCAncm93cycsICdzaXplJywgJ3NwYW4nIC8vIE5PVEU6IGlmIHlvdSBhZGQgYSBjYW1lbENhc2VkIHByb3AgdG8gdGhpcyBsaXN0LFxuLy8geW91J2xsIG5lZWQgdG8gc2V0IGF0dHJpYnV0ZU5hbWUgdG8gbmFtZS50b0xvd2VyQ2FzZSgpXG4vLyBpbnN0ZWFkIGluIHRoZSBhc3NpZ25tZW50IGJlbG93LlxuXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFBPU0lUSVZFX05VTUVSSUMsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBUaGVzZSBhcmUgSFRNTCBhdHRyaWJ1dGVzIHRoYXQgbXVzdCBiZSBudW1iZXJzLlxuXG5bJ3Jvd1NwYW4nLCAnc3RhcnQnXS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIE5VTUVSSUMsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgbmFtZS50b0xvd2VyQ2FzZSgpLCAvLyBhdHRyaWJ1dGVOYW1lXG4gIG51bGwsIC8vIGF0dHJpYnV0ZU5hbWVzcGFjZVxuICBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7XG52YXIgQ0FNRUxJWkUgPSAvW1xcLVxcOl0oW2Etel0pL2c7XG5cbnZhciBjYXBpdGFsaXplID0gZnVuY3Rpb24gKHRva2VuKSB7XG4gIHJldHVybiB0b2tlblsxXS50b1VwcGVyQ2FzZSgpO1xufTsgLy8gVGhpcyBpcyBhIGxpc3Qgb2YgYWxsIFNWRyBhdHRyaWJ1dGVzIHRoYXQgbmVlZCBzcGVjaWFsIGNhc2luZywgbmFtZXNwYWNpbmcsXG4vLyBvciBib29sZWFuIHZhbHVlIGFzc2lnbm1lbnQuIFJlZ3VsYXIgYXR0cmlidXRlcyB0aGF0IGp1c3QgYWNjZXB0IHN0cmluZ3Ncbi8vIGFuZCBoYXZlIHRoZSBzYW1lIG5hbWVzIGFyZSBvbWl0dGVkLCBqdXN0IGxpa2UgaW4gdGhlIEhUTUwgYXR0cmlidXRlIGZpbHRlci5cbi8vIFNvbWUgb2YgdGhlc2UgYXR0cmlidXRlcyBjYW4gYmUgaGFyZCB0byBmaW5kLiBUaGlzIGxpc3Qgd2FzIGNyZWF0ZWQgYnlcbi8vIHNjcmFwaW5nIHRoZSBNRE4gZG9jdW1lbnRhdGlvbi5cblxuXG5bJ2FjY2VudC1oZWlnaHQnLCAnYWxpZ25tZW50LWJhc2VsaW5lJywgJ2FyYWJpYy1mb3JtJywgJ2Jhc2VsaW5lLXNoaWZ0JywgJ2NhcC1oZWlnaHQnLCAnY2xpcC1wYXRoJywgJ2NsaXAtcnVsZScsICdjb2xvci1pbnRlcnBvbGF0aW9uJywgJ2NvbG9yLWludGVycG9sYXRpb24tZmlsdGVycycsICdjb2xvci1wcm9maWxlJywgJ2NvbG9yLXJlbmRlcmluZycsICdkb21pbmFudC1iYXNlbGluZScsICdlbmFibGUtYmFja2dyb3VuZCcsICdmaWxsLW9wYWNpdHknLCAnZmlsbC1ydWxlJywgJ2Zsb29kLWNvbG9yJywgJ2Zsb29kLW9wYWNpdHknLCAnZm9udC1mYW1pbHknLCAnZm9udC1zaXplJywgJ2ZvbnQtc2l6ZS1hZGp1c3QnLCAnZm9udC1zdHJldGNoJywgJ2ZvbnQtc3R5bGUnLCAnZm9udC12YXJpYW50JywgJ2ZvbnQtd2VpZ2h0JywgJ2dseXBoLW5hbWUnLCAnZ2x5cGgtb3JpZW50YXRpb24taG9yaXpvbnRhbCcsICdnbHlwaC1vcmllbnRhdGlvbi12ZXJ0aWNhbCcsICdob3Jpei1hZHYteCcsICdob3Jpei1vcmlnaW4teCcsICdpbWFnZS1yZW5kZXJpbmcnLCAnbGV0dGVyLXNwYWNpbmcnLCAnbGlnaHRpbmctY29sb3InLCAnbWFya2VyLWVuZCcsICdtYXJrZXItbWlkJywgJ21hcmtlci1zdGFydCcsICdvdmVybGluZS1wb3NpdGlvbicsICdvdmVybGluZS10aGlja25lc3MnLCAncGFpbnQtb3JkZXInLCAncGFub3NlLTEnLCAncG9pbnRlci1ldmVudHMnLCAncmVuZGVyaW5nLWludGVudCcsICdzaGFwZS1yZW5kZXJpbmcnLCAnc3RvcC1jb2xvcicsICdzdG9wLW9wYWNpdHknLCAnc3RyaWtldGhyb3VnaC1wb3NpdGlvbicsICdzdHJpa2V0aHJvdWdoLXRoaWNrbmVzcycsICdzdHJva2UtZGFzaGFycmF5JywgJ3N0cm9rZS1kYXNob2Zmc2V0JywgJ3N0cm9rZS1saW5lY2FwJywgJ3N0cm9rZS1saW5lam9pbicsICdzdHJva2UtbWl0ZXJsaW1pdCcsICdzdHJva2Utb3BhY2l0eScsICdzdHJva2Utd2lkdGgnLCAndGV4dC1hbmNob3InLCAndGV4dC1kZWNvcmF0aW9uJywgJ3RleHQtcmVuZGVyaW5nJywgJ3VuZGVybGluZS1wb3NpdGlvbicsICd1bmRlcmxpbmUtdGhpY2tuZXNzJywgJ3VuaWNvZGUtYmlkaScsICd1bmljb2RlLXJhbmdlJywgJ3VuaXRzLXBlci1lbScsICd2LWFscGhhYmV0aWMnLCAndi1oYW5naW5nJywgJ3YtaWRlb2dyYXBoaWMnLCAndi1tYXRoZW1hdGljYWwnLCAndmVjdG9yLWVmZmVjdCcsICd2ZXJ0LWFkdi15JywgJ3ZlcnQtb3JpZ2luLXgnLCAndmVydC1vcmlnaW4teScsICd3b3JkLXNwYWNpbmcnLCAnd3JpdGluZy1tb2RlJywgJ3htbG5zOnhsaW5rJywgJ3gtaGVpZ2h0JyAvLyBOT1RFOiBpZiB5b3UgYWRkIGEgY2FtZWxDYXNlZCBwcm9wIHRvIHRoaXMgbGlzdCxcbi8vIHlvdSdsbCBuZWVkIHRvIHNldCBhdHRyaWJ1dGVOYW1lIHRvIG5hbWUudG9Mb3dlckNhc2UoKVxuLy8gaW5zdGVhZCBpbiB0aGUgYXNzaWdubWVudCBiZWxvdy5cbl0uZm9yRWFjaChmdW5jdGlvbiAoYXR0cmlidXRlTmFtZSkge1xuICB2YXIgbmFtZSA9IGF0dHJpYnV0ZU5hbWUucmVwbGFjZShDQU1FTElaRSwgY2FwaXRhbGl6ZSk7XG4gIHByb3BlcnRpZXNbbmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKG5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLCBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgZmFsc2UsIC8vIHNhbml0aXplVVJMXG4gIGZhbHNlKTtcbn0pOyAvLyBTdHJpbmcgU1ZHIGF0dHJpYnV0ZXMgd2l0aCB0aGUgeGxpbmsgbmFtZXNwYWNlLlxuXG5bJ3hsaW5rOmFjdHVhdGUnLCAneGxpbms6YXJjcm9sZScsICd4bGluazpyb2xlJywgJ3hsaW5rOnNob3cnLCAneGxpbms6dGl0bGUnLCAneGxpbms6dHlwZScgLy8gTk9URTogaWYgeW91IGFkZCBhIGNhbWVsQ2FzZWQgcHJvcCB0byB0aGlzIGxpc3QsXG4vLyB5b3UnbGwgbmVlZCB0byBzZXQgYXR0cmlidXRlTmFtZSB0byBuYW1lLnRvTG93ZXJDYXNlKClcbi8vIGluc3RlYWQgaW4gdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG5dLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgdmFyIG5hbWUgPSBhdHRyaWJ1dGVOYW1lLnJlcGxhY2UoQ0FNRUxJWkUsIGNhcGl0YWxpemUpO1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZSwgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCBmYWxzZSwgLy8gc2FuaXRpemVVUkxcbiAgZmFsc2UpO1xufSk7IC8vIFN0cmluZyBTVkcgYXR0cmlidXRlcyB3aXRoIHRoZSB4bWwgbmFtZXNwYWNlLlxuXG5bJ3htbDpiYXNlJywgJ3htbDpsYW5nJywgJ3htbDpzcGFjZScgLy8gTk9URTogaWYgeW91IGFkZCBhIGNhbWVsQ2FzZWQgcHJvcCB0byB0aGlzIGxpc3QsXG4vLyB5b3UnbGwgbmVlZCB0byBzZXQgYXR0cmlidXRlTmFtZSB0byBuYW1lLnRvTG93ZXJDYXNlKClcbi8vIGluc3RlYWQgaW4gdGhlIGFzc2lnbm1lbnQgYmVsb3cuXG5dLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgdmFyIG5hbWUgPSBhdHRyaWJ1dGVOYW1lLnJlcGxhY2UoQ0FNRUxJWkUsIGNhcGl0YWxpemUpO1xuICBwcm9wZXJ0aWVzW25hbWVdID0gbmV3IFByb3BlcnR5SW5mb1JlY29yZChuYW1lLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbiAgYXR0cmlidXRlTmFtZSwgJ2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZScsIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXR0cmlidXRlIGV4aXN0cyBib3RoIGluIEhUTUwgYW5kIFNWRy5cbi8vIFRoZSBhdHRyaWJ1dGUgbmFtZSBpcyBjYXNlLXNlbnNpdGl2ZSBpbiBTVkcgc28gd2UgY2FuJ3QganVzdCB1c2Vcbi8vIHRoZSBSZWFjdCBuYW1lIGxpa2Ugd2UgZG8gZm9yIGF0dHJpYnV0ZXMgdGhhdCBleGlzdCBvbmx5IGluIEhUTUwuXG5cblsndGFiSW5kZXgnLCAnY3Jvc3NPcmlnaW4nXS5mb3JFYWNoKGZ1bmN0aW9uIChhdHRyaWJ1dGVOYW1lKSB7XG4gIHByb3BlcnRpZXNbYXR0cmlidXRlTmFtZV0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKGF0dHJpYnV0ZU5hbWUsIFNUUklORywgZmFsc2UsIC8vIG11c3RVc2VQcm9wZXJ0eVxuICBhdHRyaWJ1dGVOYW1lLnRvTG93ZXJDYXNlKCksIC8vIGF0dHJpYnV0ZU5hbWVcbiAgbnVsbCwgLy8gYXR0cmlidXRlTmFtZXNwYWNlXG4gIGZhbHNlLCAvLyBzYW5pdGl6ZVVSTFxuICBmYWxzZSk7XG59KTsgLy8gVGhlc2UgYXR0cmlidXRlcyBhY2NlcHQgVVJMcy4gVGhlc2UgbXVzdCBub3QgYWxsb3cgamF2YXNjcmlwdDogVVJMUy5cbi8vIFRoZXNlIHdpbGwgYWxzbyBuZWVkIHRvIGFjY2VwdCBUcnVzdGVkIFR5cGVzIG9iamVjdCBpbiB0aGUgZnV0dXJlLlxuXG52YXIgeGxpbmtIcmVmID0gJ3hsaW5rSHJlZic7XG5wcm9wZXJ0aWVzW3hsaW5rSHJlZl0gPSBuZXcgUHJvcGVydHlJbmZvUmVjb3JkKCd4bGlua0hyZWYnLCBTVFJJTkcsIGZhbHNlLCAvLyBtdXN0VXNlUHJvcGVydHlcbid4bGluazpocmVmJywgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCB0cnVlLCAvLyBzYW5pdGl6ZVVSTFxuZmFsc2UpO1xuWydzcmMnLCAnaHJlZicsICdhY3Rpb24nLCAnZm9ybUFjdGlvbiddLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZU5hbWUpIHtcbiAgcHJvcGVydGllc1thdHRyaWJ1dGVOYW1lXSA9IG5ldyBQcm9wZXJ0eUluZm9SZWNvcmQoYXR0cmlidXRlTmFtZSwgU1RSSU5HLCBmYWxzZSwgLy8gbXVzdFVzZVByb3BlcnR5XG4gIGF0dHJpYnV0ZU5hbWUudG9Mb3dlckNhc2UoKSwgLy8gYXR0cmlidXRlTmFtZVxuICBudWxsLCAvLyBhdHRyaWJ1dGVOYW1lc3BhY2VcbiAgdHJ1ZSwgLy8gc2FuaXRpemVVUkxcbiAgdHJ1ZSk7XG59KTtcblxuLy8gYW5kIGFueSBuZXdsaW5lIG9yIHRhYiBhcmUgZmlsdGVyZWQgb3V0IGFzIGlmIHRoZXkncmUgbm90IHBhcnQgb2YgdGhlIFVSTC5cbi8vIGh0dHBzOi8vdXJsLnNwZWMud2hhdHdnLm9yZy8jdXJsLXBhcnNpbmdcbi8vIFRhYiBvciBuZXdsaW5lIGFyZSBkZWZpbmVkIGFzIFxcclxcblxcdDpcbi8vIGh0dHBzOi8vaW5mcmEuc3BlYy53aGF0d2cub3JnLyNhc2NpaS10YWItb3ItbmV3bGluZVxuLy8gQSBDMCBjb250cm9sIGlzIGEgY29kZSBwb2ludCBpbiB0aGUgcmFuZ2UgXFx1MDAwMCBOVUxMIHRvIFxcdTAwMUZcbi8vIElORk9STUFUSU9OIFNFUEFSQVRPUiBPTkUsIGluY2x1c2l2ZTpcbi8vIGh0dHBzOi8vaW5mcmEuc3BlYy53aGF0d2cub3JnLyNjMC1jb250cm9sLW9yLXNwYWNlXG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxudmFyIGlzSmF2YVNjcmlwdFByb3RvY29sID0gL15bXFx1MDAwMC1cXHUwMDFGIF0qaltcXHJcXG5cXHRdKmFbXFxyXFxuXFx0XSp2W1xcclxcblxcdF0qYVtcXHJcXG5cXHRdKnNbXFxyXFxuXFx0XSpjW1xcclxcblxcdF0qcltcXHJcXG5cXHRdKmlbXFxyXFxuXFx0XSpwW1xcclxcblxcdF0qdFtcXHJcXG5cXHRdKlxcOi9pO1xudmFyIGRpZFdhcm4gPSBmYWxzZTtcblxuZnVuY3Rpb24gc2FuaXRpemVVUkwodXJsKSB7XG4gIHtcbiAgICBpZiAoIWRpZFdhcm4gJiYgaXNKYXZhU2NyaXB0UHJvdG9jb2wudGVzdCh1cmwpKSB7XG4gICAgICBkaWRXYXJuID0gdHJ1ZTtcblxuICAgICAgZXJyb3IoJ0EgZnV0dXJlIHZlcnNpb24gb2YgUmVhY3Qgd2lsbCBibG9jayBqYXZhc2NyaXB0OiBVUkxzIGFzIGEgc2VjdXJpdHkgcHJlY2F1dGlvbi4gJyArICdVc2UgZXZlbnQgaGFuZGxlcnMgaW5zdGVhZCBpZiB5b3UgY2FuLiBJZiB5b3UgbmVlZCB0byBnZW5lcmF0ZSB1bnNhZmUgSFRNTCB0cnkgJyArICd1c2luZyBkYW5nZXJvdXNseVNldElubmVySFRNTCBpbnN0ZWFkLiBSZWFjdCB3YXMgcGFzc2VkICVzLicsIEpTT04uc3RyaW5naWZ5KHVybCkpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgdmFsdWUgZm9yIGEgcHJvcGVydHkgb24gYSBub2RlLiBPbmx5IHVzZWQgaW4gREVWIGZvciBTU1IgdmFsaWRhdGlvbi5cbiAqIFRoZSBcImV4cGVjdGVkXCIgYXJndW1lbnQgaXMgdXNlZCBhcyBhIGhpbnQgb2Ygd2hhdCB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMuXG4gKiBTb21lIHByb3BlcnRpZXMgaGF2ZSBtdWx0aXBsZSBlcXVpdmFsZW50IHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gZ2V0VmFsdWVGb3JQcm9wZXJ0eShub2RlLCBuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvKSB7XG4gIHtcbiAgICBpZiAocHJvcGVydHlJbmZvLm11c3RVc2VQcm9wZXJ0eSkge1xuICAgICAgdmFyIHByb3BlcnR5TmFtZSA9IHByb3BlcnR5SW5mby5wcm9wZXJ0eU5hbWU7XG4gICAgICByZXR1cm4gbm9kZVtwcm9wZXJ0eU5hbWVdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGNoZWNrIHByb3RlY3RzIG11bHRpcGxlIHVzZXMgb2YgYGV4cGVjdGVkYCwgd2hpY2ggaXMgd2h5IHRoZVxuICAgICAgLy8gcmVhY3QtaW50ZXJuYWwvc2FmZS1zdHJpbmctY29lcmNpb24gcnVsZSBpcyBkaXNhYmxlZCBpbiBzZXZlcmFsIHNwb3RzXG4gICAgICAvLyBiZWxvdy5cbiAgICAgIHtcbiAgICAgICAgY2hlY2tBdHRyaWJ1dGVTdHJpbmdDb2VyY2lvbihleHBlY3RlZCwgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICggcHJvcGVydHlJbmZvLnNhbml0aXplVVJMKSB7XG4gICAgICAgIC8vIElmIHdlIGhhdmVuJ3QgZnVsbHkgZGlzYWJsZWQgamF2YXNjcmlwdDogVVJMcywgYW5kIGlmXG4gICAgICAgIC8vIHRoZSBoeWRyYXRpb24gaXMgc3VjY2Vzc2Z1bCBvZiBhIGphdmFzY3JpcHQ6IFVSTCwgd2VcbiAgICAgICAgLy8gc3RpbGwgd2FudCB0byB3YXJuIG9uIHRoZSBjbGllbnQuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgICBzYW5pdGl6ZVVSTCgnJyArIGV4cGVjdGVkKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGF0dHJpYnV0ZU5hbWUgPSBwcm9wZXJ0eUluZm8uYXR0cmlidXRlTmFtZTtcbiAgICAgIHZhciBzdHJpbmdWYWx1ZSA9IG51bGw7XG5cbiAgICAgIGlmIChwcm9wZXJ0eUluZm8udHlwZSA9PT0gT1ZFUkxPQURFRF9CT09MRUFOKSB7XG4gICAgICAgIGlmIChub2RlLmhhc0F0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IG5vZGUuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpO1xuXG4gICAgICAgICAgaWYgKHZhbHVlID09PSAnJykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICB9IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuXG5cbiAgICAgICAgICBpZiAodmFsdWUgPT09ICcnICsgZXhwZWN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBleHBlY3RlZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS5oYXNBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkpIHtcbiAgICAgICAgaWYgKHNob3VsZFJlbW92ZUF0dHJpYnV0ZShuYW1lLCBleHBlY3RlZCwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgICAgICAvLyBXZSBoYWQgYW4gYXR0cmlidXRlIGJ1dCBzaG91bGRuJ3QgaGF2ZSBoYWQgb25lLCBzbyByZWFkIGl0XG4gICAgICAgICAgLy8gZm9yIHRoZSBlcnJvciBtZXNzYWdlLlxuICAgICAgICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wZXJ0eUluZm8udHlwZSA9PT0gQk9PTEVBTikge1xuICAgICAgICAgIC8vIElmIHRoaXMgd2FzIGEgYm9vbGVhbiwgaXQgZG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgdmFsdWUgaXNcbiAgICAgICAgICAvLyB0aGUgZmFjdCB0aGF0IHdlIGhhdmUgaXQgaXMgdGhlIHNhbWUgYXMgdGhlIGV4cGVjdGVkLlxuICAgICAgICAgIHJldHVybiBleHBlY3RlZDtcbiAgICAgICAgfSAvLyBFdmVuIGlmIHRoaXMgcHJvcGVydHkgdXNlcyBhIG5hbWVzcGFjZSB3ZSB1c2UgZ2V0QXR0cmlidXRlXG4gICAgICAgIC8vIGJlY2F1c2Ugd2UgYXNzdW1lIGl0cyBuYW1lc3BhY2VkIG5hbWUgaXMgdGhlIHNhbWUgYXMgb3VyIGNvbmZpZy5cbiAgICAgICAgLy8gVG8gdXNlIGdldEF0dHJpYnV0ZU5TIHdlIG5lZWQgdGhlIGxvY2FsIG5hbWUgd2hpY2ggd2UgZG9uJ3QgaGF2ZVxuICAgICAgICAvLyBpbiBvdXIgY29uZmlnIGF0bS5cblxuXG4gICAgICAgIHN0cmluZ1ZhbHVlID0gbm9kZS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGUobmFtZSwgZXhwZWN0ZWQsIHByb3BlcnR5SW5mbywgZmFsc2UpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmdWYWx1ZSA9PT0gbnVsbCA/IGV4cGVjdGVkIDogc3RyaW5nVmFsdWU7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICAgICAgfSBlbHNlIGlmIChzdHJpbmdWYWx1ZSA9PT0gJycgKyBleHBlY3RlZCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0ZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gc3RyaW5nVmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEdldCB0aGUgdmFsdWUgZm9yIGEgYXR0cmlidXRlIG9uIGEgbm9kZS4gT25seSB1c2VkIGluIERFViBmb3IgU1NSIHZhbGlkYXRpb24uXG4gKiBUaGUgdGhpcmQgYXJndW1lbnQgaXMgdXNlZCBhcyBhIGhpbnQgb2Ygd2hhdCB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMuIFNvbWVcbiAqIGF0dHJpYnV0ZXMgaGF2ZSBtdWx0aXBsZSBlcXVpdmFsZW50IHZhbHVlcy5cbiAqL1xuXG5mdW5jdGlvbiBnZXRWYWx1ZUZvckF0dHJpYnV0ZShub2RlLCBuYW1lLCBleHBlY3RlZCwgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAge1xuICAgIGlmICghaXNBdHRyaWJ1dGVOYW1lU2FmZShuYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghbm9kZS5oYXNBdHRyaWJ1dGUobmFtZSkpIHtcbiAgICAgIHJldHVybiBleHBlY3RlZCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgdmFsdWUgPSBub2RlLmdldEF0dHJpYnV0ZShuYW1lKTtcblxuICAgIHtcbiAgICAgIGNoZWNrQXR0cmlidXRlU3RyaW5nQ29lcmNpb24oZXhwZWN0ZWQsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA9PT0gJycgKyBleHBlY3RlZCkge1xuICAgICAgcmV0dXJuIGV4cGVjdGVkO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuLyoqXG4gKiBTZXRzIHRoZSB2YWx1ZSBmb3IgYSBwcm9wZXJ0eSBvbiBhIG5vZGUuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICovXG5cbmZ1bmN0aW9uIHNldFZhbHVlRm9yUHJvcGVydHkobm9kZSwgbmFtZSwgdmFsdWUsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gIHZhciBwcm9wZXJ0eUluZm8gPSBnZXRQcm9wZXJ0eUluZm8obmFtZSk7XG5cbiAgaWYgKHNob3VsZElnbm9yZUF0dHJpYnV0ZShuYW1lLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGUobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgaXNDdXN0b21Db21wb25lbnRUYWcpKSB7XG4gICAgdmFsdWUgPSBudWxsO1xuICB9XG5cblxuICBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcgfHwgcHJvcGVydHlJbmZvID09PSBudWxsKSB7XG4gICAgaWYgKGlzQXR0cmlidXRlTmFtZVNhZmUobmFtZSkpIHtcbiAgICAgIHZhciBfYXR0cmlidXRlTmFtZSA9IG5hbWU7XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShfYXR0cmlidXRlTmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB7XG4gICAgICAgICAgY2hlY2tBdHRyaWJ1dGVTdHJpbmdDb2VyY2lvbih2YWx1ZSwgbmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShfYXR0cmlidXRlTmFtZSwgICcnICsgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBtdXN0VXNlUHJvcGVydHkgPSBwcm9wZXJ0eUluZm8ubXVzdFVzZVByb3BlcnR5O1xuXG4gIGlmIChtdXN0VXNlUHJvcGVydHkpIHtcbiAgICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHlJbmZvLnByb3BlcnR5TmFtZTtcblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdmFyIHR5cGUgPSBwcm9wZXJ0eUluZm8udHlwZTtcbiAgICAgIG5vZGVbcHJvcGVydHlOYW1lXSA9IHR5cGUgPT09IEJPT0xFQU4gPyBmYWxzZSA6ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDb250cmFyeSB0byBgc2V0QXR0cmlidXRlYCwgb2JqZWN0IHByb3BlcnRpZXMgYXJlIHByb3Blcmx5XG4gICAgICAvLyBgdG9TdHJpbmdgZWQgYnkgSUU4LzkuXG4gICAgICBub2RlW3Byb3BlcnR5TmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH0gLy8gVGhlIHJlc3QgYXJlIHRyZWF0ZWQgYXMgYXR0cmlidXRlcyB3aXRoIHNwZWNpYWwgY2FzZXMuXG5cblxuICB2YXIgYXR0cmlidXRlTmFtZSA9IHByb3BlcnR5SW5mby5hdHRyaWJ1dGVOYW1lLFxuICAgICAgYXR0cmlidXRlTmFtZXNwYWNlID0gcHJvcGVydHlJbmZvLmF0dHJpYnV0ZU5hbWVzcGFjZTtcblxuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgX3R5cGUgPSBwcm9wZXJ0eUluZm8udHlwZTtcbiAgICB2YXIgYXR0cmlidXRlVmFsdWU7XG5cbiAgICBpZiAoX3R5cGUgPT09IEJPT0xFQU4gfHwgX3R5cGUgPT09IE9WRVJMT0FERURfQk9PTEVBTiAmJiB2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgLy8gSWYgYXR0cmlidXRlIHR5cGUgaXMgYm9vbGVhbiwgd2Uga25vdyBmb3Igc3VyZSBpdCB3b24ndCBiZSBhbiBleGVjdXRpb24gc2lua1xuICAgICAgLy8gYW5kIHdlIHdvbid0IHJlcXVpcmUgVHJ1c3RlZCBUeXBlIGhlcmUuXG4gICAgICBhdHRyaWJ1dGVWYWx1ZSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBgc2V0QXR0cmlidXRlYCB3aXRoIG9iamVjdHMgYmVjb21lcyBvbmx5IGBbb2JqZWN0XWAgaW4gSUU4LzksXG4gICAgICAvLyAoJycgKyB2YWx1ZSkgbWFrZXMgaXQgb3V0cHV0IHRoZSBjb3JyZWN0IHRvU3RyaW5nKCktdmFsdWUuXG4gICAgICB7XG4gICAgICAgIHtcbiAgICAgICAgICBjaGVja0F0dHJpYnV0ZVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBhdHRyaWJ1dGVOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF0dHJpYnV0ZVZhbHVlID0gJycgKyB2YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByb3BlcnR5SW5mby5zYW5pdGl6ZVVSTCkge1xuICAgICAgICBzYW5pdGl6ZVVSTChhdHRyaWJ1dGVWYWx1ZS50b1N0cmluZygpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXR0cmlidXRlTmFtZXNwYWNlKSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZU5TKGF0dHJpYnV0ZU5hbWVzcGFjZSwgYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVWYWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIEFUVEVOVElPTlxuLy8gV2hlbiBhZGRpbmcgbmV3IHN5bWJvbHMgdG8gdGhpcyBmaWxlLFxuLy8gUGxlYXNlIGNvbnNpZGVyIGFsc28gYWRkaW5nIHRvICdyZWFjdC1kZXZ0b29scy1zaGFyZWQvc3JjL2JhY2tlbmQvUmVhY3RTeW1ib2xzJ1xuLy8gVGhlIFN5bWJvbCB1c2VkIHRvIHRhZyB0aGUgUmVhY3RFbGVtZW50LWxpa2UgdHlwZXMuXG52YXIgUkVBQ1RfRUxFTUVOVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZWxlbWVudCcpO1xudmFyIFJFQUNUX1BPUlRBTF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QucG9ydGFsJyk7XG52YXIgUkVBQ1RfRlJBR01FTlRfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LmZyYWdtZW50Jyk7XG52YXIgUkVBQ1RfU1RSSUNUX01PREVfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN0cmljdF9tb2RlJyk7XG52YXIgUkVBQ1RfUFJPRklMRVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb2ZpbGVyJyk7XG52YXIgUkVBQ1RfUFJPVklERVJfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnByb3ZpZGVyJyk7XG52YXIgUkVBQ1RfQ09OVEVYVF9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuY29udGV4dCcpO1xudmFyIFJFQUNUX0ZPUldBUkRfUkVGX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5mb3J3YXJkX3JlZicpO1xudmFyIFJFQUNUX1NVU1BFTlNFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zdXNwZW5zZScpO1xudmFyIFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRSA9IFN5bWJvbC5mb3IoJ3JlYWN0LnN1c3BlbnNlX2xpc3QnKTtcbnZhciBSRUFDVF9NRU1PX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5tZW1vJyk7XG52YXIgUkVBQ1RfTEFaWV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubGF6eScpO1xudmFyIFJFQUNUX1NDT1BFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5zY29wZScpO1xudmFyIFJFQUNUX0RFQlVHX1RSQUNJTkdfTU9ERV9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QuZGVidWdfdHJhY2VfbW9kZScpO1xudmFyIFJFQUNUX09GRlNDUkVFTl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3Qub2Zmc2NyZWVuJyk7XG52YXIgUkVBQ1RfTEVHQUNZX0hJRERFTl9UWVBFID0gU3ltYm9sLmZvcigncmVhY3QubGVnYWN5X2hpZGRlbicpO1xudmFyIFJFQUNUX0NBQ0hFX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC5jYWNoZScpO1xudmFyIFJFQUNUX1RSQUNJTkdfTUFSS0VSX1RZUEUgPSBTeW1ib2wuZm9yKCdyZWFjdC50cmFjaW5nX21hcmtlcicpO1xudmFyIE1BWUJFX0lURVJBVE9SX1NZTUJPTCA9IFN5bWJvbC5pdGVyYXRvcjtcbnZhciBGQVVYX0lURVJBVE9SX1NZTUJPTCA9ICdAQGl0ZXJhdG9yJztcbmZ1bmN0aW9uIGdldEl0ZXJhdG9yRm4obWF5YmVJdGVyYWJsZSkge1xuICBpZiAobWF5YmVJdGVyYWJsZSA9PT0gbnVsbCB8fCB0eXBlb2YgbWF5YmVJdGVyYWJsZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBtYXliZUl0ZXJhdG9yID0gTUFZQkVfSVRFUkFUT1JfU1lNQk9MICYmIG1heWJlSXRlcmFibGVbTUFZQkVfSVRFUkFUT1JfU1lNQk9MXSB8fCBtYXliZUl0ZXJhYmxlW0ZBVVhfSVRFUkFUT1JfU1lNQk9MXTtcblxuICBpZiAodHlwZW9mIG1heWJlSXRlcmF0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gbWF5YmVJdGVyYXRvcjtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxuLy8gSGVscGVycyB0byBwYXRjaCBjb25zb2xlLmxvZ3MgdG8gYXZvaWQgbG9nZ2luZyBkdXJpbmcgc2lkZS1lZmZlY3QgZnJlZVxuLy8gcmVwbGF5aW5nIG9uIHJlbmRlciBmdW5jdGlvbi4gVGhpcyBjdXJyZW50bHkgb25seSBwYXRjaGVzIHRoZSBvYmplY3Rcbi8vIGxhemlseSB3aGljaCB3b24ndCBjb3ZlciBpZiB0aGUgbG9nIGZ1bmN0aW9uIHdhcyBleHRyYWN0ZWQgZWFnZXJseS5cbi8vIFdlIGNvdWxkIGFsc28gZWFnZXJseSBwYXRjaCB0aGUgbWV0aG9kLlxudmFyIGRpc2FibGVkRGVwdGggPSAwO1xudmFyIHByZXZMb2c7XG52YXIgcHJldkluZm87XG52YXIgcHJldldhcm47XG52YXIgcHJldkVycm9yO1xudmFyIHByZXZHcm91cDtcbnZhciBwcmV2R3JvdXBDb2xsYXBzZWQ7XG52YXIgcHJldkdyb3VwRW5kO1xuXG5mdW5jdGlvbiBkaXNhYmxlZExvZygpIHt9XG5cbmRpc2FibGVkTG9nLl9fcmVhY3REaXNhYmxlZExvZyA9IHRydWU7XG5mdW5jdGlvbiBkaXNhYmxlTG9ncygpIHtcbiAge1xuICAgIGlmIChkaXNhYmxlZERlcHRoID09PSAwKSB7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSByZWFjdC1pbnRlcm5hbC9uby1wcm9kdWN0aW9uLWxvZ2dpbmcgKi9cbiAgICAgIHByZXZMb2cgPSBjb25zb2xlLmxvZztcbiAgICAgIHByZXZJbmZvID0gY29uc29sZS5pbmZvO1xuICAgICAgcHJldldhcm4gPSBjb25zb2xlLndhcm47XG4gICAgICBwcmV2RXJyb3IgPSBjb25zb2xlLmVycm9yO1xuICAgICAgcHJldkdyb3VwID0gY29uc29sZS5ncm91cDtcbiAgICAgIHByZXZHcm91cENvbGxhcHNlZCA9IGNvbnNvbGUuZ3JvdXBDb2xsYXBzZWQ7XG4gICAgICBwcmV2R3JvdXBFbmQgPSBjb25zb2xlLmdyb3VwRW5kOyAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE5MDk5XG5cbiAgICAgIHZhciBwcm9wcyA9IHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogZGlzYWJsZWRMb2csXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICB9OyAvLyAkRmxvd0ZpeE1lIEZsb3cgdGhpbmtzIGNvbnNvbGUgaXMgaW1tdXRhYmxlLlxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zb2xlLCB7XG4gICAgICAgIGluZm86IHByb3BzLFxuICAgICAgICBsb2c6IHByb3BzLFxuICAgICAgICB3YXJuOiBwcm9wcyxcbiAgICAgICAgZXJyb3I6IHByb3BzLFxuICAgICAgICBncm91cDogcHJvcHMsXG4gICAgICAgIGdyb3VwQ29sbGFwc2VkOiBwcm9wcyxcbiAgICAgICAgZ3JvdXBFbmQ6IHByb3BzXG4gICAgICB9KTtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgfVxuXG4gICAgZGlzYWJsZWREZXB0aCsrO1xuICB9XG59XG5mdW5jdGlvbiByZWVuYWJsZUxvZ3MoKSB7XG4gIHtcbiAgICBkaXNhYmxlZERlcHRoLS07XG5cbiAgICBpZiAoZGlzYWJsZWREZXB0aCA9PT0gMCkge1xuICAgICAgLyogZXNsaW50LWRpc2FibGUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nICovXG4gICAgICB2YXIgcHJvcHMgPSB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH07IC8vICRGbG93Rml4TWUgRmxvdyB0aGlua3MgY29uc29sZSBpcyBpbW11dGFibGUuXG5cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGNvbnNvbGUsIHtcbiAgICAgICAgbG9nOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZMb2dcbiAgICAgICAgfSksXG4gICAgICAgIGluZm86IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkluZm9cbiAgICAgICAgfSksXG4gICAgICAgIHdhcm46IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldldhcm5cbiAgICAgICAgfSksXG4gICAgICAgIGVycm9yOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZFcnJvclxuICAgICAgICB9KSxcbiAgICAgICAgZ3JvdXA6IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICAgICAgICB2YWx1ZTogcHJldkdyb3VwXG4gICAgICAgIH0pLFxuICAgICAgICBncm91cENvbGxhcHNlZDogYXNzaWduKHt9LCBwcm9wcywge1xuICAgICAgICAgIHZhbHVlOiBwcmV2R3JvdXBDb2xsYXBzZWRcbiAgICAgICAgfSksXG4gICAgICAgIGdyb3VwRW5kOiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgICAgICAgdmFsdWU6IHByZXZHcm91cEVuZFxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZyAqL1xuICAgIH1cblxuICAgIGlmIChkaXNhYmxlZERlcHRoIDwgMCkge1xuICAgICAgZXJyb3IoJ2Rpc2FibGVkRGVwdGggZmVsbCBiZWxvdyB6ZXJvLiAnICsgJ1RoaXMgaXMgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudERpc3BhdGNoZXI7XG52YXIgcHJlZml4O1xuZnVuY3Rpb24gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUobmFtZSwgc291cmNlLCBvd25lckZuKSB7XG4gIHtcbiAgICBpZiAocHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEV4dHJhY3QgdGhlIFZNIHNwZWNpZmljIHByZWZpeCB1c2VkIGJ5IGVhY2ggbGluZS5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgIHZhciBtYXRjaCA9IHguc3RhY2sudHJpbSgpLm1hdGNoKC9cXG4oICooYXQgKT8pLyk7XG4gICAgICAgIHByZWZpeCA9IG1hdGNoICYmIG1hdGNoWzFdIHx8ICcnO1xuICAgICAgfVxuICAgIH0gLy8gV2UgdXNlIHRoZSBwcmVmaXggdG8gZW5zdXJlIG91ciBzdGFja3MgbGluZSB1cCB3aXRoIG5hdGl2ZSBzdGFjayBmcmFtZXMuXG5cblxuICAgIHJldHVybiAnXFxuJyArIHByZWZpeCArIG5hbWU7XG4gIH1cbn1cbnZhciByZWVudHJ5ID0gZmFsc2U7XG52YXIgY29tcG9uZW50RnJhbWVDYWNoZTtcblxue1xuICB2YXIgUG9zc2libHlXZWFrTWFwID0gdHlwZW9mIFdlYWtNYXAgPT09ICdmdW5jdGlvbicgPyBXZWFrTWFwIDogTWFwO1xuICBjb21wb25lbnRGcmFtZUNhY2hlID0gbmV3IFBvc3NpYmx5V2Vha01hcCgpO1xufVxuXG5mdW5jdGlvbiBkZXNjcmliZU5hdGl2ZUNvbXBvbmVudEZyYW1lKGZuLCBjb25zdHJ1Y3QpIHtcbiAgLy8gSWYgc29tZXRoaW5nIGFza2VkIGZvciBhIHN0YWNrIGluc2lkZSBhIGZha2UgcmVuZGVyLCBpdCBzaG91bGQgZ2V0IGlnbm9yZWQuXG4gIGlmICggIWZuIHx8IHJlZW50cnkpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICB7XG4gICAgdmFyIGZyYW1lID0gY29tcG9uZW50RnJhbWVDYWNoZS5nZXQoZm4pO1xuXG4gICAgaWYgKGZyYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmcmFtZTtcbiAgICB9XG4gIH1cblxuICB2YXIgY29udHJvbDtcbiAgcmVlbnRyeSA9IHRydWU7XG4gIHZhciBwcmV2aW91c1ByZXBhcmVTdGFja1RyYWNlID0gRXJyb3IucHJlcGFyZVN0YWNrVHJhY2U7IC8vICRGbG93Rml4TWUgSXQgZG9lcyBhY2NlcHQgdW5kZWZpbmVkLlxuXG4gIEVycm9yLnByZXBhcmVTdGFja1RyYWNlID0gdW5kZWZpbmVkO1xuICB2YXIgcHJldmlvdXNEaXNwYXRjaGVyO1xuXG4gIHtcbiAgICBwcmV2aW91c0Rpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLmN1cnJlbnQ7IC8vIFNldCB0aGUgZGlzcGF0Y2hlciBpbiBERVYgYmVjYXVzZSB0aGlzIG1pZ2h0IGJlIGNhbGwgaW4gdGhlIHJlbmRlciBmdW5jdGlvblxuICAgIC8vIGZvciB3YXJuaW5ncy5cblxuICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIuY3VycmVudCA9IG51bGw7XG4gICAgZGlzYWJsZUxvZ3MoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgLy8gVGhpcyBzaG91bGQgdGhyb3cuXG4gICAgaWYgKGNvbnN0cnVjdCkge1xuICAgICAgLy8gU29tZXRoaW5nIHNob3VsZCBiZSBzZXR0aW5nIHRoZSBwcm9wcyBpbiB0aGUgY29uc3RydWN0b3IuXG4gICAgICB2YXIgRmFrZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoKTtcbiAgICAgIH07IC8vICRGbG93Rml4TWVcblxuXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRmFrZS5wcm90b3R5cGUsICdwcm9wcycsIHtcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gV2UgdXNlIGEgdGhyb3dpbmcgc2V0dGVyIGluc3RlYWQgb2YgZnJvemVuIG9yIG5vbi13cml0YWJsZSBwcm9wc1xuICAgICAgICAgIC8vIGJlY2F1c2UgdGhhdCB3b24ndCB0aHJvdyBpbiBhIG5vbi1zdHJpY3QgbW9kZSBmdW5jdGlvbi5cbiAgICAgICAgICB0aHJvdyBFcnJvcigpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyAmJiBSZWZsZWN0LmNvbnN0cnVjdCkge1xuICAgICAgICAvLyBXZSBjb25zdHJ1Y3QgYSBkaWZmZXJlbnQgY29udHJvbCBmb3IgdGhpcyBjYXNlIHRvIGluY2x1ZGUgYW55IGV4dHJhXG4gICAgICAgIC8vIGZyYW1lcyBhZGRlZCBieSB0aGUgY29uc3RydWN0IGNhbGwuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoRmFrZSwgW10pO1xuICAgICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgICAgY29udHJvbCA9IHg7XG4gICAgICAgIH1cblxuICAgICAgICBSZWZsZWN0LmNvbnN0cnVjdChmbiwgW10sIEZha2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBGYWtlLmNhbGwoKTtcbiAgICAgICAgfSBjYXRjaCAoeCkge1xuICAgICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgICB9XG5cbiAgICAgICAgZm4uY2FsbChGYWtlLnByb3RvdHlwZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRocm93IEVycm9yKCk7XG4gICAgICB9IGNhdGNoICh4KSB7XG4gICAgICAgIGNvbnRyb2wgPSB4O1xuICAgICAgfVxuXG4gICAgICBmbigpO1xuICAgIH1cbiAgfSBjYXRjaCAoc2FtcGxlKSB7XG4gICAgLy8gVGhpcyBpcyBpbmxpbmVkIG1hbnVhbGx5IGJlY2F1c2UgY2xvc3VyZSBkb2Vzbid0IGRvIGl0IGZvciB1cy5cbiAgICBpZiAoc2FtcGxlICYmIGNvbnRyb2wgJiYgdHlwZW9mIHNhbXBsZS5zdGFjayA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFRoaXMgZXh0cmFjdHMgdGhlIGZpcnN0IGZyYW1lIGZyb20gdGhlIHNhbXBsZSB0aGF0IGlzbid0IGFsc28gaW4gdGhlIGNvbnRyb2wuXG4gICAgICAvLyBTa2lwcGluZyBvbmUgZnJhbWUgdGhhdCB3ZSBhc3N1bWUgaXMgdGhlIGZyYW1lIHRoYXQgY2FsbHMgdGhlIHR3by5cbiAgICAgIHZhciBzYW1wbGVMaW5lcyA9IHNhbXBsZS5zdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICB2YXIgY29udHJvbExpbmVzID0gY29udHJvbC5zdGFjay5zcGxpdCgnXFxuJyk7XG4gICAgICB2YXIgcyA9IHNhbXBsZUxpbmVzLmxlbmd0aCAtIDE7XG4gICAgICB2YXIgYyA9IGNvbnRyb2xMaW5lcy5sZW5ndGggLSAxO1xuXG4gICAgICB3aGlsZSAocyA+PSAxICYmIGMgPj0gMCAmJiBzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgIC8vIFdlIGV4cGVjdCBhdCBsZWFzdCBvbmUgc3RhY2sgZnJhbWUgdG8gYmUgc2hhcmVkLlxuICAgICAgICAvLyBUeXBpY2FsbHkgdGhpcyB3aWxsIGJlIHRoZSByb290IG1vc3Qgb25lLiBIb3dldmVyLCBzdGFjayBmcmFtZXMgbWF5IGJlXG4gICAgICAgIC8vIGN1dCBvZmYgZHVlIHRvIG1heGltdW0gc3RhY2sgbGltaXRzLiBJbiB0aGlzIGNhc2UsIG9uZSBtYXliZSBjdXQgb2ZmXG4gICAgICAgIC8vIGVhcmxpZXIgdGhhbiB0aGUgb3RoZXIuIFdlIGFzc3VtZSB0aGF0IHRoZSBzYW1wbGUgaXMgbG9uZ2VyIG9yIHRoZSBzYW1lXG4gICAgICAgIC8vIGFuZCB0aGVyZSBmb3IgY3V0IG9mZiBlYXJsaWVyLiBTbyB3ZSBzaG91bGQgZmluZCB0aGUgcm9vdCBtb3N0IGZyYW1lIGluXG4gICAgICAgIC8vIHRoZSBzYW1wbGUgc29tZXdoZXJlIGluIHRoZSBjb250cm9sLlxuICAgICAgICBjLS07XG4gICAgICB9XG5cbiAgICAgIGZvciAoOyBzID49IDEgJiYgYyA+PSAwOyBzLS0sIGMtLSkge1xuICAgICAgICAvLyBOZXh0IHdlIGZpbmQgdGhlIGZpcnN0IG9uZSB0aGF0IGlzbid0IHRoZSBzYW1lIHdoaWNoIHNob3VsZCBiZSB0aGVcbiAgICAgICAgLy8gZnJhbWUgdGhhdCBjYWxsZWQgb3VyIHNhbXBsZSBmdW5jdGlvbiBhbmQgdGhlIGNvbnRyb2wuXG4gICAgICAgIGlmIChzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgICAgLy8gSW4gVjgsIHRoZSBmaXJzdCBsaW5lIGlzIGRlc2NyaWJpbmcgdGhlIG1lc3NhZ2UgYnV0IG90aGVyIFZNcyBkb24ndC5cbiAgICAgICAgICAvLyBJZiB3ZSdyZSBhYm91dCB0byByZXR1cm4gdGhlIGZpcnN0IGxpbmUsIGFuZCB0aGUgY29udHJvbCBpcyBhbHNvIG9uIHRoZSBzYW1lXG4gICAgICAgICAgLy8gbGluZSwgdGhhdCdzIGEgcHJldHR5IGdvb2QgaW5kaWNhdG9yIHRoYXQgb3VyIHNhbXBsZSB0aHJldyBhdCBzYW1lIGxpbmUgYXNcbiAgICAgICAgICAvLyB0aGUgY29udHJvbC4gSS5lLiBiZWZvcmUgd2UgZW50ZXJlZCB0aGUgc2FtcGxlIGZyYW1lLiBTbyB3ZSBpZ25vcmUgdGhpcyByZXN1bHQuXG4gICAgICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIHlvdSBwYXNzZWQgYSBjbGFzcyB0byBmdW5jdGlvbiBjb21wb25lbnQsIG9yIG5vbi1mdW5jdGlvbi5cbiAgICAgICAgICBpZiAocyAhPT0gMSB8fCBjICE9PSAxKSB7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgIHMtLTtcbiAgICAgICAgICAgICAgYy0tOyAvLyBXZSBtYXkgc3RpbGwgaGF2ZSBzaW1pbGFyIGludGVybWVkaWF0ZSBmcmFtZXMgZnJvbSB0aGUgY29uc3RydWN0IGNhbGwuXG4gICAgICAgICAgICAgIC8vIFRoZSBuZXh0IG9uZSB0aGF0IGlzbid0IHRoZSBzYW1lIHNob3VsZCBiZSBvdXIgbWF0Y2ggdGhvdWdoLlxuXG4gICAgICAgICAgICAgIGlmIChjIDwgMCB8fCBzYW1wbGVMaW5lc1tzXSAhPT0gY29udHJvbExpbmVzW2NdKSB7XG4gICAgICAgICAgICAgICAgLy8gVjggYWRkcyBhIFwibmV3XCIgcHJlZml4IGZvciBuYXRpdmUgY2xhc3Nlcy4gTGV0J3MgcmVtb3ZlIGl0IHRvIG1ha2UgaXQgcHJldHRpZXIuXG4gICAgICAgICAgICAgICAgdmFyIF9mcmFtZSA9ICdcXG4nICsgc2FtcGxlTGluZXNbc10ucmVwbGFjZSgnIGF0IG5ldyAnLCAnIGF0ICcpOyAvLyBJZiBvdXIgY29tcG9uZW50IGZyYW1lIGlzIGxhYmVsZWQgXCI8YW5vbnltb3VzPlwiXG4gICAgICAgICAgICAgICAgLy8gYnV0IHdlIGhhdmUgYSB1c2VyLXByb3ZpZGVkIFwiZGlzcGxheU5hbWVcIlxuICAgICAgICAgICAgICAgIC8vIHNwbGljZSBpdCBpbiB0byBtYWtlIHRoZSBzdGFjayBtb3JlIHJlYWRhYmxlLlxuXG5cbiAgICAgICAgICAgICAgICBpZiAoZm4uZGlzcGxheU5hbWUgJiYgX2ZyYW1lLmluY2x1ZGVzKCc8YW5vbnltb3VzPicpKSB7XG4gICAgICAgICAgICAgICAgICBfZnJhbWUgPSBfZnJhbWUucmVwbGFjZSgnPGFub255bW91cz4nLCBmbi5kaXNwbGF5TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRGcmFtZUNhY2hlLnNldChmbiwgX2ZyYW1lKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IC8vIFJldHVybiB0aGUgbGluZSB3ZSBmb3VuZC5cblxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9mcmFtZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAocyA+PSAxICYmIGMgPj0gMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgcmVlbnRyeSA9IGZhbHNlO1xuXG4gICAge1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlci5jdXJyZW50ID0gcHJldmlvdXNEaXNwYXRjaGVyO1xuICAgICAgcmVlbmFibGVMb2dzKCk7XG4gICAgfVxuXG4gICAgRXJyb3IucHJlcGFyZVN0YWNrVHJhY2UgPSBwcmV2aW91c1ByZXBhcmVTdGFja1RyYWNlO1xuICB9IC8vIEZhbGxiYWNrIHRvIGp1c3QgdXNpbmcgdGhlIG5hbWUgaWYgd2UgY291bGRuJ3QgbWFrZSBpdCB0aHJvdy5cblxuXG4gIHZhciBuYW1lID0gZm4gPyBmbi5kaXNwbGF5TmFtZSB8fCBmbi5uYW1lIDogJyc7XG4gIHZhciBzeW50aGV0aWNGcmFtZSA9IG5hbWUgPyBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZShuYW1lKSA6ICcnO1xuXG4gIHtcbiAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb21wb25lbnRGcmFtZUNhY2hlLnNldChmbiwgc3ludGhldGljRnJhbWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzeW50aGV0aWNGcmFtZTtcbn1cblxuZnVuY3Rpb24gZGVzY3JpYmVDbGFzc0NvbXBvbmVudEZyYW1lKGN0b3IsIHNvdXJjZSwgb3duZXJGbikge1xuICB7XG4gICAgcmV0dXJuIGRlc2NyaWJlTmF0aXZlQ29tcG9uZW50RnJhbWUoY3RvciwgdHJ1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZShmbiwgc291cmNlLCBvd25lckZuKSB7XG4gIHtcbiAgICByZXR1cm4gZGVzY3JpYmVOYXRpdmVDb21wb25lbnRGcmFtZShmbiwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZENvbnN0cnVjdChDb21wb25lbnQpIHtcbiAgdmFyIHByb3RvdHlwZSA9IENvbXBvbmVudC5wcm90b3R5cGU7XG4gIHJldHVybiAhIShwcm90b3R5cGUgJiYgcHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQpO1xufVxuXG5mdW5jdGlvbiBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYodHlwZSwgc291cmNlLCBvd25lckZuKSB7XG5cbiAgaWYgKHR5cGUgPT0gbnVsbCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHtcbiAgICAgIHJldHVybiBkZXNjcmliZU5hdGl2ZUNvbXBvbmVudEZyYW1lKHR5cGUsIHNob3VsZENvbnN0cnVjdCh0eXBlKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSh0eXBlKTtcbiAgfVxuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2UnKTtcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQnVpbHRJbkNvbXBvbmVudEZyYW1lKCdTdXNwZW5zZUxpc3QnKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgcmV0dXJuIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZSh0eXBlLnJlbmRlcik7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICAvLyBNZW1vIG1heSBjb250YWluIGFueSBjb21wb25lbnQgdHlwZSBzbyB3ZSByZWN1cnNpdmVseSByZXNvbHZlIGl0LlxuICAgICAgICByZXR1cm4gZGVzY3JpYmVVbmtub3duRWxlbWVudFR5cGVGcmFtZUluREVWKHR5cGUudHlwZSwgc291cmNlLCBvd25lckZuKTtcblxuICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IHR5cGU7XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBMYXp5IG1heSBjb250YWluIGFueSBjb21wb25lbnQgdHlwZSBzbyB3ZSByZWN1cnNpdmVseSByZXNvbHZlIGl0LlxuICAgICAgICAgICAgcmV0dXJuIGRlc2NyaWJlVW5rbm93bkVsZW1lbnRUeXBlRnJhbWVJbkRFVihpbml0KHBheWxvYWQpLCBzb3VyY2UsIG93bmVyRm4pO1xuICAgICAgICAgIH0gY2F0Y2ggKHgpIHt9XG4gICAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGRlc2NyaWJlRmliZXIoZmliZXIpIHtcbiAgdmFyIG93bmVyID0gIGZpYmVyLl9kZWJ1Z093bmVyID8gZmliZXIuX2RlYnVnT3duZXIudHlwZSA6IG51bGwgO1xuICB2YXIgc291cmNlID0gIGZpYmVyLl9kZWJ1Z1NvdXJjZSA7XG5cbiAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoZmliZXIudHlwZSk7XG5cbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ0xhenknKTtcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVCdWlsdEluQ29tcG9uZW50RnJhbWUoJ1N1c3BlbnNlJyk7XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHJldHVybiBkZXNjcmliZUJ1aWx0SW5Db21wb25lbnRGcmFtZSgnU3VzcGVuc2VMaXN0Jyk7XG5cbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICByZXR1cm4gZGVzY3JpYmVGdW5jdGlvbkNvbXBvbmVudEZyYW1lKGZpYmVyLnR5cGUpO1xuXG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgcmV0dXJuIGRlc2NyaWJlRnVuY3Rpb25Db21wb25lbnRGcmFtZShmaWJlci50eXBlLnJlbmRlcik7XG5cbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgcmV0dXJuIGRlc2NyaWJlQ2xhc3NDb21wb25lbnRGcmFtZShmaWJlci50eXBlKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJyc7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0U3RhY2tCeUZpYmVySW5EZXZBbmRQcm9kKHdvcmtJblByb2dyZXNzKSB7XG4gIHRyeSB7XG4gICAgdmFyIGluZm8gPSAnJztcbiAgICB2YXIgbm9kZSA9IHdvcmtJblByb2dyZXNzO1xuXG4gICAgZG8ge1xuICAgICAgaW5mbyArPSBkZXNjcmliZUZpYmVyKG5vZGUpO1xuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH0gd2hpbGUgKG5vZGUpO1xuXG4gICAgcmV0dXJuIGluZm87XG4gIH0gY2F0Y2ggKHgpIHtcbiAgICByZXR1cm4gJ1xcbkVycm9yIGdlbmVyYXRpbmcgc3RhY2s6ICcgKyB4Lm1lc3NhZ2UgKyAnXFxuJyArIHguc3RhY2s7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0V3JhcHBlZE5hbWUob3V0ZXJUeXBlLCBpbm5lclR5cGUsIHdyYXBwZXJOYW1lKSB7XG4gIHZhciBkaXNwbGF5TmFtZSA9IG91dGVyVHlwZS5kaXNwbGF5TmFtZTtcblxuICBpZiAoZGlzcGxheU5hbWUpIHtcbiAgICByZXR1cm4gZGlzcGxheU5hbWU7XG4gIH1cblxuICB2YXIgZnVuY3Rpb25OYW1lID0gaW5uZXJUeXBlLmRpc3BsYXlOYW1lIHx8IGlubmVyVHlwZS5uYW1lIHx8ICcnO1xuICByZXR1cm4gZnVuY3Rpb25OYW1lICE9PSAnJyA/IHdyYXBwZXJOYW1lICsgXCIoXCIgKyBmdW5jdGlvbk5hbWUgKyBcIilcIiA6IHdyYXBwZXJOYW1lO1xufSAvLyBLZWVwIGluIHN5bmMgd2l0aCByZWFjdC1yZWNvbmNpbGVyL2dldENvbXBvbmVudE5hbWVGcm9tRmliZXJcblxuXG5mdW5jdGlvbiBnZXRDb250ZXh0TmFtZSh0eXBlKSB7XG4gIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8ICdDb250ZXh0Jztcbn0gLy8gTm90ZSB0aGF0IHRoZSByZWNvbmNpbGVyIHBhY2thZ2Ugc2hvdWxkIGdlbmVyYWxseSBwcmVmZXIgdG8gdXNlIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoKSBpbnN0ZWFkLlxuXG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlKSB7XG4gIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAvLyBIb3N0IHJvb3QsIHRleHQgbm9kZSBvciBqdXN0IGludmFsaWQgdHlwZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICBpZiAodHlwZW9mIHR5cGUudGFnID09PSAnbnVtYmVyJykge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIGFuIHVuZXhwZWN0ZWQgb2JqZWN0IGluIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSgpLiAnICsgJ1RoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCB0eXBlLm5hbWUgfHwgbnVsbDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgUkVBQ1RfRlJBR01FTlRfVFlQRTpcbiAgICAgIHJldHVybiAnRnJhZ21lbnQnO1xuXG4gICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgIHJldHVybiAnUG9ydGFsJztcblxuICAgIGNhc2UgUkVBQ1RfUFJPRklMRVJfVFlQRTpcbiAgICAgIHJldHVybiAnUHJvZmlsZXInO1xuXG4gICAgY2FzZSBSRUFDVF9TVFJJQ1RfTU9ERV9UWVBFOlxuICAgICAgcmV0dXJuICdTdHJpY3RNb2RlJztcblxuICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgIHJldHVybiAnU3VzcGVuc2UnO1xuXG4gICAgY2FzZSBSRUFDVF9TVVNQRU5TRV9MSVNUX1RZUEU6XG4gICAgICByZXR1cm4gJ1N1c3BlbnNlTGlzdCc7XG5cbiAgfVxuXG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHR5cGUuJCR0eXBlb2YpIHtcbiAgICAgIGNhc2UgUkVBQ1RfQ09OVEVYVF9UWVBFOlxuICAgICAgICB2YXIgY29udGV4dCA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShjb250ZXh0KSArICcuQ29uc3VtZXInO1xuXG4gICAgICBjYXNlIFJFQUNUX1BST1ZJREVSX1RZUEU6XG4gICAgICAgIHZhciBwcm92aWRlciA9IHR5cGU7XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0TmFtZShwcm92aWRlci5fY29udGV4dCkgKyAnLlByb3ZpZGVyJztcblxuICAgICAgY2FzZSBSRUFDVF9GT1JXQVJEX1JFRl9UWVBFOlxuICAgICAgICByZXR1cm4gZ2V0V3JhcHBlZE5hbWUodHlwZSwgdHlwZS5yZW5kZXIsICdGb3J3YXJkUmVmJyk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfTUVNT19UWVBFOlxuICAgICAgICB2YXIgb3V0ZXJOYW1lID0gdHlwZS5kaXNwbGF5TmFtZSB8fCBudWxsO1xuXG4gICAgICAgIGlmIChvdXRlck5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gb3V0ZXJOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZSh0eXBlLnR5cGUpIHx8ICdNZW1vJztcblxuICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IHR5cGU7XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBsYXp5Q29tcG9uZW50Ll9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGluaXQocGF5bG9hZCkpO1xuICAgICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0V3JhcHBlZE5hbWUkMShvdXRlclR5cGUsIGlubmVyVHlwZSwgd3JhcHBlck5hbWUpIHtcbiAgdmFyIGZ1bmN0aW9uTmFtZSA9IGlubmVyVHlwZS5kaXNwbGF5TmFtZSB8fCBpbm5lclR5cGUubmFtZSB8fCAnJztcbiAgcmV0dXJuIG91dGVyVHlwZS5kaXNwbGF5TmFtZSB8fCAoZnVuY3Rpb25OYW1lICE9PSAnJyA/IHdyYXBwZXJOYW1lICsgXCIoXCIgKyBmdW5jdGlvbk5hbWUgKyBcIilcIiA6IHdyYXBwZXJOYW1lKTtcbn0gLy8gS2VlcCBpbiBzeW5jIHdpdGggc2hhcmVkL2dldENvbXBvbmVudE5hbWVGcm9tVHlwZVxuXG5cbmZ1bmN0aW9uIGdldENvbnRleHROYW1lJDEodHlwZSkge1xuICByZXR1cm4gdHlwZS5kaXNwbGF5TmFtZSB8fCAnQ29udGV4dCc7XG59XG5cbmZ1bmN0aW9uIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHtcbiAgdmFyIHRhZyA9IGZpYmVyLnRhZyxcbiAgICAgIHR5cGUgPSBmaWJlci50eXBlO1xuXG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSBDYWNoZUNvbXBvbmVudDpcbiAgICAgIHJldHVybiAnQ2FjaGUnO1xuXG4gICAgY2FzZSBDb250ZXh0Q29uc3VtZXI6XG4gICAgICB2YXIgY29udGV4dCA9IHR5cGU7XG4gICAgICByZXR1cm4gZ2V0Q29udGV4dE5hbWUkMShjb250ZXh0KSArICcuQ29uc3VtZXInO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB2YXIgcHJvdmlkZXIgPSB0eXBlO1xuICAgICAgcmV0dXJuIGdldENvbnRleHROYW1lJDEocHJvdmlkZXIuX2NvbnRleHQpICsgJy5Qcm92aWRlcic7XG5cbiAgICBjYXNlIERlaHlkcmF0ZWRGcmFnbWVudDpcbiAgICAgIHJldHVybiAnRGVoeWRyYXRlZEZyYWdtZW50JztcblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHJldHVybiBnZXRXcmFwcGVkTmFtZSQxKHR5cGUsIHR5cGUucmVuZGVyLCAnRm9yd2FyZFJlZicpO1xuXG4gICAgY2FzZSBGcmFnbWVudDpcbiAgICAgIHJldHVybiAnRnJhZ21lbnQnO1xuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgLy8gSG9zdCBjb21wb25lbnQgdHlwZSBpcyB0aGUgZGlzcGxheSBuYW1lIChlLmcuIFwiZGl2XCIsIFwiVmlld1wiKVxuICAgICAgcmV0dXJuIHR5cGU7XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICByZXR1cm4gJ1BvcnRhbCc7XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAgcmV0dXJuICdSb290JztcblxuICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICByZXR1cm4gJ1RleHQnO1xuXG4gICAgY2FzZSBMYXp5Q29tcG9uZW50OlxuICAgICAgLy8gTmFtZSBjb21lcyBmcm9tIHRoZSB0eXBlIGluIHRoaXMgY2FzZTsgd2UgZG9uJ3QgaGF2ZSBhIHRhZy5cbiAgICAgIHJldHVybiBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSk7XG5cbiAgICBjYXNlIE1vZGU6XG4gICAgICBpZiAodHlwZSA9PT0gUkVBQ1RfU1RSSUNUX01PREVfVFlQRSkge1xuICAgICAgICAvLyBEb24ndCBiZSBsZXNzIHNwZWNpZmljIHRoYW4gc2hhcmVkL2dldENvbXBvbmVudE5hbWVGcm9tVHlwZVxuICAgICAgICByZXR1cm4gJ1N0cmljdE1vZGUnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gJ01vZGUnO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICByZXR1cm4gJ09mZnNjcmVlbic7XG5cbiAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgcmV0dXJuICdQcm9maWxlcic7XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAgcmV0dXJuICdTY29wZSc7XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAgcmV0dXJuICdTdXNwZW5zZSc7XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHJldHVybiAnU3VzcGVuc2VMaXN0JztcblxuICAgIGNhc2UgVHJhY2luZ01hcmtlckNvbXBvbmVudDpcbiAgICAgIHJldHVybiAnVHJhY2luZ01hcmtlcic7XG4gICAgLy8gVGhlIGRpc3BsYXkgbmFtZSBmb3IgdGhpcyB0YWdzIGNvbWUgZnJvbSB0aGUgdXNlci1wcm92aWRlZCB0eXBlOlxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgSW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50OlxuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIE1lbW9Db21wb25lbnQ6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiB0eXBlLmRpc3BsYXlOYW1lIHx8IHR5cGUubmFtZSB8fCBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB0eXBlO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbnZhciBSZWFjdERlYnVnQ3VycmVudEZyYW1lID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZTtcbnZhciBjdXJyZW50ID0gbnVsbDtcbnZhciBpc1JlbmRlcmluZyA9IGZhbHNlO1xuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyT3duZXJOYW1lSW5EZXZPck51bGwoKSB7XG4gIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG93bmVyID0gY3VycmVudC5fZGVidWdPd25lcjtcblxuICAgIGlmIChvd25lciAhPT0gbnVsbCAmJiB0eXBlb2Ygb3duZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihvd25lcik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldEN1cnJlbnRGaWJlclN0YWNrSW5EZXYoKSB7XG4gIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH0gLy8gU2FmZSBiZWNhdXNlIGlmIGN1cnJlbnQgZmliZXIgZXhpc3RzLCB3ZSBhcmUgcmVjb25jaWxpbmcsXG4gICAgLy8gYW5kIGl0IGlzIGd1YXJhbnRlZWQgdG8gYmUgdGhlIHdvcmstaW4tcHJvZ3Jlc3MgdmVyc2lvbi5cblxuXG4gICAgcmV0dXJuIGdldFN0YWNrQnlGaWJlckluRGV2QW5kUHJvZChjdXJyZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldEN1cnJlbnRGaWJlcigpIHtcbiAge1xuICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0Q3VycmVudFN0YWNrID0gbnVsbDtcbiAgICBjdXJyZW50ID0gbnVsbDtcbiAgICBpc1JlbmRlcmluZyA9IGZhbHNlO1xuICB9XG59XG5mdW5jdGlvbiBzZXRDdXJyZW50RmliZXIoZmliZXIpIHtcbiAge1xuICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUuZ2V0Q3VycmVudFN0YWNrID0gZmliZXIgPT09IG51bGwgPyBudWxsIDogZ2V0Q3VycmVudEZpYmVyU3RhY2tJbkRldjtcbiAgICBjdXJyZW50ID0gZmliZXI7XG4gICAgaXNSZW5kZXJpbmcgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyKCkge1xuICB7XG4gICAgcmV0dXJuIGN1cnJlbnQ7XG4gIH1cbn1cbmZ1bmN0aW9uIHNldElzUmVuZGVyaW5nKHJlbmRlcmluZykge1xuICB7XG4gICAgaXNSZW5kZXJpbmcgPSByZW5kZXJpbmc7XG4gIH1cbn1cblxuLy8gRmxvdyBkb2VzIG5vdCBhbGxvdyBzdHJpbmcgY29uY2F0ZW5hdGlvbiBvZiBtb3N0IG5vbi1zdHJpbmcgdHlwZXMuIFRvIHdvcmtcbi8vIGFyb3VuZCB0aGlzIGxpbWl0YXRpb24sIHdlIHVzZSBhbiBvcGFxdWUgdHlwZSB0aGF0IGNhbiBvbmx5IGJlIG9idGFpbmVkIGJ5XG4vLyBwYXNzaW5nIHRoZSB2YWx1ZSB0aHJvdWdoIGdldFRvU3RyaW5nVmFsdWUgZmlyc3QuXG5mdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkge1xuICAvLyBUaGUgY29lcmNpb24gc2FmZXR5IGNoZWNrIGlzIHBlcmZvcm1lZCBpbiBnZXRUb1N0cmluZ1ZhbHVlKCkuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9zYWZlLXN0cmluZy1jb2VyY2lvblxuICByZXR1cm4gJycgKyB2YWx1ZTtcbn1cbmZ1bmN0aW9uIGdldFRvU3RyaW5nVmFsdWUodmFsdWUpIHtcbiAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICB7XG4gICAgICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2YWx1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBmdW5jdGlvbiwgc3ltYm9sIGFyZSBhc3NpZ25lZCBhcyBlbXB0eSBzdHJpbmdzXG4gICAgICByZXR1cm4gJyc7XG4gIH1cbn1cblxudmFyIGhhc1JlYWRPbmx5VmFsdWUgPSB7XG4gIGJ1dHRvbjogdHJ1ZSxcbiAgY2hlY2tib3g6IHRydWUsXG4gIGltYWdlOiB0cnVlLFxuICBoaWRkZW46IHRydWUsXG4gIHJhZGlvOiB0cnVlLFxuICByZXNldDogdHJ1ZSxcbiAgc3VibWl0OiB0cnVlXG59O1xuZnVuY3Rpb24gY2hlY2tDb250cm9sbGVkVmFsdWVQcm9wcyh0YWdOYW1lLCBwcm9wcykge1xuICB7XG4gICAgaWYgKCEoaGFzUmVhZE9ubHlWYWx1ZVtwcm9wcy50eXBlXSB8fCBwcm9wcy5vbkNoYW5nZSB8fCBwcm9wcy5vbklucHV0IHx8IHByb3BzLnJlYWRPbmx5IHx8IHByb3BzLmRpc2FibGVkIHx8IHByb3BzLnZhbHVlID09IG51bGwpKSB7XG4gICAgICBlcnJvcignWW91IHByb3ZpZGVkIGEgYHZhbHVlYCBwcm9wIHRvIGEgZm9ybSBmaWVsZCB3aXRob3V0IGFuICcgKyAnYG9uQ2hhbmdlYCBoYW5kbGVyLiBUaGlzIHdpbGwgcmVuZGVyIGEgcmVhZC1vbmx5IGZpZWxkLiBJZiAnICsgJ3RoZSBmaWVsZCBzaG91bGQgYmUgbXV0YWJsZSB1c2UgYGRlZmF1bHRWYWx1ZWAuIE90aGVyd2lzZSwgJyArICdzZXQgZWl0aGVyIGBvbkNoYW5nZWAgb3IgYHJlYWRPbmx5YC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIShwcm9wcy5vbkNoYW5nZSB8fCBwcm9wcy5yZWFkT25seSB8fCBwcm9wcy5kaXNhYmxlZCB8fCBwcm9wcy5jaGVja2VkID09IG51bGwpKSB7XG4gICAgICBlcnJvcignWW91IHByb3ZpZGVkIGEgYGNoZWNrZWRgIHByb3AgdG8gYSBmb3JtIGZpZWxkIHdpdGhvdXQgYW4gJyArICdgb25DaGFuZ2VgIGhhbmRsZXIuIFRoaXMgd2lsbCByZW5kZXIgYSByZWFkLW9ubHkgZmllbGQuIElmICcgKyAndGhlIGZpZWxkIHNob3VsZCBiZSBtdXRhYmxlIHVzZSBgZGVmYXVsdENoZWNrZWRgLiBPdGhlcndpc2UsICcgKyAnc2V0IGVpdGhlciBgb25DaGFuZ2VgIG9yIGByZWFkT25seWAuJyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2hlY2thYmxlKGVsZW0pIHtcbiAgdmFyIHR5cGUgPSBlbGVtLnR5cGU7XG4gIHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWU7XG4gIHJldHVybiBub2RlTmFtZSAmJiBub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaW5wdXQnICYmICh0eXBlID09PSAnY2hlY2tib3gnIHx8IHR5cGUgPT09ICdyYWRpbycpO1xufVxuXG5mdW5jdGlvbiBnZXRUcmFja2VyKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUuX3ZhbHVlVHJhY2tlcjtcbn1cblxuZnVuY3Rpb24gZGV0YWNoVHJhY2tlcihub2RlKSB7XG4gIG5vZGUuX3ZhbHVlVHJhY2tlciA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlRnJvbU5vZGUobm9kZSkge1xuICB2YXIgdmFsdWUgPSAnJztcblxuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBpZiAoaXNDaGVja2FibGUobm9kZSkpIHtcbiAgICB2YWx1ZSA9IG5vZGUuY2hlY2tlZCA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBub2RlLnZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cmFja1ZhbHVlT25Ob2RlKG5vZGUpIHtcbiAgdmFyIHZhbHVlRmllbGQgPSBpc0NoZWNrYWJsZShub2RlKSA/ICdjaGVja2VkJyA6ICd2YWx1ZSc7XG4gIHZhciBkZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihub2RlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgdmFsdWVGaWVsZCk7XG5cbiAge1xuICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbihub2RlW3ZhbHVlRmllbGRdKTtcbiAgfVxuXG4gIHZhciBjdXJyZW50VmFsdWUgPSAnJyArIG5vZGVbdmFsdWVGaWVsZF07IC8vIGlmIHNvbWVvbmUgaGFzIGFscmVhZHkgZGVmaW5lZCBhIHZhbHVlIG9yIFNhZmFyaSwgdGhlbiBiYWlsXG4gIC8vIGFuZCBkb24ndCB0cmFjayB2YWx1ZSB3aWxsIGNhdXNlIG92ZXIgcmVwb3J0aW5nIG9mIGNoYW5nZXMsXG4gIC8vIGJ1dCBpdCdzIGJldHRlciB0aGVuIGEgaGFyZCBmYWlsdXJlXG4gIC8vIChuZWVkZWQgZm9yIGNlcnRhaW4gdGVzdHMgdGhhdCBzcHlPbiBpbnB1dCB2YWx1ZXMgYW5kIFNhZmFyaSlcblxuICBpZiAobm9kZS5oYXNPd25Qcm9wZXJ0eSh2YWx1ZUZpZWxkKSB8fCB0eXBlb2YgZGVzY3JpcHRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIGRlc2NyaXB0b3IuZ2V0ICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBkZXNjcmlwdG9yLnNldCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBnZXQgPSBkZXNjcmlwdG9yLmdldCxcbiAgICAgIHNldCA9IGRlc2NyaXB0b3Iuc2V0O1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkobm9kZSwgdmFsdWVGaWVsZCwge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBnZXQuY2FsbCh0aGlzKTtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICB7XG4gICAgICAgIGNoZWNrRm9ybUZpZWxkVmFsdWVTdHJpbmdDb2VyY2lvbih2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRWYWx1ZSA9ICcnICsgdmFsdWU7XG4gICAgICBzZXQuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgfVxuICB9KTsgLy8gV2UgY291bGQndmUgcGFzc2VkIHRoaXMgdGhlIGZpcnN0IHRpbWVcbiAgLy8gYnV0IGl0IHRyaWdnZXJzIGEgYnVnIGluIElFMTEgYW5kIEVkZ2UgMTQvMTUuXG4gIC8vIENhbGxpbmcgZGVmaW5lUHJvcGVydHkoKSBhZ2FpbiBzaG91bGQgYmUgZXF1aXZhbGVudC5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMTc2OFxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShub2RlLCB2YWx1ZUZpZWxkLCB7XG4gICAgZW51bWVyYWJsZTogZGVzY3JpcHRvci5lbnVtZXJhYmxlXG4gIH0pO1xuICB2YXIgdHJhY2tlciA9IHtcbiAgICBnZXRWYWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGN1cnJlbnRWYWx1ZTtcbiAgICB9LFxuICAgIHNldFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIHtcbiAgICAgICAgY2hlY2tGb3JtRmllbGRWYWx1ZVN0cmluZ0NvZXJjaW9uKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudFZhbHVlID0gJycgKyB2YWx1ZTtcbiAgICB9LFxuICAgIHN0b3BUcmFja2luZzogZnVuY3Rpb24gKCkge1xuICAgICAgZGV0YWNoVHJhY2tlcihub2RlKTtcbiAgICAgIGRlbGV0ZSBub2RlW3ZhbHVlRmllbGRdO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHRyYWNrZXI7XG59XG5cbmZ1bmN0aW9uIHRyYWNrKG5vZGUpIHtcbiAgaWYgKGdldFRyYWNrZXIobm9kZSkpIHtcbiAgICByZXR1cm47XG4gIH0gLy8gVE9ETzogT25jZSBpdCdzIGp1c3QgRmliZXIgd2UgY2FuIG1vdmUgdGhpcyB0byBub2RlLl93cmFwcGVyU3RhdGVcblxuXG4gIG5vZGUuX3ZhbHVlVHJhY2tlciA9IHRyYWNrVmFsdWVPbk5vZGUobm9kZSk7XG59XG5mdW5jdGlvbiB1cGRhdGVWYWx1ZUlmQ2hhbmdlZChub2RlKSB7XG4gIGlmICghbm9kZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB0cmFja2VyID0gZ2V0VHJhY2tlcihub2RlKTsgLy8gaWYgdGhlcmUgaXMgbm8gdHJhY2tlciBhdCB0aGlzIHBvaW50IGl0J3MgdW5saWtlbHlcbiAgLy8gdGhhdCB0cnlpbmcgYWdhaW4gd2lsbCBzdWNjZWVkXG5cbiAgaWYgKCF0cmFja2VyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB2YXIgbGFzdFZhbHVlID0gdHJhY2tlci5nZXRWYWx1ZSgpO1xuICB2YXIgbmV4dFZhbHVlID0gZ2V0VmFsdWVGcm9tTm9kZShub2RlKTtcblxuICBpZiAobmV4dFZhbHVlICE9PSBsYXN0VmFsdWUpIHtcbiAgICB0cmFja2VyLnNldFZhbHVlKG5leHRWYWx1ZSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldEFjdGl2ZUVsZW1lbnQoZG9jKSB7XG4gIGRvYyA9IGRvYyB8fCAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IGRvY3VtZW50IDogdW5kZWZpbmVkKTtcblxuICBpZiAodHlwZW9mIGRvYyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGRvYy5hY3RpdmVFbGVtZW50IHx8IGRvYy5ib2R5O1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGRvYy5ib2R5O1xuICB9XG59XG5cbnZhciBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUgPSBmYWxzZTtcbnZhciBkaWRXYXJuQ2hlY2tlZERlZmF1bHRDaGVja2VkID0gZmFsc2U7XG52YXIgZGlkV2FybkNvbnRyb2xsZWRUb1VuY29udHJvbGxlZCA9IGZhbHNlO1xudmFyIGRpZFdhcm5VbmNvbnRyb2xsZWRUb0NvbnRyb2xsZWQgPSBmYWxzZTtcblxuZnVuY3Rpb24gaXNDb250cm9sbGVkKHByb3BzKSB7XG4gIHZhciB1c2VzQ2hlY2tlZCA9IHByb3BzLnR5cGUgPT09ICdjaGVja2JveCcgfHwgcHJvcHMudHlwZSA9PT0gJ3JhZGlvJztcbiAgcmV0dXJuIHVzZXNDaGVja2VkID8gcHJvcHMuY2hlY2tlZCAhPSBudWxsIDogcHJvcHMudmFsdWUgIT0gbnVsbDtcbn1cbi8qKlxuICogSW1wbGVtZW50cyBhbiA8aW5wdXQ+IGhvc3QgY29tcG9uZW50IHRoYXQgYWxsb3dzIHNldHRpbmcgdGhlc2Ugb3B0aW9uYWxcbiAqIHByb3BzOiBgY2hlY2tlZGAsIGB2YWx1ZWAsIGBkZWZhdWx0Q2hlY2tlZGAsIGFuZCBgZGVmYXVsdFZhbHVlYC5cbiAqXG4gKiBJZiBgY2hlY2tlZGAgb3IgYHZhbHVlYCBhcmUgbm90IHN1cHBsaWVkIChvciBudWxsL3VuZGVmaW5lZCksIHVzZXIgYWN0aW9uc1xuICogdGhhdCBhZmZlY3QgdGhlIGNoZWNrZWQgc3RhdGUgb3IgdmFsdWUgd2lsbCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogSWYgdGhleSBhcmUgc3VwcGxpZWQgKGFuZCBub3QgbnVsbC91bmRlZmluZWQpLCB0aGUgcmVuZGVyZWQgZWxlbWVudCB3aWxsIG5vdFxuICogdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSBlbGVtZW50LiBJbnN0ZWFkLCB0aGUgcHJvcHMgbXVzdCBjaGFuZ2UgaW4gb3JkZXIgZm9yXG4gKiB0aGUgcmVuZGVyZWQgZWxlbWVudCB0byBiZSB1cGRhdGVkLlxuICpcbiAqIFRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGwgYmUgaW5pdGlhbGl6ZWQgYXMgdW5jaGVja2VkIChvciBgZGVmYXVsdENoZWNrZWRgKVxuICogd2l0aCBhbiBlbXB0eSB2YWx1ZSAob3IgYGRlZmF1bHRWYWx1ZWApLlxuICpcbiAqIFNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDEyL1dELWh0bWw1LTIwMTIxMDI1L3RoZS1pbnB1dC1lbGVtZW50Lmh0bWxcbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEhvc3RQcm9wcyhlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIHZhciBjaGVja2VkID0gcHJvcHMuY2hlY2tlZDtcbiAgdmFyIGhvc3RQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICBkZWZhdWx0Q2hlY2tlZDogdW5kZWZpbmVkLFxuICAgIGRlZmF1bHRWYWx1ZTogdW5kZWZpbmVkLFxuICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgY2hlY2tlZDogY2hlY2tlZCAhPSBudWxsID8gY2hlY2tlZCA6IG5vZGUuX3dyYXBwZXJTdGF0ZS5pbml0aWFsQ2hlY2tlZFxuICB9KTtcbiAgcmV0dXJuIGhvc3RQcm9wcztcbn1cbmZ1bmN0aW9uIGluaXRXcmFwcGVyU3RhdGUoZWxlbWVudCwgcHJvcHMpIHtcbiAge1xuICAgIGNoZWNrQ29udHJvbGxlZFZhbHVlUHJvcHMoJ2lucHV0JywgcHJvcHMpO1xuXG4gICAgaWYgKHByb3BzLmNoZWNrZWQgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5kZWZhdWx0Q2hlY2tlZCAhPT0gdW5kZWZpbmVkICYmICFkaWRXYXJuQ2hlY2tlZERlZmF1bHRDaGVja2VkKSB7XG4gICAgICBlcnJvcignJXMgY29udGFpbnMgYW4gaW5wdXQgb2YgdHlwZSAlcyB3aXRoIGJvdGggY2hlY2tlZCBhbmQgZGVmYXVsdENoZWNrZWQgcHJvcHMuICcgKyAnSW5wdXQgZWxlbWVudHMgbXVzdCBiZSBlaXRoZXIgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgJyArICcoc3BlY2lmeSBlaXRoZXIgdGhlIGNoZWNrZWQgcHJvcCwgb3IgdGhlIGRlZmF1bHRDaGVja2VkIHByb3AsIGJ1dCBub3QgJyArICdib3RoKS4gRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCBpbnB1dCAnICsgJ2VsZW1lbnQgYW5kIHJlbW92ZSBvbmUgb2YgdGhlc2UgcHJvcHMuIE1vcmUgaW5mbzogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJywgZ2V0Q3VycmVudEZpYmVyT3duZXJOYW1lSW5EZXZPck51bGwoKSB8fCAnQSBjb21wb25lbnQnLCBwcm9wcy50eXBlKTtcblxuICAgICAgZGlkV2FybkNoZWNrZWREZWZhdWx0Q2hlY2tlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgcHJvcHMuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiYgIWRpZFdhcm5WYWx1ZURlZmF1bHRWYWx1ZSkge1xuICAgICAgZXJyb3IoJyVzIGNvbnRhaW5zIGFuIGlucHV0IG9mIHR5cGUgJXMgd2l0aCBib3RoIHZhbHVlIGFuZCBkZWZhdWx0VmFsdWUgcHJvcHMuICcgKyAnSW5wdXQgZWxlbWVudHMgbXVzdCBiZSBlaXRoZXIgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgJyArICcoc3BlY2lmeSBlaXRoZXIgdGhlIHZhbHVlIHByb3AsIG9yIHRoZSBkZWZhdWx0VmFsdWUgcHJvcCwgYnV0IG5vdCAnICsgJ2JvdGgpLiBEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIGlucHV0ICcgKyAnZWxlbWVudCBhbmQgcmVtb3ZlIG9uZSBvZiB0aGVzZSBwcm9wcy4gTW9yZSBpbmZvOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9jb250cm9sbGVkLWNvbXBvbmVudHMnLCBnZXRDdXJyZW50RmliZXJPd25lck5hbWVJbkRldk9yTnVsbCgpIHx8ICdBIGNvbXBvbmVudCcsIHByb3BzLnR5cGUpO1xuXG4gICAgICBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdmFyIGRlZmF1bHRWYWx1ZSA9IHByb3BzLmRlZmF1bHRWYWx1ZSA9PSBudWxsID8gJycgOiBwcm9wcy5kZWZhdWx0VmFsdWU7XG4gIG5vZGUuX3dyYXBwZXJTdGF0ZSA9IHtcbiAgICBpbml0aWFsQ2hlY2tlZDogcHJvcHMuY2hlY2tlZCAhPSBudWxsID8gcHJvcHMuY2hlY2tlZCA6IHByb3BzLmRlZmF1bHRDaGVja2VkLFxuICAgIGluaXRpYWxWYWx1ZTogZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy52YWx1ZSAhPSBudWxsID8gcHJvcHMudmFsdWUgOiBkZWZhdWx0VmFsdWUpLFxuICAgIGNvbnRyb2xsZWQ6IGlzQ29udHJvbGxlZChwcm9wcylcbiAgfTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZUNoZWNrZWQoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB2YXIgY2hlY2tlZCA9IHByb3BzLmNoZWNrZWQ7XG5cbiAgaWYgKGNoZWNrZWQgIT0gbnVsbCkge1xuICAgIHNldFZhbHVlRm9yUHJvcGVydHkobm9kZSwgJ2NoZWNrZWQnLCBjaGVja2VkLCBmYWxzZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHVwZGF0ZVdyYXBwZXIoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuXG4gIHtcbiAgICB2YXIgY29udHJvbGxlZCA9IGlzQ29udHJvbGxlZChwcm9wcyk7XG5cbiAgICBpZiAoIW5vZGUuX3dyYXBwZXJTdGF0ZS5jb250cm9sbGVkICYmIGNvbnRyb2xsZWQgJiYgIWRpZFdhcm5VbmNvbnRyb2xsZWRUb0NvbnRyb2xsZWQpIHtcbiAgICAgIGVycm9yKCdBIGNvbXBvbmVudCBpcyBjaGFuZ2luZyBhbiB1bmNvbnRyb2xsZWQgaW5wdXQgdG8gYmUgY29udHJvbGxlZC4gJyArICdUaGlzIGlzIGxpa2VseSBjYXVzZWQgYnkgdGhlIHZhbHVlIGNoYW5naW5nIGZyb20gdW5kZWZpbmVkIHRvICcgKyAnYSBkZWZpbmVkIHZhbHVlLCB3aGljaCBzaG91bGQgbm90IGhhcHBlbi4gJyArICdEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIGlucHV0ICcgKyAnZWxlbWVudCBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBjb21wb25lbnQuIE1vcmUgaW5mbzogaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycpO1xuXG4gICAgICBkaWRXYXJuVW5jb250cm9sbGVkVG9Db250cm9sbGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAobm9kZS5fd3JhcHBlclN0YXRlLmNvbnRyb2xsZWQgJiYgIWNvbnRyb2xsZWQgJiYgIWRpZFdhcm5Db250cm9sbGVkVG9VbmNvbnRyb2xsZWQpIHtcbiAgICAgIGVycm9yKCdBIGNvbXBvbmVudCBpcyBjaGFuZ2luZyBhIGNvbnRyb2xsZWQgaW5wdXQgdG8gYmUgdW5jb250cm9sbGVkLiAnICsgJ1RoaXMgaXMgbGlrZWx5IGNhdXNlZCBieSB0aGUgdmFsdWUgY2hhbmdpbmcgZnJvbSBhIGRlZmluZWQgdG8gJyArICd1bmRlZmluZWQsIHdoaWNoIHNob3VsZCBub3QgaGFwcGVuLiAnICsgJ0RlY2lkZSBiZXR3ZWVuIHVzaW5nIGEgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgaW5wdXQgJyArICdlbGVtZW50IGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIGNvbXBvbmVudC4gTW9yZSBpbmZvOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJyk7XG5cbiAgICAgIGRpZFdhcm5Db250cm9sbGVkVG9VbmNvbnRyb2xsZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNoZWNrZWQoZWxlbWVudCwgcHJvcHMpO1xuICB2YXIgdmFsdWUgPSBnZXRUb1N0cmluZ1ZhbHVlKHByb3BzLnZhbHVlKTtcbiAgdmFyIHR5cGUgPSBwcm9wcy50eXBlO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBpZiAodmFsdWUgPT09IDAgJiYgbm9kZS52YWx1ZSA9PT0gJycgfHwgLy8gV2UgZXhwbGljaXRseSB3YW50IHRvIGNvZXJjZSB0byBudW1iZXIgaGVyZSBpZiBwb3NzaWJsZS5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgbm9kZS52YWx1ZSAhPSB2YWx1ZSkge1xuICAgICAgICBub2RlLnZhbHVlID0gdG9TdHJpbmcodmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS52YWx1ZSAhPT0gdG9TdHJpbmcodmFsdWUpKSB7XG4gICAgICBub2RlLnZhbHVlID0gdG9TdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3VibWl0JyB8fCB0eXBlID09PSAncmVzZXQnKSB7XG4gICAgLy8gU3VibWl0L3Jlc2V0IGlucHV0cyBuZWVkIHRoZSBhdHRyaWJ1dGUgcmVtb3ZlZCBjb21wbGV0ZWx5IHRvIGF2b2lkXG4gICAgLy8gYmxhbmstdGV4dCBidXR0b25zLlxuICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKCd2YWx1ZScpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHtcbiAgICAvLyBXaGVuIHN5bmNpbmcgdGhlIHZhbHVlIGF0dHJpYnV0ZSwgdGhlIHZhbHVlIGNvbWVzIGZyb20gYSBjYXNjYWRlIG9mXG4gICAgLy8gcHJvcGVydGllczpcbiAgICAvLyAgMS4gVGhlIHZhbHVlIFJlYWN0IHByb3BlcnR5XG4gICAgLy8gIDIuIFRoZSBkZWZhdWx0VmFsdWUgUmVhY3QgcHJvcGVydHlcbiAgICAvLyAgMy4gT3RoZXJ3aXNlIHRoZXJlIHNob3VsZCBiZSBubyBjaGFuZ2VcbiAgICBpZiAocHJvcHMuaGFzT3duUHJvcGVydHkoJ3ZhbHVlJykpIHtcbiAgICAgIHNldERlZmF1bHRWYWx1ZShub2RlLCBwcm9wcy50eXBlLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmIChwcm9wcy5oYXNPd25Qcm9wZXJ0eSgnZGVmYXVsdFZhbHVlJykpIHtcbiAgICAgIHNldERlZmF1bHRWYWx1ZShub2RlLCBwcm9wcy50eXBlLCBnZXRUb1N0cmluZ1ZhbHVlKHByb3BzLmRlZmF1bHRWYWx1ZSkpO1xuICAgIH1cbiAgfVxuXG4gIHtcbiAgICAvLyBXaGVuIHN5bmNpbmcgdGhlIGNoZWNrZWQgYXR0cmlidXRlLCBpdCBvbmx5IGNoYW5nZXMgd2hlbiBpdCBuZWVkc1xuICAgIC8vIHRvIGJlIHJlbW92ZWQsIHN1Y2ggYXMgdHJhbnNpdGlvbmluZyBmcm9tIGEgY2hlY2tib3ggaW50byBhIHRleHQgaW5wdXRcbiAgICBpZiAocHJvcHMuY2hlY2tlZCA9PSBudWxsICYmIHByb3BzLmRlZmF1bHRDaGVja2VkICE9IG51bGwpIHtcbiAgICAgIG5vZGUuZGVmYXVsdENoZWNrZWQgPSAhIXByb3BzLmRlZmF1bHRDaGVja2VkO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcG9zdE1vdW50V3JhcHBlcihlbGVtZW50LCBwcm9wcywgaXNIeWRyYXRpbmcpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50OyAvLyBEbyBub3QgYXNzaWduIHZhbHVlIGlmIGl0IGlzIGFscmVhZHkgc2V0LiBUaGlzIHByZXZlbnRzIHVzZXIgdGV4dCBpbnB1dFxuICAvLyBmcm9tIGJlaW5nIGxvc3QgZHVyaW5nIFNTUiBoeWRyYXRpb24uXG5cbiAgaWYgKHByb3BzLmhhc093blByb3BlcnR5KCd2YWx1ZScpIHx8IHByb3BzLmhhc093blByb3BlcnR5KCdkZWZhdWx0VmFsdWUnKSkge1xuICAgIHZhciB0eXBlID0gcHJvcHMudHlwZTtcbiAgICB2YXIgaXNCdXR0b24gPSB0eXBlID09PSAnc3VibWl0JyB8fCB0eXBlID09PSAncmVzZXQnOyAvLyBBdm9pZCBzZXR0aW5nIHZhbHVlIGF0dHJpYnV0ZSBvbiBzdWJtaXQvcmVzZXQgaW5wdXRzIGFzIGl0IG92ZXJyaWRlcyB0aGVcbiAgICAvLyBkZWZhdWx0IHZhbHVlIHByb3ZpZGVkIGJ5IHRoZSBicm93c2VyLiBTZWU6ICMxMjg3MlxuXG4gICAgaWYgKGlzQnV0dG9uICYmIChwcm9wcy52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHByb3BzLnZhbHVlID09PSBudWxsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbml0aWFsVmFsdWUgPSB0b1N0cmluZyhub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlKTsgLy8gRG8gbm90IGFzc2lnbiB2YWx1ZSBpZiBpdCBpcyBhbHJlYWR5IHNldC4gVGhpcyBwcmV2ZW50cyB1c2VyIHRleHQgaW5wdXRcbiAgICAvLyBmcm9tIGJlaW5nIGxvc3QgZHVyaW5nIFNTUiBoeWRyYXRpb24uXG5cbiAgICBpZiAoIWlzSHlkcmF0aW5nKSB7XG4gICAgICB7XG4gICAgICAgIC8vIFdoZW4gc3luY2luZyB0aGUgdmFsdWUgYXR0cmlidXRlLCB0aGUgdmFsdWUgcHJvcGVydHkgc2hvdWxkIHVzZVxuICAgICAgICAvLyB0aGUgd3JhcHBlclN0YXRlLl9pbml0aWFsVmFsdWUgcHJvcGVydHkuIFRoaXMgdXNlczpcbiAgICAgICAgLy9cbiAgICAgICAgLy8gICAxLiBUaGUgdmFsdWUgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgICAgIC8vICAgMi4gVGhlIGRlZmF1bHRWYWx1ZSBSZWFjdCBwcm9wZXJ0eSB3aGVuIHByZXNlbnRcbiAgICAgICAgLy8gICAzLiBBbiBlbXB0eSBzdHJpbmdcbiAgICAgICAgaWYgKGluaXRpYWxWYWx1ZSAhPT0gbm9kZS52YWx1ZSkge1xuICAgICAgICAgIG5vZGUudmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBPdGhlcndpc2UsIHRoZSB2YWx1ZSBhdHRyaWJ1dGUgaXMgc3luY2hyb25pemVkIHRvIHRoZSBwcm9wZXJ0eSxcbiAgICAgIC8vIHNvIHdlIGFzc2lnbiBkZWZhdWx0VmFsdWUgdG8gdGhlIHNhbWUgdGhpbmcgYXMgdGhlIHZhbHVlIHByb3BlcnR5XG4gICAgICAvLyBhc3NpZ25tZW50IHN0ZXAgYWJvdmUuXG4gICAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgICB9XG4gIH0gLy8gTm9ybWFsbHksIHdlJ2QganVzdCBkbyBgbm9kZS5jaGVja2VkID0gbm9kZS5jaGVja2VkYCB1cG9uIGluaXRpYWwgbW91bnQsIGxlc3MgdGhpcyBidWdcbiAgLy8gdGhpcyBpcyBuZWVkZWQgdG8gd29yayBhcm91bmQgYSBjaHJvbWUgYnVnIHdoZXJlIHNldHRpbmcgZGVmYXVsdENoZWNrZWRcbiAgLy8gd2lsbCBzb21ldGltZXMgaW5mbHVlbmNlIHRoZSB2YWx1ZSBvZiBjaGVja2VkIChldmVuIGFmdGVyIGRldGFjaG1lbnQpLlxuICAvLyBSZWZlcmVuY2U6IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTYwODQxNlxuICAvLyBXZSBuZWVkIHRvIHRlbXBvcmFyaWx5IHVuc2V0IG5hbWUgdG8gYXZvaWQgZGlzcnVwdGluZyByYWRpbyBidXR0b24gZ3JvdXBzLlxuXG5cbiAgdmFyIG5hbWUgPSBub2RlLm5hbWU7XG5cbiAgaWYgKG5hbWUgIT09ICcnKSB7XG4gICAgbm9kZS5uYW1lID0gJyc7XG4gIH1cblxuICB7XG4gICAgLy8gV2hlbiBzeW5jaW5nIHRoZSBjaGVja2VkIGF0dHJpYnV0ZSwgYm90aCB0aGUgY2hlY2tlZCBwcm9wZXJ0eSBhbmRcbiAgICAvLyBhdHRyaWJ1dGUgYXJlIGFzc2lnbmVkIGF0IHRoZSBzYW1lIHRpbWUgdXNpbmcgZGVmYXVsdENoZWNrZWQuIFRoaXMgdXNlczpcbiAgICAvL1xuICAgIC8vICAgMS4gVGhlIGNoZWNrZWQgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgLy8gICAyLiBUaGUgZGVmYXVsdENoZWNrZWQgUmVhY3QgcHJvcGVydHkgd2hlbiBwcmVzZW50XG4gICAgLy8gICAzLiBPdGhlcndpc2UsIGZhbHNlXG4gICAgbm9kZS5kZWZhdWx0Q2hlY2tlZCA9ICFub2RlLmRlZmF1bHRDaGVja2VkO1xuICAgIG5vZGUuZGVmYXVsdENoZWNrZWQgPSAhIW5vZGUuX3dyYXBwZXJTdGF0ZS5pbml0aWFsQ2hlY2tlZDtcbiAgfVxuXG4gIGlmIChuYW1lICE9PSAnJykge1xuICAgIG5vZGUubmFtZSA9IG5hbWU7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVDb250cm9sbGVkU3RhdGUoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB1cGRhdGVXcmFwcGVyKG5vZGUsIHByb3BzKTtcbiAgdXBkYXRlTmFtZWRDb3VzaW5zKG5vZGUsIHByb3BzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTmFtZWRDb3VzaW5zKHJvb3ROb2RlLCBwcm9wcykge1xuICB2YXIgbmFtZSA9IHByb3BzLm5hbWU7XG5cbiAgaWYgKHByb3BzLnR5cGUgPT09ICdyYWRpbycgJiYgbmFtZSAhPSBudWxsKSB7XG4gICAgdmFyIHF1ZXJ5Um9vdCA9IHJvb3ROb2RlO1xuXG4gICAgd2hpbGUgKHF1ZXJ5Um9vdC5wYXJlbnROb2RlKSB7XG4gICAgICBxdWVyeVJvb3QgPSBxdWVyeVJvb3QucGFyZW50Tm9kZTtcbiAgICB9IC8vIElmIGByb290Tm9kZS5mb3JtYCB3YXMgbm9uLW51bGwsIHRoZW4gd2UgY291bGQgdHJ5IGBmb3JtLmVsZW1lbnRzYCxcbiAgICAvLyBidXQgdGhhdCBzb21ldGltZXMgYmVoYXZlcyBzdHJhbmdlbHkgaW4gSUU4LiBXZSBjb3VsZCBhbHNvIHRyeSB1c2luZ1xuICAgIC8vIGBmb3JtLmdldEVsZW1lbnRzQnlOYW1lYCwgYnV0IHRoYXQgd2lsbCBvbmx5IHJldHVybiBkaXJlY3QgY2hpbGRyZW5cbiAgICAvLyBhbmQgd29uJ3QgaW5jbHVkZSBpbnB1dHMgdGhhdCB1c2UgdGhlIEhUTUw1IGBmb3JtPWAgYXR0cmlidXRlLiBTaW5jZVxuICAgIC8vIHRoZSBpbnB1dCBtaWdodCBub3QgZXZlbiBiZSBpbiBhIGZvcm0uIEl0IG1pZ2h0IG5vdCBldmVuIGJlIGluIHRoZVxuICAgIC8vIGRvY3VtZW50LiBMZXQncyBqdXN0IHVzZSB0aGUgbG9jYWwgYHF1ZXJ5U2VsZWN0b3JBbGxgIHRvIGVuc3VyZSB3ZSBkb24ndFxuICAgIC8vIG1pc3MgYW55dGhpbmcuXG5cblxuICAgIHtcbiAgICAgIGNoZWNrQXR0cmlidXRlU3RyaW5nQ29lcmNpb24obmFtZSwgJ25hbWUnKTtcbiAgICB9XG5cbiAgICB2YXIgZ3JvdXAgPSBxdWVyeVJvb3QucXVlcnlTZWxlY3RvckFsbCgnaW5wdXRbbmFtZT0nICsgSlNPTi5zdHJpbmdpZnkoJycgKyBuYW1lKSArICddW3R5cGU9XCJyYWRpb1wiXScpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm91cC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG90aGVyTm9kZSA9IGdyb3VwW2ldO1xuXG4gICAgICBpZiAob3RoZXJOb2RlID09PSByb290Tm9kZSB8fCBvdGhlck5vZGUuZm9ybSAhPT0gcm9vdE5vZGUuZm9ybSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gLy8gVGhpcyB3aWxsIHRocm93IGlmIHJhZGlvIGJ1dHRvbnMgcmVuZGVyZWQgYnkgZGlmZmVyZW50IGNvcGllcyBvZiBSZWFjdFxuICAgICAgLy8gYW5kIHRoZSBzYW1lIG5hbWUgYXJlIHJlbmRlcmVkIGludG8gdGhlIHNhbWUgZm9ybSAoc2FtZSBhcyAjMTkzOSkuXG4gICAgICAvLyBUaGF0J3MgcHJvYmFibHkgb2theTsgd2UgZG9uJ3Qgc3VwcG9ydCBpdCBqdXN0IGFzIHdlIGRvbid0IHN1cHBvcnRcbiAgICAgIC8vIG1peGluZyBSZWFjdCByYWRpbyBidXR0b25zIHdpdGggbm9uLVJlYWN0IG9uZXMuXG5cblxuICAgICAgdmFyIG90aGVyUHJvcHMgPSBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKG90aGVyTm9kZSk7XG5cbiAgICAgIGlmICghb3RoZXJQcm9wcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlYWN0RE9NSW5wdXQ6IE1peGluZyBSZWFjdCBhbmQgbm9uLVJlYWN0IHJhZGlvIGlucHV0cyB3aXRoIHRoZSAnICsgJ3NhbWUgYG5hbWVgIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICB9IC8vIFdlIG5lZWQgdXBkYXRlIHRoZSB0cmFja2VkIHZhbHVlIG9uIHRoZSBuYW1lZCBjb3VzaW4gc2luY2UgdGhlIHZhbHVlXG4gICAgICAvLyB3YXMgY2hhbmdlZCBidXQgdGhlIGlucHV0IHNhdyBubyBldmVudCBvciB2YWx1ZSBzZXRcblxuXG4gICAgICB1cGRhdGVWYWx1ZUlmQ2hhbmdlZChvdGhlck5vZGUpOyAvLyBJZiB0aGlzIGlzIGEgY29udHJvbGxlZCByYWRpbyBidXR0b24gZ3JvdXAsIGZvcmNpbmcgdGhlIGlucHV0IHRoYXRcbiAgICAgIC8vIHdhcyBwcmV2aW91c2x5IGNoZWNrZWQgdG8gdXBkYXRlIHdpbGwgY2F1c2UgaXQgdG8gYmUgY29tZSByZS1jaGVja2VkXG4gICAgICAvLyBhcyBhcHByb3ByaWF0ZS5cblxuICAgICAgdXBkYXRlV3JhcHBlcihvdGhlck5vZGUsIG90aGVyUHJvcHMpO1xuICAgIH1cbiAgfVxufSAvLyBJbiBDaHJvbWUsIGFzc2lnbmluZyBkZWZhdWx0VmFsdWUgdG8gY2VydGFpbiBpbnB1dCB0eXBlcyB0cmlnZ2VycyBpbnB1dCB2YWxpZGF0aW9uLlxuLy8gRm9yIG51bWJlciBpbnB1dHMsIHRoZSBkaXNwbGF5IHZhbHVlIGxvc2VzIHRyYWlsaW5nIGRlY2ltYWwgcG9pbnRzLiBGb3IgZW1haWwgaW5wdXRzLFxuLy8gQ2hyb21lIHJhaXNlcyBcIlRoZSBzcGVjaWZpZWQgdmFsdWUgPHg+IGlzIG5vdCBhIHZhbGlkIGVtYWlsIGFkZHJlc3NcIi5cbi8vXG4vLyBIZXJlIHdlIGNoZWNrIHRvIHNlZSBpZiB0aGUgZGVmYXVsdFZhbHVlIGhhcyBhY3R1YWxseSBjaGFuZ2VkLCBhdm9pZGluZyB0aGVzZSBwcm9ibGVtc1xuLy8gd2hlbiB0aGUgdXNlciBpcyBpbnB1dHRpbmcgdGV4dFxuLy9cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvNzI1M1xuXG5cbmZ1bmN0aW9uIHNldERlZmF1bHRWYWx1ZShub2RlLCB0eXBlLCB2YWx1ZSkge1xuICBpZiAoIC8vIEZvY3VzZWQgbnVtYmVyIGlucHV0cyBzeW5jaHJvbml6ZSBvbiBibHVyLiBTZWUgQ2hhbmdlRXZlbnRQbHVnaW4uanNcbiAgdHlwZSAhPT0gJ251bWJlcicgfHwgZ2V0QWN0aXZlRWxlbWVudChub2RlLm93bmVyRG9jdW1lbnQpICE9PSBub2RlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIG5vZGUuZGVmYXVsdFZhbHVlID0gdG9TdHJpbmcobm9kZS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZSk7XG4gICAgfSBlbHNlIGlmIChub2RlLmRlZmF1bHRWYWx1ZSAhPT0gdG9TdHJpbmcodmFsdWUpKSB7XG4gICAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IHRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIGRpZFdhcm5TZWxlY3RlZFNldE9uT3B0aW9uID0gZmFsc2U7XG52YXIgZGlkV2FybkludmFsaWRDaGlsZCA9IGZhbHNlO1xudmFyIGRpZFdhcm5JbnZhbGlkSW5uZXJIVE1MID0gZmFsc2U7XG4vKipcbiAqIEltcGxlbWVudHMgYW4gPG9wdGlvbj4gaG9zdCBjb21wb25lbnQgdGhhdCB3YXJucyB3aGVuIGBzZWxlY3RlZGAgaXMgc2V0LlxuICovXG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcHMoZWxlbWVudCwgcHJvcHMpIHtcbiAge1xuICAgIC8vIElmIGEgdmFsdWUgaXMgbm90IHByb3ZpZGVkLCB0aGVuIHRoZSBjaGlsZHJlbiBtdXN0IGJlIHNpbXBsZS5cbiAgICBpZiAocHJvcHMudmFsdWUgPT0gbnVsbCkge1xuICAgICAgaWYgKHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ29iamVjdCcgJiYgcHJvcHMuY2hpbGRyZW4gIT09IG51bGwpIHtcbiAgICAgICAgUmVhY3QuQ2hpbGRyZW4uZm9yRWFjaChwcm9wcy5jaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgaWYgKGNoaWxkID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGNoaWxkID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgY2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFkaWRXYXJuSW52YWxpZENoaWxkKSB7XG4gICAgICAgICAgICBkaWRXYXJuSW52YWxpZENoaWxkID0gdHJ1ZTtcblxuICAgICAgICAgICAgZXJyb3IoJ0Nhbm5vdCBpbmZlciB0aGUgb3B0aW9uIHZhbHVlIG9mIGNvbXBsZXggY2hpbGRyZW4uICcgKyAnUGFzcyBhIGB2YWx1ZWAgcHJvcCBvciB1c2UgYSBwbGFpbiBzdHJpbmcgYXMgY2hpbGRyZW4gdG8gPG9wdGlvbj4uJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAocHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgIT0gbnVsbCkge1xuICAgICAgICBpZiAoIWRpZFdhcm5JbnZhbGlkSW5uZXJIVE1MKSB7XG4gICAgICAgICAgZGlkV2FybkludmFsaWRJbm5lckhUTUwgPSB0cnVlO1xuXG4gICAgICAgICAgZXJyb3IoJ1Bhc3MgYSBgdmFsdWVgIHByb3AgaWYgeW91IHNldCBkYW5nZXJvdXNseUlubmVySFRNTCBzbyBSZWFjdCBrbm93cyAnICsgJ3doaWNoIHZhbHVlIHNob3VsZCBiZSBzZWxlY3RlZC4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gVE9ETzogUmVtb3ZlIHN1cHBvcnQgZm9yIGBzZWxlY3RlZGAgaW4gPG9wdGlvbj4uXG5cblxuICAgIGlmIChwcm9wcy5zZWxlY3RlZCAhPSBudWxsICYmICFkaWRXYXJuU2VsZWN0ZWRTZXRPbk9wdGlvbikge1xuICAgICAgZXJyb3IoJ1VzZSB0aGUgYGRlZmF1bHRWYWx1ZWAgb3IgYHZhbHVlYCBwcm9wcyBvbiA8c2VsZWN0PiBpbnN0ZWFkIG9mICcgKyAnc2V0dGluZyBgc2VsZWN0ZWRgIG9uIDxvcHRpb24+LicpO1xuXG4gICAgICBkaWRXYXJuU2VsZWN0ZWRTZXRPbk9wdGlvbiA9IHRydWU7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwb3N0TW91bnRXcmFwcGVyJDEoZWxlbWVudCwgcHJvcHMpIHtcbiAgLy8gdmFsdWU9XCJcIiBzaG91bGQgbWFrZSBhIHZhbHVlIGF0dHJpYnV0ZSAoIzYyMTkpXG4gIGlmIChwcm9wcy52YWx1ZSAhPSBudWxsKSB7XG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgdG9TdHJpbmcoZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy52YWx1ZSkpKTtcbiAgfVxufVxuXG52YXIgaXNBcnJheUltcGwgPSBBcnJheS5pc0FycmF5OyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVkZWNsYXJlXG5cbmZ1bmN0aW9uIGlzQXJyYXkoYSkge1xuICByZXR1cm4gaXNBcnJheUltcGwoYSk7XG59XG5cbnZhciBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUkMTtcblxue1xuICBkaWRXYXJuVmFsdWVEZWZhdWx0VmFsdWUkMSA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXREZWNsYXJhdGlvbkVycm9yQWRkZW5kdW0oKSB7XG4gIHZhciBvd25lck5hbWUgPSBnZXRDdXJyZW50RmliZXJPd25lck5hbWVJbkRldk9yTnVsbCgpO1xuXG4gIGlmIChvd25lck5hbWUpIHtcbiAgICByZXR1cm4gJ1xcblxcbkNoZWNrIHRoZSByZW5kZXIgbWV0aG9kIG9mIGAnICsgb3duZXJOYW1lICsgJ2AuJztcbiAgfVxuXG4gIHJldHVybiAnJztcbn1cblxudmFyIHZhbHVlUHJvcE5hbWVzID0gWyd2YWx1ZScsICdkZWZhdWx0VmFsdWUnXTtcbi8qKlxuICogVmFsaWRhdGlvbiBmdW5jdGlvbiBmb3IgYHZhbHVlYCBhbmQgYGRlZmF1bHRWYWx1ZWAuXG4gKi9cblxuZnVuY3Rpb24gY2hlY2tTZWxlY3RQcm9wVHlwZXMocHJvcHMpIHtcbiAge1xuICAgIGNoZWNrQ29udHJvbGxlZFZhbHVlUHJvcHMoJ3NlbGVjdCcsIHByb3BzKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVQcm9wTmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwcm9wTmFtZSA9IHZhbHVlUHJvcE5hbWVzW2ldO1xuXG4gICAgICBpZiAocHJvcHNbcHJvcE5hbWVdID09IG51bGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBwcm9wTmFtZUlzQXJyYXkgPSBpc0FycmF5KHByb3BzW3Byb3BOYW1lXSk7XG5cbiAgICAgIGlmIChwcm9wcy5tdWx0aXBsZSAmJiAhcHJvcE5hbWVJc0FycmF5KSB7XG4gICAgICAgIGVycm9yKCdUaGUgYCVzYCBwcm9wIHN1cHBsaWVkIHRvIDxzZWxlY3Q+IG11c3QgYmUgYW4gYXJyYXkgaWYgJyArICdgbXVsdGlwbGVgIGlzIHRydWUuJXMnLCBwcm9wTmFtZSwgZ2V0RGVjbGFyYXRpb25FcnJvckFkZGVuZHVtKCkpO1xuICAgICAgfSBlbHNlIGlmICghcHJvcHMubXVsdGlwbGUgJiYgcHJvcE5hbWVJc0FycmF5KSB7XG4gICAgICAgIGVycm9yKCdUaGUgYCVzYCBwcm9wIHN1cHBsaWVkIHRvIDxzZWxlY3Q+IG11c3QgYmUgYSBzY2FsYXIgJyArICd2YWx1ZSBpZiBgbXVsdGlwbGVgIGlzIGZhbHNlLiVzJywgcHJvcE5hbWUsIGdldERlY2xhcmF0aW9uRXJyb3JBZGRlbmR1bSgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlT3B0aW9ucyhub2RlLCBtdWx0aXBsZSwgcHJvcFZhbHVlLCBzZXREZWZhdWx0U2VsZWN0ZWQpIHtcbiAgdmFyIG9wdGlvbnMgPSBub2RlLm9wdGlvbnM7XG5cbiAgaWYgKG11bHRpcGxlKSB7XG4gICAgdmFyIHNlbGVjdGVkVmFsdWVzID0gcHJvcFZhbHVlO1xuICAgIHZhciBzZWxlY3RlZFZhbHVlID0ge307XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdGVkVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBQcmVmaXggdG8gYXZvaWQgY2hhb3Mgd2l0aCBzcGVjaWFsIGtleXMuXG4gICAgICBzZWxlY3RlZFZhbHVlWyckJyArIHNlbGVjdGVkVmFsdWVzW2ldXSA9IHRydWU7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IG9wdGlvbnMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgc2VsZWN0ZWQgPSBzZWxlY3RlZFZhbHVlLmhhc093blByb3BlcnR5KCckJyArIG9wdGlvbnNbX2ldLnZhbHVlKTtcblxuICAgICAgaWYgKG9wdGlvbnNbX2ldLnNlbGVjdGVkICE9PSBzZWxlY3RlZCkge1xuICAgICAgICBvcHRpb25zW19pXS5zZWxlY3RlZCA9IHNlbGVjdGVkO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2VsZWN0ZWQgJiYgc2V0RGVmYXVsdFNlbGVjdGVkKSB7XG4gICAgICAgIG9wdGlvbnNbX2ldLmRlZmF1bHRTZWxlY3RlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIERvIG5vdCBzZXQgYHNlbGVjdC52YWx1ZWAgYXMgZXhhY3QgYmVoYXZpb3IgaXNuJ3QgY29uc2lzdGVudCBhY3Jvc3MgYWxsXG4gICAgLy8gYnJvd3NlcnMgZm9yIGFsbCBjYXNlcy5cbiAgICB2YXIgX3NlbGVjdGVkVmFsdWUgPSB0b1N0cmluZyhnZXRUb1N0cmluZ1ZhbHVlKHByb3BWYWx1ZSkpO1xuXG4gICAgdmFyIGRlZmF1bHRTZWxlY3RlZCA9IG51bGw7XG5cbiAgICBmb3IgKHZhciBfaTIgPSAwOyBfaTIgPCBvcHRpb25zLmxlbmd0aDsgX2kyKyspIHtcbiAgICAgIGlmIChvcHRpb25zW19pMl0udmFsdWUgPT09IF9zZWxlY3RlZFZhbHVlKSB7XG4gICAgICAgIG9wdGlvbnNbX2kyXS5zZWxlY3RlZCA9IHRydWU7XG5cbiAgICAgICAgaWYgKHNldERlZmF1bHRTZWxlY3RlZCkge1xuICAgICAgICAgIG9wdGlvbnNbX2kyXS5kZWZhdWx0U2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGVmYXVsdFNlbGVjdGVkID09PSBudWxsICYmICFvcHRpb25zW19pMl0uZGlzYWJsZWQpIHtcbiAgICAgICAgZGVmYXVsdFNlbGVjdGVkID0gb3B0aW9uc1tfaTJdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkZWZhdWx0U2VsZWN0ZWQgIT09IG51bGwpIHtcbiAgICAgIGRlZmF1bHRTZWxlY3RlZC5zZWxlY3RlZCA9IHRydWU7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEltcGxlbWVudHMgYSA8c2VsZWN0PiBob3N0IGNvbXBvbmVudCB0aGF0IGFsbG93cyBvcHRpb25hbGx5IHNldHRpbmcgdGhlXG4gKiBwcm9wcyBgdmFsdWVgIGFuZCBgZGVmYXVsdFZhbHVlYC4gSWYgYG11bHRpcGxlYCBpcyBmYWxzZSwgdGhlIHByb3AgbXVzdCBiZSBhXG4gKiBzdHJpbmdhYmxlLiBJZiBgbXVsdGlwbGVgIGlzIHRydWUsIHRoZSBwcm9wIG11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5nYWJsZXMuXG4gKlxuICogSWYgYHZhbHVlYCBpcyBub3Qgc3VwcGxpZWQgKG9yIG51bGwvdW5kZWZpbmVkKSwgdXNlciBhY3Rpb25zIHRoYXQgY2hhbmdlIHRoZVxuICogc2VsZWN0ZWQgb3B0aW9uIHdpbGwgdHJpZ2dlciB1cGRhdGVzIHRvIHRoZSByZW5kZXJlZCBvcHRpb25zLlxuICpcbiAqIElmIGl0IGlzIHN1cHBsaWVkIChhbmQgbm90IG51bGwvdW5kZWZpbmVkKSwgdGhlIHJlbmRlcmVkIG9wdGlvbnMgd2lsbCBub3RcbiAqIHVwZGF0ZSBpbiByZXNwb25zZSB0byB1c2VyIGFjdGlvbnMuIEluc3RlYWQsIHRoZSBgdmFsdWVgIHByb3AgbXVzdCBjaGFuZ2UgaW5cbiAqIG9yZGVyIGZvciB0aGUgcmVuZGVyZWQgb3B0aW9ucyB0byB1cGRhdGUuXG4gKlxuICogSWYgYGRlZmF1bHRWYWx1ZWAgaXMgcHJvdmlkZWQsIGFueSBvcHRpb25zIHdpdGggdGhlIHN1cHBsaWVkIHZhbHVlcyB3aWxsIGJlXG4gKiBzZWxlY3RlZC5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEhvc3RQcm9wcyQxKGVsZW1lbnQsIHByb3BzKSB7XG4gIHJldHVybiBhc3NpZ24oe30sIHByb3BzLCB7XG4gICAgdmFsdWU6IHVuZGVmaW5lZFxuICB9KTtcbn1cbmZ1bmN0aW9uIGluaXRXcmFwcGVyU3RhdGUkMShlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG5cbiAge1xuICAgIGNoZWNrU2VsZWN0UHJvcFR5cGVzKHByb3BzKTtcbiAgfVxuXG4gIG5vZGUuX3dyYXBwZXJTdGF0ZSA9IHtcbiAgICB3YXNNdWx0aXBsZTogISFwcm9wcy5tdWx0aXBsZVxuICB9O1xuXG4gIHtcbiAgICBpZiAocHJvcHMudmFsdWUgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZGlkV2FyblZhbHVlRGVmYXVsdFZhbHVlJDEpIHtcbiAgICAgIGVycm9yKCdTZWxlY3QgZWxlbWVudHMgbXVzdCBiZSBlaXRoZXIgY29udHJvbGxlZCBvciB1bmNvbnRyb2xsZWQgJyArICcoc3BlY2lmeSBlaXRoZXIgdGhlIHZhbHVlIHByb3AsIG9yIHRoZSBkZWZhdWx0VmFsdWUgcHJvcCwgYnV0IG5vdCAnICsgJ2JvdGgpLiBEZWNpZGUgYmV0d2VlbiB1c2luZyBhIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkIHNlbGVjdCAnICsgJ2VsZW1lbnQgYW5kIHJlbW92ZSBvbmUgb2YgdGhlc2UgcHJvcHMuIE1vcmUgaW5mbzogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvY29udHJvbGxlZC1jb21wb25lbnRzJyk7XG5cbiAgICAgIGRpZFdhcm5WYWx1ZURlZmF1bHRWYWx1ZSQxID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHBvc3RNb3VudFdyYXBwZXIkMihlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIG5vZGUubXVsdGlwbGUgPSAhIXByb3BzLm11bHRpcGxlO1xuICB2YXIgdmFsdWUgPSBwcm9wcy52YWx1ZTtcblxuICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgIHVwZGF0ZU9wdGlvbnMobm9kZSwgISFwcm9wcy5tdWx0aXBsZSwgdmFsdWUsIGZhbHNlKTtcbiAgfSBlbHNlIGlmIChwcm9wcy5kZWZhdWx0VmFsdWUgIT0gbnVsbCkge1xuICAgIHVwZGF0ZU9wdGlvbnMobm9kZSwgISFwcm9wcy5tdWx0aXBsZSwgcHJvcHMuZGVmYXVsdFZhbHVlLCB0cnVlKTtcbiAgfVxufVxuZnVuY3Rpb24gcG9zdFVwZGF0ZVdyYXBwZXIoZWxlbWVudCwgcHJvcHMpIHtcbiAgdmFyIG5vZGUgPSBlbGVtZW50O1xuICB2YXIgd2FzTXVsdGlwbGUgPSBub2RlLl93cmFwcGVyU3RhdGUud2FzTXVsdGlwbGU7XG4gIG5vZGUuX3dyYXBwZXJTdGF0ZS53YXNNdWx0aXBsZSA9ICEhcHJvcHMubXVsdGlwbGU7XG4gIHZhciB2YWx1ZSA9IHByb3BzLnZhbHVlO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgdXBkYXRlT3B0aW9ucyhub2RlLCAhIXByb3BzLm11bHRpcGxlLCB2YWx1ZSwgZmFsc2UpO1xuICB9IGVsc2UgaWYgKHdhc011bHRpcGxlICE9PSAhIXByb3BzLm11bHRpcGxlKSB7XG4gICAgLy8gRm9yIHNpbXBsaWNpdHksIHJlYXBwbHkgYGRlZmF1bHRWYWx1ZWAgaWYgYG11bHRpcGxlYCBpcyB0b2dnbGVkLlxuICAgIGlmIChwcm9wcy5kZWZhdWx0VmFsdWUgIT0gbnVsbCkge1xuICAgICAgdXBkYXRlT3B0aW9ucyhub2RlLCAhIXByb3BzLm11bHRpcGxlLCBwcm9wcy5kZWZhdWx0VmFsdWUsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZXZlcnQgdGhlIHNlbGVjdCBiYWNrIHRvIGl0cyBkZWZhdWx0IHVuc2VsZWN0ZWQgc3RhdGUuXG4gICAgICB1cGRhdGVPcHRpb25zKG5vZGUsICEhcHJvcHMubXVsdGlwbGUsIHByb3BzLm11bHRpcGxlID8gW10gOiAnJywgZmFsc2UpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZSQxKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcbiAgdmFyIHZhbHVlID0gcHJvcHMudmFsdWU7XG5cbiAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICB1cGRhdGVPcHRpb25zKG5vZGUsICEhcHJvcHMubXVsdGlwbGUsIHZhbHVlLCBmYWxzZSk7XG4gIH1cbn1cblxudmFyIGRpZFdhcm5WYWxEZWZhdWx0VmFsID0gZmFsc2U7XG5cbi8qKlxuICogSW1wbGVtZW50cyBhIDx0ZXh0YXJlYT4gaG9zdCBjb21wb25lbnQgdGhhdCBhbGxvd3Mgc2V0dGluZyBgdmFsdWVgLCBhbmRcbiAqIGBkZWZhdWx0VmFsdWVgLiBUaGlzIGRpZmZlcnMgZnJvbSB0aGUgdHJhZGl0aW9uYWwgRE9NIEFQSSBiZWNhdXNlIHZhbHVlIGlzXG4gKiB1c3VhbGx5IHNldCBhcyBQQ0RBVEEgY2hpbGRyZW4uXG4gKlxuICogSWYgYHZhbHVlYCBpcyBub3Qgc3VwcGxpZWQgKG9yIG51bGwvdW5kZWZpbmVkKSwgdXNlciBhY3Rpb25zIHRoYXQgYWZmZWN0IHRoZVxuICogdmFsdWUgd2lsbCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogSWYgYHZhbHVlYCBpcyBzdXBwbGllZCAoYW5kIG5vdCBudWxsL3VuZGVmaW5lZCksIHRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGxcbiAqIG5vdCB0cmlnZ2VyIHVwZGF0ZXMgdG8gdGhlIGVsZW1lbnQuIEluc3RlYWQsIHRoZSBgdmFsdWVgIHByb3AgbXVzdCBjaGFuZ2UgaW5cbiAqIG9yZGVyIGZvciB0aGUgcmVuZGVyZWQgZWxlbWVudCB0byBiZSB1cGRhdGVkLlxuICpcbiAqIFRoZSByZW5kZXJlZCBlbGVtZW50IHdpbGwgYmUgaW5pdGlhbGl6ZWQgd2l0aCBhbiBlbXB0eSB2YWx1ZSwgdGhlIHByb3BcbiAqIGBkZWZhdWx0VmFsdWVgIGlmIHNwZWNpZmllZCwgb3IgdGhlIGNoaWxkcmVuIGNvbnRlbnQgKGRlcHJlY2F0ZWQpLlxuICovXG5mdW5jdGlvbiBnZXRIb3N0UHJvcHMkMihlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG5cbiAgaWYgKHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2BkYW5nZXJvdXNseVNldElubmVySFRNTGAgZG9lcyBub3QgbWFrZSBzZW5zZSBvbiA8dGV4dGFyZWE+LicpO1xuICB9IC8vIEFsd2F5cyBzZXQgY2hpbGRyZW4gdG8gdGhlIHNhbWUgdGhpbmcuIEluIElFOSwgdGhlIHNlbGVjdGlvbiByYW5nZSB3aWxsXG4gIC8vIGdldCByZXNldCBpZiBgdGV4dENvbnRlbnRgIGlzIG11dGF0ZWQuICBXZSBjb3VsZCBhZGQgYSBjaGVjayBpbiBzZXRUZXh0Q29udGVudFxuICAvLyB0byBvbmx5IHNldCB0aGUgdmFsdWUgaWYvd2hlbiB0aGUgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBub2RlIHZhbHVlICh3aGljaCB3b3VsZFxuICAvLyBjb21wbGV0ZWx5IHNvbHZlIHRoaXMgSUU5IGJ1ZyksIGJ1dCBTZWJhc3RpYW4rU29waGllIHNlZW1lZCB0byBsaWtlIHRoaXNcbiAgLy8gc29sdXRpb24uIFRoZSB2YWx1ZSBjYW4gYmUgYSBib29sZWFuIG9yIG9iamVjdCBzbyB0aGF0J3Mgd2h5IGl0J3MgZm9yY2VkXG4gIC8vIHRvIGJlIGEgc3RyaW5nLlxuXG5cbiAgdmFyIGhvc3RQcm9wcyA9IGFzc2lnbih7fSwgcHJvcHMsIHtcbiAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgIGRlZmF1bHRWYWx1ZTogdW5kZWZpbmVkLFxuICAgIGNoaWxkcmVuOiB0b1N0cmluZyhub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlKVxuICB9KTtcblxuICByZXR1cm4gaG9zdFByb3BzO1xufVxuZnVuY3Rpb24gaW5pdFdyYXBwZXJTdGF0ZSQyKGVsZW1lbnQsIHByb3BzKSB7XG4gIHZhciBub2RlID0gZWxlbWVudDtcblxuICB7XG4gICAgY2hlY2tDb250cm9sbGVkVmFsdWVQcm9wcygndGV4dGFyZWEnLCBwcm9wcyk7XG5cbiAgICBpZiAocHJvcHMudmFsdWUgIT09IHVuZGVmaW5lZCAmJiBwcm9wcy5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZGlkV2FyblZhbERlZmF1bHRWYWwpIHtcbiAgICAgIGVycm9yKCclcyBjb250YWlucyBhIHRleHRhcmVhIHdpdGggYm90aCB2YWx1ZSBhbmQgZGVmYXVsdFZhbHVlIHByb3BzLiAnICsgJ1RleHRhcmVhIGVsZW1lbnRzIG11c3QgYmUgZWl0aGVyIGNvbnRyb2xsZWQgb3IgdW5jb250cm9sbGVkICcgKyAnKHNwZWNpZnkgZWl0aGVyIHRoZSB2YWx1ZSBwcm9wLCBvciB0aGUgZGVmYXVsdFZhbHVlIHByb3AsIGJ1dCBub3QgJyArICdib3RoKS4gRGVjaWRlIGJldHdlZW4gdXNpbmcgYSBjb250cm9sbGVkIG9yIHVuY29udHJvbGxlZCB0ZXh0YXJlYSAnICsgJ2FuZCByZW1vdmUgb25lIG9mIHRoZXNlIHByb3BzLiBNb3JlIGluZm86ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2NvbnRyb2xsZWQtY29tcG9uZW50cycsIGdldEN1cnJlbnRGaWJlck93bmVyTmFtZUluRGV2T3JOdWxsKCkgfHwgJ0EgY29tcG9uZW50Jyk7XG5cbiAgICAgIGRpZFdhcm5WYWxEZWZhdWx0VmFsID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICB2YXIgaW5pdGlhbFZhbHVlID0gcHJvcHMudmFsdWU7IC8vIE9ubHkgYm90aGVyIGZldGNoaW5nIGRlZmF1bHQgdmFsdWUgaWYgd2UncmUgZ29pbmcgdG8gdXNlIGl0XG5cbiAgaWYgKGluaXRpYWxWYWx1ZSA9PSBudWxsKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgICAgIGRlZmF1bHRWYWx1ZSA9IHByb3BzLmRlZmF1bHRWYWx1ZTtcblxuICAgIGlmIChjaGlsZHJlbiAhPSBudWxsKSB7XG4gICAgICB7XG4gICAgICAgIGVycm9yKCdVc2UgdGhlIGBkZWZhdWx0VmFsdWVgIG9yIGB2YWx1ZWAgcHJvcHMgaW5zdGVhZCBvZiBzZXR0aW5nICcgKyAnY2hpbGRyZW4gb24gPHRleHRhcmVhPi4nKTtcbiAgICAgIH1cblxuICAgICAge1xuICAgICAgICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lmIHlvdSBzdXBwbHkgYGRlZmF1bHRWYWx1ZWAgb24gYSA8dGV4dGFyZWE+LCBkbyBub3QgcGFzcyBjaGlsZHJlbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJzx0ZXh0YXJlYT4gY2FuIG9ubHkgaGF2ZSBhdCBtb3N0IG9uZSBjaGlsZC4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuWzBdO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVmYXVsdFZhbHVlID0gY2hpbGRyZW47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRlZmF1bHRWYWx1ZSA9PSBudWxsKSB7XG4gICAgICBkZWZhdWx0VmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBpbml0aWFsVmFsdWUgPSBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICBub2RlLl93cmFwcGVyU3RhdGUgPSB7XG4gICAgaW5pdGlhbFZhbHVlOiBnZXRUb1N0cmluZ1ZhbHVlKGluaXRpYWxWYWx1ZSlcbiAgfTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZVdyYXBwZXIkMShlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7XG4gIHZhciB2YWx1ZSA9IGdldFRvU3RyaW5nVmFsdWUocHJvcHMudmFsdWUpO1xuICB2YXIgZGVmYXVsdFZhbHVlID0gZ2V0VG9TdHJpbmdWYWx1ZShwcm9wcy5kZWZhdWx0VmFsdWUpO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgLy8gQ2FzdCBgdmFsdWVgIHRvIGEgc3RyaW5nIHRvIGVuc3VyZSB0aGUgdmFsdWUgaXMgc2V0IGNvcnJlY3RseS4gV2hpbGVcbiAgICAvLyBicm93c2VycyB0eXBpY2FsbHkgZG8gdGhpcyBhcyBuZWNlc3NhcnksIGpzZG9tIGRvZXNuJ3QuXG4gICAgdmFyIG5ld1ZhbHVlID0gdG9TdHJpbmcodmFsdWUpOyAvLyBUbyBhdm9pZCBzaWRlIGVmZmVjdHMgKHN1Y2ggYXMgbG9zaW5nIHRleHQgc2VsZWN0aW9uKSwgb25seSBzZXQgdmFsdWUgaWYgY2hhbmdlZFxuXG4gICAgaWYgKG5ld1ZhbHVlICE9PSBub2RlLnZhbHVlKSB7XG4gICAgICBub2RlLnZhbHVlID0gbmV3VmFsdWU7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmRlZmF1bHRWYWx1ZSA9PSBudWxsICYmIG5vZGUuZGVmYXVsdFZhbHVlICE9PSBuZXdWYWx1ZSkge1xuICAgICAgbm9kZS5kZWZhdWx0VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAoZGVmYXVsdFZhbHVlICE9IG51bGwpIHtcbiAgICBub2RlLmRlZmF1bHRWYWx1ZSA9IHRvU3RyaW5nKGRlZmF1bHRWYWx1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHBvc3RNb3VudFdyYXBwZXIkMyhlbGVtZW50LCBwcm9wcykge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQ7IC8vIFRoaXMgaXMgaW4gcG9zdE1vdW50IGJlY2F1c2Ugd2UgbmVlZCBhY2Nlc3MgdG8gdGhlIERPTSBub2RlLCB3aGljaCBpcyBub3RcbiAgLy8gYXZhaWxhYmxlIHVudGlsIGFmdGVyIHRoZSBjb21wb25lbnQgaGFzIG1vdW50ZWQuXG5cbiAgdmFyIHRleHRDb250ZW50ID0gbm9kZS50ZXh0Q29udGVudDsgLy8gT25seSBzZXQgbm9kZS52YWx1ZSBpZiB0ZXh0Q29udGVudCBpcyBlcXVhbCB0byB0aGUgZXhwZWN0ZWRcbiAgLy8gaW5pdGlhbCB2YWx1ZS4gSW4gSUUxMC9JRTExIHRoZXJlIGlzIGEgYnVnIHdoZXJlIHRoZSBwbGFjZWhvbGRlciBhdHRyaWJ1dGVcbiAgLy8gd2lsbCBwb3B1bGF0ZSB0ZXh0Q29udGVudCBhcyB3ZWxsLlxuICAvLyBodHRwczovL2RldmVsb3Blci5taWNyb3NvZnQuY29tL21pY3Jvc29mdC1lZGdlL3BsYXRmb3JtL2lzc3Vlcy8xMDE1MjUvXG5cbiAgaWYgKHRleHRDb250ZW50ID09PSBub2RlLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlKSB7XG4gICAgaWYgKHRleHRDb250ZW50ICE9PSAnJyAmJiB0ZXh0Q29udGVudCAhPT0gbnVsbCkge1xuICAgICAgbm9kZS52YWx1ZSA9IHRleHRDb250ZW50O1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZSQyKGVsZW1lbnQsIHByb3BzKSB7XG4gIC8vIERPTSBjb21wb25lbnQgaXMgc3RpbGwgbW91bnRlZDsgdXBkYXRlXG4gIHVwZGF0ZVdyYXBwZXIkMShlbGVtZW50LCBwcm9wcyk7XG59XG5cbnZhciBIVE1MX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sJztcbnZhciBNQVRIX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MJztcbnZhciBTVkdfTkFNRVNQQUNFID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJzsgLy8gQXNzdW1lcyB0aGVyZSBpcyBubyBwYXJlbnQgbmFtZXNwYWNlLlxuXG5mdW5jdGlvbiBnZXRJbnRyaW5zaWNOYW1lc3BhY2UodHlwZSkge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdzdmcnOlxuICAgICAgcmV0dXJuIFNWR19OQU1FU1BBQ0U7XG5cbiAgICBjYXNlICdtYXRoJzpcbiAgICAgIHJldHVybiBNQVRIX05BTUVTUEFDRTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gSFRNTF9OQU1FU1BBQ0U7XG4gIH1cbn1cbmZ1bmN0aW9uIGdldENoaWxkTmFtZXNwYWNlKHBhcmVudE5hbWVzcGFjZSwgdHlwZSkge1xuICBpZiAocGFyZW50TmFtZXNwYWNlID09IG51bGwgfHwgcGFyZW50TmFtZXNwYWNlID09PSBIVE1MX05BTUVTUEFDRSkge1xuICAgIC8vIE5vIChvciBkZWZhdWx0KSBwYXJlbnQgbmFtZXNwYWNlOiBwb3RlbnRpYWwgZW50cnkgcG9pbnQuXG4gICAgcmV0dXJuIGdldEludHJpbnNpY05hbWVzcGFjZSh0eXBlKTtcbiAgfVxuXG4gIGlmIChwYXJlbnROYW1lc3BhY2UgPT09IFNWR19OQU1FU1BBQ0UgJiYgdHlwZSA9PT0gJ2ZvcmVpZ25PYmplY3QnKSB7XG4gICAgLy8gV2UncmUgbGVhdmluZyBTVkcuXG4gICAgcmV0dXJuIEhUTUxfTkFNRVNQQUNFO1xuICB9IC8vIEJ5IGRlZmF1bHQsIHBhc3MgbmFtZXNwYWNlIGJlbG93LlxuXG5cbiAgcmV0dXJuIHBhcmVudE5hbWVzcGFjZTtcbn1cblxuLyogZ2xvYmFscyBNU0FwcCAqL1xuXG4vKipcbiAqIENyZWF0ZSBhIGZ1bmN0aW9uIHdoaWNoIGhhcyAndW5zYWZlJyBwcml2aWxlZ2VzIChyZXF1aXJlZCBieSB3aW5kb3dzOCBhcHBzKVxuICovXG52YXIgY3JlYXRlTWljcm9zb2Z0VW5zYWZlTG9jYWxGdW5jdGlvbiA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gIGlmICh0eXBlb2YgTVNBcHAgIT09ICd1bmRlZmluZWQnICYmIE1TQXBwLmV4ZWNVbnNhZmVMb2NhbEZ1bmN0aW9uKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChhcmcwLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gICAgICBNU0FwcC5leGVjVW5zYWZlTG9jYWxGdW5jdGlvbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBmdW5jKGFyZzAsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZnVuYztcbiAgfVxufTtcblxudmFyIHJldXNhYmxlU1ZHQ29udGFpbmVyO1xuLyoqXG4gKiBTZXQgdGhlIGlubmVySFRNTCBwcm9wZXJ0eSBvZiBhIG5vZGVcbiAqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG5vZGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gKiBAaW50ZXJuYWxcbiAqL1xuXG52YXIgc2V0SW5uZXJIVE1MID0gY3JlYXRlTWljcm9zb2Z0VW5zYWZlTG9jYWxGdW5jdGlvbihmdW5jdGlvbiAobm9kZSwgaHRtbCkge1xuICBpZiAobm9kZS5uYW1lc3BhY2VVUkkgPT09IFNWR19OQU1FU1BBQ0UpIHtcblxuICAgIGlmICghKCdpbm5lckhUTUwnIGluIG5vZGUpKSB7XG4gICAgICAvLyBJRSBkb2VzIG5vdCBoYXZlIGlubmVySFRNTCBmb3IgU1ZHIG5vZGVzLCBzbyBpbnN0ZWFkIHdlIGluamVjdCB0aGVcbiAgICAgIC8vIG5ldyBtYXJrdXAgaW4gYSB0ZW1wIG5vZGUgYW5kIHRoZW4gbW92ZSB0aGUgY2hpbGQgbm9kZXMgYWNyb3NzIGludG9cbiAgICAgIC8vIHRoZSB0YXJnZXQgbm9kZVxuICAgICAgcmV1c2FibGVTVkdDb250YWluZXIgPSByZXVzYWJsZVNWR0NvbnRhaW5lciB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIHJldXNhYmxlU1ZHQ29udGFpbmVyLmlubmVySFRNTCA9ICc8c3ZnPicgKyBodG1sLnZhbHVlT2YoKS50b1N0cmluZygpICsgJzwvc3ZnPic7XG4gICAgICB2YXIgc3ZnTm9kZSA9IHJldXNhYmxlU1ZHQ29udGFpbmVyLmZpcnN0Q2hpbGQ7XG5cbiAgICAgIHdoaWxlIChub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmZpcnN0Q2hpbGQpO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAoc3ZnTm9kZS5maXJzdENoaWxkKSB7XG4gICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoc3ZnTm9kZS5maXJzdENoaWxkKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIG5vZGUuaW5uZXJIVE1MID0gaHRtbDtcbn0pO1xuXG4vKipcbiAqIEhUTUwgbm9kZVR5cGUgdmFsdWVzIHRoYXQgcmVwcmVzZW50IHRoZSB0eXBlIG9mIHRoZSBub2RlXG4gKi9cbnZhciBFTEVNRU5UX05PREUgPSAxO1xudmFyIFRFWFRfTk9ERSA9IDM7XG52YXIgQ09NTUVOVF9OT0RFID0gODtcbnZhciBET0NVTUVOVF9OT0RFID0gOTtcbnZhciBET0NVTUVOVF9GUkFHTUVOVF9OT0RFID0gMTE7XG5cbi8qKlxuICogU2V0IHRoZSB0ZXh0Q29udGVudCBwcm9wZXJ0eSBvZiBhIG5vZGUuIEZvciB0ZXh0IHVwZGF0ZXMsIGl0J3MgZmFzdGVyXG4gKiB0byBzZXQgdGhlIGBub2RlVmFsdWVgIG9mIHRoZSBUZXh0IG5vZGUgZGlyZWN0bHkgaW5zdGVhZCBvZiB1c2luZ1xuICogYC50ZXh0Q29udGVudGAgd2hpY2ggd2lsbCByZW1vdmUgdGhlIGV4aXN0aW5nIG5vZGUgYW5kIGNyZWF0ZSBhIG5ldyBvbmUuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQGludGVybmFsXG4gKi9cblxudmFyIHNldFRleHRDb250ZW50ID0gZnVuY3Rpb24gKG5vZGUsIHRleHQpIHtcbiAgaWYgKHRleHQpIHtcbiAgICB2YXIgZmlyc3RDaGlsZCA9IG5vZGUuZmlyc3RDaGlsZDtcblxuICAgIGlmIChmaXJzdENoaWxkICYmIGZpcnN0Q2hpbGQgPT09IG5vZGUubGFzdENoaWxkICYmIGZpcnN0Q2hpbGQubm9kZVR5cGUgPT09IFRFWFRfTk9ERSkge1xuICAgICAgZmlyc3RDaGlsZC5ub2RlVmFsdWUgPSB0ZXh0O1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIG5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xufTtcblxuLy8gTGlzdCBkZXJpdmVkIGZyb20gR2Vja28gc291cmNlIGNvZGU6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9nZWNrby1kZXYvYmxvYi80ZTYzOGVmYzcxL2xheW91dC9zdHlsZS90ZXN0L3Byb3BlcnR5X2RhdGFiYXNlLmpzXG52YXIgc2hvcnRoYW5kVG9Mb25naGFuZCA9IHtcbiAgYW5pbWF0aW9uOiBbJ2FuaW1hdGlvbkRlbGF5JywgJ2FuaW1hdGlvbkRpcmVjdGlvbicsICdhbmltYXRpb25EdXJhdGlvbicsICdhbmltYXRpb25GaWxsTW9kZScsICdhbmltYXRpb25JdGVyYXRpb25Db3VudCcsICdhbmltYXRpb25OYW1lJywgJ2FuaW1hdGlvblBsYXlTdGF0ZScsICdhbmltYXRpb25UaW1pbmdGdW5jdGlvbiddLFxuICBiYWNrZ3JvdW5kOiBbJ2JhY2tncm91bmRBdHRhY2htZW50JywgJ2JhY2tncm91bmRDbGlwJywgJ2JhY2tncm91bmRDb2xvcicsICdiYWNrZ3JvdW5kSW1hZ2UnLCAnYmFja2dyb3VuZE9yaWdpbicsICdiYWNrZ3JvdW5kUG9zaXRpb25YJywgJ2JhY2tncm91bmRQb3NpdGlvblknLCAnYmFja2dyb3VuZFJlcGVhdCcsICdiYWNrZ3JvdW5kU2l6ZSddLFxuICBiYWNrZ3JvdW5kUG9zaXRpb246IFsnYmFja2dyb3VuZFBvc2l0aW9uWCcsICdiYWNrZ3JvdW5kUG9zaXRpb25ZJ10sXG4gIGJvcmRlcjogWydib3JkZXJCb3R0b21Db2xvcicsICdib3JkZXJCb3R0b21TdHlsZScsICdib3JkZXJCb3R0b21XaWR0aCcsICdib3JkZXJJbWFnZU91dHNldCcsICdib3JkZXJJbWFnZVJlcGVhdCcsICdib3JkZXJJbWFnZVNsaWNlJywgJ2JvcmRlckltYWdlU291cmNlJywgJ2JvcmRlckltYWdlV2lkdGgnLCAnYm9yZGVyTGVmdENvbG9yJywgJ2JvcmRlckxlZnRTdHlsZScsICdib3JkZXJMZWZ0V2lkdGgnLCAnYm9yZGVyUmlnaHRDb2xvcicsICdib3JkZXJSaWdodFN0eWxlJywgJ2JvcmRlclJpZ2h0V2lkdGgnLCAnYm9yZGVyVG9wQ29sb3InLCAnYm9yZGVyVG9wU3R5bGUnLCAnYm9yZGVyVG9wV2lkdGgnXSxcbiAgYm9yZGVyQmxvY2tFbmQ6IFsnYm9yZGVyQmxvY2tFbmRDb2xvcicsICdib3JkZXJCbG9ja0VuZFN0eWxlJywgJ2JvcmRlckJsb2NrRW5kV2lkdGgnXSxcbiAgYm9yZGVyQmxvY2tTdGFydDogWydib3JkZXJCbG9ja1N0YXJ0Q29sb3InLCAnYm9yZGVyQmxvY2tTdGFydFN0eWxlJywgJ2JvcmRlckJsb2NrU3RhcnRXaWR0aCddLFxuICBib3JkZXJCb3R0b206IFsnYm9yZGVyQm90dG9tQ29sb3InLCAnYm9yZGVyQm90dG9tU3R5bGUnLCAnYm9yZGVyQm90dG9tV2lkdGgnXSxcbiAgYm9yZGVyQ29sb3I6IFsnYm9yZGVyQm90dG9tQ29sb3InLCAnYm9yZGVyTGVmdENvbG9yJywgJ2JvcmRlclJpZ2h0Q29sb3InLCAnYm9yZGVyVG9wQ29sb3InXSxcbiAgYm9yZGVySW1hZ2U6IFsnYm9yZGVySW1hZ2VPdXRzZXQnLCAnYm9yZGVySW1hZ2VSZXBlYXQnLCAnYm9yZGVySW1hZ2VTbGljZScsICdib3JkZXJJbWFnZVNvdXJjZScsICdib3JkZXJJbWFnZVdpZHRoJ10sXG4gIGJvcmRlcklubGluZUVuZDogWydib3JkZXJJbmxpbmVFbmRDb2xvcicsICdib3JkZXJJbmxpbmVFbmRTdHlsZScsICdib3JkZXJJbmxpbmVFbmRXaWR0aCddLFxuICBib3JkZXJJbmxpbmVTdGFydDogWydib3JkZXJJbmxpbmVTdGFydENvbG9yJywgJ2JvcmRlcklubGluZVN0YXJ0U3R5bGUnLCAnYm9yZGVySW5saW5lU3RhcnRXaWR0aCddLFxuICBib3JkZXJMZWZ0OiBbJ2JvcmRlckxlZnRDb2xvcicsICdib3JkZXJMZWZ0U3R5bGUnLCAnYm9yZGVyTGVmdFdpZHRoJ10sXG4gIGJvcmRlclJhZGl1czogWydib3JkZXJCb3R0b21MZWZ0UmFkaXVzJywgJ2JvcmRlckJvdHRvbVJpZ2h0UmFkaXVzJywgJ2JvcmRlclRvcExlZnRSYWRpdXMnLCAnYm9yZGVyVG9wUmlnaHRSYWRpdXMnXSxcbiAgYm9yZGVyUmlnaHQ6IFsnYm9yZGVyUmlnaHRDb2xvcicsICdib3JkZXJSaWdodFN0eWxlJywgJ2JvcmRlclJpZ2h0V2lkdGgnXSxcbiAgYm9yZGVyU3R5bGU6IFsnYm9yZGVyQm90dG9tU3R5bGUnLCAnYm9yZGVyTGVmdFN0eWxlJywgJ2JvcmRlclJpZ2h0U3R5bGUnLCAnYm9yZGVyVG9wU3R5bGUnXSxcbiAgYm9yZGVyVG9wOiBbJ2JvcmRlclRvcENvbG9yJywgJ2JvcmRlclRvcFN0eWxlJywgJ2JvcmRlclRvcFdpZHRoJ10sXG4gIGJvcmRlcldpZHRoOiBbJ2JvcmRlckJvdHRvbVdpZHRoJywgJ2JvcmRlckxlZnRXaWR0aCcsICdib3JkZXJSaWdodFdpZHRoJywgJ2JvcmRlclRvcFdpZHRoJ10sXG4gIGNvbHVtblJ1bGU6IFsnY29sdW1uUnVsZUNvbG9yJywgJ2NvbHVtblJ1bGVTdHlsZScsICdjb2x1bW5SdWxlV2lkdGgnXSxcbiAgY29sdW1uczogWydjb2x1bW5Db3VudCcsICdjb2x1bW5XaWR0aCddLFxuICBmbGV4OiBbJ2ZsZXhCYXNpcycsICdmbGV4R3JvdycsICdmbGV4U2hyaW5rJ10sXG4gIGZsZXhGbG93OiBbJ2ZsZXhEaXJlY3Rpb24nLCAnZmxleFdyYXAnXSxcbiAgZm9udDogWydmb250RmFtaWx5JywgJ2ZvbnRGZWF0dXJlU2V0dGluZ3MnLCAnZm9udEtlcm5pbmcnLCAnZm9udExhbmd1YWdlT3ZlcnJpZGUnLCAnZm9udFNpemUnLCAnZm9udFNpemVBZGp1c3QnLCAnZm9udFN0cmV0Y2gnLCAnZm9udFN0eWxlJywgJ2ZvbnRWYXJpYW50JywgJ2ZvbnRWYXJpYW50QWx0ZXJuYXRlcycsICdmb250VmFyaWFudENhcHMnLCAnZm9udFZhcmlhbnRFYXN0QXNpYW4nLCAnZm9udFZhcmlhbnRMaWdhdHVyZXMnLCAnZm9udFZhcmlhbnROdW1lcmljJywgJ2ZvbnRWYXJpYW50UG9zaXRpb24nLCAnZm9udFdlaWdodCcsICdsaW5lSGVpZ2h0J10sXG4gIGZvbnRWYXJpYW50OiBbJ2ZvbnRWYXJpYW50QWx0ZXJuYXRlcycsICdmb250VmFyaWFudENhcHMnLCAnZm9udFZhcmlhbnRFYXN0QXNpYW4nLCAnZm9udFZhcmlhbnRMaWdhdHVyZXMnLCAnZm9udFZhcmlhbnROdW1lcmljJywgJ2ZvbnRWYXJpYW50UG9zaXRpb24nXSxcbiAgZ2FwOiBbJ2NvbHVtbkdhcCcsICdyb3dHYXAnXSxcbiAgZ3JpZDogWydncmlkQXV0b0NvbHVtbnMnLCAnZ3JpZEF1dG9GbG93JywgJ2dyaWRBdXRvUm93cycsICdncmlkVGVtcGxhdGVBcmVhcycsICdncmlkVGVtcGxhdGVDb2x1bW5zJywgJ2dyaWRUZW1wbGF0ZVJvd3MnXSxcbiAgZ3JpZEFyZWE6IFsnZ3JpZENvbHVtbkVuZCcsICdncmlkQ29sdW1uU3RhcnQnLCAnZ3JpZFJvd0VuZCcsICdncmlkUm93U3RhcnQnXSxcbiAgZ3JpZENvbHVtbjogWydncmlkQ29sdW1uRW5kJywgJ2dyaWRDb2x1bW5TdGFydCddLFxuICBncmlkQ29sdW1uR2FwOiBbJ2NvbHVtbkdhcCddLFxuICBncmlkR2FwOiBbJ2NvbHVtbkdhcCcsICdyb3dHYXAnXSxcbiAgZ3JpZFJvdzogWydncmlkUm93RW5kJywgJ2dyaWRSb3dTdGFydCddLFxuICBncmlkUm93R2FwOiBbJ3Jvd0dhcCddLFxuICBncmlkVGVtcGxhdGU6IFsnZ3JpZFRlbXBsYXRlQXJlYXMnLCAnZ3JpZFRlbXBsYXRlQ29sdW1ucycsICdncmlkVGVtcGxhdGVSb3dzJ10sXG4gIGxpc3RTdHlsZTogWydsaXN0U3R5bGVJbWFnZScsICdsaXN0U3R5bGVQb3NpdGlvbicsICdsaXN0U3R5bGVUeXBlJ10sXG4gIG1hcmdpbjogWydtYXJnaW5Cb3R0b20nLCAnbWFyZ2luTGVmdCcsICdtYXJnaW5SaWdodCcsICdtYXJnaW5Ub3AnXSxcbiAgbWFya2VyOiBbJ21hcmtlckVuZCcsICdtYXJrZXJNaWQnLCAnbWFya2VyU3RhcnQnXSxcbiAgbWFzazogWydtYXNrQ2xpcCcsICdtYXNrQ29tcG9zaXRlJywgJ21hc2tJbWFnZScsICdtYXNrTW9kZScsICdtYXNrT3JpZ2luJywgJ21hc2tQb3NpdGlvblgnLCAnbWFza1Bvc2l0aW9uWScsICdtYXNrUmVwZWF0JywgJ21hc2tTaXplJ10sXG4gIG1hc2tQb3NpdGlvbjogWydtYXNrUG9zaXRpb25YJywgJ21hc2tQb3NpdGlvblknXSxcbiAgb3V0bGluZTogWydvdXRsaW5lQ29sb3InLCAnb3V0bGluZVN0eWxlJywgJ291dGxpbmVXaWR0aCddLFxuICBvdmVyZmxvdzogWydvdmVyZmxvd1gnLCAnb3ZlcmZsb3dZJ10sXG4gIHBhZGRpbmc6IFsncGFkZGluZ0JvdHRvbScsICdwYWRkaW5nTGVmdCcsICdwYWRkaW5nUmlnaHQnLCAncGFkZGluZ1RvcCddLFxuICBwbGFjZUNvbnRlbnQ6IFsnYWxpZ25Db250ZW50JywgJ2p1c3RpZnlDb250ZW50J10sXG4gIHBsYWNlSXRlbXM6IFsnYWxpZ25JdGVtcycsICdqdXN0aWZ5SXRlbXMnXSxcbiAgcGxhY2VTZWxmOiBbJ2FsaWduU2VsZicsICdqdXN0aWZ5U2VsZiddLFxuICB0ZXh0RGVjb3JhdGlvbjogWyd0ZXh0RGVjb3JhdGlvbkNvbG9yJywgJ3RleHREZWNvcmF0aW9uTGluZScsICd0ZXh0RGVjb3JhdGlvblN0eWxlJ10sXG4gIHRleHRFbXBoYXNpczogWyd0ZXh0RW1waGFzaXNDb2xvcicsICd0ZXh0RW1waGFzaXNTdHlsZSddLFxuICB0cmFuc2l0aW9uOiBbJ3RyYW5zaXRpb25EZWxheScsICd0cmFuc2l0aW9uRHVyYXRpb24nLCAndHJhbnNpdGlvblByb3BlcnR5JywgJ3RyYW5zaXRpb25UaW1pbmdGdW5jdGlvbiddLFxuICB3b3JkV3JhcDogWydvdmVyZmxvd1dyYXAnXVxufTtcblxuLyoqXG4gKiBDU1MgcHJvcGVydGllcyB3aGljaCBhY2NlcHQgbnVtYmVycyBidXQgYXJlIG5vdCBpbiB1bml0cyBvZiBcInB4XCIuXG4gKi9cbnZhciBpc1VuaXRsZXNzTnVtYmVyID0ge1xuICBhbmltYXRpb25JdGVyYXRpb25Db3VudDogdHJ1ZSxcbiAgYXNwZWN0UmF0aW86IHRydWUsXG4gIGJvcmRlckltYWdlT3V0c2V0OiB0cnVlLFxuICBib3JkZXJJbWFnZVNsaWNlOiB0cnVlLFxuICBib3JkZXJJbWFnZVdpZHRoOiB0cnVlLFxuICBib3hGbGV4OiB0cnVlLFxuICBib3hGbGV4R3JvdXA6IHRydWUsXG4gIGJveE9yZGluYWxHcm91cDogdHJ1ZSxcbiAgY29sdW1uQ291bnQ6IHRydWUsXG4gIGNvbHVtbnM6IHRydWUsXG4gIGZsZXg6IHRydWUsXG4gIGZsZXhHcm93OiB0cnVlLFxuICBmbGV4UG9zaXRpdmU6IHRydWUsXG4gIGZsZXhTaHJpbms6IHRydWUsXG4gIGZsZXhOZWdhdGl2ZTogdHJ1ZSxcbiAgZmxleE9yZGVyOiB0cnVlLFxuICBncmlkQXJlYTogdHJ1ZSxcbiAgZ3JpZFJvdzogdHJ1ZSxcbiAgZ3JpZFJvd0VuZDogdHJ1ZSxcbiAgZ3JpZFJvd1NwYW46IHRydWUsXG4gIGdyaWRSb3dTdGFydDogdHJ1ZSxcbiAgZ3JpZENvbHVtbjogdHJ1ZSxcbiAgZ3JpZENvbHVtbkVuZDogdHJ1ZSxcbiAgZ3JpZENvbHVtblNwYW46IHRydWUsXG4gIGdyaWRDb2x1bW5TdGFydDogdHJ1ZSxcbiAgZm9udFdlaWdodDogdHJ1ZSxcbiAgbGluZUNsYW1wOiB0cnVlLFxuICBsaW5lSGVpZ2h0OiB0cnVlLFxuICBvcGFjaXR5OiB0cnVlLFxuICBvcmRlcjogdHJ1ZSxcbiAgb3JwaGFuczogdHJ1ZSxcbiAgdGFiU2l6ZTogdHJ1ZSxcbiAgd2lkb3dzOiB0cnVlLFxuICB6SW5kZXg6IHRydWUsXG4gIHpvb206IHRydWUsXG4gIC8vIFNWRy1yZWxhdGVkIHByb3BlcnRpZXNcbiAgZmlsbE9wYWNpdHk6IHRydWUsXG4gIGZsb29kT3BhY2l0eTogdHJ1ZSxcbiAgc3RvcE9wYWNpdHk6IHRydWUsXG4gIHN0cm9rZURhc2hhcnJheTogdHJ1ZSxcbiAgc3Ryb2tlRGFzaG9mZnNldDogdHJ1ZSxcbiAgc3Ryb2tlTWl0ZXJsaW1pdDogdHJ1ZSxcbiAgc3Ryb2tlT3BhY2l0eTogdHJ1ZSxcbiAgc3Ryb2tlV2lkdGg6IHRydWVcbn07XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXggdmVuZG9yLXNwZWNpZmljIHByZWZpeCwgZWc6IFdlYmtpdFxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBzdHlsZSBuYW1lLCBlZzogdHJhbnNpdGlvbkR1cmF0aW9uXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHN0eWxlIG5hbWUgcHJlZml4ZWQgd2l0aCBgcHJlZml4YCwgcHJvcGVybHkgY2FtZWxDYXNlZCwgZWc6XG4gKiBXZWJraXRUcmFuc2l0aW9uRHVyYXRpb25cbiAqL1xuXG5mdW5jdGlvbiBwcmVmaXhLZXkocHJlZml4LCBrZXkpIHtcbiAgcmV0dXJuIHByZWZpeCArIGtleS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGtleS5zdWJzdHJpbmcoMSk7XG59XG4vKipcbiAqIFN1cHBvcnQgc3R5bGUgbmFtZXMgdGhhdCBtYXkgY29tZSBwYXNzZWQgaW4gcHJlZml4ZWQgYnkgYWRkaW5nIHBlcm11dGF0aW9uc1xuICogb2YgdmVuZG9yIHByZWZpeGVzLlxuICovXG5cblxudmFyIHByZWZpeGVzID0gWydXZWJraXQnLCAnbXMnLCAnTW96JywgJ08nXTsgLy8gVXNpbmcgT2JqZWN0LmtleXMgaGVyZSwgb3IgZWxzZSB0aGUgdmFuaWxsYSBmb3ItaW4gbG9vcCBtYWtlcyBJRTggZ28gaW50byBhblxuLy8gaW5maW5pdGUgbG9vcCwgYmVjYXVzZSBpdCBpdGVyYXRlcyBvdmVyIHRoZSBuZXdseSBhZGRlZCBwcm9wcyB0b28uXG5cbk9iamVjdC5rZXlzKGlzVW5pdGxlc3NOdW1iZXIpLmZvckVhY2goZnVuY3Rpb24gKHByb3ApIHtcbiAgcHJlZml4ZXMuZm9yRWFjaChmdW5jdGlvbiAocHJlZml4KSB7XG4gICAgaXNVbml0bGVzc051bWJlcltwcmVmaXhLZXkocHJlZml4LCBwcm9wKV0gPSBpc1VuaXRsZXNzTnVtYmVyW3Byb3BdO1xuICB9KTtcbn0pO1xuXG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIHRoZSBwcm9wZXIgY3NzIHdyaXRhYmxlIHZhbHVlLiBUaGUgc3R5bGUgbmFtZSBgbmFtZWBcbiAqIHNob3VsZCBiZSBsb2dpY2FsIChubyBoeXBoZW5zKSwgYXMgc3BlY2lmaWVkXG4gKiBpbiBgQ1NTUHJvcGVydHkuaXNVbml0bGVzc051bWJlcmAuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgQ1NTIHByb3BlcnR5IG5hbWUgc3VjaCBhcyBgdG9wTWFyZ2luYC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQ1NTIHByb3BlcnR5IHZhbHVlIHN1Y2ggYXMgYDEwcHhgLlxuICogQHJldHVybiB7c3RyaW5nfSBOb3JtYWxpemVkIHN0eWxlIHZhbHVlIHdpdGggZGltZW5zaW9ucyBhcHBsaWVkLlxuICovXG5cbmZ1bmN0aW9uIGRhbmdlcm91c1N0eWxlVmFsdWUobmFtZSwgdmFsdWUsIGlzQ3VzdG9tUHJvcGVydHkpIHtcbiAgLy8gTm90ZSB0aGF0IHdlJ3ZlIHJlbW92ZWQgZXNjYXBlVGV4dEZvckJyb3dzZXIoKSBjYWxscyBoZXJlIHNpbmNlIHRoZVxuICAvLyB3aG9sZSBzdHJpbmcgd2lsbCBiZSBlc2NhcGVkIHdoZW4gdGhlIGF0dHJpYnV0ZSBpcyBpbmplY3RlZCBpbnRvXG4gIC8vIHRoZSBtYXJrdXAuIElmIHlvdSBwcm92aWRlIHVuc2FmZSB1c2VyIGRhdGEgaGVyZSB0aGV5IGNhbiBpbmplY3RcbiAgLy8gYXJiaXRyYXJ5IENTUyB3aGljaCBtYXkgYmUgcHJvYmxlbWF0aWMgKEkgY291bGRuJ3QgcmVwcm8gdGhpcyk6XG4gIC8vIGh0dHBzOi8vd3d3Lm93YXNwLm9yZy9pbmRleC5waHAvWFNTX0ZpbHRlcl9FdmFzaW9uX0NoZWF0X1NoZWV0XG4gIC8vIGh0dHA6Ly93d3cudGhlc3Bhbm5lci5jby51ay8yMDA3LzExLzI2L3VsdGltYXRlLXhzcy1jc3MtaW5qZWN0aW9uL1xuICAvLyBUaGlzIGlzIG5vdCBhbiBYU1MgaG9sZSBidXQgaW5zdGVhZCBhIHBvdGVudGlhbCBDU1MgaW5qZWN0aW9uIGlzc3VlXG4gIC8vIHdoaWNoIGhhcyBsZWFkIHRvIGEgZ3JlYXRlciBkaXNjdXNzaW9uIGFib3V0IGhvdyB3ZSdyZSBnb2luZyB0b1xuICAvLyB0cnVzdCBVUkxzIG1vdmluZyBmb3J3YXJkLiBTZWUgIzIxMTU5MDFcbiAgdmFyIGlzRW1wdHkgPSB2YWx1ZSA9PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09PSAnJztcblxuICBpZiAoaXNFbXB0eSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmICghaXNDdXN0b21Qcm9wZXJ0eSAmJiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIHZhbHVlICE9PSAwICYmICEoaXNVbml0bGVzc051bWJlci5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiBpc1VuaXRsZXNzTnVtYmVyW25hbWVdKSkge1xuICAgIHJldHVybiB2YWx1ZSArICdweCc7IC8vIFByZXN1bWVzIGltcGxpY2l0ICdweCcgc3VmZml4IGZvciB1bml0bGVzcyBudW1iZXJzXG4gIH1cblxuICB7XG4gICAgY2hlY2tDU1NQcm9wZXJ0eVN0cmluZ0NvZXJjaW9uKHZhbHVlLCBuYW1lKTtcbiAgfVxuXG4gIHJldHVybiAoJycgKyB2YWx1ZSkudHJpbSgpO1xufVxuXG52YXIgdXBwZXJjYXNlUGF0dGVybiA9IC8oW0EtWl0pL2c7XG52YXIgbXNQYXR0ZXJuID0gL15tcy0vO1xuLyoqXG4gKiBIeXBoZW5hdGVzIGEgY2FtZWxjYXNlZCBDU1MgcHJvcGVydHkgbmFtZSwgZm9yIGV4YW1wbGU6XG4gKlxuICogICA+IGh5cGhlbmF0ZVN0eWxlTmFtZSgnYmFja2dyb3VuZENvbG9yJylcbiAqICAgPCBcImJhY2tncm91bmQtY29sb3JcIlxuICogICA+IGh5cGhlbmF0ZVN0eWxlTmFtZSgnTW96VHJhbnNpdGlvbicpXG4gKiAgIDwgXCItbW96LXRyYW5zaXRpb25cIlxuICogICA+IGh5cGhlbmF0ZVN0eWxlTmFtZSgnbXNUcmFuc2l0aW9uJylcbiAqICAgPCBcIi1tcy10cmFuc2l0aW9uXCJcbiAqXG4gKiBBcyBNb2Rlcm5penIgc3VnZ2VzdHMgKGh0dHA6Ly9tb2Rlcm5penIuY29tL2RvY3MvI3ByZWZpeGVkKSwgYW4gYG1zYCBwcmVmaXhcbiAqIGlzIGNvbnZlcnRlZCB0byBgLW1zLWAuXG4gKi9cblxuZnVuY3Rpb24gaHlwaGVuYXRlU3R5bGVOYW1lKG5hbWUpIHtcbiAgcmV0dXJuIG5hbWUucmVwbGFjZSh1cHBlcmNhc2VQYXR0ZXJuLCAnLSQxJykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKG1zUGF0dGVybiwgJy1tcy0nKTtcbn1cblxudmFyIHdhcm5WYWxpZFN0eWxlID0gZnVuY3Rpb24gKCkge307XG5cbntcbiAgLy8gJ21zVHJhbnNmb3JtJyBpcyBjb3JyZWN0LCBidXQgdGhlIG90aGVyIHByZWZpeGVzIHNob3VsZCBiZSBjYXBpdGFsaXplZFxuICB2YXIgYmFkVmVuZG9yZWRTdHlsZU5hbWVQYXR0ZXJuID0gL14oPzp3ZWJraXR8bW96fG8pW0EtWl0vO1xuICB2YXIgbXNQYXR0ZXJuJDEgPSAvXi1tcy0vO1xuICB2YXIgaHlwaGVuUGF0dGVybiA9IC8tKC4pL2c7IC8vIHN0eWxlIHZhbHVlcyBzaG91bGRuJ3QgY29udGFpbiBhIHNlbWljb2xvblxuXG4gIHZhciBiYWRTdHlsZVZhbHVlV2l0aFNlbWljb2xvblBhdHRlcm4gPSAvO1xccyokLztcbiAgdmFyIHdhcm5lZFN0eWxlTmFtZXMgPSB7fTtcbiAgdmFyIHdhcm5lZFN0eWxlVmFsdWVzID0ge307XG4gIHZhciB3YXJuZWRGb3JOYU5WYWx1ZSA9IGZhbHNlO1xuICB2YXIgd2FybmVkRm9ySW5maW5pdHlWYWx1ZSA9IGZhbHNlO1xuXG4gIHZhciBjYW1lbGl6ZSA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoaHlwaGVuUGF0dGVybiwgZnVuY3Rpb24gKF8sIGNoYXJhY3Rlcikge1xuICAgICAgcmV0dXJuIGNoYXJhY3Rlci50b1VwcGVyQ2FzZSgpO1xuICAgIH0pO1xuICB9O1xuXG4gIHZhciB3YXJuSHlwaGVuYXRlZFN0eWxlTmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgaWYgKHdhcm5lZFN0eWxlTmFtZXMuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgd2FybmVkU3R5bGVOYW1lc1tuYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZFN0eWxlTmFtZXNbbmFtZV0gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ1Vuc3VwcG9ydGVkIHN0eWxlIHByb3BlcnR5ICVzLiBEaWQgeW91IG1lYW4gJXM/JywgbmFtZSwgLy8gQXMgQW5kaSBTbWl0aCBzdWdnZXN0c1xuICAgIC8vIChodHRwOi8vd3d3LmFuZGlzbWl0aC5jb20vYmxvZy8yMDEyLzAyL21vZGVybml6ci1wcmVmaXhlZC8pLCBhbiBgLW1zYCBwcmVmaXhcbiAgICAvLyBpcyBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlIGBtc2AuXG4gICAgY2FtZWxpemUobmFtZS5yZXBsYWNlKG1zUGF0dGVybiQxLCAnbXMtJykpKTtcbiAgfTtcblxuICB2YXIgd2FybkJhZFZlbmRvcmVkU3R5bGVOYW1lID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBpZiAod2FybmVkU3R5bGVOYW1lcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiB3YXJuZWRTdHlsZU5hbWVzW25hbWVdKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2FybmVkU3R5bGVOYW1lc1tuYW1lXSA9IHRydWU7XG5cbiAgICBlcnJvcignVW5zdXBwb3J0ZWQgdmVuZG9yLXByZWZpeGVkIHN0eWxlIHByb3BlcnR5ICVzLiBEaWQgeW91IG1lYW4gJXM/JywgbmFtZSwgbmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoMSkpO1xuICB9O1xuXG4gIHZhciB3YXJuU3R5bGVWYWx1ZVdpdGhTZW1pY29sb24gPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICBpZiAod2FybmVkU3R5bGVWYWx1ZXMuaGFzT3duUHJvcGVydHkodmFsdWUpICYmIHdhcm5lZFN0eWxlVmFsdWVzW3ZhbHVlXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZFN0eWxlVmFsdWVzW3ZhbHVlXSA9IHRydWU7XG5cbiAgICBlcnJvcihcIlN0eWxlIHByb3BlcnR5IHZhbHVlcyBzaG91bGRuJ3QgY29udGFpbiBhIHNlbWljb2xvbi4gXCIgKyAnVHJ5IFwiJXM6ICVzXCIgaW5zdGVhZC4nLCBuYW1lLCB2YWx1ZS5yZXBsYWNlKGJhZFN0eWxlVmFsdWVXaXRoU2VtaWNvbG9uUGF0dGVybiwgJycpKTtcbiAgfTtcblxuICB2YXIgd2FyblN0eWxlVmFsdWVJc05hTiA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgIGlmICh3YXJuZWRGb3JOYU5WYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHdhcm5lZEZvck5hTlZhbHVlID0gdHJ1ZTtcblxuICAgIGVycm9yKCdgTmFOYCBpcyBhbiBpbnZhbGlkIHZhbHVlIGZvciB0aGUgYCVzYCBjc3Mgc3R5bGUgcHJvcGVydHkuJywgbmFtZSk7XG4gIH07XG5cbiAgdmFyIHdhcm5TdHlsZVZhbHVlSXNJbmZpbml0eSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgIGlmICh3YXJuZWRGb3JJbmZpbml0eVZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2FybmVkRm9ySW5maW5pdHlWYWx1ZSA9IHRydWU7XG5cbiAgICBlcnJvcignYEluZmluaXR5YCBpcyBhbiBpbnZhbGlkIHZhbHVlIGZvciB0aGUgYCVzYCBjc3Mgc3R5bGUgcHJvcGVydHkuJywgbmFtZSk7XG4gIH07XG5cbiAgd2FyblZhbGlkU3R5bGUgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICBpZiAobmFtZS5pbmRleE9mKCctJykgPiAtMSkge1xuICAgICAgd2Fybkh5cGhlbmF0ZWRTdHlsZU5hbWUobmFtZSk7XG4gICAgfSBlbHNlIGlmIChiYWRWZW5kb3JlZFN0eWxlTmFtZVBhdHRlcm4udGVzdChuYW1lKSkge1xuICAgICAgd2FybkJhZFZlbmRvcmVkU3R5bGVOYW1lKG5hbWUpO1xuICAgIH0gZWxzZSBpZiAoYmFkU3R5bGVWYWx1ZVdpdGhTZW1pY29sb25QYXR0ZXJuLnRlc3QodmFsdWUpKSB7XG4gICAgICB3YXJuU3R5bGVWYWx1ZVdpdGhTZW1pY29sb24obmFtZSwgdmFsdWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICBpZiAoaXNOYU4odmFsdWUpKSB7XG4gICAgICAgIHdhcm5TdHlsZVZhbHVlSXNOYU4obmFtZSwgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmICghaXNGaW5pdGUodmFsdWUpKSB7XG4gICAgICAgIHdhcm5TdHlsZVZhbHVlSXNJbmZpbml0eShuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG52YXIgd2FyblZhbGlkU3R5bGUkMSA9IHdhcm5WYWxpZFN0eWxlO1xuXG4vKipcbiAqIE9wZXJhdGlvbnMgZm9yIGRlYWxpbmcgd2l0aCBDU1MgcHJvcGVydGllcy5cbiAqL1xuXG4vKipcbiAqIFRoaXMgY3JlYXRlcyBhIHN0cmluZyB0aGF0IGlzIGV4cGVjdGVkIHRvIGJlIGVxdWl2YWxlbnQgdG8gdGhlIHN0eWxlXG4gKiBhdHRyaWJ1dGUgZ2VuZXJhdGVkIGJ5IHNlcnZlci1zaWRlIHJlbmRlcmluZy4gSXQgYnktcGFzc2VzIHdhcm5pbmdzIGFuZFxuICogc2VjdXJpdHkgY2hlY2tzIHNvIGl0J3Mgbm90IHNhZmUgdG8gdXNlIHRoaXMgdmFsdWUgZm9yIGFueXRoaW5nIG90aGVyIHRoYW5cbiAqIGNvbXBhcmlzb24uIEl0IGlzIG9ubHkgdXNlZCBpbiBERVYgZm9yIFNTUiB2YWxpZGF0aW9uLlxuICovXG5cbmZ1bmN0aW9uIGNyZWF0ZURhbmdlcm91c1N0cmluZ0ZvclN0eWxlcyhzdHlsZXMpIHtcbiAge1xuICAgIHZhciBzZXJpYWxpemVkID0gJyc7XG4gICAgdmFyIGRlbGltaXRlciA9ICcnO1xuXG4gICAgZm9yICh2YXIgc3R5bGVOYW1lIGluIHN0eWxlcykge1xuICAgICAgaWYgKCFzdHlsZXMuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0eWxlVmFsdWUgPSBzdHlsZXNbc3R5bGVOYW1lXTtcblxuICAgICAgaWYgKHN0eWxlVmFsdWUgIT0gbnVsbCkge1xuICAgICAgICB2YXIgaXNDdXN0b21Qcm9wZXJ0eSA9IHN0eWxlTmFtZS5pbmRleE9mKCctLScpID09PSAwO1xuICAgICAgICBzZXJpYWxpemVkICs9IGRlbGltaXRlciArIChpc0N1c3RvbVByb3BlcnR5ID8gc3R5bGVOYW1lIDogaHlwaGVuYXRlU3R5bGVOYW1lKHN0eWxlTmFtZSkpICsgJzonO1xuICAgICAgICBzZXJpYWxpemVkICs9IGRhbmdlcm91c1N0eWxlVmFsdWUoc3R5bGVOYW1lLCBzdHlsZVZhbHVlLCBpc0N1c3RvbVByb3BlcnR5KTtcbiAgICAgICAgZGVsaW1pdGVyID0gJzsnO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzZXJpYWxpemVkIHx8IG51bGw7XG4gIH1cbn1cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgZm9yIG11bHRpcGxlIHN0eWxlcyBvbiBhIG5vZGUuICBJZiBhIHZhbHVlIGlzIHNwZWNpZmllZCBhc1xuICogJycgKGVtcHR5IHN0cmluZyksIHRoZSBjb3JyZXNwb25kaW5nIHN0eWxlIHByb3BlcnR5IHdpbGwgYmUgdW5zZXQuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge29iamVjdH0gc3R5bGVzXG4gKi9cblxuZnVuY3Rpb24gc2V0VmFsdWVGb3JTdHlsZXMobm9kZSwgc3R5bGVzKSB7XG4gIHZhciBzdHlsZSA9IG5vZGUuc3R5bGU7XG5cbiAgZm9yICh2YXIgc3R5bGVOYW1lIGluIHN0eWxlcykge1xuICAgIGlmICghc3R5bGVzLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBpc0N1c3RvbVByb3BlcnR5ID0gc3R5bGVOYW1lLmluZGV4T2YoJy0tJykgPT09IDA7XG5cbiAgICB7XG4gICAgICBpZiAoIWlzQ3VzdG9tUHJvcGVydHkpIHtcbiAgICAgICAgd2FyblZhbGlkU3R5bGUkMShzdHlsZU5hbWUsIHN0eWxlc1tzdHlsZU5hbWVdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc3R5bGVWYWx1ZSA9IGRhbmdlcm91c1N0eWxlVmFsdWUoc3R5bGVOYW1lLCBzdHlsZXNbc3R5bGVOYW1lXSwgaXNDdXN0b21Qcm9wZXJ0eSk7XG5cbiAgICBpZiAoc3R5bGVOYW1lID09PSAnZmxvYXQnKSB7XG4gICAgICBzdHlsZU5hbWUgPSAnY3NzRmxvYXQnO1xuICAgIH1cblxuICAgIGlmIChpc0N1c3RvbVByb3BlcnR5KSB7XG4gICAgICBzdHlsZS5zZXRQcm9wZXJ0eShzdHlsZU5hbWUsIHN0eWxlVmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHlsZVtzdHlsZU5hbWVdID0gc3R5bGVWYWx1ZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNWYWx1ZUVtcHR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nIHx8IHZhbHVlID09PSAnJztcbn1cbi8qKlxuICogR2l2ZW4ge2NvbG9yOiAncmVkJywgb3ZlcmZsb3c6ICdoaWRkZW4nfSByZXR1cm5zIHtcbiAqICAgY29sb3I6ICdjb2xvcicsXG4gKiAgIG92ZXJmbG93WDogJ292ZXJmbG93JyxcbiAqICAgb3ZlcmZsb3dZOiAnb3ZlcmZsb3cnLFxuICogfS4gVGhpcyBjYW4gYmUgcmVhZCBhcyBcInRoZSBvdmVyZmxvd1kgcHJvcGVydHkgd2FzIHNldCBieSB0aGUgb3ZlcmZsb3dcbiAqIHNob3J0aGFuZFwiLiBUaGF0IGlzLCB0aGUgdmFsdWVzIGFyZSB0aGUgcHJvcGVydHkgdGhhdCBlYWNoIHdhcyBkZXJpdmVkIGZyb20uXG4gKi9cblxuXG5mdW5jdGlvbiBleHBhbmRTaG9ydGhhbmRNYXAoc3R5bGVzKSB7XG4gIHZhciBleHBhbmRlZCA9IHt9O1xuXG4gIGZvciAodmFyIGtleSBpbiBzdHlsZXMpIHtcbiAgICB2YXIgbG9uZ2hhbmRzID0gc2hvcnRoYW5kVG9Mb25naGFuZFtrZXldIHx8IFtrZXldO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsb25naGFuZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGV4cGFuZGVkW2xvbmdoYW5kc1tpXV0gPSBrZXk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGV4cGFuZGVkO1xufVxuLyoqXG4gKiBXaGVuIG1peGluZyBzaG9ydGhhbmQgYW5kIGxvbmdoYW5kIHByb3BlcnR5IG5hbWVzLCB3ZSB3YXJuIGR1cmluZyB1cGRhdGVzIGlmXG4gKiB3ZSBleHBlY3QgYW4gaW5jb3JyZWN0IHJlc3VsdCB0byBvY2N1ci4gSW4gcGFydGljdWxhciwgd2Ugd2FybiBmb3I6XG4gKlxuICogVXBkYXRpbmcgYSBzaG9ydGhhbmQgcHJvcGVydHkgKGxvbmdoYW5kIGdldHMgb3ZlcndyaXR0ZW4pOlxuICogICB7Zm9udDogJ2ZvbycsIGZvbnRWYXJpYW50OiAnYmFyJ30gLT4ge2ZvbnQ6ICdiYXonLCBmb250VmFyaWFudDogJ2Jhcid9XG4gKiAgIGJlY29tZXMgLnN0eWxlLmZvbnQgPSAnYmF6J1xuICogUmVtb3ZpbmcgYSBzaG9ydGhhbmQgcHJvcGVydHkgKGxvbmdoYW5kIGdldHMgbG9zdCB0b28pOlxuICogICB7Zm9udDogJ2ZvbycsIGZvbnRWYXJpYW50OiAnYmFyJ30gLT4ge2ZvbnRWYXJpYW50OiAnYmFyJ31cbiAqICAgYmVjb21lcyAuc3R5bGUuZm9udCA9ICcnXG4gKiBSZW1vdmluZyBhIGxvbmdoYW5kIHByb3BlcnR5IChzaG91bGQgcmV2ZXJ0IHRvIHNob3J0aGFuZDsgZG9lc24ndCk6XG4gKiAgIHtmb250OiAnZm9vJywgZm9udFZhcmlhbnQ6ICdiYXInfSAtPiB7Zm9udDogJ2Zvbyd9XG4gKiAgIGJlY29tZXMgLnN0eWxlLmZvbnRWYXJpYW50ID0gJydcbiAqL1xuXG5cbmZ1bmN0aW9uIHZhbGlkYXRlU2hvcnRoYW5kUHJvcGVydHlDb2xsaXNpb25JbkRldihzdHlsZVVwZGF0ZXMsIG5leHRTdHlsZXMpIHtcbiAge1xuICAgIGlmICghbmV4dFN0eWxlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBleHBhbmRlZFVwZGF0ZXMgPSBleHBhbmRTaG9ydGhhbmRNYXAoc3R5bGVVcGRhdGVzKTtcbiAgICB2YXIgZXhwYW5kZWRTdHlsZXMgPSBleHBhbmRTaG9ydGhhbmRNYXAobmV4dFN0eWxlcyk7XG4gICAgdmFyIHdhcm5lZEFib3V0ID0ge307XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gZXhwYW5kZWRVcGRhdGVzKSB7XG4gICAgICB2YXIgb3JpZ2luYWxLZXkgPSBleHBhbmRlZFVwZGF0ZXNba2V5XTtcbiAgICAgIHZhciBjb3JyZWN0T3JpZ2luYWxLZXkgPSBleHBhbmRlZFN0eWxlc1trZXldO1xuXG4gICAgICBpZiAoY29ycmVjdE9yaWdpbmFsS2V5ICYmIG9yaWdpbmFsS2V5ICE9PSBjb3JyZWN0T3JpZ2luYWxLZXkpIHtcbiAgICAgICAgdmFyIHdhcm5pbmdLZXkgPSBvcmlnaW5hbEtleSArICcsJyArIGNvcnJlY3RPcmlnaW5hbEtleTtcblxuICAgICAgICBpZiAod2FybmVkQWJvdXRbd2FybmluZ0tleV0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdhcm5lZEFib3V0W3dhcm5pbmdLZXldID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignJXMgYSBzdHlsZSBwcm9wZXJ0eSBkdXJpbmcgcmVyZW5kZXIgKCVzKSB3aGVuIGEgJyArICdjb25mbGljdGluZyBwcm9wZXJ0eSBpcyBzZXQgKCVzKSBjYW4gbGVhZCB0byBzdHlsaW5nIGJ1Z3MuIFRvICcgKyBcImF2b2lkIHRoaXMsIGRvbid0IG1peCBzaG9ydGhhbmQgYW5kIG5vbi1zaG9ydGhhbmQgcHJvcGVydGllcyBcIiArICdmb3IgdGhlIHNhbWUgdmFsdWU7IGluc3RlYWQsIHJlcGxhY2UgdGhlIHNob3J0aGFuZCB3aXRoICcgKyAnc2VwYXJhdGUgdmFsdWVzLicsIGlzVmFsdWVFbXB0eShzdHlsZVVwZGF0ZXNbb3JpZ2luYWxLZXldKSA/ICdSZW1vdmluZycgOiAnVXBkYXRpbmcnLCBvcmlnaW5hbEtleSwgY29ycmVjdE9yaWdpbmFsS2V5KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gRm9yIEhUTUwsIGNlcnRhaW4gdGFncyBzaG91bGQgb21pdCB0aGVpciBjbG9zZSB0YWcuIFdlIGtlZXAgYSBsaXN0IGZvclxuLy8gdGhvc2Ugc3BlY2lhbC1jYXNlIHRhZ3MuXG52YXIgb21pdHRlZENsb3NlVGFncyA9IHtcbiAgYXJlYTogdHJ1ZSxcbiAgYmFzZTogdHJ1ZSxcbiAgYnI6IHRydWUsXG4gIGNvbDogdHJ1ZSxcbiAgZW1iZWQ6IHRydWUsXG4gIGhyOiB0cnVlLFxuICBpbWc6IHRydWUsXG4gIGlucHV0OiB0cnVlLFxuICBrZXlnZW46IHRydWUsXG4gIGxpbms6IHRydWUsXG4gIG1ldGE6IHRydWUsXG4gIHBhcmFtOiB0cnVlLFxuICBzb3VyY2U6IHRydWUsXG4gIHRyYWNrOiB0cnVlLFxuICB3YnI6IHRydWUgLy8gTk9URTogbWVudWl0ZW0ncyBjbG9zZSB0YWcgc2hvdWxkIGJlIG9taXR0ZWQsIGJ1dCB0aGF0IGNhdXNlcyBwcm9ibGVtcy5cblxufTtcblxuLy8gYG9taXR0ZWRDbG9zZVRhZ3NgIGV4Y2VwdCB0aGF0IGBtZW51aXRlbWAgc2hvdWxkIHN0aWxsIGhhdmUgaXRzIGNsb3NpbmcgdGFnLlxuXG52YXIgdm9pZEVsZW1lbnRUYWdzID0gYXNzaWduKHtcbiAgbWVudWl0ZW06IHRydWVcbn0sIG9taXR0ZWRDbG9zZVRhZ3MpO1xuXG52YXIgSFRNTCA9ICdfX2h0bWwnO1xuXG5mdW5jdGlvbiBhc3NlcnRWYWxpZFByb3BzKHRhZywgcHJvcHMpIHtcbiAgaWYgKCFwcm9wcykge1xuICAgIHJldHVybjtcbiAgfSAvLyBOb3RlIHRoZSB1c2Ugb2YgYD09YCB3aGljaCBjaGVja3MgZm9yIG51bGwgb3IgdW5kZWZpbmVkLlxuXG5cbiAgaWYgKHZvaWRFbGVtZW50VGFnc1t0YWddKSB7XG4gICAgaWYgKHByb3BzLmNoaWxkcmVuICE9IG51bGwgfHwgcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRhZyArIFwiIGlzIGEgdm9pZCBlbGVtZW50IHRhZyBhbmQgbXVzdCBuZWl0aGVyIGhhdmUgYGNoaWxkcmVuYCBub3IgXCIgKyAndXNlIGBkYW5nZXJvdXNseVNldElubmVySFRNTGAuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9IG51bGwpIHtcbiAgICBpZiAocHJvcHMuY2hpbGRyZW4gIT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gb25seSBzZXQgb25lIG9mIGBjaGlsZHJlbmAgb3IgYHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYC4nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9PSAnb2JqZWN0JyB8fCAhKEhUTUwgaW4gcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Bwcm9wcy5kYW5nZXJvdXNseVNldElubmVySFRNTGAgbXVzdCBiZSBpbiB0aGUgZm9ybSBge19faHRtbDogLi4ufWAuICcgKyAnUGxlYXNlIHZpc2l0IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9kYW5nZXJvdXNseS1zZXQtaW5uZXItaHRtbCAnICsgJ2ZvciBtb3JlIGluZm9ybWF0aW9uLicpO1xuICAgIH1cbiAgfVxuXG4gIHtcbiAgICBpZiAoIXByb3BzLnN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZyAmJiBwcm9wcy5jb250ZW50RWRpdGFibGUgJiYgcHJvcHMuY2hpbGRyZW4gIT0gbnVsbCkge1xuICAgICAgZXJyb3IoJ0EgY29tcG9uZW50IGlzIGBjb250ZW50RWRpdGFibGVgIGFuZCBjb250YWlucyBgY2hpbGRyZW5gIG1hbmFnZWQgYnkgJyArICdSZWFjdC4gSXQgaXMgbm93IHlvdXIgcmVzcG9uc2liaWxpdHkgdG8gZ3VhcmFudGVlIHRoYXQgbm9uZSBvZiAnICsgJ3Rob3NlIG5vZGVzIGFyZSB1bmV4cGVjdGVkbHkgbW9kaWZpZWQgb3IgZHVwbGljYXRlZC4gVGhpcyBpcyAnICsgJ3Byb2JhYmx5IG5vdCBpbnRlbnRpb25hbC4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAocHJvcHMuc3R5bGUgIT0gbnVsbCAmJiB0eXBlb2YgcHJvcHMuc3R5bGUgIT09ICdvYmplY3QnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgYHN0eWxlYCBwcm9wIGV4cGVjdHMgYSBtYXBwaW5nIGZyb20gc3R5bGUgcHJvcGVydGllcyB0byB2YWx1ZXMsICcgKyBcIm5vdCBhIHN0cmluZy4gRm9yIGV4YW1wbGUsIHN0eWxlPXt7bWFyZ2luUmlnaHQ6IHNwYWNpbmcgKyAnZW0nfX0gd2hlbiBcIiArICd1c2luZyBKU1guJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNDdXN0b21Db21wb25lbnQodGFnTmFtZSwgcHJvcHMpIHtcbiAgaWYgKHRhZ05hbWUuaW5kZXhPZignLScpID09PSAtMSkge1xuICAgIHJldHVybiB0eXBlb2YgcHJvcHMuaXMgPT09ICdzdHJpbmcnO1xuICB9XG5cbiAgc3dpdGNoICh0YWdOYW1lKSB7XG4gICAgLy8gVGhlc2UgYXJlIHJlc2VydmVkIFNWRyBhbmQgTWF0aE1MIGVsZW1lbnRzLlxuICAgIC8vIFdlIGRvbid0IG1pbmQgdGhpcyBsaXN0IHRvbyBtdWNoIGJlY2F1c2Ugd2UgZXhwZWN0IGl0IHRvIG5ldmVyIGdyb3cuXG4gICAgLy8gVGhlIGFsdGVybmF0aXZlIGlzIHRvIHRyYWNrIHRoZSBuYW1lc3BhY2UgaW4gYSBmZXcgcGxhY2VzIHdoaWNoIGlzIGNvbnZvbHV0ZWQuXG4gICAgLy8gaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3dlYmNvbXBvbmVudHMvc3BlYy9jdXN0b20vI2N1c3RvbS1lbGVtZW50cy1jb3JlLWNvbmNlcHRzXG4gICAgY2FzZSAnYW5ub3RhdGlvbi14bWwnOlxuICAgIGNhc2UgJ2NvbG9yLXByb2ZpbGUnOlxuICAgIGNhc2UgJ2ZvbnQtZmFjZSc6XG4gICAgY2FzZSAnZm9udC1mYWNlLXNyYyc6XG4gICAgY2FzZSAnZm9udC1mYWNlLXVyaSc6XG4gICAgY2FzZSAnZm9udC1mYWNlLWZvcm1hdCc6XG4gICAgY2FzZSAnZm9udC1mYWNlLW5hbWUnOlxuICAgIGNhc2UgJ21pc3NpbmctZ2x5cGgnOlxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG59XG5cbi8vIFdoZW4gYWRkaW5nIGF0dHJpYnV0ZXMgdG8gdGhlIEhUTUwgb3IgU1ZHIGFsbG93ZWQgYXR0cmlidXRlIGxpc3QsIGJlIHN1cmUgdG9cbi8vIGFsc28gYWRkIHRoZW0gdG8gdGhpcyBtb2R1bGUgdG8gZW5zdXJlIGNhc2luZyBhbmQgaW5jb3JyZWN0IG5hbWVcbi8vIHdhcm5pbmdzLlxudmFyIHBvc3NpYmxlU3RhbmRhcmROYW1lcyA9IHtcbiAgLy8gSFRNTFxuICBhY2NlcHQ6ICdhY2NlcHQnLFxuICBhY2NlcHRjaGFyc2V0OiAnYWNjZXB0Q2hhcnNldCcsXG4gICdhY2NlcHQtY2hhcnNldCc6ICdhY2NlcHRDaGFyc2V0JyxcbiAgYWNjZXNza2V5OiAnYWNjZXNzS2V5JyxcbiAgYWN0aW9uOiAnYWN0aW9uJyxcbiAgYWxsb3dmdWxsc2NyZWVuOiAnYWxsb3dGdWxsU2NyZWVuJyxcbiAgYWx0OiAnYWx0JyxcbiAgYXM6ICdhcycsXG4gIGFzeW5jOiAnYXN5bmMnLFxuICBhdXRvY2FwaXRhbGl6ZTogJ2F1dG9DYXBpdGFsaXplJyxcbiAgYXV0b2NvbXBsZXRlOiAnYXV0b0NvbXBsZXRlJyxcbiAgYXV0b2NvcnJlY3Q6ICdhdXRvQ29ycmVjdCcsXG4gIGF1dG9mb2N1czogJ2F1dG9Gb2N1cycsXG4gIGF1dG9wbGF5OiAnYXV0b1BsYXknLFxuICBhdXRvc2F2ZTogJ2F1dG9TYXZlJyxcbiAgY2FwdHVyZTogJ2NhcHR1cmUnLFxuICBjZWxscGFkZGluZzogJ2NlbGxQYWRkaW5nJyxcbiAgY2VsbHNwYWNpbmc6ICdjZWxsU3BhY2luZycsXG4gIGNoYWxsZW5nZTogJ2NoYWxsZW5nZScsXG4gIGNoYXJzZXQ6ICdjaGFyU2V0JyxcbiAgY2hlY2tlZDogJ2NoZWNrZWQnLFxuICBjaGlsZHJlbjogJ2NoaWxkcmVuJyxcbiAgY2l0ZTogJ2NpdGUnLFxuICBjbGFzczogJ2NsYXNzTmFtZScsXG4gIGNsYXNzaWQ6ICdjbGFzc0lEJyxcbiAgY2xhc3NuYW1lOiAnY2xhc3NOYW1lJyxcbiAgY29sczogJ2NvbHMnLFxuICBjb2xzcGFuOiAnY29sU3BhbicsXG4gIGNvbnRlbnQ6ICdjb250ZW50JyxcbiAgY29udGVudGVkaXRhYmxlOiAnY29udGVudEVkaXRhYmxlJyxcbiAgY29udGV4dG1lbnU6ICdjb250ZXh0TWVudScsXG4gIGNvbnRyb2xzOiAnY29udHJvbHMnLFxuICBjb250cm9sc2xpc3Q6ICdjb250cm9sc0xpc3QnLFxuICBjb29yZHM6ICdjb29yZHMnLFxuICBjcm9zc29yaWdpbjogJ2Nyb3NzT3JpZ2luJyxcbiAgZGFuZ2Vyb3VzbHlzZXRpbm5lcmh0bWw6ICdkYW5nZXJvdXNseVNldElubmVySFRNTCcsXG4gIGRhdGE6ICdkYXRhJyxcbiAgZGF0ZXRpbWU6ICdkYXRlVGltZScsXG4gIGRlZmF1bHQ6ICdkZWZhdWx0JyxcbiAgZGVmYXVsdGNoZWNrZWQ6ICdkZWZhdWx0Q2hlY2tlZCcsXG4gIGRlZmF1bHR2YWx1ZTogJ2RlZmF1bHRWYWx1ZScsXG4gIGRlZmVyOiAnZGVmZXInLFxuICBkaXI6ICdkaXInLFxuICBkaXNhYmxlZDogJ2Rpc2FibGVkJyxcbiAgZGlzYWJsZXBpY3R1cmVpbnBpY3R1cmU6ICdkaXNhYmxlUGljdHVyZUluUGljdHVyZScsXG4gIGRpc2FibGVyZW1vdGVwbGF5YmFjazogJ2Rpc2FibGVSZW1vdGVQbGF5YmFjaycsXG4gIGRvd25sb2FkOiAnZG93bmxvYWQnLFxuICBkcmFnZ2FibGU6ICdkcmFnZ2FibGUnLFxuICBlbmN0eXBlOiAnZW5jVHlwZScsXG4gIGVudGVya2V5aGludDogJ2VudGVyS2V5SGludCcsXG4gIGZvcjogJ2h0bWxGb3InLFxuICBmb3JtOiAnZm9ybScsXG4gIGZvcm1tZXRob2Q6ICdmb3JtTWV0aG9kJyxcbiAgZm9ybWFjdGlvbjogJ2Zvcm1BY3Rpb24nLFxuICBmb3JtZW5jdHlwZTogJ2Zvcm1FbmNUeXBlJyxcbiAgZm9ybW5vdmFsaWRhdGU6ICdmb3JtTm9WYWxpZGF0ZScsXG4gIGZvcm10YXJnZXQ6ICdmb3JtVGFyZ2V0JyxcbiAgZnJhbWVib3JkZXI6ICdmcmFtZUJvcmRlcicsXG4gIGhlYWRlcnM6ICdoZWFkZXJzJyxcbiAgaGVpZ2h0OiAnaGVpZ2h0JyxcbiAgaGlkZGVuOiAnaGlkZGVuJyxcbiAgaGlnaDogJ2hpZ2gnLFxuICBocmVmOiAnaHJlZicsXG4gIGhyZWZsYW5nOiAnaHJlZkxhbmcnLFxuICBodG1sZm9yOiAnaHRtbEZvcicsXG4gIGh0dHBlcXVpdjogJ2h0dHBFcXVpdicsXG4gICdodHRwLWVxdWl2JzogJ2h0dHBFcXVpdicsXG4gIGljb246ICdpY29uJyxcbiAgaWQ6ICdpZCcsXG4gIGltYWdlc2l6ZXM6ICdpbWFnZVNpemVzJyxcbiAgaW1hZ2VzcmNzZXQ6ICdpbWFnZVNyY1NldCcsXG4gIGlubmVyaHRtbDogJ2lubmVySFRNTCcsXG4gIGlucHV0bW9kZTogJ2lucHV0TW9kZScsXG4gIGludGVncml0eTogJ2ludGVncml0eScsXG4gIGlzOiAnaXMnLFxuICBpdGVtaWQ6ICdpdGVtSUQnLFxuICBpdGVtcHJvcDogJ2l0ZW1Qcm9wJyxcbiAgaXRlbXJlZjogJ2l0ZW1SZWYnLFxuICBpdGVtc2NvcGU6ICdpdGVtU2NvcGUnLFxuICBpdGVtdHlwZTogJ2l0ZW1UeXBlJyxcbiAga2V5cGFyYW1zOiAna2V5UGFyYW1zJyxcbiAga2V5dHlwZTogJ2tleVR5cGUnLFxuICBraW5kOiAna2luZCcsXG4gIGxhYmVsOiAnbGFiZWwnLFxuICBsYW5nOiAnbGFuZycsXG4gIGxpc3Q6ICdsaXN0JyxcbiAgbG9vcDogJ2xvb3AnLFxuICBsb3c6ICdsb3cnLFxuICBtYW5pZmVzdDogJ21hbmlmZXN0JyxcbiAgbWFyZ2lud2lkdGg6ICdtYXJnaW5XaWR0aCcsXG4gIG1hcmdpbmhlaWdodDogJ21hcmdpbkhlaWdodCcsXG4gIG1heDogJ21heCcsXG4gIG1heGxlbmd0aDogJ21heExlbmd0aCcsXG4gIG1lZGlhOiAnbWVkaWEnLFxuICBtZWRpYWdyb3VwOiAnbWVkaWFHcm91cCcsXG4gIG1ldGhvZDogJ21ldGhvZCcsXG4gIG1pbjogJ21pbicsXG4gIG1pbmxlbmd0aDogJ21pbkxlbmd0aCcsXG4gIG11bHRpcGxlOiAnbXVsdGlwbGUnLFxuICBtdXRlZDogJ211dGVkJyxcbiAgbmFtZTogJ25hbWUnLFxuICBub21vZHVsZTogJ25vTW9kdWxlJyxcbiAgbm9uY2U6ICdub25jZScsXG4gIG5vdmFsaWRhdGU6ICdub1ZhbGlkYXRlJyxcbiAgb3BlbjogJ29wZW4nLFxuICBvcHRpbXVtOiAnb3B0aW11bScsXG4gIHBhdHRlcm46ICdwYXR0ZXJuJyxcbiAgcGxhY2Vob2xkZXI6ICdwbGFjZWhvbGRlcicsXG4gIHBsYXlzaW5saW5lOiAncGxheXNJbmxpbmUnLFxuICBwb3N0ZXI6ICdwb3N0ZXInLFxuICBwcmVsb2FkOiAncHJlbG9hZCcsXG4gIHByb2ZpbGU6ICdwcm9maWxlJyxcbiAgcmFkaW9ncm91cDogJ3JhZGlvR3JvdXAnLFxuICByZWFkb25seTogJ3JlYWRPbmx5JyxcbiAgcmVmZXJyZXJwb2xpY3k6ICdyZWZlcnJlclBvbGljeScsXG4gIHJlbDogJ3JlbCcsXG4gIHJlcXVpcmVkOiAncmVxdWlyZWQnLFxuICByZXZlcnNlZDogJ3JldmVyc2VkJyxcbiAgcm9sZTogJ3JvbGUnLFxuICByb3dzOiAncm93cycsXG4gIHJvd3NwYW46ICdyb3dTcGFuJyxcbiAgc2FuZGJveDogJ3NhbmRib3gnLFxuICBzY29wZTogJ3Njb3BlJyxcbiAgc2NvcGVkOiAnc2NvcGVkJyxcbiAgc2Nyb2xsaW5nOiAnc2Nyb2xsaW5nJyxcbiAgc2VhbWxlc3M6ICdzZWFtbGVzcycsXG4gIHNlbGVjdGVkOiAnc2VsZWN0ZWQnLFxuICBzaGFwZTogJ3NoYXBlJyxcbiAgc2l6ZTogJ3NpemUnLFxuICBzaXplczogJ3NpemVzJyxcbiAgc3BhbjogJ3NwYW4nLFxuICBzcGVsbGNoZWNrOiAnc3BlbGxDaGVjaycsXG4gIHNyYzogJ3NyYycsXG4gIHNyY2RvYzogJ3NyY0RvYycsXG4gIHNyY2xhbmc6ICdzcmNMYW5nJyxcbiAgc3Jjc2V0OiAnc3JjU2V0JyxcbiAgc3RhcnQ6ICdzdGFydCcsXG4gIHN0ZXA6ICdzdGVwJyxcbiAgc3R5bGU6ICdzdHlsZScsXG4gIHN1bW1hcnk6ICdzdW1tYXJ5JyxcbiAgdGFiaW5kZXg6ICd0YWJJbmRleCcsXG4gIHRhcmdldDogJ3RhcmdldCcsXG4gIHRpdGxlOiAndGl0bGUnLFxuICB0eXBlOiAndHlwZScsXG4gIHVzZW1hcDogJ3VzZU1hcCcsXG4gIHZhbHVlOiAndmFsdWUnLFxuICB3aWR0aDogJ3dpZHRoJyxcbiAgd21vZGU6ICd3bW9kZScsXG4gIHdyYXA6ICd3cmFwJyxcbiAgLy8gU1ZHXG4gIGFib3V0OiAnYWJvdXQnLFxuICBhY2NlbnRoZWlnaHQ6ICdhY2NlbnRIZWlnaHQnLFxuICAnYWNjZW50LWhlaWdodCc6ICdhY2NlbnRIZWlnaHQnLFxuICBhY2N1bXVsYXRlOiAnYWNjdW11bGF0ZScsXG4gIGFkZGl0aXZlOiAnYWRkaXRpdmUnLFxuICBhbGlnbm1lbnRiYXNlbGluZTogJ2FsaWdubWVudEJhc2VsaW5lJyxcbiAgJ2FsaWdubWVudC1iYXNlbGluZSc6ICdhbGlnbm1lbnRCYXNlbGluZScsXG4gIGFsbG93cmVvcmRlcjogJ2FsbG93UmVvcmRlcicsXG4gIGFscGhhYmV0aWM6ICdhbHBoYWJldGljJyxcbiAgYW1wbGl0dWRlOiAnYW1wbGl0dWRlJyxcbiAgYXJhYmljZm9ybTogJ2FyYWJpY0Zvcm0nLFxuICAnYXJhYmljLWZvcm0nOiAnYXJhYmljRm9ybScsXG4gIGFzY2VudDogJ2FzY2VudCcsXG4gIGF0dHJpYnV0ZW5hbWU6ICdhdHRyaWJ1dGVOYW1lJyxcbiAgYXR0cmlidXRldHlwZTogJ2F0dHJpYnV0ZVR5cGUnLFxuICBhdXRvcmV2ZXJzZTogJ2F1dG9SZXZlcnNlJyxcbiAgYXppbXV0aDogJ2F6aW11dGgnLFxuICBiYXNlZnJlcXVlbmN5OiAnYmFzZUZyZXF1ZW5jeScsXG4gIGJhc2VsaW5lc2hpZnQ6ICdiYXNlbGluZVNoaWZ0JyxcbiAgJ2Jhc2VsaW5lLXNoaWZ0JzogJ2Jhc2VsaW5lU2hpZnQnLFxuICBiYXNlcHJvZmlsZTogJ2Jhc2VQcm9maWxlJyxcbiAgYmJveDogJ2Jib3gnLFxuICBiZWdpbjogJ2JlZ2luJyxcbiAgYmlhczogJ2JpYXMnLFxuICBieTogJ2J5JyxcbiAgY2FsY21vZGU6ICdjYWxjTW9kZScsXG4gIGNhcGhlaWdodDogJ2NhcEhlaWdodCcsXG4gICdjYXAtaGVpZ2h0JzogJ2NhcEhlaWdodCcsXG4gIGNsaXA6ICdjbGlwJyxcbiAgY2xpcHBhdGg6ICdjbGlwUGF0aCcsXG4gICdjbGlwLXBhdGgnOiAnY2xpcFBhdGgnLFxuICBjbGlwcGF0aHVuaXRzOiAnY2xpcFBhdGhVbml0cycsXG4gIGNsaXBydWxlOiAnY2xpcFJ1bGUnLFxuICAnY2xpcC1ydWxlJzogJ2NsaXBSdWxlJyxcbiAgY29sb3I6ICdjb2xvcicsXG4gIGNvbG9yaW50ZXJwb2xhdGlvbjogJ2NvbG9ySW50ZXJwb2xhdGlvbicsXG4gICdjb2xvci1pbnRlcnBvbGF0aW9uJzogJ2NvbG9ySW50ZXJwb2xhdGlvbicsXG4gIGNvbG9yaW50ZXJwb2xhdGlvbmZpbHRlcnM6ICdjb2xvckludGVycG9sYXRpb25GaWx0ZXJzJyxcbiAgJ2NvbG9yLWludGVycG9sYXRpb24tZmlsdGVycyc6ICdjb2xvckludGVycG9sYXRpb25GaWx0ZXJzJyxcbiAgY29sb3Jwcm9maWxlOiAnY29sb3JQcm9maWxlJyxcbiAgJ2NvbG9yLXByb2ZpbGUnOiAnY29sb3JQcm9maWxlJyxcbiAgY29sb3JyZW5kZXJpbmc6ICdjb2xvclJlbmRlcmluZycsXG4gICdjb2xvci1yZW5kZXJpbmcnOiAnY29sb3JSZW5kZXJpbmcnLFxuICBjb250ZW50c2NyaXB0dHlwZTogJ2NvbnRlbnRTY3JpcHRUeXBlJyxcbiAgY29udGVudHN0eWxldHlwZTogJ2NvbnRlbnRTdHlsZVR5cGUnLFxuICBjdXJzb3I6ICdjdXJzb3InLFxuICBjeDogJ2N4JyxcbiAgY3k6ICdjeScsXG4gIGQ6ICdkJyxcbiAgZGF0YXR5cGU6ICdkYXRhdHlwZScsXG4gIGRlY2VsZXJhdGU6ICdkZWNlbGVyYXRlJyxcbiAgZGVzY2VudDogJ2Rlc2NlbnQnLFxuICBkaWZmdXNlY29uc3RhbnQ6ICdkaWZmdXNlQ29uc3RhbnQnLFxuICBkaXJlY3Rpb246ICdkaXJlY3Rpb24nLFxuICBkaXNwbGF5OiAnZGlzcGxheScsXG4gIGRpdmlzb3I6ICdkaXZpc29yJyxcbiAgZG9taW5hbnRiYXNlbGluZTogJ2RvbWluYW50QmFzZWxpbmUnLFxuICAnZG9taW5hbnQtYmFzZWxpbmUnOiAnZG9taW5hbnRCYXNlbGluZScsXG4gIGR1cjogJ2R1cicsXG4gIGR4OiAnZHgnLFxuICBkeTogJ2R5JyxcbiAgZWRnZW1vZGU6ICdlZGdlTW9kZScsXG4gIGVsZXZhdGlvbjogJ2VsZXZhdGlvbicsXG4gIGVuYWJsZWJhY2tncm91bmQ6ICdlbmFibGVCYWNrZ3JvdW5kJyxcbiAgJ2VuYWJsZS1iYWNrZ3JvdW5kJzogJ2VuYWJsZUJhY2tncm91bmQnLFxuICBlbmQ6ICdlbmQnLFxuICBleHBvbmVudDogJ2V4cG9uZW50JyxcbiAgZXh0ZXJuYWxyZXNvdXJjZXNyZXF1aXJlZDogJ2V4dGVybmFsUmVzb3VyY2VzUmVxdWlyZWQnLFxuICBmaWxsOiAnZmlsbCcsXG4gIGZpbGxvcGFjaXR5OiAnZmlsbE9wYWNpdHknLFxuICAnZmlsbC1vcGFjaXR5JzogJ2ZpbGxPcGFjaXR5JyxcbiAgZmlsbHJ1bGU6ICdmaWxsUnVsZScsXG4gICdmaWxsLXJ1bGUnOiAnZmlsbFJ1bGUnLFxuICBmaWx0ZXI6ICdmaWx0ZXInLFxuICBmaWx0ZXJyZXM6ICdmaWx0ZXJSZXMnLFxuICBmaWx0ZXJ1bml0czogJ2ZpbHRlclVuaXRzJyxcbiAgZmxvb2RvcGFjaXR5OiAnZmxvb2RPcGFjaXR5JyxcbiAgJ2Zsb29kLW9wYWNpdHknOiAnZmxvb2RPcGFjaXR5JyxcbiAgZmxvb2Rjb2xvcjogJ2Zsb29kQ29sb3InLFxuICAnZmxvb2QtY29sb3InOiAnZmxvb2RDb2xvcicsXG4gIGZvY3VzYWJsZTogJ2ZvY3VzYWJsZScsXG4gIGZvbnRmYW1pbHk6ICdmb250RmFtaWx5JyxcbiAgJ2ZvbnQtZmFtaWx5JzogJ2ZvbnRGYW1pbHknLFxuICBmb250c2l6ZTogJ2ZvbnRTaXplJyxcbiAgJ2ZvbnQtc2l6ZSc6ICdmb250U2l6ZScsXG4gIGZvbnRzaXplYWRqdXN0OiAnZm9udFNpemVBZGp1c3QnLFxuICAnZm9udC1zaXplLWFkanVzdCc6ICdmb250U2l6ZUFkanVzdCcsXG4gIGZvbnRzdHJldGNoOiAnZm9udFN0cmV0Y2gnLFxuICAnZm9udC1zdHJldGNoJzogJ2ZvbnRTdHJldGNoJyxcbiAgZm9udHN0eWxlOiAnZm9udFN0eWxlJyxcbiAgJ2ZvbnQtc3R5bGUnOiAnZm9udFN0eWxlJyxcbiAgZm9udHZhcmlhbnQ6ICdmb250VmFyaWFudCcsXG4gICdmb250LXZhcmlhbnQnOiAnZm9udFZhcmlhbnQnLFxuICBmb250d2VpZ2h0OiAnZm9udFdlaWdodCcsXG4gICdmb250LXdlaWdodCc6ICdmb250V2VpZ2h0JyxcbiAgZm9ybWF0OiAnZm9ybWF0JyxcbiAgZnJvbTogJ2Zyb20nLFxuICBmeDogJ2Z4JyxcbiAgZnk6ICdmeScsXG4gIGcxOiAnZzEnLFxuICBnMjogJ2cyJyxcbiAgZ2x5cGhuYW1lOiAnZ2x5cGhOYW1lJyxcbiAgJ2dseXBoLW5hbWUnOiAnZ2x5cGhOYW1lJyxcbiAgZ2x5cGhvcmllbnRhdGlvbmhvcml6b250YWw6ICdnbHlwaE9yaWVudGF0aW9uSG9yaXpvbnRhbCcsXG4gICdnbHlwaC1vcmllbnRhdGlvbi1ob3Jpem9udGFsJzogJ2dseXBoT3JpZW50YXRpb25Ib3Jpem9udGFsJyxcbiAgZ2x5cGhvcmllbnRhdGlvbnZlcnRpY2FsOiAnZ2x5cGhPcmllbnRhdGlvblZlcnRpY2FsJyxcbiAgJ2dseXBoLW9yaWVudGF0aW9uLXZlcnRpY2FsJzogJ2dseXBoT3JpZW50YXRpb25WZXJ0aWNhbCcsXG4gIGdseXBocmVmOiAnZ2x5cGhSZWYnLFxuICBncmFkaWVudHRyYW5zZm9ybTogJ2dyYWRpZW50VHJhbnNmb3JtJyxcbiAgZ3JhZGllbnR1bml0czogJ2dyYWRpZW50VW5pdHMnLFxuICBoYW5naW5nOiAnaGFuZ2luZycsXG4gIGhvcml6YWR2eDogJ2hvcml6QWR2WCcsXG4gICdob3Jpei1hZHYteCc6ICdob3JpekFkdlgnLFxuICBob3Jpem9yaWdpbng6ICdob3Jpek9yaWdpblgnLFxuICAnaG9yaXotb3JpZ2luLXgnOiAnaG9yaXpPcmlnaW5YJyxcbiAgaWRlb2dyYXBoaWM6ICdpZGVvZ3JhcGhpYycsXG4gIGltYWdlcmVuZGVyaW5nOiAnaW1hZ2VSZW5kZXJpbmcnLFxuICAnaW1hZ2UtcmVuZGVyaW5nJzogJ2ltYWdlUmVuZGVyaW5nJyxcbiAgaW4yOiAnaW4yJyxcbiAgaW46ICdpbicsXG4gIGlubGlzdDogJ2lubGlzdCcsXG4gIGludGVyY2VwdDogJ2ludGVyY2VwdCcsXG4gIGsxOiAnazEnLFxuICBrMjogJ2syJyxcbiAgazM6ICdrMycsXG4gIGs0OiAnazQnLFxuICBrOiAnaycsXG4gIGtlcm5lbG1hdHJpeDogJ2tlcm5lbE1hdHJpeCcsXG4gIGtlcm5lbHVuaXRsZW5ndGg6ICdrZXJuZWxVbml0TGVuZ3RoJyxcbiAga2VybmluZzogJ2tlcm5pbmcnLFxuICBrZXlwb2ludHM6ICdrZXlQb2ludHMnLFxuICBrZXlzcGxpbmVzOiAna2V5U3BsaW5lcycsXG4gIGtleXRpbWVzOiAna2V5VGltZXMnLFxuICBsZW5ndGhhZGp1c3Q6ICdsZW5ndGhBZGp1c3QnLFxuICBsZXR0ZXJzcGFjaW5nOiAnbGV0dGVyU3BhY2luZycsXG4gICdsZXR0ZXItc3BhY2luZyc6ICdsZXR0ZXJTcGFjaW5nJyxcbiAgbGlnaHRpbmdjb2xvcjogJ2xpZ2h0aW5nQ29sb3InLFxuICAnbGlnaHRpbmctY29sb3InOiAnbGlnaHRpbmdDb2xvcicsXG4gIGxpbWl0aW5nY29uZWFuZ2xlOiAnbGltaXRpbmdDb25lQW5nbGUnLFxuICBsb2NhbDogJ2xvY2FsJyxcbiAgbWFya2VyZW5kOiAnbWFya2VyRW5kJyxcbiAgJ21hcmtlci1lbmQnOiAnbWFya2VyRW5kJyxcbiAgbWFya2VyaGVpZ2h0OiAnbWFya2VySGVpZ2h0JyxcbiAgbWFya2VybWlkOiAnbWFya2VyTWlkJyxcbiAgJ21hcmtlci1taWQnOiAnbWFya2VyTWlkJyxcbiAgbWFya2Vyc3RhcnQ6ICdtYXJrZXJTdGFydCcsXG4gICdtYXJrZXItc3RhcnQnOiAnbWFya2VyU3RhcnQnLFxuICBtYXJrZXJ1bml0czogJ21hcmtlclVuaXRzJyxcbiAgbWFya2Vyd2lkdGg6ICdtYXJrZXJXaWR0aCcsXG4gIG1hc2s6ICdtYXNrJyxcbiAgbWFza2NvbnRlbnR1bml0czogJ21hc2tDb250ZW50VW5pdHMnLFxuICBtYXNrdW5pdHM6ICdtYXNrVW5pdHMnLFxuICBtYXRoZW1hdGljYWw6ICdtYXRoZW1hdGljYWwnLFxuICBtb2RlOiAnbW9kZScsXG4gIG51bW9jdGF2ZXM6ICdudW1PY3RhdmVzJyxcbiAgb2Zmc2V0OiAnb2Zmc2V0JyxcbiAgb3BhY2l0eTogJ29wYWNpdHknLFxuICBvcGVyYXRvcjogJ29wZXJhdG9yJyxcbiAgb3JkZXI6ICdvcmRlcicsXG4gIG9yaWVudDogJ29yaWVudCcsXG4gIG9yaWVudGF0aW9uOiAnb3JpZW50YXRpb24nLFxuICBvcmlnaW46ICdvcmlnaW4nLFxuICBvdmVyZmxvdzogJ292ZXJmbG93JyxcbiAgb3ZlcmxpbmVwb3NpdGlvbjogJ292ZXJsaW5lUG9zaXRpb24nLFxuICAnb3ZlcmxpbmUtcG9zaXRpb24nOiAnb3ZlcmxpbmVQb3NpdGlvbicsXG4gIG92ZXJsaW5ldGhpY2tuZXNzOiAnb3ZlcmxpbmVUaGlja25lc3MnLFxuICAnb3ZlcmxpbmUtdGhpY2tuZXNzJzogJ292ZXJsaW5lVGhpY2tuZXNzJyxcbiAgcGFpbnRvcmRlcjogJ3BhaW50T3JkZXInLFxuICAncGFpbnQtb3JkZXInOiAncGFpbnRPcmRlcicsXG4gIHBhbm9zZTE6ICdwYW5vc2UxJyxcbiAgJ3Bhbm9zZS0xJzogJ3Bhbm9zZTEnLFxuICBwYXRobGVuZ3RoOiAncGF0aExlbmd0aCcsXG4gIHBhdHRlcm5jb250ZW50dW5pdHM6ICdwYXR0ZXJuQ29udGVudFVuaXRzJyxcbiAgcGF0dGVybnRyYW5zZm9ybTogJ3BhdHRlcm5UcmFuc2Zvcm0nLFxuICBwYXR0ZXJudW5pdHM6ICdwYXR0ZXJuVW5pdHMnLFxuICBwb2ludGVyZXZlbnRzOiAncG9pbnRlckV2ZW50cycsXG4gICdwb2ludGVyLWV2ZW50cyc6ICdwb2ludGVyRXZlbnRzJyxcbiAgcG9pbnRzOiAncG9pbnRzJyxcbiAgcG9pbnRzYXR4OiAncG9pbnRzQXRYJyxcbiAgcG9pbnRzYXR5OiAncG9pbnRzQXRZJyxcbiAgcG9pbnRzYXR6OiAncG9pbnRzQXRaJyxcbiAgcHJlZml4OiAncHJlZml4JyxcbiAgcHJlc2VydmVhbHBoYTogJ3ByZXNlcnZlQWxwaGEnLFxuICBwcmVzZXJ2ZWFzcGVjdHJhdGlvOiAncHJlc2VydmVBc3BlY3RSYXRpbycsXG4gIHByaW1pdGl2ZXVuaXRzOiAncHJpbWl0aXZlVW5pdHMnLFxuICBwcm9wZXJ0eTogJ3Byb3BlcnR5JyxcbiAgcjogJ3InLFxuICByYWRpdXM6ICdyYWRpdXMnLFxuICByZWZ4OiAncmVmWCcsXG4gIHJlZnk6ICdyZWZZJyxcbiAgcmVuZGVyaW5naW50ZW50OiAncmVuZGVyaW5nSW50ZW50JyxcbiAgJ3JlbmRlcmluZy1pbnRlbnQnOiAncmVuZGVyaW5nSW50ZW50JyxcbiAgcmVwZWF0Y291bnQ6ICdyZXBlYXRDb3VudCcsXG4gIHJlcGVhdGR1cjogJ3JlcGVhdER1cicsXG4gIHJlcXVpcmVkZXh0ZW5zaW9uczogJ3JlcXVpcmVkRXh0ZW5zaW9ucycsXG4gIHJlcXVpcmVkZmVhdHVyZXM6ICdyZXF1aXJlZEZlYXR1cmVzJyxcbiAgcmVzb3VyY2U6ICdyZXNvdXJjZScsXG4gIHJlc3RhcnQ6ICdyZXN0YXJ0JyxcbiAgcmVzdWx0OiAncmVzdWx0JyxcbiAgcmVzdWx0czogJ3Jlc3VsdHMnLFxuICByb3RhdGU6ICdyb3RhdGUnLFxuICByeDogJ3J4JyxcbiAgcnk6ICdyeScsXG4gIHNjYWxlOiAnc2NhbGUnLFxuICBzZWN1cml0eTogJ3NlY3VyaXR5JyxcbiAgc2VlZDogJ3NlZWQnLFxuICBzaGFwZXJlbmRlcmluZzogJ3NoYXBlUmVuZGVyaW5nJyxcbiAgJ3NoYXBlLXJlbmRlcmluZyc6ICdzaGFwZVJlbmRlcmluZycsXG4gIHNsb3BlOiAnc2xvcGUnLFxuICBzcGFjaW5nOiAnc3BhY2luZycsXG4gIHNwZWN1bGFyY29uc3RhbnQ6ICdzcGVjdWxhckNvbnN0YW50JyxcbiAgc3BlY3VsYXJleHBvbmVudDogJ3NwZWN1bGFyRXhwb25lbnQnLFxuICBzcGVlZDogJ3NwZWVkJyxcbiAgc3ByZWFkbWV0aG9kOiAnc3ByZWFkTWV0aG9kJyxcbiAgc3RhcnRvZmZzZXQ6ICdzdGFydE9mZnNldCcsXG4gIHN0ZGRldmlhdGlvbjogJ3N0ZERldmlhdGlvbicsXG4gIHN0ZW1oOiAnc3RlbWgnLFxuICBzdGVtdjogJ3N0ZW12JyxcbiAgc3RpdGNodGlsZXM6ICdzdGl0Y2hUaWxlcycsXG4gIHN0b3Bjb2xvcjogJ3N0b3BDb2xvcicsXG4gICdzdG9wLWNvbG9yJzogJ3N0b3BDb2xvcicsXG4gIHN0b3BvcGFjaXR5OiAnc3RvcE9wYWNpdHknLFxuICAnc3RvcC1vcGFjaXR5JzogJ3N0b3BPcGFjaXR5JyxcbiAgc3RyaWtldGhyb3VnaHBvc2l0aW9uOiAnc3RyaWtldGhyb3VnaFBvc2l0aW9uJyxcbiAgJ3N0cmlrZXRocm91Z2gtcG9zaXRpb24nOiAnc3RyaWtldGhyb3VnaFBvc2l0aW9uJyxcbiAgc3RyaWtldGhyb3VnaHRoaWNrbmVzczogJ3N0cmlrZXRocm91Z2hUaGlja25lc3MnLFxuICAnc3RyaWtldGhyb3VnaC10aGlja25lc3MnOiAnc3RyaWtldGhyb3VnaFRoaWNrbmVzcycsXG4gIHN0cmluZzogJ3N0cmluZycsXG4gIHN0cm9rZTogJ3N0cm9rZScsXG4gIHN0cm9rZWRhc2hhcnJheTogJ3N0cm9rZURhc2hhcnJheScsXG4gICdzdHJva2UtZGFzaGFycmF5JzogJ3N0cm9rZURhc2hhcnJheScsXG4gIHN0cm9rZWRhc2hvZmZzZXQ6ICdzdHJva2VEYXNob2Zmc2V0JyxcbiAgJ3N0cm9rZS1kYXNob2Zmc2V0JzogJ3N0cm9rZURhc2hvZmZzZXQnLFxuICBzdHJva2VsaW5lY2FwOiAnc3Ryb2tlTGluZWNhcCcsXG4gICdzdHJva2UtbGluZWNhcCc6ICdzdHJva2VMaW5lY2FwJyxcbiAgc3Ryb2tlbGluZWpvaW46ICdzdHJva2VMaW5lam9pbicsXG4gICdzdHJva2UtbGluZWpvaW4nOiAnc3Ryb2tlTGluZWpvaW4nLFxuICBzdHJva2VtaXRlcmxpbWl0OiAnc3Ryb2tlTWl0ZXJsaW1pdCcsXG4gICdzdHJva2UtbWl0ZXJsaW1pdCc6ICdzdHJva2VNaXRlcmxpbWl0JyxcbiAgc3Ryb2tld2lkdGg6ICdzdHJva2VXaWR0aCcsXG4gICdzdHJva2Utd2lkdGgnOiAnc3Ryb2tlV2lkdGgnLFxuICBzdHJva2VvcGFjaXR5OiAnc3Ryb2tlT3BhY2l0eScsXG4gICdzdHJva2Utb3BhY2l0eSc6ICdzdHJva2VPcGFjaXR5JyxcbiAgc3VwcHJlc3Njb250ZW50ZWRpdGFibGV3YXJuaW5nOiAnc3VwcHJlc3NDb250ZW50RWRpdGFibGVXYXJuaW5nJyxcbiAgc3VwcHJlc3NoeWRyYXRpb253YXJuaW5nOiAnc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nJyxcbiAgc3VyZmFjZXNjYWxlOiAnc3VyZmFjZVNjYWxlJyxcbiAgc3lzdGVtbGFuZ3VhZ2U6ICdzeXN0ZW1MYW5ndWFnZScsXG4gIHRhYmxldmFsdWVzOiAndGFibGVWYWx1ZXMnLFxuICB0YXJnZXR4OiAndGFyZ2V0WCcsXG4gIHRhcmdldHk6ICd0YXJnZXRZJyxcbiAgdGV4dGFuY2hvcjogJ3RleHRBbmNob3InLFxuICAndGV4dC1hbmNob3InOiAndGV4dEFuY2hvcicsXG4gIHRleHRkZWNvcmF0aW9uOiAndGV4dERlY29yYXRpb24nLFxuICAndGV4dC1kZWNvcmF0aW9uJzogJ3RleHREZWNvcmF0aW9uJyxcbiAgdGV4dGxlbmd0aDogJ3RleHRMZW5ndGgnLFxuICB0ZXh0cmVuZGVyaW5nOiAndGV4dFJlbmRlcmluZycsXG4gICd0ZXh0LXJlbmRlcmluZyc6ICd0ZXh0UmVuZGVyaW5nJyxcbiAgdG86ICd0bycsXG4gIHRyYW5zZm9ybTogJ3RyYW5zZm9ybScsXG4gIHR5cGVvZjogJ3R5cGVvZicsXG4gIHUxOiAndTEnLFxuICB1MjogJ3UyJyxcbiAgdW5kZXJsaW5lcG9zaXRpb246ICd1bmRlcmxpbmVQb3NpdGlvbicsXG4gICd1bmRlcmxpbmUtcG9zaXRpb24nOiAndW5kZXJsaW5lUG9zaXRpb24nLFxuICB1bmRlcmxpbmV0aGlja25lc3M6ICd1bmRlcmxpbmVUaGlja25lc3MnLFxuICAndW5kZXJsaW5lLXRoaWNrbmVzcyc6ICd1bmRlcmxpbmVUaGlja25lc3MnLFxuICB1bmljb2RlOiAndW5pY29kZScsXG4gIHVuaWNvZGViaWRpOiAndW5pY29kZUJpZGknLFxuICAndW5pY29kZS1iaWRpJzogJ3VuaWNvZGVCaWRpJyxcbiAgdW5pY29kZXJhbmdlOiAndW5pY29kZVJhbmdlJyxcbiAgJ3VuaWNvZGUtcmFuZ2UnOiAndW5pY29kZVJhbmdlJyxcbiAgdW5pdHNwZXJlbTogJ3VuaXRzUGVyRW0nLFxuICAndW5pdHMtcGVyLWVtJzogJ3VuaXRzUGVyRW0nLFxuICB1bnNlbGVjdGFibGU6ICd1bnNlbGVjdGFibGUnLFxuICB2YWxwaGFiZXRpYzogJ3ZBbHBoYWJldGljJyxcbiAgJ3YtYWxwaGFiZXRpYyc6ICd2QWxwaGFiZXRpYycsXG4gIHZhbHVlczogJ3ZhbHVlcycsXG4gIHZlY3RvcmVmZmVjdDogJ3ZlY3RvckVmZmVjdCcsXG4gICd2ZWN0b3ItZWZmZWN0JzogJ3ZlY3RvckVmZmVjdCcsXG4gIHZlcnNpb246ICd2ZXJzaW9uJyxcbiAgdmVydGFkdnk6ICd2ZXJ0QWR2WScsXG4gICd2ZXJ0LWFkdi15JzogJ3ZlcnRBZHZZJyxcbiAgdmVydG9yaWdpbng6ICd2ZXJ0T3JpZ2luWCcsXG4gICd2ZXJ0LW9yaWdpbi14JzogJ3ZlcnRPcmlnaW5YJyxcbiAgdmVydG9yaWdpbnk6ICd2ZXJ0T3JpZ2luWScsXG4gICd2ZXJ0LW9yaWdpbi15JzogJ3ZlcnRPcmlnaW5ZJyxcbiAgdmhhbmdpbmc6ICd2SGFuZ2luZycsXG4gICd2LWhhbmdpbmcnOiAndkhhbmdpbmcnLFxuICB2aWRlb2dyYXBoaWM6ICd2SWRlb2dyYXBoaWMnLFxuICAndi1pZGVvZ3JhcGhpYyc6ICd2SWRlb2dyYXBoaWMnLFxuICB2aWV3Ym94OiAndmlld0JveCcsXG4gIHZpZXd0YXJnZXQ6ICd2aWV3VGFyZ2V0JyxcbiAgdmlzaWJpbGl0eTogJ3Zpc2liaWxpdHknLFxuICB2bWF0aGVtYXRpY2FsOiAndk1hdGhlbWF0aWNhbCcsXG4gICd2LW1hdGhlbWF0aWNhbCc6ICd2TWF0aGVtYXRpY2FsJyxcbiAgdm9jYWI6ICd2b2NhYicsXG4gIHdpZHRoczogJ3dpZHRocycsXG4gIHdvcmRzcGFjaW5nOiAnd29yZFNwYWNpbmcnLFxuICAnd29yZC1zcGFjaW5nJzogJ3dvcmRTcGFjaW5nJyxcbiAgd3JpdGluZ21vZGU6ICd3cml0aW5nTW9kZScsXG4gICd3cml0aW5nLW1vZGUnOiAnd3JpdGluZ01vZGUnLFxuICB4MTogJ3gxJyxcbiAgeDI6ICd4MicsXG4gIHg6ICd4JyxcbiAgeGNoYW5uZWxzZWxlY3RvcjogJ3hDaGFubmVsU2VsZWN0b3InLFxuICB4aGVpZ2h0OiAneEhlaWdodCcsXG4gICd4LWhlaWdodCc6ICd4SGVpZ2h0JyxcbiAgeGxpbmthY3R1YXRlOiAneGxpbmtBY3R1YXRlJyxcbiAgJ3hsaW5rOmFjdHVhdGUnOiAneGxpbmtBY3R1YXRlJyxcbiAgeGxpbmthcmNyb2xlOiAneGxpbmtBcmNyb2xlJyxcbiAgJ3hsaW5rOmFyY3JvbGUnOiAneGxpbmtBcmNyb2xlJyxcbiAgeGxpbmtocmVmOiAneGxpbmtIcmVmJyxcbiAgJ3hsaW5rOmhyZWYnOiAneGxpbmtIcmVmJyxcbiAgeGxpbmtyb2xlOiAneGxpbmtSb2xlJyxcbiAgJ3hsaW5rOnJvbGUnOiAneGxpbmtSb2xlJyxcbiAgeGxpbmtzaG93OiAneGxpbmtTaG93JyxcbiAgJ3hsaW5rOnNob3cnOiAneGxpbmtTaG93JyxcbiAgeGxpbmt0aXRsZTogJ3hsaW5rVGl0bGUnLFxuICAneGxpbms6dGl0bGUnOiAneGxpbmtUaXRsZScsXG4gIHhsaW5rdHlwZTogJ3hsaW5rVHlwZScsXG4gICd4bGluazp0eXBlJzogJ3hsaW5rVHlwZScsXG4gIHhtbGJhc2U6ICd4bWxCYXNlJyxcbiAgJ3htbDpiYXNlJzogJ3htbEJhc2UnLFxuICB4bWxsYW5nOiAneG1sTGFuZycsXG4gICd4bWw6bGFuZyc6ICd4bWxMYW5nJyxcbiAgeG1sbnM6ICd4bWxucycsXG4gICd4bWw6c3BhY2UnOiAneG1sU3BhY2UnLFxuICB4bWxuc3hsaW5rOiAneG1sbnNYbGluaycsXG4gICd4bWxuczp4bGluayc6ICd4bWxuc1hsaW5rJyxcbiAgeG1sc3BhY2U6ICd4bWxTcGFjZScsXG4gIHkxOiAneTEnLFxuICB5MjogJ3kyJyxcbiAgeTogJ3knLFxuICB5Y2hhbm5lbHNlbGVjdG9yOiAneUNoYW5uZWxTZWxlY3RvcicsXG4gIHo6ICd6JyxcbiAgem9vbWFuZHBhbjogJ3pvb21BbmRQYW4nXG59O1xuXG52YXIgYXJpYVByb3BlcnRpZXMgPSB7XG4gICdhcmlhLWN1cnJlbnQnOiAwLFxuICAvLyBzdGF0ZVxuICAnYXJpYS1kZXNjcmlwdGlvbic6IDAsXG4gICdhcmlhLWRldGFpbHMnOiAwLFxuICAnYXJpYS1kaXNhYmxlZCc6IDAsXG4gIC8vIHN0YXRlXG4gICdhcmlhLWhpZGRlbic6IDAsXG4gIC8vIHN0YXRlXG4gICdhcmlhLWludmFsaWQnOiAwLFxuICAvLyBzdGF0ZVxuICAnYXJpYS1rZXlzaG9ydGN1dHMnOiAwLFxuICAnYXJpYS1sYWJlbCc6IDAsXG4gICdhcmlhLXJvbGVkZXNjcmlwdGlvbic6IDAsXG4gIC8vIFdpZGdldCBBdHRyaWJ1dGVzXG4gICdhcmlhLWF1dG9jb21wbGV0ZSc6IDAsXG4gICdhcmlhLWNoZWNrZWQnOiAwLFxuICAnYXJpYS1leHBhbmRlZCc6IDAsXG4gICdhcmlhLWhhc3BvcHVwJzogMCxcbiAgJ2FyaWEtbGV2ZWwnOiAwLFxuICAnYXJpYS1tb2RhbCc6IDAsXG4gICdhcmlhLW11bHRpbGluZSc6IDAsXG4gICdhcmlhLW11bHRpc2VsZWN0YWJsZSc6IDAsXG4gICdhcmlhLW9yaWVudGF0aW9uJzogMCxcbiAgJ2FyaWEtcGxhY2Vob2xkZXInOiAwLFxuICAnYXJpYS1wcmVzc2VkJzogMCxcbiAgJ2FyaWEtcmVhZG9ubHknOiAwLFxuICAnYXJpYS1yZXF1aXJlZCc6IDAsXG4gICdhcmlhLXNlbGVjdGVkJzogMCxcbiAgJ2FyaWEtc29ydCc6IDAsXG4gICdhcmlhLXZhbHVlbWF4JzogMCxcbiAgJ2FyaWEtdmFsdWVtaW4nOiAwLFxuICAnYXJpYS12YWx1ZW5vdyc6IDAsXG4gICdhcmlhLXZhbHVldGV4dCc6IDAsXG4gIC8vIExpdmUgUmVnaW9uIEF0dHJpYnV0ZXNcbiAgJ2FyaWEtYXRvbWljJzogMCxcbiAgJ2FyaWEtYnVzeSc6IDAsXG4gICdhcmlhLWxpdmUnOiAwLFxuICAnYXJpYS1yZWxldmFudCc6IDAsXG4gIC8vIERyYWctYW5kLURyb3AgQXR0cmlidXRlc1xuICAnYXJpYS1kcm9wZWZmZWN0JzogMCxcbiAgJ2FyaWEtZ3JhYmJlZCc6IDAsXG4gIC8vIFJlbGF0aW9uc2hpcCBBdHRyaWJ1dGVzXG4gICdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnOiAwLFxuICAnYXJpYS1jb2xjb3VudCc6IDAsXG4gICdhcmlhLWNvbGluZGV4JzogMCxcbiAgJ2FyaWEtY29sc3Bhbic6IDAsXG4gICdhcmlhLWNvbnRyb2xzJzogMCxcbiAgJ2FyaWEtZGVzY3JpYmVkYnknOiAwLFxuICAnYXJpYS1lcnJvcm1lc3NhZ2UnOiAwLFxuICAnYXJpYS1mbG93dG8nOiAwLFxuICAnYXJpYS1sYWJlbGxlZGJ5JzogMCxcbiAgJ2FyaWEtb3ducyc6IDAsXG4gICdhcmlhLXBvc2luc2V0JzogMCxcbiAgJ2FyaWEtcm93Y291bnQnOiAwLFxuICAnYXJpYS1yb3dpbmRleCc6IDAsXG4gICdhcmlhLXJvd3NwYW4nOiAwLFxuICAnYXJpYS1zZXRzaXplJzogMFxufTtcblxudmFyIHdhcm5lZFByb3BlcnRpZXMgPSB7fTtcbnZhciByQVJJQSA9IG5ldyBSZWdFeHAoJ14oYXJpYSktWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xudmFyIHJBUklBQ2FtZWwgPSBuZXcgUmVnRXhwKCdeKGFyaWEpW0EtWl1bJyArIEFUVFJJQlVURV9OQU1FX0NIQVIgKyAnXSokJyk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcGVydHkodGFnTmFtZSwgbmFtZSkge1xuICB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwod2FybmVkUHJvcGVydGllcywgbmFtZSkgJiYgd2FybmVkUHJvcGVydGllc1tuYW1lXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHJBUklBQ2FtZWwudGVzdChuYW1lKSkge1xuICAgICAgdmFyIGFyaWFOYW1lID0gJ2FyaWEtJyArIG5hbWUuc2xpY2UoNCkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhciBjb3JyZWN0TmFtZSA9IGFyaWFQcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KGFyaWFOYW1lKSA/IGFyaWFOYW1lIDogbnVsbDsgLy8gSWYgdGhpcyBpcyBhbiBhcmlhLSogYXR0cmlidXRlLCBidXQgaXMgbm90IGxpc3RlZCBpbiB0aGUga25vd24gRE9NXG4gICAgICAvLyBET00gcHJvcGVydGllcywgdGhlbiBpdCBpcyBhbiBpbnZhbGlkIGFyaWEtKiBhdHRyaWJ1dGUuXG5cbiAgICAgIGlmIChjb3JyZWN0TmFtZSA9PSBudWxsKSB7XG4gICAgICAgIGVycm9yKCdJbnZhbGlkIEFSSUEgYXR0cmlidXRlIGAlc2AuIEFSSUEgYXR0cmlidXRlcyBmb2xsb3cgdGhlIHBhdHRlcm4gYXJpYS0qIGFuZCBtdXN0IGJlIGxvd2VyY2FzZS4nLCBuYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IC8vIGFyaWEtKiBhdHRyaWJ1dGVzIHNob3VsZCBiZSBsb3dlcmNhc2U7IHN1Z2dlc3QgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uLlxuXG5cbiAgICAgIGlmIChuYW1lICE9PSBjb3JyZWN0TmFtZSkge1xuICAgICAgICBlcnJvcignSW52YWxpZCBBUklBIGF0dHJpYnV0ZSBgJXNgLiBEaWQgeW91IG1lYW4gYCVzYD8nLCBuYW1lLCBjb3JyZWN0TmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyQVJJQS50ZXN0KG5hbWUpKSB7XG4gICAgICB2YXIgbG93ZXJDYXNlZE5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICB2YXIgc3RhbmRhcmROYW1lID0gYXJpYVByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkobG93ZXJDYXNlZE5hbWUpID8gbG93ZXJDYXNlZE5hbWUgOiBudWxsOyAvLyBJZiB0aGlzIGlzIGFuIGFyaWEtKiBhdHRyaWJ1dGUsIGJ1dCBpcyBub3QgbGlzdGVkIGluIHRoZSBrbm93biBET01cbiAgICAgIC8vIERPTSBwcm9wZXJ0aWVzLCB0aGVuIGl0IGlzIGFuIGludmFsaWQgYXJpYS0qIGF0dHJpYnV0ZS5cblxuICAgICAgaWYgKHN0YW5kYXJkTmFtZSA9PSBudWxsKSB7XG4gICAgICAgIHdhcm5lZFByb3BlcnRpZXNbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9IC8vIGFyaWEtKiBhdHRyaWJ1dGVzIHNob3VsZCBiZSBsb3dlcmNhc2U7IHN1Z2dlc3QgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uLlxuXG5cbiAgICAgIGlmIChuYW1lICE9PSBzdGFuZGFyZE5hbWUpIHtcbiAgICAgICAgZXJyb3IoJ1Vua25vd24gQVJJQSBhdHRyaWJ1dGUgYCVzYC4gRGlkIHlvdSBtZWFuIGAlc2A/JywgbmFtZSwgc3RhbmRhcmROYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHdhcm5JbnZhbGlkQVJJQVByb3BzKHR5cGUsIHByb3BzKSB7XG4gIHtcbiAgICB2YXIgaW52YWxpZFByb3BzID0gW107XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gcHJvcHMpIHtcbiAgICAgIHZhciBpc1ZhbGlkID0gdmFsaWRhdGVQcm9wZXJ0eSh0eXBlLCBrZXkpO1xuXG4gICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgaW52YWxpZFByb3BzLnB1c2goa2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdW5rbm93blByb3BTdHJpbmcgPSBpbnZhbGlkUHJvcHMubWFwKGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICByZXR1cm4gJ2AnICsgcHJvcCArICdgJztcbiAgICB9KS5qb2luKCcsICcpO1xuXG4gICAgaWYgKGludmFsaWRQcm9wcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIGFyaWEgcHJvcCAlcyBvbiA8JXM+IHRhZy4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWFyaWEtcHJvcHMnLCB1bmtub3duUHJvcFN0cmluZywgdHlwZSk7XG4gICAgfSBlbHNlIGlmIChpbnZhbGlkUHJvcHMubGVuZ3RoID4gMSkge1xuICAgICAgZXJyb3IoJ0ludmFsaWQgYXJpYSBwcm9wcyAlcyBvbiA8JXM+IHRhZy4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWFyaWEtcHJvcHMnLCB1bmtub3duUHJvcFN0cmluZywgdHlwZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcGVydGllcyh0eXBlLCBwcm9wcykge1xuICBpZiAoaXNDdXN0b21Db21wb25lbnQodHlwZSwgcHJvcHMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgd2FybkludmFsaWRBUklBUHJvcHModHlwZSwgcHJvcHMpO1xufVxuXG52YXIgZGlkV2FyblZhbHVlTnVsbCA9IGZhbHNlO1xuZnVuY3Rpb24gdmFsaWRhdGVQcm9wZXJ0aWVzJDEodHlwZSwgcHJvcHMpIHtcbiAge1xuICAgIGlmICh0eXBlICE9PSAnaW5wdXQnICYmIHR5cGUgIT09ICd0ZXh0YXJlYScgJiYgdHlwZSAhPT0gJ3NlbGVjdCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMgIT0gbnVsbCAmJiBwcm9wcy52YWx1ZSA9PT0gbnVsbCAmJiAhZGlkV2FyblZhbHVlTnVsbCkge1xuICAgICAgZGlkV2FyblZhbHVlTnVsbCA9IHRydWU7XG5cbiAgICAgIGlmICh0eXBlID09PSAnc2VsZWN0JyAmJiBwcm9wcy5tdWx0aXBsZSkge1xuICAgICAgICBlcnJvcignYHZhbHVlYCBwcm9wIG9uIGAlc2Agc2hvdWxkIG5vdCBiZSBudWxsLiAnICsgJ0NvbnNpZGVyIHVzaW5nIGFuIGVtcHR5IGFycmF5IHdoZW4gYG11bHRpcGxlYCBpcyBzZXQgdG8gYHRydWVgICcgKyAndG8gY2xlYXIgdGhlIGNvbXBvbmVudCBvciBgdW5kZWZpbmVkYCBmb3IgdW5jb250cm9sbGVkIGNvbXBvbmVudHMuJywgdHlwZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcignYHZhbHVlYCBwcm9wIG9uIGAlc2Agc2hvdWxkIG5vdCBiZSBudWxsLiAnICsgJ0NvbnNpZGVyIHVzaW5nIGFuIGVtcHR5IHN0cmluZyB0byBjbGVhciB0aGUgY29tcG9uZW50IG9yIGB1bmRlZmluZWRgICcgKyAnZm9yIHVuY29udHJvbGxlZCBjb21wb25lbnRzLicsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG52YXIgdmFsaWRhdGVQcm9wZXJ0eSQxID0gZnVuY3Rpb24gKCkge307XG5cbntcbiAgdmFyIHdhcm5lZFByb3BlcnRpZXMkMSA9IHt9O1xuICB2YXIgRVZFTlRfTkFNRV9SRUdFWCA9IC9eb24uLztcbiAgdmFyIElOVkFMSURfRVZFTlRfTkFNRV9SRUdFWCA9IC9eb25bXkEtWl0vO1xuICB2YXIgckFSSUEkMSA9IG5ldyBSZWdFeHAoJ14oYXJpYSktWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xuICB2YXIgckFSSUFDYW1lbCQxID0gbmV3IFJlZ0V4cCgnXihhcmlhKVtBLVpdWycgKyBBVFRSSUJVVEVfTkFNRV9DSEFSICsgJ10qJCcpO1xuXG4gIHZhbGlkYXRlUHJvcGVydHkkMSA9IGZ1bmN0aW9uICh0YWdOYW1lLCBuYW1lLCB2YWx1ZSwgZXZlbnRSZWdpc3RyeSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHdhcm5lZFByb3BlcnRpZXMkMSwgbmFtZSkgJiYgd2FybmVkUHJvcGVydGllcyQxW25hbWVdKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgbG93ZXJDYXNlZE5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobG93ZXJDYXNlZE5hbWUgPT09ICdvbmZvY3VzaW4nIHx8IGxvd2VyQ2FzZWROYW1lID09PSAnb25mb2N1c291dCcpIHtcbiAgICAgIGVycm9yKCdSZWFjdCB1c2VzIG9uRm9jdXMgYW5kIG9uQmx1ciBpbnN0ZWFkIG9mIG9uRm9jdXNJbiBhbmQgb25Gb2N1c091dC4gJyArICdBbGwgUmVhY3QgZXZlbnRzIGFyZSBub3JtYWxpemVkIHRvIGJ1YmJsZSwgc28gb25Gb2N1c0luIGFuZCBvbkZvY3VzT3V0ICcgKyAnYXJlIG5vdCBuZWVkZWQvc3VwcG9ydGVkIGJ5IFJlYWN0LicpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSAvLyBXZSBjYW4ndCByZWx5IG9uIHRoZSBldmVudCBzeXN0ZW0gYmVpbmcgaW5qZWN0ZWQgb24gdGhlIHNlcnZlci5cblxuXG4gICAgaWYgKGV2ZW50UmVnaXN0cnkgIT0gbnVsbCkge1xuICAgICAgdmFyIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMgPSBldmVudFJlZ2lzdHJ5LnJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMsXG4gICAgICAgICAgcG9zc2libGVSZWdpc3RyYXRpb25OYW1lcyA9IGV2ZW50UmVnaXN0cnkucG9zc2libGVSZWdpc3RyYXRpb25OYW1lcztcblxuICAgICAgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWdpc3RyYXRpb25OYW1lID0gcG9zc2libGVSZWdpc3RyYXRpb25OYW1lcy5oYXNPd25Qcm9wZXJ0eShsb3dlckNhc2VkTmFtZSkgPyBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzW2xvd2VyQ2FzZWROYW1lXSA6IG51bGw7XG5cbiAgICAgIGlmIChyZWdpc3RyYXRpb25OYW1lICE9IG51bGwpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgZXZlbnQgaGFuZGxlciBwcm9wZXJ0eSBgJXNgLiBEaWQgeW91IG1lYW4gYCVzYD8nLCBuYW1lLCByZWdpc3RyYXRpb25OYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKEVWRU5UX05BTUVfUkVHRVgudGVzdChuYW1lKSkge1xuICAgICAgICBlcnJvcignVW5rbm93biBldmVudCBoYW5kbGVyIHByb3BlcnR5IGAlc2AuIEl0IHdpbGwgYmUgaWdub3JlZC4nLCBuYW1lKTtcblxuICAgICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKEVWRU5UX05BTUVfUkVHRVgudGVzdChuYW1lKSkge1xuICAgICAgLy8gSWYgbm8gZXZlbnQgcGx1Z2lucyBoYXZlIGJlZW4gaW5qZWN0ZWQsIHdlIGFyZSBpbiBhIHNlcnZlciBlbnZpcm9ubWVudC5cbiAgICAgIC8vIFNvIHdlIGNhbid0IHRlbGwgaWYgdGhlIGV2ZW50IG5hbWUgaXMgY29ycmVjdCBmb3Igc3VyZSwgYnV0IHdlIGNhbiBmaWx0ZXJcbiAgICAgIC8vIG91dCBrbm93biBiYWQgb25lcyBsaWtlIGBvbmNsaWNrYC4gV2UgY2FuJ3Qgc3VnZ2VzdCBhIHNwZWNpZmljIHJlcGxhY2VtZW50IHRob3VnaC5cbiAgICAgIGlmIChJTlZBTElEX0VWRU5UX05BTUVfUkVHRVgudGVzdChuYW1lKSkge1xuICAgICAgICBlcnJvcignSW52YWxpZCBldmVudCBoYW5kbGVyIHByb3BlcnR5IGAlc2AuICcgKyAnUmVhY3QgZXZlbnRzIHVzZSB0aGUgY2FtZWxDYXNlIG5hbWluZyBjb252ZW50aW9uLCBmb3IgZXhhbXBsZSBgb25DbGlja2AuJywgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IC8vIExldCB0aGUgQVJJQSBhdHRyaWJ1dGUgaG9vayB2YWxpZGF0ZSBBUklBIGF0dHJpYnV0ZXNcblxuXG4gICAgaWYgKHJBUklBJDEudGVzdChuYW1lKSB8fCByQVJJQUNhbWVsJDEudGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGxvd2VyQ2FzZWROYW1lID09PSAnaW5uZXJodG1sJykge1xuICAgICAgZXJyb3IoJ0RpcmVjdGx5IHNldHRpbmcgcHJvcGVydHkgYGlubmVySFRNTGAgaXMgbm90IHBlcm1pdHRlZC4gJyArICdGb3IgbW9yZSBpbmZvcm1hdGlvbiwgbG9va3VwIGRvY3VtZW50YXRpb24gb24gYGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MYC4nKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChsb3dlckNhc2VkTmFtZSA9PT0gJ2FyaWEnKSB7XG4gICAgICBlcnJvcignVGhlIGBhcmlhYCBhdHRyaWJ1dGUgaXMgcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UgaW4gUmVhY3QuICcgKyAnUGFzcyBpbmRpdmlkdWFsIGBhcmlhLWAgYXR0cmlidXRlcyBpbnN0ZWFkLicpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGxvd2VyQ2FzZWROYW1lID09PSAnaXMnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIGEgYCVzYCBmb3IgYSBzdHJpbmcgYXR0cmlidXRlIGBpc2AuIElmIHRoaXMgaXMgZXhwZWN0ZWQsIGNhc3QgJyArICd0aGUgdmFsdWUgdG8gYSBzdHJpbmcuJywgdHlwZW9mIHZhbHVlKTtcblxuICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIGlzTmFOKHZhbHVlKSkge1xuICAgICAgZXJyb3IoJ1JlY2VpdmVkIE5hTiBmb3IgdGhlIGAlc2AgYXR0cmlidXRlLiBJZiB0aGlzIGlzIGV4cGVjdGVkLCBjYXN0ICcgKyAndGhlIHZhbHVlIHRvIGEgc3RyaW5nLicsIG5hbWUpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHByb3BlcnR5SW5mbyA9IGdldFByb3BlcnR5SW5mbyhuYW1lKTtcbiAgICB2YXIgaXNSZXNlcnZlZCA9IHByb3BlcnR5SW5mbyAhPT0gbnVsbCAmJiBwcm9wZXJ0eUluZm8udHlwZSA9PT0gUkVTRVJWRUQ7IC8vIEtub3duIGF0dHJpYnV0ZXMgc2hvdWxkIG1hdGNoIHRoZSBjYXNpbmcgc3BlY2lmaWVkIGluIHRoZSBwcm9wZXJ0eSBjb25maWcuXG5cbiAgICBpZiAocG9zc2libGVTdGFuZGFyZE5hbWVzLmhhc093blByb3BlcnR5KGxvd2VyQ2FzZWROYW1lKSkge1xuICAgICAgdmFyIHN0YW5kYXJkTmFtZSA9IHBvc3NpYmxlU3RhbmRhcmROYW1lc1tsb3dlckNhc2VkTmFtZV07XG5cbiAgICAgIGlmIChzdGFuZGFyZE5hbWUgIT09IG5hbWUpIHtcbiAgICAgICAgZXJyb3IoJ0ludmFsaWQgRE9NIHByb3BlcnR5IGAlc2AuIERpZCB5b3UgbWVhbiBgJXNgPycsIG5hbWUsIHN0YW5kYXJkTmFtZSk7XG5cbiAgICAgICAgd2FybmVkUHJvcGVydGllcyQxW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaXNSZXNlcnZlZCAmJiBuYW1lICE9PSBsb3dlckNhc2VkTmFtZSkge1xuICAgICAgLy8gVW5rbm93biBhdHRyaWJ1dGVzIHNob3VsZCBoYXZlIGxvd2VyY2FzZSBjYXNpbmcgc2luY2UgdGhhdCdzIGhvdyB0aGV5XG4gICAgICAvLyB3aWxsIGJlIGNhc2VkIGFueXdheSB3aXRoIHNlcnZlciByZW5kZXJpbmcuXG4gICAgICBlcnJvcignUmVhY3QgZG9lcyBub3QgcmVjb2duaXplIHRoZSBgJXNgIHByb3Agb24gYSBET00gZWxlbWVudC4gSWYgeW91ICcgKyAnaW50ZW50aW9uYWxseSB3YW50IGl0IHRvIGFwcGVhciBpbiB0aGUgRE9NIGFzIGEgY3VzdG9tICcgKyAnYXR0cmlidXRlLCBzcGVsbCBpdCBhcyBsb3dlcmNhc2UgYCVzYCBpbnN0ZWFkLiAnICsgJ0lmIHlvdSBhY2NpZGVudGFsbHkgcGFzc2VkIGl0IGZyb20gYSBwYXJlbnQgY29tcG9uZW50LCByZW1vdmUgJyArICdpdCBmcm9tIHRoZSBET00gZWxlbWVudC4nLCBuYW1lLCBsb3dlckNhc2VkTmFtZSk7XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicgJiYgc2hvdWxkUmVtb3ZlQXR0cmlidXRlV2l0aFdhcm5pbmcobmFtZSwgdmFsdWUsIHByb3BlcnR5SW5mbywgZmFsc2UpKSB7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZXJyb3IoJ1JlY2VpdmVkIGAlc2AgZm9yIGEgbm9uLWJvb2xlYW4gYXR0cmlidXRlIGAlc2AuXFxuXFxuJyArICdJZiB5b3Ugd2FudCB0byB3cml0ZSBpdCB0byB0aGUgRE9NLCBwYXNzIGEgc3RyaW5nIGluc3RlYWQ6ICcgKyAnJXM9XCIlc1wiIG9yICVzPXt2YWx1ZS50b1N0cmluZygpfS4nLCB2YWx1ZSwgbmFtZSwgbmFtZSwgdmFsdWUsIG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IoJ1JlY2VpdmVkIGAlc2AgZm9yIGEgbm9uLWJvb2xlYW4gYXR0cmlidXRlIGAlc2AuXFxuXFxuJyArICdJZiB5b3Ugd2FudCB0byB3cml0ZSBpdCB0byB0aGUgRE9NLCBwYXNzIGEgc3RyaW5nIGluc3RlYWQ6ICcgKyAnJXM9XCIlc1wiIG9yICVzPXt2YWx1ZS50b1N0cmluZygpfS5cXG5cXG4nICsgJ0lmIHlvdSB1c2VkIHRvIGNvbmRpdGlvbmFsbHkgb21pdCBpdCB3aXRoICVzPXtjb25kaXRpb24gJiYgdmFsdWV9LCAnICsgJ3Bhc3MgJXM9e2NvbmRpdGlvbiA/IHZhbHVlIDogdW5kZWZpbmVkfSBpbnN0ZWFkLicsIHZhbHVlLCBuYW1lLCBuYW1lLCB2YWx1ZSwgbmFtZSwgbmFtZSwgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IC8vIE5vdyB0aGF0IHdlJ3ZlIHZhbGlkYXRlZCBjYXNpbmcsIGRvIG5vdCB2YWxpZGF0ZVxuICAgIC8vIGRhdGEgdHlwZXMgZm9yIHJlc2VydmVkIHByb3BzXG5cblxuICAgIGlmIChpc1Jlc2VydmVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IC8vIFdhcm4gd2hlbiBhIGtub3duIGF0dHJpYnV0ZSBpcyBhIGJhZCB0eXBlXG5cblxuICAgIGlmIChzaG91bGRSZW1vdmVBdHRyaWJ1dGVXaXRoV2FybmluZyhuYW1lLCB2YWx1ZSwgcHJvcGVydHlJbmZvLCBmYWxzZSkpIHtcbiAgICAgIHdhcm5lZFByb3BlcnRpZXMkMVtuYW1lXSA9IHRydWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBXYXJuIHdoZW4gcGFzc2luZyB0aGUgc3RyaW5ncyAnZmFsc2UnIG9yICd0cnVlJyBpbnRvIGEgYm9vbGVhbiBwcm9wXG5cblxuICAgIGlmICgodmFsdWUgPT09ICdmYWxzZScgfHwgdmFsdWUgPT09ICd0cnVlJykgJiYgcHJvcGVydHlJbmZvICE9PSBudWxsICYmIHByb3BlcnR5SW5mby50eXBlID09PSBCT09MRUFOKSB7XG4gICAgICBlcnJvcignUmVjZWl2ZWQgdGhlIHN0cmluZyBgJXNgIGZvciB0aGUgYm9vbGVhbiBhdHRyaWJ1dGUgYCVzYC4gJyArICclcyAnICsgJ0RpZCB5b3UgbWVhbiAlcz17JXN9PycsIHZhbHVlLCBuYW1lLCB2YWx1ZSA9PT0gJ2ZhbHNlJyA/ICdUaGUgYnJvd3NlciB3aWxsIGludGVycHJldCBpdCBhcyBhIHRydXRoeSB2YWx1ZS4nIDogJ0FsdGhvdWdoIHRoaXMgd29ya3MsIGl0IHdpbGwgbm90IHdvcmsgYXMgZXhwZWN0ZWQgaWYgeW91IHBhc3MgdGhlIHN0cmluZyBcImZhbHNlXCIuJywgbmFtZSwgdmFsdWUpO1xuXG4gICAgICB3YXJuZWRQcm9wZXJ0aWVzJDFbbmFtZV0gPSB0cnVlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbnZhciB3YXJuVW5rbm93blByb3BlcnRpZXMgPSBmdW5jdGlvbiAodHlwZSwgcHJvcHMsIGV2ZW50UmVnaXN0cnkpIHtcbiAge1xuICAgIHZhciB1bmtub3duUHJvcHMgPSBbXTtcblxuICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgdmFyIGlzVmFsaWQgPSB2YWxpZGF0ZVByb3BlcnR5JDEodHlwZSwga2V5LCBwcm9wc1trZXldLCBldmVudFJlZ2lzdHJ5KTtcblxuICAgICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgIHVua25vd25Qcm9wcy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHVua25vd25Qcm9wU3RyaW5nID0gdW5rbm93blByb3BzLm1hcChmdW5jdGlvbiAocHJvcCkge1xuICAgICAgcmV0dXJuICdgJyArIHByb3AgKyAnYCc7XG4gICAgfSkuam9pbignLCAnKTtcblxuICAgIGlmICh1bmtub3duUHJvcHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBlcnJvcignSW52YWxpZCB2YWx1ZSBmb3IgcHJvcCAlcyBvbiA8JXM+IHRhZy4gRWl0aGVyIHJlbW92ZSBpdCBmcm9tIHRoZSBlbGVtZW50LCAnICsgJ29yIHBhc3MgYSBzdHJpbmcgb3IgbnVtYmVyIHZhbHVlIHRvIGtlZXAgaXQgaW4gdGhlIERPTS4gJyArICdGb3IgZGV0YWlscywgc2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9hdHRyaWJ1dGUtYmVoYXZpb3IgJywgdW5rbm93blByb3BTdHJpbmcsIHR5cGUpO1xuICAgIH0gZWxzZSBpZiAodW5rbm93blByb3BzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGVycm9yKCdJbnZhbGlkIHZhbHVlcyBmb3IgcHJvcHMgJXMgb24gPCVzPiB0YWcuIEVpdGhlciByZW1vdmUgdGhlbSBmcm9tIHRoZSBlbGVtZW50LCAnICsgJ29yIHBhc3MgYSBzdHJpbmcgb3IgbnVtYmVyIHZhbHVlIHRvIGtlZXAgdGhlbSBpbiB0aGUgRE9NLiAnICsgJ0ZvciBkZXRhaWxzLCBzZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL2F0dHJpYnV0ZS1iZWhhdmlvciAnLCB1bmtub3duUHJvcFN0cmluZywgdHlwZSk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3BlcnRpZXMkMih0eXBlLCBwcm9wcywgZXZlbnRSZWdpc3RyeSkge1xuICBpZiAoaXNDdXN0b21Db21wb25lbnQodHlwZSwgcHJvcHMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgd2FyblVua25vd25Qcm9wZXJ0aWVzKHR5cGUsIHByb3BzLCBldmVudFJlZ2lzdHJ5KTtcbn1cblxudmFyIElTX0VWRU5UX0hBTkRMRV9OT05fTUFOQUdFRF9OT0RFID0gMTtcbnZhciBJU19OT05fREVMRUdBVEVEID0gMSA8PCAxO1xudmFyIElTX0NBUFRVUkVfUEhBU0UgPSAxIDw8IDI7XG4vLyBzZXQgdG8gTEVHQUNZX0ZCX1NVUFBPUlQuIExFR0FDWV9GQl9TVVBQT1JUIG9ubHkgZ2V0cyBzZXQgd2hlblxuLy8gd2UgY2FsbCB3aWxsRGVmZXJMYXRlckZvckxlZ2FjeUZCU3VwcG9ydCwgdGh1cyBub3QgYmFpbGluZyBvdXRcbi8vIHdpbGwgcmVzdWx0IGluIGVuZGxlc3MgY3ljbGVzIGxpa2UgYW4gaW5maW5pdGUgbG9vcC5cbi8vIFdlIGFsc28gZG9uJ3Qgd2FudCB0byBkZWZlciBkdXJpbmcgZXZlbnQgcmVwbGF5aW5nLlxuXG52YXIgU0hPVUxEX05PVF9QUk9DRVNTX1BPTFlGSUxMX0VWRU5UX1BMVUdJTlMgPSBJU19FVkVOVF9IQU5ETEVfTk9OX01BTkFHRURfTk9ERSB8IElTX05PTl9ERUxFR0FURUQgfCBJU19DQVBUVVJFX1BIQVNFO1xuXG4vLyBUaGlzIGV4aXN0cyB0byBhdm9pZCBjaXJjdWxhciBkZXBlbmRlbmN5IGJldHdlZW4gUmVhY3RET01FdmVudFJlcGxheWluZ1xuLy8gYW5kIERPTVBsdWdpbkV2ZW50U3lzdGVtLlxudmFyIGN1cnJlbnRSZXBsYXlpbmdFdmVudCA9IG51bGw7XG5mdW5jdGlvbiBzZXRSZXBsYXlpbmdFdmVudChldmVudCkge1xuICB7XG4gICAgaWYgKGN1cnJlbnRSZXBsYXlpbmdFdmVudCAhPT0gbnVsbCkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIGN1cnJlbnRseSByZXBsYXlpbmcgZXZlbnQgdG8gYmUgbnVsbC4gVGhpcyBlcnJvciAnICsgJ2lzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGN1cnJlbnRSZXBsYXlpbmdFdmVudCA9IGV2ZW50O1xufVxuZnVuY3Rpb24gcmVzZXRSZXBsYXlpbmdFdmVudCgpIHtcbiAge1xuICAgIGlmIChjdXJyZW50UmVwbGF5aW5nRXZlbnQgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCBjdXJyZW50bHkgcmVwbGF5aW5nIGV2ZW50IHRvIG5vdCBiZSBudWxsLiBUaGlzIGVycm9yICcgKyAnaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgY3VycmVudFJlcGxheWluZ0V2ZW50ID0gbnVsbDtcbn1cbmZ1bmN0aW9uIGlzUmVwbGF5aW5nRXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIGV2ZW50ID09PSBjdXJyZW50UmVwbGF5aW5nRXZlbnQ7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgdGFyZ2V0IG5vZGUgZnJvbSBhIG5hdGl2ZSBicm93c2VyIGV2ZW50IGJ5IGFjY291bnRpbmcgZm9yXG4gKiBpbmNvbnNpc3RlbmNpZXMgaW4gYnJvd3NlciBET00gQVBJcy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtET01FdmVudFRhcmdldH0gVGFyZ2V0IG5vZGUuXG4gKi9cblxuZnVuY3Rpb24gZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpIHtcbiAgLy8gRmFsbGJhY2sgdG8gbmF0aXZlRXZlbnQuc3JjRWxlbWVudCBmb3IgSUU5XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTI1MDZcbiAgdmFyIHRhcmdldCA9IG5hdGl2ZUV2ZW50LnRhcmdldCB8fCBuYXRpdmVFdmVudC5zcmNFbGVtZW50IHx8IHdpbmRvdzsgLy8gTm9ybWFsaXplIFNWRyA8dXNlPiBlbGVtZW50IGV2ZW50cyAjNDk2M1xuXG4gIGlmICh0YXJnZXQuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQpIHtcbiAgICB0YXJnZXQgPSB0YXJnZXQuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQ7XG4gIH0gLy8gU2FmYXJpIG1heSBmaXJlIGV2ZW50cyBvbiB0ZXh0IG5vZGVzIChOb2RlLlRFWFRfTk9ERSBpcyAzKS5cbiAgLy8gQHNlZSBodHRwOi8vd3d3LnF1aXJrc21vZGUub3JnL2pzL2V2ZW50c19wcm9wZXJ0aWVzLmh0bWxcblxuXG4gIHJldHVybiB0YXJnZXQubm9kZVR5cGUgPT09IFRFWFRfTk9ERSA/IHRhcmdldC5wYXJlbnROb2RlIDogdGFyZ2V0O1xufVxuXG52YXIgcmVzdG9yZUltcGwgPSBudWxsO1xudmFyIHJlc3RvcmVUYXJnZXQgPSBudWxsO1xudmFyIHJlc3RvcmVRdWV1ZSA9IG51bGw7XG5cbmZ1bmN0aW9uIHJlc3RvcmVTdGF0ZU9mVGFyZ2V0KHRhcmdldCkge1xuICAvLyBXZSBwZXJmb3JtIHRoaXMgdHJhbnNsYXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgZXZlbnQgbG9vcCBzbyB0aGF0IHdlXG4gIC8vIGFsd2F5cyByZWNlaXZlIHRoZSBjb3JyZWN0IGZpYmVyIGhlcmVcbiAgdmFyIGludGVybmFsSW5zdGFuY2UgPSBnZXRJbnN0YW5jZUZyb21Ob2RlKHRhcmdldCk7XG5cbiAgaWYgKCFpbnRlcm5hbEluc3RhbmNlKSB7XG4gICAgLy8gVW5tb3VudGVkXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHR5cGVvZiByZXN0b3JlSW1wbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0UmVzdG9yZUltcGxlbWVudGF0aW9uKCkgbmVlZHMgdG8gYmUgY2FsbGVkIHRvIGhhbmRsZSBhIHRhcmdldCBmb3IgY29udHJvbGxlZCAnICsgJ2V2ZW50cy4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHZhciBzdGF0ZU5vZGUgPSBpbnRlcm5hbEluc3RhbmNlLnN0YXRlTm9kZTsgLy8gR3VhcmQgYWdhaW5zdCBGaWJlciBiZWluZyB1bm1vdW50ZWQuXG5cbiAgaWYgKHN0YXRlTm9kZSkge1xuICAgIHZhciBfcHJvcHMgPSBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKHN0YXRlTm9kZSk7XG5cbiAgICByZXN0b3JlSW1wbChpbnRlcm5hbEluc3RhbmNlLnN0YXRlTm9kZSwgaW50ZXJuYWxJbnN0YW5jZS50eXBlLCBfcHJvcHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldFJlc3RvcmVJbXBsZW1lbnRhdGlvbihpbXBsKSB7XG4gIHJlc3RvcmVJbXBsID0gaW1wbDtcbn1cbmZ1bmN0aW9uIGVucXVldWVTdGF0ZVJlc3RvcmUodGFyZ2V0KSB7XG4gIGlmIChyZXN0b3JlVGFyZ2V0KSB7XG4gICAgaWYgKHJlc3RvcmVRdWV1ZSkge1xuICAgICAgcmVzdG9yZVF1ZXVlLnB1c2godGFyZ2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdG9yZVF1ZXVlID0gW3RhcmdldF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJlc3RvcmVUYXJnZXQgPSB0YXJnZXQ7XG4gIH1cbn1cbmZ1bmN0aW9uIG5lZWRzU3RhdGVSZXN0b3JlKCkge1xuICByZXR1cm4gcmVzdG9yZVRhcmdldCAhPT0gbnVsbCB8fCByZXN0b3JlUXVldWUgIT09IG51bGw7XG59XG5mdW5jdGlvbiByZXN0b3JlU3RhdGVJZk5lZWRlZCgpIHtcbiAgaWYgKCFyZXN0b3JlVGFyZ2V0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHRhcmdldCA9IHJlc3RvcmVUYXJnZXQ7XG4gIHZhciBxdWV1ZWRUYXJnZXRzID0gcmVzdG9yZVF1ZXVlO1xuICByZXN0b3JlVGFyZ2V0ID0gbnVsbDtcbiAgcmVzdG9yZVF1ZXVlID0gbnVsbDtcbiAgcmVzdG9yZVN0YXRlT2ZUYXJnZXQodGFyZ2V0KTtcblxuICBpZiAocXVldWVkVGFyZ2V0cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcXVldWVkVGFyZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdG9yZVN0YXRlT2ZUYXJnZXQocXVldWVkVGFyZ2V0c1tpXSk7XG4gICAgfVxuICB9XG59XG5cbi8vIHRoZSByZW5kZXJlci4gU3VjaCBhcyB3aGVuIHdlJ3JlIGRpc3BhdGNoaW5nIGV2ZW50cyBvciBpZiB0aGlyZCBwYXJ0eVxuLy8gbGlicmFyaWVzIG5lZWQgdG8gY2FsbCBiYXRjaGVkVXBkYXRlcy4gRXZlbnR1YWxseSwgdGhpcyBBUEkgd2lsbCBnbyBhd2F5IHdoZW5cbi8vIGV2ZXJ5dGhpbmcgaXMgYmF0Y2hlZCBieSBkZWZhdWx0LiBXZSdsbCB0aGVuIGhhdmUgYSBzaW1pbGFyIEFQSSB0byBvcHQtb3V0IG9mXG4vLyBzY2hlZHVsZWQgd29yayBhbmQgaW5zdGVhZCBkbyBzeW5jaHJvbm91cyB3b3JrLlxuLy8gRGVmYXVsdHNcblxudmFyIGJhdGNoZWRVcGRhdGVzSW1wbCA9IGZ1bmN0aW9uIChmbiwgYm9va2tlZXBpbmcpIHtcbiAgcmV0dXJuIGZuKGJvb2trZWVwaW5nKTtcbn07XG5cbnZhciBmbHVzaFN5bmNJbXBsID0gZnVuY3Rpb24gKCkge307XG5cbnZhciBpc0luc2lkZUV2ZW50SGFuZGxlciA9IGZhbHNlO1xuXG5mdW5jdGlvbiBmaW5pc2hFdmVudEhhbmRsZXIoKSB7XG4gIC8vIEhlcmUgd2Ugd2FpdCB1bnRpbCBhbGwgdXBkYXRlcyBoYXZlIHByb3BhZ2F0ZWQsIHdoaWNoIGlzIGltcG9ydGFudFxuICAvLyB3aGVuIHVzaW5nIGNvbnRyb2xsZWQgY29tcG9uZW50cyB3aXRoaW4gbGF5ZXJzOlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE2OThcbiAgLy8gVGhlbiB3ZSByZXN0b3JlIHN0YXRlIG9mIGFueSBjb250cm9sbGVkIGNvbXBvbmVudC5cbiAgdmFyIGNvbnRyb2xsZWRDb21wb25lbnRzSGF2ZVBlbmRpbmdVcGRhdGVzID0gbmVlZHNTdGF0ZVJlc3RvcmUoKTtcblxuICBpZiAoY29udHJvbGxlZENvbXBvbmVudHNIYXZlUGVuZGluZ1VwZGF0ZXMpIHtcbiAgICAvLyBJZiBhIGNvbnRyb2xsZWQgZXZlbnQgd2FzIGZpcmVkLCB3ZSBtYXkgbmVlZCB0byByZXN0b3JlIHRoZSBzdGF0ZSBvZlxuICAgIC8vIHRoZSBET00gbm9kZSBiYWNrIHRvIHRoZSBjb250cm9sbGVkIHZhbHVlLiBUaGlzIGlzIG5lY2Vzc2FyeSB3aGVuIFJlYWN0XG4gICAgLy8gYmFpbHMgb3V0IG9mIHRoZSB1cGRhdGUgd2l0aG91dCB0b3VjaGluZyB0aGUgRE9NLlxuICAgIC8vIFRPRE86IFJlc3RvcmUgc3RhdGUgaW4gdGhlIG1pY3JvdGFzaywgYWZ0ZXIgdGhlIGRpc2NyZXRlIHVwZGF0ZXMgZmx1c2gsXG4gICAgLy8gaW5zdGVhZCBvZiBlYXJseSBmbHVzaGluZyB0aGVtIGhlcmUuXG4gICAgZmx1c2hTeW5jSW1wbCgpO1xuICAgIHJlc3RvcmVTdGF0ZUlmTmVlZGVkKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYmF0Y2hlZFVwZGF0ZXMoZm4sIGEsIGIpIHtcbiAgaWYgKGlzSW5zaWRlRXZlbnRIYW5kbGVyKSB7XG4gICAgLy8gSWYgd2UgYXJlIGN1cnJlbnRseSBpbnNpZGUgYW5vdGhlciBiYXRjaCwgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0XG4gICAgLy8gZnVsbHkgY29tcGxldGVzIGJlZm9yZSByZXN0b3Jpbmcgc3RhdGUuXG4gICAgcmV0dXJuIGZuKGEsIGIpO1xuICB9XG5cbiAgaXNJbnNpZGVFdmVudEhhbmRsZXIgPSB0cnVlO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGJhdGNoZWRVcGRhdGVzSW1wbChmbiwgYSwgYik7XG4gIH0gZmluYWxseSB7XG4gICAgaXNJbnNpZGVFdmVudEhhbmRsZXIgPSBmYWxzZTtcbiAgICBmaW5pc2hFdmVudEhhbmRsZXIoKTtcbiAgfVxufSAvLyBUT0RPOiBSZXBsYWNlIHdpdGggZmx1c2hTeW5jXG5mdW5jdGlvbiBzZXRCYXRjaGluZ0ltcGxlbWVudGF0aW9uKF9iYXRjaGVkVXBkYXRlc0ltcGwsIF9kaXNjcmV0ZVVwZGF0ZXNJbXBsLCBfZmx1c2hTeW5jSW1wbCkge1xuICBiYXRjaGVkVXBkYXRlc0ltcGwgPSBfYmF0Y2hlZFVwZGF0ZXNJbXBsO1xuICBmbHVzaFN5bmNJbXBsID0gX2ZsdXNoU3luY0ltcGw7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZXJhY3RpdmUodGFnKSB7XG4gIHJldHVybiB0YWcgPT09ICdidXR0b24nIHx8IHRhZyA9PT0gJ2lucHV0JyB8fCB0YWcgPT09ICdzZWxlY3QnIHx8IHRhZyA9PT0gJ3RleHRhcmVhJztcbn1cblxuZnVuY3Rpb24gc2hvdWxkUHJldmVudE1vdXNlRXZlbnQobmFtZSwgdHlwZSwgcHJvcHMpIHtcbiAgc3dpdGNoIChuYW1lKSB7XG4gICAgY2FzZSAnb25DbGljayc6XG4gICAgY2FzZSAnb25DbGlja0NhcHR1cmUnOlxuICAgIGNhc2UgJ29uRG91YmxlQ2xpY2snOlxuICAgIGNhc2UgJ29uRG91YmxlQ2xpY2tDYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlRG93bic6XG4gICAgY2FzZSAnb25Nb3VzZURvd25DYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlTW92ZSc6XG4gICAgY2FzZSAnb25Nb3VzZU1vdmVDYXB0dXJlJzpcbiAgICBjYXNlICdvbk1vdXNlVXAnOlxuICAgIGNhc2UgJ29uTW91c2VVcENhcHR1cmUnOlxuICAgIGNhc2UgJ29uTW91c2VFbnRlcic6XG4gICAgICByZXR1cm4gISEocHJvcHMuZGlzYWJsZWQgJiYgaXNJbnRlcmFjdGl2ZSh0eXBlKSk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7b2JqZWN0fSBpbnN0IFRoZSBpbnN0YW5jZSwgd2hpY2ggaXMgdGhlIHNvdXJjZSBvZiBldmVudHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVnaXN0cmF0aW9uTmFtZSBOYW1lIG9mIGxpc3RlbmVyIChlLmcuIGBvbkNsaWNrYCkuXG4gKiBAcmV0dXJuIHs/ZnVuY3Rpb259IFRoZSBzdG9yZWQgY2FsbGJhY2suXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRMaXN0ZW5lcihpbnN0LCByZWdpc3RyYXRpb25OYW1lKSB7XG4gIHZhciBzdGF0ZU5vZGUgPSBpbnN0LnN0YXRlTm9kZTtcblxuICBpZiAoc3RhdGVOb2RlID09PSBudWxsKSB7XG4gICAgLy8gV29yayBpbiBwcm9ncmVzcyAoZXg6IG9ubG9hZCBldmVudHMgaW4gaW5jcmVtZW50YWwgbW9kZSkuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgcHJvcHMgPSBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlKHN0YXRlTm9kZSk7XG5cbiAgaWYgKHByb3BzID09PSBudWxsKSB7XG4gICAgLy8gV29yayBpbiBwcm9ncmVzcy5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBsaXN0ZW5lciA9IHByb3BzW3JlZ2lzdHJhdGlvbk5hbWVdO1xuXG4gIGlmIChzaG91bGRQcmV2ZW50TW91c2VFdmVudChyZWdpc3RyYXRpb25OYW1lLCBpbnN0LnR5cGUsIHByb3BzKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGxpc3RlbmVyICYmIHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIGBcIiArIHJlZ2lzdHJhdGlvbk5hbWUgKyBcImAgbGlzdGVuZXIgdG8gYmUgYSBmdW5jdGlvbiwgaW5zdGVhZCBnb3QgYSB2YWx1ZSBvZiBgXCIgKyB0eXBlb2YgbGlzdGVuZXIgKyBcImAgdHlwZS5cIik7XG4gIH1cblxuICByZXR1cm4gbGlzdGVuZXI7XG59XG5cbnZhciBwYXNzaXZlQnJvd3NlckV2ZW50c1N1cHBvcnRlZCA9IGZhbHNlOyAvLyBDaGVjayBpZiBicm93c2VyIHN1cHBvcnQgZXZlbnRzIHdpdGggcGFzc2l2ZSBsaXN0ZW5lcnNcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FdmVudFRhcmdldC9hZGRFdmVudExpc3RlbmVyI1NhZmVseV9kZXRlY3Rpbmdfb3B0aW9uX3N1cHBvcnRcblxuaWYgKGNhblVzZURPTSkge1xuICB0cnkge1xuICAgIHZhciBvcHRpb25zID0ge307IC8vICRGbG93Rml4TWU6IElnbm9yZSBGbG93IGNvbXBsYWluaW5nIGFib3V0IG5lZWRpbmcgYSB2YWx1ZVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9wdGlvbnMsICdwYXNzaXZlJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHBhc3NpdmVCcm93c2VyRXZlbnRzU3VwcG9ydGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndGVzdCcsIG9wdGlvbnMsIG9wdGlvbnMpO1xuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCd0ZXN0Jywgb3B0aW9ucywgb3B0aW9ucyk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBwYXNzaXZlQnJvd3NlckV2ZW50c1N1cHBvcnRlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZUd1YXJkZWRDYWxsYmFja1Byb2QobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICB2YXIgZnVuY0FyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDMpO1xuXG4gIHRyeSB7XG4gICAgZnVuYy5hcHBseShjb250ZXh0LCBmdW5jQXJncyk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgdGhpcy5vbkVycm9yKGVycm9yKTtcbiAgfVxufVxuXG52YXIgaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbCA9IGludm9rZUd1YXJkZWRDYWxsYmFja1Byb2Q7XG5cbntcbiAgLy8gSW4gREVWIG1vZGUsIHdlIHN3YXAgb3V0IGludm9rZUd1YXJkZWRDYWxsYmFjayBmb3IgYSBzcGVjaWFsIHZlcnNpb25cbiAgLy8gdGhhdCBwbGF5cyBtb3JlIG5pY2VseSB3aXRoIHRoZSBicm93c2VyJ3MgRGV2VG9vbHMuIFRoZSBpZGVhIGlzIHRvIHByZXNlcnZlXG4gIC8vIFwiUGF1c2Ugb24gZXhjZXB0aW9uc1wiIGJlaGF2aW9yLiBCZWNhdXNlIFJlYWN0IHdyYXBzIGFsbCB1c2VyLXByb3ZpZGVkXG4gIC8vIGZ1bmN0aW9ucyBpbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2ssIGFuZCB0aGUgcHJvZHVjdGlvbiB2ZXJzaW9uIG9mXG4gIC8vIGludm9rZUd1YXJkZWRDYWxsYmFjayB1c2VzIGEgdHJ5LWNhdGNoLCBhbGwgdXNlciBleGNlcHRpb25zIGFyZSB0cmVhdGVkXG4gIC8vIGxpa2UgY2F1Z2h0IGV4Y2VwdGlvbnMsIGFuZCB0aGUgRGV2VG9vbHMgd29uJ3QgcGF1c2UgdW5sZXNzIHRoZSBkZXZlbG9wZXJcbiAgLy8gdGFrZXMgdGhlIGV4dHJhIHN0ZXAgb2YgZW5hYmxpbmcgcGF1c2Ugb24gY2F1Z2h0IGV4Y2VwdGlvbnMuIFRoaXMgaXNcbiAgLy8gdW5pbnR1aXRpdmUsIHRob3VnaCwgYmVjYXVzZSBldmVuIHRob3VnaCBSZWFjdCBoYXMgY2F1Z2h0IHRoZSBlcnJvciwgZnJvbVxuICAvLyB0aGUgZGV2ZWxvcGVyJ3MgcGVyc3BlY3RpdmUsIHRoZSBlcnJvciBpcyB1bmNhdWdodC5cbiAgLy9cbiAgLy8gVG8gcHJlc2VydmUgdGhlIGV4cGVjdGVkIFwiUGF1c2Ugb24gZXhjZXB0aW9uc1wiIGJlaGF2aW9yLCB3ZSBkb24ndCB1c2UgYVxuICAvLyB0cnktY2F0Y2ggaW4gREVWLiBJbnN0ZWFkLCB3ZSBzeW5jaHJvbm91c2x5IGRpc3BhdGNoIGEgZmFrZSBldmVudCB0byBhIGZha2VcbiAgLy8gRE9NIG5vZGUsIGFuZCBjYWxsIHRoZSB1c2VyLXByb3ZpZGVkIGNhbGxiYWNrIGZyb20gaW5zaWRlIGFuIGV2ZW50IGhhbmRsZXJcbiAgLy8gZm9yIHRoYXQgZmFrZSBldmVudC4gSWYgdGhlIGNhbGxiYWNrIHRocm93cywgdGhlIGVycm9yIGlzIFwiY2FwdHVyZWRcIiB1c2luZ1xuICAvLyBhIGdsb2JhbCBldmVudCBoYW5kbGVyLiBCdXQgYmVjYXVzZSB0aGUgZXJyb3IgaGFwcGVucyBpbiBhIGRpZmZlcmVudFxuICAvLyBldmVudCBsb29wIGNvbnRleHQsIGl0IGRvZXMgbm90IGludGVycnVwdCB0aGUgbm9ybWFsIHByb2dyYW0gZmxvdy5cbiAgLy8gRWZmZWN0aXZlbHksIHRoaXMgZ2l2ZXMgdXMgdHJ5LWNhdGNoIGJlaGF2aW9yIHdpdGhvdXQgYWN0dWFsbHkgdXNpbmdcbiAgLy8gdHJ5LWNhdGNoLiBOZWF0IVxuICAvLyBDaGVjayB0aGF0IHRoZSBicm93c2VyIHN1cHBvcnRzIHRoZSBBUElzIHdlIG5lZWQgdG8gaW1wbGVtZW50IG91ciBzcGVjaWFsXG4gIC8vIERFViB2ZXJzaW9uIG9mIGludm9rZUd1YXJkZWRDYWxsYmFja1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHdpbmRvdy5kaXNwYXRjaEV2ZW50ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIGZha2VOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncmVhY3QnKTtcblxuICAgIGludm9rZUd1YXJkZWRDYWxsYmFja0ltcGwgPSBmdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tEZXYobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICAgICAgLy8gSWYgZG9jdW1lbnQgZG9lc24ndCBleGlzdCB3ZSBrbm93IGZvciBzdXJlIHdlIHdpbGwgY3Jhc2ggaW4gdGhpcyBtZXRob2RcbiAgICAgIC8vIHdoZW4gd2UgY2FsbCBkb2N1bWVudC5jcmVhdGVFdmVudCgpLiBIb3dldmVyIHRoaXMgY2FuIGNhdXNlIGNvbmZ1c2luZ1xuICAgICAgLy8gZXJyb3JzOiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svY3JlYXRlLXJlYWN0LWFwcC9pc3N1ZXMvMzQ4MlxuICAgICAgLy8gU28gd2UgcHJlZW1wdGl2ZWx5IHRocm93IHdpdGggYSBiZXR0ZXIgbWVzc2FnZSBpbnN0ZWFkLlxuICAgICAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgZG9jdW1lbnQgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgYGRvY3VtZW50YCBnbG9iYWwgd2FzIGRlZmluZWQgd2hlbiBSZWFjdCB3YXMgaW5pdGlhbGl6ZWQsIGJ1dCBpcyBub3QgJyArICdkZWZpbmVkIGFueW1vcmUuIFRoaXMgY2FuIGhhcHBlbiBpbiBhIHRlc3QgZW52aXJvbm1lbnQgaWYgYSBjb21wb25lbnQgJyArICdzY2hlZHVsZXMgYW4gdXBkYXRlIGZyb20gYW4gYXN5bmNocm9ub3VzIGNhbGxiYWNrLCBidXQgdGhlIHRlc3QgaGFzIGFscmVhZHkgJyArICdmaW5pc2hlZCBydW5uaW5nLiBUbyBzb2x2ZSB0aGlzLCB5b3UgY2FuIGVpdGhlciB1bm1vdW50IHRoZSBjb21wb25lbnQgYXQgJyArICd0aGUgZW5kIG9mIHlvdXIgdGVzdCAoYW5kIGVuc3VyZSB0aGF0IGFueSBhc3luY2hyb25vdXMgb3BlcmF0aW9ucyBnZXQgJyArICdjYW5jZWxlZCBpbiBgY29tcG9uZW50V2lsbFVubW91bnRgKSwgb3IgeW91IGNhbiBjaGFuZ2UgdGhlIHRlc3QgaXRzZWxmICcgKyAndG8gYmUgYXN5bmNocm9ub3VzLicpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgICB2YXIgZGlkQ2FsbCA9IGZhbHNlOyAvLyBLZWVwcyB0cmFjayBvZiB3aGV0aGVyIHRoZSB1c2VyLXByb3ZpZGVkIGNhbGxiYWNrIHRocmV3IGFuIGVycm9yLiBXZVxuICAgICAgLy8gc2V0IHRoaXMgdG8gdHJ1ZSBhdCB0aGUgYmVnaW5uaW5nLCB0aGVuIHNldCBpdCB0byBmYWxzZSByaWdodCBhZnRlclxuICAgICAgLy8gY2FsbGluZyB0aGUgZnVuY3Rpb24uIElmIHRoZSBmdW5jdGlvbiBlcnJvcnMsIGBkaWRFcnJvcmAgd2lsbCBuZXZlciBiZVxuICAgICAgLy8gc2V0IHRvIGZhbHNlLiBUaGlzIHN0cmF0ZWd5IHdvcmtzIGV2ZW4gaWYgdGhlIGJyb3dzZXIgaXMgZmxha3kgYW5kXG4gICAgICAvLyBmYWlscyB0byBjYWxsIG91ciBnbG9iYWwgZXJyb3IgaGFuZGxlciwgYmVjYXVzZSBpdCBkb2Vzbid0IHJlbHkgb25cbiAgICAgIC8vIHRoZSBlcnJvciBldmVudCBhdCBhbGwuXG5cbiAgICAgIHZhciBkaWRFcnJvciA9IHRydWU7IC8vIEtlZXBzIHRyYWNrIG9mIHRoZSB2YWx1ZSBvZiB3aW5kb3cuZXZlbnQgc28gdGhhdCB3ZSBjYW4gcmVzZXQgaXRcbiAgICAgIC8vIGR1cmluZyB0aGUgY2FsbGJhY2sgdG8gbGV0IHVzZXIgY29kZSBhY2Nlc3Mgd2luZG93LmV2ZW50IGluIHRoZVxuICAgICAgLy8gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IGl0LlxuXG4gICAgICB2YXIgd2luZG93RXZlbnQgPSB3aW5kb3cuZXZlbnQ7IC8vIEtlZXBzIHRyYWNrIG9mIHRoZSBkZXNjcmlwdG9yIG9mIHdpbmRvdy5ldmVudCB0byByZXN0b3JlIGl0IGFmdGVyIGV2ZW50XG4gICAgICAvLyBkaXNwYXRjaGluZzogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMzY4OFxuXG4gICAgICB2YXIgd2luZG93RXZlbnREZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3csICdldmVudCcpO1xuXG4gICAgICBmdW5jdGlvbiByZXN0b3JlQWZ0ZXJEaXNwYXRjaCgpIHtcbiAgICAgICAgLy8gV2UgaW1tZWRpYXRlbHkgcmVtb3ZlIHRoZSBjYWxsYmFjayBmcm9tIGV2ZW50IGxpc3RlbmVycyBzbyB0aGF0XG4gICAgICAgIC8vIG5lc3RlZCBgaW52b2tlR3VhcmRlZENhbGxiYWNrYCBjYWxscyBkbyBub3QgY2xhc2guIE90aGVyd2lzZSwgYVxuICAgICAgICAvLyBuZXN0ZWQgY2FsbCB3b3VsZCB0cmlnZ2VyIHRoZSBmYWtlIGV2ZW50IGhhbmRsZXJzIG9mIGFueSBjYWxsIGhpZ2hlclxuICAgICAgICAvLyBpbiB0aGUgc3RhY2suXG4gICAgICAgIGZha2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZ0VHlwZSwgY2FsbENhbGxiYWNrLCBmYWxzZSk7IC8vIFdlIGNoZWNrIGZvciB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ2V2ZW50JykgdG8gcHJldmVudCB0aGVcbiAgICAgICAgLy8gd2luZG93LmV2ZW50IGFzc2lnbm1lbnQgaW4gYm90aCBJRSA8PSAxMCBhcyB0aGV5IHRocm93IGFuIGVycm9yXG4gICAgICAgIC8vIFwiTWVtYmVyIG5vdCBmb3VuZFwiIGluIHN0cmljdCBtb2RlLCBhbmQgaW4gRmlyZWZveCB3aGljaCBkb2VzIG5vdFxuICAgICAgICAvLyBzdXBwb3J0IHdpbmRvdy5ldmVudC5cblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5ldmVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lmhhc093blByb3BlcnR5KCdldmVudCcpKSB7XG4gICAgICAgICAgd2luZG93LmV2ZW50ID0gd2luZG93RXZlbnQ7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gQ3JlYXRlIGFuIGV2ZW50IGhhbmRsZXIgZm9yIG91ciBmYWtlIGV2ZW50LiBXZSB3aWxsIHN5bmNocm9ub3VzbHlcbiAgICAgIC8vIGRpc3BhdGNoIG91ciBmYWtlIGV2ZW50IHVzaW5nIGBkaXNwYXRjaEV2ZW50YC4gSW5zaWRlIHRoZSBoYW5kbGVyLCB3ZVxuICAgICAgLy8gY2FsbCB0aGUgdXNlci1wcm92aWRlZCBjYWxsYmFjay5cblxuXG4gICAgICB2YXIgZnVuY0FyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDMpO1xuXG4gICAgICBmdW5jdGlvbiBjYWxsQ2FsbGJhY2soKSB7XG4gICAgICAgIGRpZENhbGwgPSB0cnVlO1xuICAgICAgICByZXN0b3JlQWZ0ZXJEaXNwYXRjaCgpO1xuICAgICAgICBmdW5jLmFwcGx5KGNvbnRleHQsIGZ1bmNBcmdzKTtcbiAgICAgICAgZGlkRXJyb3IgPSBmYWxzZTtcbiAgICAgIH0gLy8gQ3JlYXRlIGEgZ2xvYmFsIGVycm9yIGV2ZW50IGhhbmRsZXIuIFdlIHVzZSB0aGlzIHRvIGNhcHR1cmUgdGhlIHZhbHVlXG4gICAgICAvLyB0aGF0IHdhcyB0aHJvd24uIEl0J3MgcG9zc2libGUgdGhhdCB0aGlzIGVycm9yIGhhbmRsZXIgd2lsbCBmaXJlIG1vcmVcbiAgICAgIC8vIHRoYW4gb25jZTsgZm9yIGV4YW1wbGUsIGlmIG5vbi1SZWFjdCBjb2RlIGFsc28gY2FsbHMgYGRpc3BhdGNoRXZlbnRgXG4gICAgICAvLyBhbmQgYSBoYW5kbGVyIGZvciB0aGF0IGV2ZW50IHRocm93cy4gV2Ugc2hvdWxkIGJlIHJlc2lsaWVudCB0byBtb3N0IG9mXG4gICAgICAvLyB0aG9zZSBjYXNlcy4gRXZlbiBpZiBvdXIgZXJyb3IgZXZlbnQgaGFuZGxlciBmaXJlcyBtb3JlIHRoYW4gb25jZSwgdGhlXG4gICAgICAvLyBsYXN0IGVycm9yIGV2ZW50IGlzIGFsd2F5cyB1c2VkLiBJZiB0aGUgY2FsbGJhY2sgYWN0dWFsbHkgZG9lcyBlcnJvcixcbiAgICAgIC8vIHdlIGtub3cgdGhhdCB0aGUgbGFzdCBlcnJvciBldmVudCBpcyB0aGUgY29ycmVjdCBvbmUsIGJlY2F1c2UgaXQncyBub3RcbiAgICAgIC8vIHBvc3NpYmxlIGZvciBhbnl0aGluZyBlbHNlIHRvIGhhdmUgaGFwcGVuZWQgaW4gYmV0d2VlbiBvdXIgY2FsbGJhY2tcbiAgICAgIC8vIGVycm9yaW5nIGFuZCB0aGUgY29kZSB0aGF0IGZvbGxvd3MgdGhlIGBkaXNwYXRjaEV2ZW50YCBjYWxsIGJlbG93LiBJZlxuICAgICAgLy8gdGhlIGNhbGxiYWNrIGRvZXNuJ3QgZXJyb3IsIGJ1dCB0aGUgZXJyb3IgZXZlbnQgd2FzIGZpcmVkLCB3ZSBrbm93IHRvXG4gICAgICAvLyBpZ25vcmUgaXQgYmVjYXVzZSBgZGlkRXJyb3JgIHdpbGwgYmUgZmFsc2UsIGFzIGRlc2NyaWJlZCBhYm92ZS5cblxuXG4gICAgICB2YXIgZXJyb3I7IC8vIFVzZSB0aGlzIHRvIHRyYWNrIHdoZXRoZXIgdGhlIGVycm9yIGV2ZW50IGlzIGV2ZXIgY2FsbGVkLlxuXG4gICAgICB2YXIgZGlkU2V0RXJyb3IgPSBmYWxzZTtcbiAgICAgIHZhciBpc0Nyb3NzT3JpZ2luRXJyb3IgPSBmYWxzZTtcblxuICAgICAgZnVuY3Rpb24gaGFuZGxlV2luZG93RXJyb3IoZXZlbnQpIHtcbiAgICAgICAgZXJyb3IgPSBldmVudC5lcnJvcjtcbiAgICAgICAgZGlkU2V0RXJyb3IgPSB0cnVlO1xuXG4gICAgICAgIGlmIChlcnJvciA9PT0gbnVsbCAmJiBldmVudC5jb2xubyA9PT0gMCAmJiBldmVudC5saW5lbm8gPT09IDApIHtcbiAgICAgICAgICBpc0Nyb3NzT3JpZ2luRXJyb3IgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICAvLyBTb21lIG90aGVyIGVycm9yIGhhbmRsZXIgaGFzIHByZXZlbnRlZCBkZWZhdWx0LlxuICAgICAgICAgIC8vIEJyb3dzZXJzIHNpbGVuY2UgdGhlIGVycm9yIHJlcG9ydCBpZiB0aGlzIGhhcHBlbnMuXG4gICAgICAgICAgLy8gV2UnbGwgcmVtZW1iZXIgdGhpcyB0byBsYXRlciBkZWNpZGUgd2hldGhlciB0byBsb2cgaXQgb3Igbm90LlxuICAgICAgICAgIGlmIChlcnJvciAhPSBudWxsICYmIHR5cGVvZiBlcnJvciA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGVycm9yLl9zdXBwcmVzc0xvZ2dpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfSBjYXRjaCAoaW5uZXIpIHsvLyBJZ25vcmUuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8vIENyZWF0ZSBhIGZha2UgZXZlbnQgdHlwZS5cblxuXG4gICAgICB2YXIgZXZ0VHlwZSA9IFwicmVhY3QtXCIgKyAobmFtZSA/IG5hbWUgOiAnaW52b2tlZ3VhcmRlZGNhbGxiYWNrJyk7IC8vIEF0dGFjaCBvdXIgZXZlbnQgaGFuZGxlcnNcblxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgaGFuZGxlV2luZG93RXJyb3IpO1xuICAgICAgZmFrZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldnRUeXBlLCBjYWxsQ2FsbGJhY2ssIGZhbHNlKTsgLy8gU3luY2hyb25vdXNseSBkaXNwYXRjaCBvdXIgZmFrZSBldmVudC4gSWYgdGhlIHVzZXItcHJvdmlkZWQgZnVuY3Rpb25cbiAgICAgIC8vIGVycm9ycywgaXQgd2lsbCB0cmlnZ2VyIG91ciBnbG9iYWwgZXJyb3IgaGFuZGxlci5cblxuICAgICAgZXZ0LmluaXRFdmVudChldnRUeXBlLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgZmFrZU5vZGUuZGlzcGF0Y2hFdmVudChldnQpO1xuXG4gICAgICBpZiAod2luZG93RXZlbnREZXNjcmlwdG9yKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csICdldmVudCcsIHdpbmRvd0V2ZW50RGVzY3JpcHRvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChkaWRDYWxsICYmIGRpZEVycm9yKSB7XG4gICAgICAgIGlmICghZGlkU2V0RXJyb3IpIHtcbiAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgZXJyb3JlZCwgYnV0IHRoZSBlcnJvciBldmVudCBuZXZlciBmaXJlZC5cbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgIGVycm9yID0gbmV3IEVycm9yKCdBbiBlcnJvciB3YXMgdGhyb3duIGluc2lkZSBvbmUgb2YgeW91ciBjb21wb25lbnRzLCBidXQgUmVhY3QgJyArIFwiZG9lc24ndCBrbm93IHdoYXQgaXQgd2FzLiBUaGlzIGlzIGxpa2VseSBkdWUgdG8gYnJvd3NlciBcIiArICdmbGFraW5lc3MuIFJlYWN0IGRvZXMgaXRzIGJlc3QgdG8gcHJlc2VydmUgdGhlIFwiUGF1c2Ugb24gJyArICdleGNlcHRpb25zXCIgYmVoYXZpb3Igb2YgdGhlIERldlRvb2xzLCB3aGljaCByZXF1aXJlcyBzb21lICcgKyBcIkRFVi1tb2RlIG9ubHkgdHJpY2tzLiBJdCdzIHBvc3NpYmxlIHRoYXQgdGhlc2UgZG9uJ3Qgd29yayBpbiBcIiArICd5b3VyIGJyb3dzZXIuIFRyeSB0cmlnZ2VyaW5nIHRoZSBlcnJvciBpbiBwcm9kdWN0aW9uIG1vZGUsICcgKyAnb3Igc3dpdGNoaW5nIHRvIGEgbW9kZXJuIGJyb3dzZXIuIElmIHlvdSBzdXNwZWN0IHRoYXQgdGhpcyBpcyAnICsgJ2FjdHVhbGx5IGFuIGlzc3VlIHdpdGggUmVhY3QsIHBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQ3Jvc3NPcmlnaW5FcnJvcikge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoXCJBIGNyb3NzLW9yaWdpbiBlcnJvciB3YXMgdGhyb3duLiBSZWFjdCBkb2Vzbid0IGhhdmUgYWNjZXNzIHRvIFwiICsgJ3RoZSBhY3R1YWwgZXJyb3Igb2JqZWN0IGluIGRldmVsb3BtZW50LiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvY3Jvc3NvcmlnaW4tZXJyb3IgZm9yIG1vcmUgaW5mb3JtYXRpb24uJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9uRXJyb3IoZXJyb3IpO1xuICAgICAgfSAvLyBSZW1vdmUgb3VyIGV2ZW50IGxpc3RlbmVyc1xuXG5cbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdlcnJvcicsIGhhbmRsZVdpbmRvd0Vycm9yKTtcblxuICAgICAgaWYgKCFkaWRDYWxsKSB7XG4gICAgICAgIC8vIFNvbWV0aGluZyB3ZW50IHJlYWxseSB3cm9uZywgYW5kIG91ciBldmVudCB3YXMgbm90IGRpc3BhdGNoZWQuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTY3MzRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xNjU4NVxuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gdGhlIHByb2R1Y3Rpb24gaW1wbGVtZW50YXRpb24uXG4gICAgICAgIHJlc3RvcmVBZnRlckRpc3BhdGNoKCk7XG4gICAgICAgIHJldHVybiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tQcm9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxuXG52YXIgaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbCQxID0gaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbDtcblxudmFyIGhhc0Vycm9yID0gZmFsc2U7XG52YXIgY2F1Z2h0RXJyb3IgPSBudWxsOyAvLyBVc2VkIGJ5IGV2ZW50IHN5c3RlbSB0byBjYXB0dXJlL3JldGhyb3cgdGhlIGZpcnN0IGVycm9yLlxuXG52YXIgaGFzUmV0aHJvd0Vycm9yID0gZmFsc2U7XG52YXIgcmV0aHJvd0Vycm9yID0gbnVsbDtcbnZhciByZXBvcnRlciA9IHtcbiAgb25FcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgaGFzRXJyb3IgPSB0cnVlO1xuICAgIGNhdWdodEVycm9yID0gZXJyb3I7XG4gIH1cbn07XG4vKipcbiAqIENhbGwgYSBmdW5jdGlvbiB3aGlsZSBndWFyZGluZyBhZ2FpbnN0IGVycm9ycyB0aGF0IGhhcHBlbnMgd2l0aGluIGl0LlxuICogUmV0dXJucyBhbiBlcnJvciBpZiBpdCB0aHJvd3MsIG90aGVyd2lzZSBudWxsLlxuICpcbiAqIEluIHByb2R1Y3Rpb24sIHRoaXMgaXMgaW1wbGVtZW50ZWQgdXNpbmcgYSB0cnktY2F0Y2guIFRoZSByZWFzb24gd2UgZG9uJ3RcbiAqIHVzZSBhIHRyeS1jYXRjaCBkaXJlY3RseSBpcyBzbyB0aGF0IHdlIGNhbiBzd2FwIG91dCBhIGRpZmZlcmVudFxuICogaW1wbGVtZW50YXRpb24gaW4gREVWIG1vZGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgdGhlIGd1YXJkIHRvIHVzZSBmb3IgbG9nZ2luZyBvciBkZWJ1Z2dpbmdcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGludm9rZVxuICogQHBhcmFtIHsqfSBjb250ZXh0IFRoZSBjb250ZXh0IHRvIHVzZSB3aGVuIGNhbGxpbmcgdGhlIGZ1bmN0aW9uXG4gKiBAcGFyYW0gey4uLip9IGFyZ3MgQXJndW1lbnRzIGZvciBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGludm9rZUd1YXJkZWRDYWxsYmFjayhuYW1lLCBmdW5jLCBjb250ZXh0LCBhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIGhhc0Vycm9yID0gZmFsc2U7XG4gIGNhdWdodEVycm9yID0gbnVsbDtcbiAgaW52b2tlR3VhcmRlZENhbGxiYWNrSW1wbCQxLmFwcGx5KHJlcG9ydGVyLCBhcmd1bWVudHMpO1xufVxuLyoqXG4gKiBTYW1lIGFzIGludm9rZUd1YXJkZWRDYWxsYmFjaywgYnV0IGluc3RlYWQgb2YgcmV0dXJuaW5nIGFuIGVycm9yLCBpdCBzdG9yZXNcbiAqIGl0IGluIGEgZ2xvYmFsIHNvIGl0IGNhbiBiZSByZXRocm93biBieSBgcmV0aHJvd0NhdWdodEVycm9yYCBsYXRlci5cbiAqIFRPRE86IFNlZSBpZiBjYXVnaHRFcnJvciBhbmQgcmV0aHJvd0Vycm9yIGNhbiBiZSB1bmlmaWVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG9mIHRoZSBndWFyZCB0byB1c2UgZm9yIGxvZ2dpbmcgb3IgZGVidWdnaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnZva2VcbiAqIEBwYXJhbSB7Kn0gY29udGV4dCBUaGUgY29udGV4dCB0byB1c2Ugd2hlbiBjYWxsaW5nIHRoZSBmdW5jdGlvblxuICogQHBhcmFtIHsuLi4qfSBhcmdzIEFyZ3VtZW50cyBmb3IgZnVuY3Rpb25cbiAqL1xuXG5mdW5jdGlvbiBpbnZva2VHdWFyZGVkQ2FsbGJhY2tBbmRDYXRjaEZpcnN0RXJyb3IobmFtZSwgZnVuYywgY29udGV4dCwgYSwgYiwgYywgZCwgZSwgZikge1xuICBpbnZva2VHdWFyZGVkQ2FsbGJhY2suYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICBpZiAoaGFzRXJyb3IpIHtcbiAgICB2YXIgZXJyb3IgPSBjbGVhckNhdWdodEVycm9yKCk7XG5cbiAgICBpZiAoIWhhc1JldGhyb3dFcnJvcikge1xuICAgICAgaGFzUmV0aHJvd0Vycm9yID0gdHJ1ZTtcbiAgICAgIHJldGhyb3dFcnJvciA9IGVycm9yO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBEdXJpbmcgZXhlY3V0aW9uIG9mIGd1YXJkZWQgZnVuY3Rpb25zIHdlIHdpbGwgY2FwdHVyZSB0aGUgZmlyc3QgZXJyb3Igd2hpY2hcbiAqIHdlIHdpbGwgcmV0aHJvdyB0byBiZSBoYW5kbGVkIGJ5IHRoZSB0b3AgbGV2ZWwgZXJyb3IgaGFuZGxlci5cbiAqL1xuXG5mdW5jdGlvbiByZXRocm93Q2F1Z2h0RXJyb3IoKSB7XG4gIGlmIChoYXNSZXRocm93RXJyb3IpIHtcbiAgICB2YXIgZXJyb3IgPSByZXRocm93RXJyb3I7XG4gICAgaGFzUmV0aHJvd0Vycm9yID0gZmFsc2U7XG4gICAgcmV0aHJvd0Vycm9yID0gbnVsbDtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuZnVuY3Rpb24gaGFzQ2F1Z2h0RXJyb3IoKSB7XG4gIHJldHVybiBoYXNFcnJvcjtcbn1cbmZ1bmN0aW9uIGNsZWFyQ2F1Z2h0RXJyb3IoKSB7XG4gIGlmIChoYXNFcnJvcikge1xuICAgIHZhciBlcnJvciA9IGNhdWdodEVycm9yO1xuICAgIGhhc0Vycm9yID0gZmFsc2U7XG4gICAgY2F1Z2h0RXJyb3IgPSBudWxsO1xuICAgIHJldHVybiBlcnJvcjtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyQ2F1Z2h0RXJyb3Igd2FzIGNhbGxlZCBidXQgbm8gZXJyb3Igd2FzIGNhcHR1cmVkLiBUaGlzIGVycm9yICcgKyAnaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBgUmVhY3RJbnN0YW5jZU1hcGAgbWFpbnRhaW5zIGEgbWFwcGluZyBmcm9tIGEgcHVibGljIGZhY2luZyBzdGF0ZWZ1bFxuICogaW5zdGFuY2UgKGtleSkgYW5kIHRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiAodmFsdWUpLiBUaGlzIGFsbG93cyBwdWJsaWNcbiAqIG1ldGhvZHMgdG8gYWNjZXB0IHRoZSB1c2VyIGZhY2luZyBpbnN0YW5jZSBhcyBhbiBhcmd1bWVudCBhbmQgbWFwIHRoZW0gYmFja1xuICogdG8gaW50ZXJuYWwgbWV0aG9kcy5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBtb2R1bGUgaXMgY3VycmVudGx5IHNoYXJlZCBhbmQgYXNzdW1lZCB0byBiZSBzdGF0ZWxlc3MuXG4gKiBJZiB0aGlzIGJlY29tZXMgYW4gYWN0dWFsIE1hcCwgdGhhdCB3aWxsIGJyZWFrLlxuICovXG5mdW5jdGlvbiBnZXQoa2V5KSB7XG4gIHJldHVybiBrZXkuX3JlYWN0SW50ZXJuYWxzO1xufVxuZnVuY3Rpb24gaGFzKGtleSkge1xuICByZXR1cm4ga2V5Ll9yZWFjdEludGVybmFscyAhPT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAga2V5Ll9yZWFjdEludGVybmFscyA9IHZhbHVlO1xufVxuXG4vLyBEb24ndCBjaGFuZ2UgdGhlc2UgdHdvIHZhbHVlcy4gVGhleSdyZSB1c2VkIGJ5IFJlYWN0IERldiBUb29scy5cbnZhciBOb0ZsYWdzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICovXG4wO1xudmFyIFBlcmZvcm1lZFdvcmsgPVxuLyogICAgICAgICAgICAgICAgKi9cbjE7IC8vIFlvdSBjYW4gY2hhbmdlIHRoZSByZXN0IChhbmQgYWRkIG1vcmUpLlxuXG52YXIgUGxhY2VtZW50ID1cbi8qICAgICAgICAgICAgICAgICAgICAqL1xuMjtcbnZhciBVcGRhdGUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG40O1xudmFyIENoaWxkRGVsZXRpb24gPVxuLyogICAgICAgICAgICAgICAgKi9cbjE2O1xudmFyIENvbnRlbnRSZXNldCA9XG4vKiAgICAgICAgICAgICAgICAgKi9cbjMyO1xudmFyIENhbGxiYWNrID1cbi8qICAgICAgICAgICAgICAgICAgICAgKi9cbjY0O1xudmFyIERpZENhcHR1cmUgPVxuLyogICAgICAgICAgICAgICAgICAgKi9cbjEyODtcbnZhciBGb3JjZUNsaWVudFJlbmRlciA9XG4vKiAgICAgICAgICAgICovXG4yNTY7XG52YXIgUmVmID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuNTEyO1xudmFyIFNuYXBzaG90ID1cbi8qICAgICAgICAgICAgICAgICAgICAgKi9cbjEwMjQ7XG52YXIgUGFzc2l2ZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAqL1xuMjA0ODtcbnZhciBIeWRyYXRpbmcgPVxuLyogICAgICAgICAgICAgICAgICAgICovXG40MDk2O1xudmFyIFZpc2liaWxpdHkgPVxuLyogICAgICAgICAgICAgICAgICAgKi9cbjgxOTI7XG52YXIgU3RvcmVDb25zaXN0ZW5jeSA9XG4vKiAgICAgICAgICAgICAqL1xuMTYzODQ7XG52YXIgTGlmZWN5Y2xlRWZmZWN0TWFzayA9IFBhc3NpdmUgfCBVcGRhdGUgfCBDYWxsYmFjayB8IFJlZiB8IFNuYXBzaG90IHwgU3RvcmVDb25zaXN0ZW5jeTsgLy8gVW5pb24gb2YgYWxsIGNvbW1pdCBmbGFncyAoZmxhZ3Mgd2l0aCB0aGUgbGlmZXRpbWUgb2YgYSBwYXJ0aWN1bGFyIGNvbW1pdClcblxudmFyIEhvc3RFZmZlY3RNYXNrID1cbi8qICAgICAgICAgICAgICAgKi9cbjMyNzY3OyAvLyBUaGVzZSBhcmUgbm90IHJlYWxseSBzaWRlIGVmZmVjdHMsIGJ1dCB3ZSBzdGlsbCByZXVzZSB0aGlzIGZpZWxkLlxuXG52YXIgSW5jb21wbGV0ZSA9XG4vKiAgICAgICAgICAgICAgICAgICAqL1xuMzI3Njg7XG52YXIgU2hvdWxkQ2FwdHVyZSA9XG4vKiAgICAgICAgICAgICAgICAqL1xuNjU1MzY7XG52YXIgRm9yY2VVcGRhdGVGb3JMZWdhY3lTdXNwZW5zZSA9XG4vKiAqL1xuMTMxMDcyO1xudmFyIEZvcmtlZCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEwNDg1NzY7IC8vIFN0YXRpYyB0YWdzIGRlc2NyaWJlIGFzcGVjdHMgb2YgYSBmaWJlciB0aGF0IGFyZSBub3Qgc3BlY2lmaWMgdG8gYSByZW5kZXIsXG4vLyBlLmcuIGEgZmliZXIgdXNlcyBhIHBhc3NpdmUgZWZmZWN0IChldmVuIGlmIHRoZXJlIGFyZSBubyB1cGRhdGVzIG9uIHRoaXMgcGFydGljdWxhciByZW5kZXIpLlxuLy8gVGhpcyBlbmFibGVzIHVzIHRvIGRlZmVyIG1vcmUgd29yayBpbiB0aGUgdW5tb3VudCBjYXNlLFxuLy8gc2luY2Ugd2UgY2FuIGRlZmVyIHRyYXZlcnNpbmcgdGhlIHRyZWUgZHVyaW5nIGxheW91dCB0byBsb29rIGZvciBQYXNzaXZlIGVmZmVjdHMsXG4vLyBhbmQgaW5zdGVhZCByZWx5IG9uIHRoZSBzdGF0aWMgZmxhZyBhcyBhIHNpZ25hbCB0aGF0IHRoZXJlIG1heSBiZSBjbGVhbnVwIHdvcmsuXG5cbnZhciBSZWZTdGF0aWMgPVxuLyogICAgICAgICAgICAgICAgICAgICovXG4yMDk3MTUyO1xudmFyIExheW91dFN0YXRpYyA9XG4vKiAgICAgICAgICAgICAgICAgKi9cbjQxOTQzMDQ7XG52YXIgUGFzc2l2ZVN0YXRpYyA9XG4vKiAgICAgICAgICAgICAgICAqL1xuODM4ODYwODsgLy8gVGhlc2UgZmxhZ3MgYWxsb3cgdXMgdG8gdHJhdmVyc2UgdG8gZmliZXJzIHRoYXQgaGF2ZSBlZmZlY3RzIG9uIG1vdW50XG4vLyB3aXRob3V0IHRyYXZlcnNpbmcgdGhlIGVudGlyZSB0cmVlIGFmdGVyIGV2ZXJ5IGNvbW1pdCBmb3Jcbi8vIGRvdWJsZSBpbnZva2luZ1xuXG52YXIgTW91bnRMYXlvdXREZXYgPVxuLyogICAgICAgICAgICAgICAqL1xuMTY3NzcyMTY7XG52YXIgTW91bnRQYXNzaXZlRGV2ID1cbi8qICAgICAgICAgICAgICAqL1xuMzM1NTQ0MzI7IC8vIEdyb3VwcyBvZiBmbGFncyB0aGF0IGFyZSB1c2VkIGluIHRoZSBjb21taXQgcGhhc2UgdG8gc2tpcCBvdmVyIHRyZWVzIHRoYXRcbi8vIGRvbid0IGNvbnRhaW4gZWZmZWN0cywgYnkgY2hlY2tpbmcgc3VidHJlZUZsYWdzLlxuXG52YXIgQmVmb3JlTXV0YXRpb25NYXNrID0gLy8gVE9ETzogUmVtb3ZlIFVwZGF0ZSBmbGFnIGZyb20gYmVmb3JlIG11dGF0aW9uIHBoYXNlIGJ5IHJlLWxhbmRpbmcgVmlzaWJpbGl0eVxuLy8gZmxhZyBsb2dpYyAoc2VlICMyMDA0MylcblVwZGF0ZSB8IFNuYXBzaG90IHwgKCAwKTtcbnZhciBNdXRhdGlvbk1hc2sgPSBQbGFjZW1lbnQgfCBVcGRhdGUgfCBDaGlsZERlbGV0aW9uIHwgQ29udGVudFJlc2V0IHwgUmVmIHwgSHlkcmF0aW5nIHwgVmlzaWJpbGl0eTtcbnZhciBMYXlvdXRNYXNrID0gVXBkYXRlIHwgQ2FsbGJhY2sgfCBSZWYgfCBWaXNpYmlsaXR5OyAvLyBUT0RPOiBTcGxpdCBpbnRvIFBhc3NpdmVNb3VudE1hc2sgYW5kIFBhc3NpdmVVbm1vdW50TWFza1xuXG52YXIgUGFzc2l2ZU1hc2sgPSBQYXNzaXZlIHwgQ2hpbGREZWxldGlvbjsgLy8gVW5pb24gb2YgdGFncyB0aGF0IGRvbid0IGdldCByZXNldCBvbiBjbG9uZXMuXG4vLyBUaGlzIGFsbG93cyBjZXJ0YWluIGNvbmNlcHRzIHRvIHBlcnNpc3Qgd2l0aG91dCByZWNhbGN1bGF0aW5nIHRoZW0sXG4vLyBlLmcuIHdoZXRoZXIgYSBzdWJ0cmVlIGNvbnRhaW5zIHBhc3NpdmUgZWZmZWN0cyBvciBwb3J0YWxzLlxuXG52YXIgU3RhdGljTWFzayA9IExheW91dFN0YXRpYyB8IFBhc3NpdmVTdGF0aWMgfCBSZWZTdGF0aWM7XG5cbnZhciBSZWFjdEN1cnJlbnRPd25lciA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudE93bmVyO1xuZnVuY3Rpb24gZ2V0TmVhcmVzdE1vdW50ZWRGaWJlcihmaWJlcikge1xuICB2YXIgbm9kZSA9IGZpYmVyO1xuICB2YXIgbmVhcmVzdE1vdW50ZWQgPSBmaWJlcjtcblxuICBpZiAoIWZpYmVyLmFsdGVybmF0ZSkge1xuICAgIC8vIElmIHRoZXJlIGlzIG5vIGFsdGVybmF0ZSwgdGhpcyBtaWdodCBiZSBhIG5ldyB0cmVlIHRoYXQgaXNuJ3QgaW5zZXJ0ZWRcbiAgICAvLyB5ZXQuIElmIGl0IGlzLCB0aGVuIGl0IHdpbGwgaGF2ZSBhIHBlbmRpbmcgaW5zZXJ0aW9uIGVmZmVjdCBvbiBpdC5cbiAgICB2YXIgbmV4dE5vZGUgPSBub2RlO1xuXG4gICAgZG8ge1xuICAgICAgbm9kZSA9IG5leHROb2RlO1xuXG4gICAgICBpZiAoKG5vZGUuZmxhZ3MgJiAoUGxhY2VtZW50IHwgSHlkcmF0aW5nKSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhbiBpbnNlcnRpb24gb3IgaW4tcHJvZ3Jlc3MgaHlkcmF0aW9uLiBUaGUgbmVhcmVzdCBwb3NzaWJsZVxuICAgICAgICAvLyBtb3VudGVkIGZpYmVyIGlzIHRoZSBwYXJlbnQgYnV0IHdlIG5lZWQgdG8gY29udGludWUgdG8gZmlndXJlIG91dFxuICAgICAgICAvLyBpZiB0aGF0IG9uZSBpcyBzdGlsbCBtb3VudGVkLlxuICAgICAgICBuZWFyZXN0TW91bnRlZCA9IG5vZGUucmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBuZXh0Tm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH0gd2hpbGUgKG5leHROb2RlKTtcbiAgfSBlbHNlIHtcbiAgICB3aGlsZSAobm9kZS5yZXR1cm4pIHtcbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAobm9kZS50YWcgPT09IEhvc3RSb290KSB7XG4gICAgLy8gVE9ETzogQ2hlY2sgaWYgdGhpcyB3YXMgYSBuZXN0ZWQgSG9zdFJvb3Qgd2hlbiB1c2VkIHdpdGhcbiAgICAvLyByZW5kZXJDb250YWluZXJJbnRvU3VidHJlZS5cbiAgICByZXR1cm4gbmVhcmVzdE1vdW50ZWQ7XG4gIH0gLy8gSWYgd2UgZGlkbid0IGhpdCB0aGUgcm9vdCwgdGhhdCBtZWFucyB0aGF0IHdlJ3JlIGluIGFuIGRpc2Nvbm5lY3RlZCB0cmVlXG4gIC8vIHRoYXQgaGFzIGJlZW4gdW5tb3VudGVkLlxuXG5cbiAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBnZXRTdXNwZW5zZUluc3RhbmNlRnJvbUZpYmVyKGZpYmVyKSB7XG4gIGlmIChmaWJlci50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50KSB7XG4gICAgdmFyIHN1c3BlbnNlU3RhdGUgPSBmaWJlci5tZW1vaXplZFN0YXRlO1xuXG4gICAgaWYgKHN1c3BlbnNlU3RhdGUgPT09IG51bGwpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICBzdXNwZW5zZVN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyRnJvbUZpYmVyKGZpYmVyKSB7XG4gIHJldHVybiBmaWJlci50YWcgPT09IEhvc3RSb290ID8gZmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8gOiBudWxsO1xufVxuZnVuY3Rpb24gaXNGaWJlck1vdW50ZWQoZmliZXIpIHtcbiAgcmV0dXJuIGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpID09PSBmaWJlcjtcbn1cbmZ1bmN0aW9uIGlzTW91bnRlZChjb21wb25lbnQpIHtcbiAge1xuICAgIHZhciBvd25lciA9IFJlYWN0Q3VycmVudE93bmVyLmN1cnJlbnQ7XG5cbiAgICBpZiAob3duZXIgIT09IG51bGwgJiYgb3duZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgdmFyIG93bmVyRmliZXIgPSBvd25lcjtcbiAgICAgIHZhciBpbnN0YW5jZSA9IG93bmVyRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICBpZiAoIWluc3RhbmNlLl93YXJuZWRBYm91dFJlZnNJblJlbmRlcikge1xuICAgICAgICBlcnJvcignJXMgaXMgYWNjZXNzaW5nIGlzTW91bnRlZCBpbnNpZGUgaXRzIHJlbmRlcigpIGZ1bmN0aW9uLiAnICsgJ3JlbmRlcigpIHNob3VsZCBiZSBhIHB1cmUgZnVuY3Rpb24gb2YgcHJvcHMgYW5kIHN0YXRlLiBJdCBzaG91bGQgJyArICduZXZlciBhY2Nlc3Mgc29tZXRoaW5nIHRoYXQgcmVxdWlyZXMgc3RhbGUgZGF0YSBmcm9tIHRoZSBwcmV2aW91cyAnICsgJ3JlbmRlciwgc3VjaCBhcyByZWZzLiBNb3ZlIHRoaXMgbG9naWMgdG8gY29tcG9uZW50RGlkTW91bnQgYW5kICcgKyAnY29tcG9uZW50RGlkVXBkYXRlIGluc3RlYWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihvd25lckZpYmVyKSB8fCAnQSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgaW5zdGFuY2UuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICB2YXIgZmliZXIgPSBnZXQoY29tcG9uZW50KTtcblxuICBpZiAoIWZpYmVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpID09PSBmaWJlcjtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0SXNNb3VudGVkKGZpYmVyKSB7XG4gIGlmIChnZXROZWFyZXN0TW91bnRlZEZpYmVyKGZpYmVyKSAhPT0gZmliZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudEZpYmVyVXNpbmdTbG93UGF0aChmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmICghYWx0ZXJuYXRlKSB7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gYWx0ZXJuYXRlLCB0aGVuIHdlIG9ubHkgbmVlZCB0byBjaGVjayBpZiBpdCBpcyBtb3VudGVkLlxuICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIoZmliZXIpO1xuXG4gICAgaWYgKG5lYXJlc3RNb3VudGVkID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgICB9XG5cbiAgICBpZiAobmVhcmVzdE1vdW50ZWQgIT09IGZpYmVyKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gZmliZXI7XG4gIH0gLy8gSWYgd2UgaGF2ZSB0d28gcG9zc2libGUgYnJhbmNoZXMsIHdlJ2xsIHdhbGsgYmFja3dhcmRzIHVwIHRvIHRoZSByb290XG4gIC8vIHRvIHNlZSB3aGF0IHBhdGggdGhlIHJvb3QgcG9pbnRzIHRvLiBPbiB0aGUgd2F5IHdlIG1heSBoaXQgb25lIG9mIHRoZVxuICAvLyBzcGVjaWFsIGNhc2VzIGFuZCB3ZSdsbCBkZWFsIHdpdGggdGhlbS5cblxuXG4gIHZhciBhID0gZmliZXI7XG4gIHZhciBiID0gYWx0ZXJuYXRlO1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdmFyIHBhcmVudEEgPSBhLnJldHVybjtcblxuICAgIGlmIChwYXJlbnRBID09PSBudWxsKSB7XG4gICAgICAvLyBXZSdyZSBhdCB0aGUgcm9vdC5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBwYXJlbnRCID0gcGFyZW50QS5hbHRlcm5hdGU7XG5cbiAgICBpZiAocGFyZW50QiA9PT0gbnVsbCkge1xuICAgICAgLy8gVGhlcmUgaXMgbm8gYWx0ZXJuYXRlLiBUaGlzIGlzIGFuIHVudXN1YWwgY2FzZS4gQ3VycmVudGx5LCBpdCBvbmx5XG4gICAgICAvLyBoYXBwZW5zIHdoZW4gYSBTdXNwZW5zZSBjb21wb25lbnQgaXMgaGlkZGVuLiBBbiBleHRyYSBmcmFnbWVudCBmaWJlclxuICAgICAgLy8gaXMgaW5zZXJ0ZWQgaW4gYmV0d2VlbiB0aGUgU3VzcGVuc2UgZmliZXIgYW5kIGl0cyBjaGlsZHJlbi4gU2tpcFxuICAgICAgLy8gb3ZlciB0aGlzIGV4dHJhIGZyYWdtZW50IGZpYmVyIGFuZCBwcm9jZWVkIHRvIHRoZSBuZXh0IHBhcmVudC5cbiAgICAgIHZhciBuZXh0UGFyZW50ID0gcGFyZW50QS5yZXR1cm47XG5cbiAgICAgIGlmIChuZXh0UGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgIGEgPSBiID0gbmV4dFBhcmVudDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IC8vIElmIHRoZXJlJ3Mgbm8gcGFyZW50LCB3ZSdyZSBhdCB0aGUgcm9vdC5cblxuXG4gICAgICBicmVhaztcbiAgICB9IC8vIElmIGJvdGggY29waWVzIG9mIHRoZSBwYXJlbnQgZmliZXIgcG9pbnQgdG8gdGhlIHNhbWUgY2hpbGQsIHdlIGNhblxuICAgIC8vIGFzc3VtZSB0aGF0IHRoZSBjaGlsZCBpcyBjdXJyZW50LiBUaGlzIGhhcHBlbnMgd2hlbiB3ZSBiYWlsb3V0IG9uIGxvd1xuICAgIC8vIHByaW9yaXR5OiB0aGUgYmFpbGVkIG91dCBmaWJlcidzIGNoaWxkIHJldXNlcyB0aGUgY3VycmVudCBjaGlsZC5cblxuXG4gICAgaWYgKHBhcmVudEEuY2hpbGQgPT09IHBhcmVudEIuY2hpbGQpIHtcbiAgICAgIHZhciBjaGlsZCA9IHBhcmVudEEuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgICBpZiAoY2hpbGQgPT09IGEpIHtcbiAgICAgICAgICAvLyBXZSd2ZSBkZXRlcm1pbmVkIHRoYXQgQSBpcyB0aGUgY3VycmVudCBicmFuY2guXG4gICAgICAgICAgYXNzZXJ0SXNNb3VudGVkKHBhcmVudEEpO1xuICAgICAgICAgIHJldHVybiBmaWJlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjaGlsZCA9PT0gYikge1xuICAgICAgICAgIC8vIFdlJ3ZlIGRldGVybWluZWQgdGhhdCBCIGlzIHRoZSBjdXJyZW50IGJyYW5jaC5cbiAgICAgICAgICBhc3NlcnRJc01vdW50ZWQocGFyZW50QSk7XG4gICAgICAgICAgcmV0dXJuIGFsdGVybmF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgICAgIH0gLy8gV2Ugc2hvdWxkIG5ldmVyIGhhdmUgYW4gYWx0ZXJuYXRlIGZvciBhbnkgbW91bnRpbmcgbm9kZS4gU28gdGhlIG9ubHlcbiAgICAgIC8vIHdheSB0aGlzIGNvdWxkIHBvc3NpYmx5IGhhcHBlbiBpcyBpZiB0aGlzIHdhcyB1bm1vdW50ZWQsIGlmIGF0IGFsbC5cblxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgICB9XG5cbiAgICBpZiAoYS5yZXR1cm4gIT09IGIucmV0dXJuKSB7XG4gICAgICAvLyBUaGUgcmV0dXJuIHBvaW50ZXIgb2YgQSBhbmQgdGhlIHJldHVybiBwb2ludGVyIG9mIEIgcG9pbnQgdG8gZGlmZmVyZW50XG4gICAgICAvLyBmaWJlcnMuIFdlIGFzc3VtZSB0aGF0IHJldHVybiBwb2ludGVycyBuZXZlciBjcmlzcy1jcm9zcywgc28gQSBtdXN0XG4gICAgICAvLyBiZWxvbmcgdG8gdGhlIGNoaWxkIHNldCBvZiBBLnJldHVybiwgYW5kIEIgbXVzdCBiZWxvbmcgdG8gdGhlIGNoaWxkXG4gICAgICAvLyBzZXQgb2YgQi5yZXR1cm4uXG4gICAgICBhID0gcGFyZW50QTtcbiAgICAgIGIgPSBwYXJlbnRCO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGUgcmV0dXJuIHBvaW50ZXJzIHBvaW50IHRvIHRoZSBzYW1lIGZpYmVyLiBXZSdsbCBoYXZlIHRvIHVzZSB0aGVcbiAgICAgIC8vIGRlZmF1bHQsIHNsb3cgcGF0aDogc2NhbiB0aGUgY2hpbGQgc2V0cyBvZiBlYWNoIHBhcmVudCBhbHRlcm5hdGUgdG8gc2VlXG4gICAgICAvLyB3aGljaCBjaGlsZCBiZWxvbmdzIHRvIHdoaWNoIHNldC5cbiAgICAgIC8vXG4gICAgICAvLyBTZWFyY2ggcGFyZW50IEEncyBjaGlsZCBzZXRcbiAgICAgIHZhciBkaWRGaW5kQ2hpbGQgPSBmYWxzZTtcbiAgICAgIHZhciBfY2hpbGQgPSBwYXJlbnRBLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoX2NoaWxkKSB7XG4gICAgICAgIGlmIChfY2hpbGQgPT09IGEpIHtcbiAgICAgICAgICBkaWRGaW5kQ2hpbGQgPSB0cnVlO1xuICAgICAgICAgIGEgPSBwYXJlbnRBO1xuICAgICAgICAgIGIgPSBwYXJlbnRCO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKF9jaGlsZCA9PT0gYikge1xuICAgICAgICAgIGRpZEZpbmRDaGlsZCA9IHRydWU7XG4gICAgICAgICAgYiA9IHBhcmVudEE7XG4gICAgICAgICAgYSA9IHBhcmVudEI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBfY2hpbGQgPSBfY2hpbGQuc2libGluZztcbiAgICAgIH1cblxuICAgICAgaWYgKCFkaWRGaW5kQ2hpbGQpIHtcbiAgICAgICAgLy8gU2VhcmNoIHBhcmVudCBCJ3MgY2hpbGQgc2V0XG4gICAgICAgIF9jaGlsZCA9IHBhcmVudEIuY2hpbGQ7XG5cbiAgICAgICAgd2hpbGUgKF9jaGlsZCkge1xuICAgICAgICAgIGlmIChfY2hpbGQgPT09IGEpIHtcbiAgICAgICAgICAgIGRpZEZpbmRDaGlsZCA9IHRydWU7XG4gICAgICAgICAgICBhID0gcGFyZW50QjtcbiAgICAgICAgICAgIGIgPSBwYXJlbnRBO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKF9jaGlsZCA9PT0gYikge1xuICAgICAgICAgICAgZGlkRmluZENoaWxkID0gdHJ1ZTtcbiAgICAgICAgICAgIGIgPSBwYXJlbnRCO1xuICAgICAgICAgICAgYSA9IHBhcmVudEE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBfY2hpbGQgPSBfY2hpbGQuc2libGluZztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZGlkRmluZENoaWxkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGlsZCB3YXMgbm90IGZvdW5kIGluIGVpdGhlciBwYXJlbnQgc2V0LiBUaGlzIGluZGljYXRlcyBhIGJ1ZyAnICsgJ2luIFJlYWN0IHJlbGF0ZWQgdG8gdGhlIHJldHVybiBwb2ludGVyLiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhLmFsdGVybmF0ZSAhPT0gYikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmV0dXJuIGZpYmVycyBzaG91bGQgYWx3YXlzIGJlIGVhY2ggb3RoZXJzJyBhbHRlcm5hdGVzLiBcIiArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfSAvLyBJZiB0aGUgcm9vdCBpcyBub3QgYSBob3N0IGNvbnRhaW5lciwgd2UncmUgaW4gYSBkaXNjb25uZWN0ZWQgdHJlZS4gSS5lLlxuICAvLyB1bm1vdW50ZWQuXG5cblxuICBpZiAoYS50YWcgIT09IEhvc3RSb290KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCBub2RlIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuJyk7XG4gIH1cblxuICBpZiAoYS5zdGF0ZU5vZGUuY3VycmVudCA9PT0gYSkge1xuICAgIC8vIFdlJ3ZlIGRldGVybWluZWQgdGhhdCBBIGlzIHRoZSBjdXJyZW50IGJyYW5jaC5cbiAgICByZXR1cm4gZmliZXI7XG4gIH0gLy8gT3RoZXJ3aXNlIEIgaGFzIHRvIGJlIGN1cnJlbnQgYnJhbmNoLlxuXG5cbiAgcmV0dXJuIGFsdGVybmF0ZTtcbn1cbmZ1bmN0aW9uIGZpbmRDdXJyZW50SG9zdEZpYmVyKHBhcmVudCkge1xuICB2YXIgY3VycmVudFBhcmVudCA9IGZpbmRDdXJyZW50RmliZXJVc2luZ1Nsb3dQYXRoKHBhcmVudCk7XG4gIHJldHVybiBjdXJyZW50UGFyZW50ICE9PSBudWxsID8gZmluZEN1cnJlbnRIb3N0RmliZXJJbXBsKGN1cnJlbnRQYXJlbnQpIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZmluZEN1cnJlbnRIb3N0RmliZXJJbXBsKG5vZGUpIHtcbiAgLy8gTmV4dCB3ZSdsbCBkcmlsbCBkb3duIHRoaXMgY29tcG9uZW50IHRvIGZpbmQgdGhlIGZpcnN0IEhvc3RDb21wb25lbnQvVGV4dC5cbiAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IG5vZGUudGFnID09PSBIb3N0VGV4dCkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICB2YXIgbWF0Y2ggPSBmaW5kQ3VycmVudEhvc3RGaWJlckltcGwoY2hpbGQpO1xuXG4gICAgaWYgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfVxuXG4gICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZpbmRDdXJyZW50SG9zdEZpYmVyV2l0aE5vUG9ydGFscyhwYXJlbnQpIHtcbiAgdmFyIGN1cnJlbnRQYXJlbnQgPSBmaW5kQ3VycmVudEZpYmVyVXNpbmdTbG93UGF0aChwYXJlbnQpO1xuICByZXR1cm4gY3VycmVudFBhcmVudCAhPT0gbnVsbCA/IGZpbmRDdXJyZW50SG9zdEZpYmVyV2l0aE5vUG9ydGFsc0ltcGwoY3VycmVudFBhcmVudCkgOiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudEhvc3RGaWJlcldpdGhOb1BvcnRhbHNJbXBsKG5vZGUpIHtcbiAgLy8gTmV4dCB3ZSdsbCBkcmlsbCBkb3duIHRoaXMgY29tcG9uZW50IHRvIGZpbmQgdGhlIGZpcnN0IEhvc3RDb21wb25lbnQvVGV4dC5cbiAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IG5vZGUudGFnID09PSBIb3N0VGV4dCkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICBpZiAoY2hpbGQudGFnICE9PSBIb3N0UG9ydGFsKSB7XG4gICAgICB2YXIgbWF0Y2ggPSBmaW5kQ3VycmVudEhvc3RGaWJlcldpdGhOb1BvcnRhbHNJbXBsKGNoaWxkKTtcblxuICAgICAgaWYgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8gVGhpcyBtb2R1bGUgb25seSBleGlzdHMgYXMgYW4gRVNNIHdyYXBwZXIgYXJvdW5kIHRoZSBleHRlcm5hbCBDb21tb25KU1xudmFyIHNjaGVkdWxlQ2FsbGJhY2sgPSBTY2hlZHVsZXIudW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjaztcbnZhciBjYW5jZWxDYWxsYmFjayA9IFNjaGVkdWxlci51bnN0YWJsZV9jYW5jZWxDYWxsYmFjaztcbnZhciBzaG91bGRZaWVsZCA9IFNjaGVkdWxlci51bnN0YWJsZV9zaG91bGRZaWVsZDtcbnZhciByZXF1ZXN0UGFpbnQgPSBTY2hlZHVsZXIudW5zdGFibGVfcmVxdWVzdFBhaW50O1xudmFyIG5vdyA9IFNjaGVkdWxlci51bnN0YWJsZV9ub3c7XG52YXIgZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwgPSBTY2hlZHVsZXIudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWw7XG52YXIgSW1tZWRpYXRlUHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfSW1tZWRpYXRlUHJpb3JpdHk7XG52YXIgVXNlckJsb2NraW5nUHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHk7XG52YXIgTm9ybWFsUHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfTm9ybWFsUHJpb3JpdHk7XG52YXIgTG93UHJpb3JpdHkgPSBTY2hlZHVsZXIudW5zdGFibGVfTG93UHJpb3JpdHk7XG52YXIgSWRsZVByaW9yaXR5ID0gU2NoZWR1bGVyLnVuc3RhYmxlX0lkbGVQcmlvcml0eTtcbi8vIHRoaXMgZG9lc24ndCBhY3R1YWxseSBleGlzdCBvbiB0aGUgc2NoZWR1bGVyLCBidXQgaXQgKmRvZXMqXG4vLyBvbiBzY2hlZHVsZXIvdW5zdGFibGVfbW9jaywgd2hpY2ggd2UnbGwgbmVlZCBmb3IgaW50ZXJuYWwgdGVzdGluZ1xudmFyIHVuc3RhYmxlX3lpZWxkVmFsdWUgPSBTY2hlZHVsZXIudW5zdGFibGVfeWllbGRWYWx1ZTtcbnZhciB1bnN0YWJsZV9zZXREaXNhYmxlWWllbGRWYWx1ZSA9IFNjaGVkdWxlci51bnN0YWJsZV9zZXREaXNhYmxlWWllbGRWYWx1ZTtcblxudmFyIHJlbmRlcmVySUQgPSBudWxsO1xudmFyIGluamVjdGVkSG9vayA9IG51bGw7XG52YXIgaW5qZWN0ZWRQcm9maWxpbmdIb29rcyA9IG51bGw7XG52YXIgaGFzTG9nZ2VkRXJyb3IgPSBmYWxzZTtcbnZhciBpc0RldlRvb2xzUHJlc2VudCA9IHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnO1xuZnVuY3Rpb24gaW5qZWN0SW50ZXJuYWxzKGludGVybmFscykge1xuICBpZiAodHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBObyBEZXZUb29sc1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBob29rID0gX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fO1xuXG4gIGlmIChob29rLmlzRGlzYWJsZWQpIHtcbiAgICAvLyBUaGlzIGlzbid0IGEgcmVhbCBwcm9wZXJ0eSBvbiB0aGUgaG9vaywgYnV0IGl0IGNhbiBiZSBzZXQgdG8gb3B0IG91dFxuICAgIC8vIG9mIERldlRvb2xzIGludGVncmF0aW9uIGFuZCBhc3NvY2lhdGVkIHdhcm5pbmdzIGFuZCBsb2dzLlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMzg3N1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKCFob29rLnN1cHBvcnRzRmliZXIpIHtcbiAgICB7XG4gICAgICBlcnJvcignVGhlIGluc3RhbGxlZCB2ZXJzaW9uIG9mIFJlYWN0IERldlRvb2xzIGlzIHRvbyBvbGQgYW5kIHdpbGwgbm90IHdvcmsgJyArICd3aXRoIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgUmVhY3QuIFBsZWFzZSB1cGRhdGUgUmVhY3QgRGV2VG9vbHMuICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3JlYWN0LWRldnRvb2xzJyk7XG4gICAgfSAvLyBEZXZUb29scyBleGlzdHMsIGV2ZW4gdGhvdWdoIGl0IGRvZXNuJ3Qgc3VwcG9ydCBGaWJlci5cblxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB0cnkge1xuICAgIGlmIChlbmFibGVTY2hlZHVsaW5nUHJvZmlsZXIpIHtcbiAgICAgIC8vIENvbmRpdGlvbmFsbHkgaW5qZWN0IHRoZXNlIGhvb2tzIG9ubHkgaWYgVGltZWxpbmUgcHJvZmlsZXIgaXMgc3VwcG9ydGVkIGJ5IHRoaXMgYnVpbGQuXG4gICAgICAvLyBUaGlzIGdpdmVzIERldlRvb2xzIGEgd2F5IHRvIGZlYXR1cmUgZGV0ZWN0IHRoYXQgaXNuJ3QgdGllZCB0byB2ZXJzaW9uIG51bWJlclxuICAgICAgLy8gKHNpbmNlIHByb2ZpbGluZyBhbmQgdGltZWxpbmUgYXJlIGNvbnRyb2xsZWQgYnkgZGlmZmVyZW50IGZlYXR1cmUgZmxhZ3MpLlxuICAgICAgaW50ZXJuYWxzID0gYXNzaWduKHt9LCBpbnRlcm5hbHMsIHtcbiAgICAgICAgZ2V0TGFuZUxhYmVsTWFwOiBnZXRMYW5lTGFiZWxNYXAsXG4gICAgICAgIGluamVjdFByb2ZpbGluZ0hvb2tzOiBpbmplY3RQcm9maWxpbmdIb29rc1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVuZGVyZXJJRCA9IGhvb2suaW5qZWN0KGludGVybmFscyk7IC8vIFdlIGhhdmUgc3VjY2Vzc2Z1bGx5IGluamVjdGVkLCBzbyBub3cgaXQgaXMgc2FmZSB0byBzZXQgdXAgaG9va3MuXG5cbiAgICBpbmplY3RlZEhvb2sgPSBob29rO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICAvLyBDYXRjaCBhbGwgZXJyb3JzIGJlY2F1c2UgaXQgaXMgdW5zYWZlIHRvIHRocm93IGR1cmluZyBpbml0aWFsaXphdGlvbi5cbiAgICB7XG4gICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcy4nLCBlcnIpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChob29rLmNoZWNrRENFKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgcmVhbCBEZXZUb29scy5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUaGlzIGlzIGxpa2VseSBhIGhvb2sgaW5zdGFsbGVkIGJ5IEZhc3QgUmVmcmVzaCBydW50aW1lLlxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gb25TY2hlZHVsZVJvb3Qocm9vdCwgY2hpbGRyZW4pIHtcbiAge1xuICAgIGlmIChpbmplY3RlZEhvb2sgJiYgdHlwZW9mIGluamVjdGVkSG9vay5vblNjaGVkdWxlRmliZXJSb290ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbmplY3RlZEhvb2sub25TY2hlZHVsZUZpYmVyUm9vdChyZW5kZXJlcklELCByb290LCBjaGlsZHJlbik7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKCAhaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uQ29tbWl0Um9vdChyb290LCBldmVudFByaW9yaXR5KSB7XG4gIGlmIChpbmplY3RlZEhvb2sgJiYgdHlwZW9mIGluamVjdGVkSG9vay5vbkNvbW1pdEZpYmVyUm9vdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICB2YXIgZGlkRXJyb3IgPSAocm9vdC5jdXJyZW50LmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IERpZENhcHR1cmU7XG5cbiAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyKSB7XG4gICAgICAgIHZhciBzY2hlZHVsZXJQcmlvcml0eTtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50UHJpb3JpdHkpIHtcbiAgICAgICAgICBjYXNlIERpc2NyZXRlRXZlbnRQcmlvcml0eTpcbiAgICAgICAgICAgIHNjaGVkdWxlclByaW9yaXR5ID0gSW1tZWRpYXRlUHJpb3JpdHk7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgQ29udGludW91c0V2ZW50UHJpb3JpdHk6XG4gICAgICAgICAgICBzY2hlZHVsZXJQcmlvcml0eSA9IFVzZXJCbG9ja2luZ1ByaW9yaXR5O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlIERlZmF1bHRFdmVudFByaW9yaXR5OlxuICAgICAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHkgPSBOb3JtYWxQcmlvcml0eTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSBJZGxlRXZlbnRQcmlvcml0eTpcbiAgICAgICAgICAgIHNjaGVkdWxlclByaW9yaXR5ID0gSWRsZVByaW9yaXR5O1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHkgPSBOb3JtYWxQcmlvcml0eTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaW5qZWN0ZWRIb29rLm9uQ29tbWl0RmliZXJSb290KHJlbmRlcmVySUQsIHJvb3QsIHNjaGVkdWxlclByaW9yaXR5LCBkaWRFcnJvcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbmplY3RlZEhvb2sub25Db21taXRGaWJlclJvb3QocmVuZGVyZXJJRCwgcm9vdCwgdW5kZWZpbmVkLCBkaWRFcnJvcik7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB7XG4gICAgICAgIGlmICghaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uUG9zdENvbW1pdFJvb3Qocm9vdCkge1xuICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2sub25Qb3N0Q29tbWl0RmliZXJSb290ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGluamVjdGVkSG9vay5vblBvc3RDb21taXRGaWJlclJvb3QocmVuZGVyZXJJRCwgcm9vdCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB7XG4gICAgICAgIGlmICghaGFzTG9nZ2VkRXJyb3IpIHtcbiAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignUmVhY3QgaW5zdHJ1bWVudGF0aW9uIGVuY291bnRlcmVkIGFuIGVycm9yOiAlcycsIGVycik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG9uQ29tbWl0VW5tb3VudChmaWJlcikge1xuICBpZiAoaW5qZWN0ZWRIb29rICYmIHR5cGVvZiBpbmplY3RlZEhvb2sub25Db21taXRGaWJlclVubW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgaW5qZWN0ZWRIb29rLm9uQ29tbWl0RmliZXJVbm1vdW50KHJlbmRlcmVySUQsIGZpYmVyKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHtcbiAgICAgICAgaWYgKCFoYXNMb2dnZWRFcnJvcikge1xuICAgICAgICAgIGhhc0xvZ2dlZEVycm9yID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCdSZWFjdCBpbnN0cnVtZW50YXRpb24gZW5jb3VudGVyZWQgYW4gZXJyb3I6ICVzJywgZXJyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMobmV3SXNTdHJpY3RNb2RlKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIHVuc3RhYmxlX3lpZWxkVmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIFdlJ3JlIGluIGEgdGVzdCBiZWNhdXNlIFNjaGVkdWxlci51bnN0YWJsZV95aWVsZFZhbHVlIG9ubHkgZXhpc3RzXG4gICAgICAvLyBpbiBTY2hlZHVsZXJNb2NrLiBUbyByZWR1Y2UgdGhlIG5vaXNlIGluIHN0cmljdCBtb2RlIHRlc3RzLFxuICAgICAgLy8gc3VwcHJlc3Mgd2FybmluZ3MgYW5kIGRpc2FibGUgc2NoZWR1bGVyIHlpZWxkaW5nIGR1cmluZyB0aGUgZG91YmxlIHJlbmRlclxuICAgICAgdW5zdGFibGVfc2V0RGlzYWJsZVlpZWxkVmFsdWUobmV3SXNTdHJpY3RNb2RlKTtcbiAgICAgIHNldFN1cHByZXNzV2FybmluZyhuZXdJc1N0cmljdE1vZGUpO1xuICAgIH1cblxuICAgIGlmIChpbmplY3RlZEhvb2sgJiYgdHlwZW9mIGluamVjdGVkSG9vay5zZXRTdHJpY3RNb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpbmplY3RlZEhvb2suc2V0U3RyaWN0TW9kZShyZW5kZXJlcklELCBuZXdJc1N0cmljdE1vZGUpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoIWhhc0xvZ2dlZEVycm9yKSB7XG4gICAgICAgICAgICBoYXNMb2dnZWRFcnJvciA9IHRydWU7XG5cbiAgICAgICAgICAgIGVycm9yKCdSZWFjdCBpbnN0cnVtZW50YXRpb24gZW5jb3VudGVyZWQgYW4gZXJyb3I6ICVzJywgZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn0gLy8gUHJvZmlsZXIgQVBJIGhvb2tzXG5cbmZ1bmN0aW9uIGluamVjdFByb2ZpbGluZ0hvb2tzKHByb2ZpbGluZ0hvb2tzKSB7XG4gIGluamVjdGVkUHJvZmlsaW5nSG9va3MgPSBwcm9maWxpbmdIb29rcztcbn1cblxuZnVuY3Rpb24gZ2V0TGFuZUxhYmVsTWFwKCkge1xuICB7XG4gICAgdmFyIG1hcCA9IG5ldyBNYXAoKTtcbiAgICB2YXIgbGFuZSA9IDE7XG5cbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgVG90YWxMYW5lczsgaW5kZXgrKykge1xuICAgICAgdmFyIGxhYmVsID0gZ2V0TGFiZWxGb3JMYW5lKGxhbmUpO1xuICAgICAgbWFwLnNldChsYW5lLCBsYWJlbCk7XG4gICAgICBsYW5lICo9IDI7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrQ29tbWl0U3RhcnRlZChsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbW1pdFN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbW1pdFN0YXJ0ZWQobGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbW1pdFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tbWl0U3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tbWl0U3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQoZmliZXIpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkKGZpYmVyKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0TW91bnRTdGFydGVkKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RhcnRlZChmaWJlcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0TW91bnRTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0TW91bnRTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdFVubW91bnRTdGFydGVkKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdFVubW91bnRTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0YXJ0ZWQoZmliZXIpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZChmaWJlcikge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdGFydGVkKGZpYmVyKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RNb3VudFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RNb3VudFN0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RhcnRlZChmaWJlcikge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RhcnRlZChmaWJlcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0VW5tb3VudFN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0VW5tb3VudFN0b3BwZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrQ29tcG9uZW50RXJyb3JlZChmaWJlciwgdGhyb3duVmFsdWUsIGxhbmVzKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50RXJyb3JlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50RXJyb3JlZChmaWJlciwgdGhyb3duVmFsdWUsIGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtDb21wb25lbnRTdXNwZW5kZWQoZmliZXIsIHdha2VhYmxlLCBsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0NvbXBvbmVudFN1c3BlbmRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrQ29tcG9uZW50U3VzcGVuZGVkKGZpYmVyLCB3YWtlYWJsZSwgbGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya0xheW91dEVmZmVjdHNTdGFydGVkKGxhbmVzKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrTGF5b3V0RWZmZWN0c1N0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya0xheW91dEVmZmVjdHNTdGFydGVkKGxhbmVzKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtMYXlvdXRFZmZlY3RzU3RvcHBlZCgpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtMYXlvdXRFZmZlY3RzU3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrTGF5b3V0RWZmZWN0c1N0b3BwZWQoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtQYXNzaXZlRWZmZWN0c1N0YXJ0ZWQobGFuZXMpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtQYXNzaXZlRWZmZWN0c1N0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1Bhc3NpdmVFZmZlY3RzU3RhcnRlZChsYW5lcyk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrUGFzc2l2ZUVmZmVjdHNTdG9wcGVkKCkge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1Bhc3NpdmVFZmZlY3RzU3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUGFzc2l2ZUVmZmVjdHNTdG9wcGVkKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrUmVuZGVyU3RhcnRlZChsYW5lcykge1xuICB7XG4gICAgaWYgKGluamVjdGVkUHJvZmlsaW5nSG9va3MgIT09IG51bGwgJiYgdHlwZW9mIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclN0YXJ0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1JlbmRlclN0YXJ0ZWQobGFuZXMpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlcllpZWxkZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyWWllbGRlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyWWllbGRlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlclN0b3BwZWQoKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU3RvcHBlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU3RvcHBlZCgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1JlbmRlclNjaGVkdWxlZChsYW5lKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrUmVuZGVyU2NoZWR1bGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtSZW5kZXJTY2hlZHVsZWQobGFuZSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBtYXJrRm9yY2VVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpIHtcbiAge1xuICAgIGlmIChpbmplY3RlZFByb2ZpbGluZ0hvb2tzICE9PSBudWxsICYmIHR5cGVvZiBpbmplY3RlZFByb2ZpbGluZ0hvb2tzLm1hcmtGb3JjZVVwZGF0ZVNjaGVkdWxlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrRm9yY2VVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gbWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKSB7XG4gIHtcbiAgICBpZiAoaW5qZWN0ZWRQcm9maWxpbmdIb29rcyAhPT0gbnVsbCAmJiB0eXBlb2YgaW5qZWN0ZWRQcm9maWxpbmdIb29rcy5tYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGluamVjdGVkUHJvZmlsaW5nSG9va3MubWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIE5vTW9kZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMDsgLy8gVE9ETzogUmVtb3ZlIENvbmN1cnJlbnRNb2RlIGJ5IHJlYWRpbmcgZnJvbSB0aGUgcm9vdCB0YWcgaW5zdGVhZFxuXG52YXIgQ29uY3VycmVudE1vZGUgPVxuLyogICAgICAgICAgICAgICAgICovXG4xO1xudmFyIFByb2ZpbGVNb2RlID1cbi8qICAgICAgICAgICAgICAgICAgICAqL1xuMjtcbnZhciBTdHJpY3RMZWdhY3lNb2RlID1cbi8qICAgICAgICAgICAgICAgKi9cbjg7XG52YXIgU3RyaWN0RWZmZWN0c01vZGUgPVxuLyogICAgICAgICAgICAgICovXG4xNjtcblxuLy8gVE9ETzogVGhpcyBpcyBwcmV0dHkgd2VsbCBzdXBwb3J0ZWQgYnkgYnJvd3NlcnMuIE1heWJlIHdlIGNhbiBkcm9wIGl0LlxudmFyIGNsejMyID0gTWF0aC5jbHozMiA/IE1hdGguY2x6MzIgOiBjbHozMkZhbGxiYWNrOyAvLyBDb3VudCBsZWFkaW5nIHplcm9zLlxuLy8gQmFzZWQgb246XG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9NYXRoL2NsejMyXG5cbnZhciBsb2cgPSBNYXRoLmxvZztcbnZhciBMTjIgPSBNYXRoLkxOMjtcblxuZnVuY3Rpb24gY2x6MzJGYWxsYmFjayh4KSB7XG4gIHZhciBhc1VpbnQgPSB4ID4+PiAwO1xuXG4gIGlmIChhc1VpbnQgPT09IDApIHtcbiAgICByZXR1cm4gMzI7XG4gIH1cblxuICByZXR1cm4gMzEgLSAobG9nKGFzVWludCkgLyBMTjIgfCAwKSB8IDA7XG59XG5cbi8vIElmIHRob3NlIHZhbHVlcyBhcmUgY2hhbmdlZCB0aGF0IHBhY2thZ2Ugc2hvdWxkIGJlIHJlYnVpbHQgYW5kIHJlZGVwbG95ZWQuXG5cbnZhciBUb3RhbExhbmVzID0gMzE7XG52YXIgTm9MYW5lcyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG4wO1xudmFyIE5vTGFuZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjA7XG52YXIgU3luY0xhbmUgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuMTtcbnZhciBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lID1cbi8qICAgICovXG4yO1xudmFyIElucHV0Q29udGludW91c0xhbmUgPVxuLyogICAgICAgICAgICAgKi9cbjQ7XG52YXIgRGVmYXVsdEh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgICAqL1xuODtcbnZhciBEZWZhdWx0TGFuZSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICovXG4xNjtcbnZhciBUcmFuc2l0aW9uSHlkcmF0aW9uTGFuZSA9XG4vKiAgICAgICAgICAgICAgICAqL1xuMzI7XG52YXIgVHJhbnNpdGlvbkxhbmVzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuNDE5NDI0MDtcbnZhciBUcmFuc2l0aW9uTGFuZTEgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuNjQ7XG52YXIgVHJhbnNpdGlvbkxhbmUyID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEyODtcbnZhciBUcmFuc2l0aW9uTGFuZTMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAqL1xuMjU2O1xudmFyIFRyYW5zaXRpb25MYW5lNCA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICovXG41MTI7XG52YXIgVHJhbnNpdGlvbkxhbmU1ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEwMjQ7XG52YXIgVHJhbnNpdGlvbkxhbmU2ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjIwNDg7XG52YXIgVHJhbnNpdGlvbkxhbmU3ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjQwOTY7XG52YXIgVHJhbnNpdGlvbkxhbmU4ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjgxOTI7XG52YXIgVHJhbnNpdGlvbkxhbmU5ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjE2Mzg0O1xudmFyIFRyYW5zaXRpb25MYW5lMTAgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG4zMjc2ODtcbnZhciBUcmFuc2l0aW9uTGFuZTExID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuNjU1MzY7XG52YXIgVHJhbnNpdGlvbkxhbmUxMiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEzMTA3MjtcbnZhciBUcmFuc2l0aW9uTGFuZTEzID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAqL1xuMjYyMTQ0O1xudmFyIFRyYW5zaXRpb25MYW5lMTQgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICovXG41MjQyODg7XG52YXIgVHJhbnNpdGlvbkxhbmUxNSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjEwNDg1NzY7XG52YXIgVHJhbnNpdGlvbkxhbmUxNiA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgKi9cbjIwOTcxNTI7XG52YXIgUmV0cnlMYW5lcyA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMTMwMDIzNDI0O1xudmFyIFJldHJ5TGFuZTEgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG40MTk0MzA0O1xudmFyIFJldHJ5TGFuZTIgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG44Mzg4NjA4O1xudmFyIFJldHJ5TGFuZTMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4xNjc3NzIxNjtcbnZhciBSZXRyeUxhbmU0ID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuMzM1NTQ0MzI7XG52YXIgUmV0cnlMYW5lNSA9XG4vKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjY3MTA4ODY0O1xudmFyIFNvbWVSZXRyeUxhbmUgPSBSZXRyeUxhbmUxO1xudmFyIFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgKi9cbjEzNDIxNzcyODtcbnZhciBOb25JZGxlTGFuZXMgPVxuLyogICAgICAgICAgICAgICAgICAgICAgICAgICovXG4yNjg0MzU0NTU7XG52YXIgSWRsZUh5ZHJhdGlvbkxhbmUgPVxuLyogICAgICAgICAgICAgICAqL1xuMjY4NDM1NDU2O1xudmFyIElkbGVMYW5lID1cbi8qICAgICAgICAgICAgICAgICAgICAgICAgKi9cbjUzNjg3MDkxMjtcbnZhciBPZmZzY3JlZW5MYW5lID1cbi8qICAgICAgICAgICAgICAgICAgICovXG4xMDczNzQxODI0OyAvLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgZm9yIHRoZSBleHBlcmltZW50YWwgdGltZWxpbmUgKHJlYWN0LWRldnRvb2xzLXRpbWVsaW5lKVxuLy8gSXQgc2hvdWxkIGJlIGtlcHQgaW4gc3luYyB3aXRoIHRoZSBMYW5lcyB2YWx1ZXMgYWJvdmUuXG5cbmZ1bmN0aW9uIGdldExhYmVsRm9yTGFuZShsYW5lKSB7XG4gIHtcbiAgICBpZiAobGFuZSAmIFN5bmNMYW5lKSB7XG4gICAgICByZXR1cm4gJ1N5bmMnO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZSkge1xuICAgICAgcmV0dXJuICdJbnB1dENvbnRpbnVvdXNIeWRyYXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgSW5wdXRDb250aW51b3VzTGFuZSkge1xuICAgICAgcmV0dXJuICdJbnB1dENvbnRpbnVvdXMnO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgRGVmYXVsdEh5ZHJhdGlvbkxhbmUpIHtcbiAgICAgIHJldHVybiAnRGVmYXVsdEh5ZHJhdGlvbic7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBEZWZhdWx0TGFuZSkge1xuICAgICAgcmV0dXJuICdEZWZhdWx0JztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIFRyYW5zaXRpb25IeWRyYXRpb25MYW5lKSB7XG4gICAgICByZXR1cm4gJ1RyYW5zaXRpb25IeWRyYXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgVHJhbnNpdGlvbkxhbmVzKSB7XG4gICAgICByZXR1cm4gJ1RyYW5zaXRpb24nO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgUmV0cnlMYW5lcykge1xuICAgICAgcmV0dXJuICdSZXRyeSc7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBTZWxlY3RpdmVIeWRyYXRpb25MYW5lKSB7XG4gICAgICByZXR1cm4gJ1NlbGVjdGl2ZUh5ZHJhdGlvbic7XG4gICAgfVxuXG4gICAgaWYgKGxhbmUgJiBJZGxlSHlkcmF0aW9uTGFuZSkge1xuICAgICAgcmV0dXJuICdJZGxlSHlkcmF0aW9uJztcbiAgICB9XG5cbiAgICBpZiAobGFuZSAmIElkbGVMYW5lKSB7XG4gICAgICByZXR1cm4gJ0lkbGUnO1xuICAgIH1cblxuICAgIGlmIChsYW5lICYgT2Zmc2NyZWVuTGFuZSkge1xuICAgICAgcmV0dXJuICdPZmZzY3JlZW4nO1xuICAgIH1cbiAgfVxufVxudmFyIE5vVGltZXN0YW1wID0gLTE7XG52YXIgbmV4dFRyYW5zaXRpb25MYW5lID0gVHJhbnNpdGlvbkxhbmUxO1xudmFyIG5leHRSZXRyeUxhbmUgPSBSZXRyeUxhbmUxO1xuXG5mdW5jdGlvbiBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhsYW5lcykge1xuICBzd2l0Y2ggKGdldEhpZ2hlc3RQcmlvcml0eUxhbmUobGFuZXMpKSB7XG4gICAgY2FzZSBTeW5jTGFuZTpcbiAgICAgIHJldHVybiBTeW5jTGFuZTtcblxuICAgIGNhc2UgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBJbnB1dENvbnRpbnVvdXNMYW5lOlxuICAgICAgcmV0dXJuIElucHV0Q29udGludW91c0xhbmU7XG5cbiAgICBjYXNlIERlZmF1bHRIeWRyYXRpb25MYW5lOlxuICAgICAgcmV0dXJuIERlZmF1bHRIeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBEZWZhdWx0TGFuZTpcbiAgICAgIHJldHVybiBEZWZhdWx0TGFuZTtcblxuICAgIGNhc2UgVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU6XG4gICAgICByZXR1cm4gVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU7XG5cbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lODpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lOTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTA6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTExOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE0OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTY6XG4gICAgICByZXR1cm4gbGFuZXMgJiBUcmFuc2l0aW9uTGFuZXM7XG5cbiAgICBjYXNlIFJldHJ5TGFuZTE6XG4gICAgY2FzZSBSZXRyeUxhbmUyOlxuICAgIGNhc2UgUmV0cnlMYW5lMzpcbiAgICBjYXNlIFJldHJ5TGFuZTQ6XG4gICAgY2FzZSBSZXRyeUxhbmU1OlxuICAgICAgcmV0dXJuIGxhbmVzICYgUmV0cnlMYW5lcztcblxuICAgIGNhc2UgU2VsZWN0aXZlSHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBTZWxlY3RpdmVIeWRyYXRpb25MYW5lO1xuXG4gICAgY2FzZSBJZGxlSHlkcmF0aW9uTGFuZTpcbiAgICAgIHJldHVybiBJZGxlSHlkcmF0aW9uTGFuZTtcblxuICAgIGNhc2UgSWRsZUxhbmU6XG4gICAgICByZXR1cm4gSWRsZUxhbmU7XG5cbiAgICBjYXNlIE9mZnNjcmVlbkxhbmU6XG4gICAgICByZXR1cm4gT2Zmc2NyZWVuTGFuZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIGVycm9yKCdTaG91bGQgaGF2ZSBmb3VuZCBtYXRjaGluZyBsYW5lcy4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH0gLy8gVGhpcyBzaG91bGRuJ3QgYmUgcmVhY2hhYmxlLCBidXQgYXMgYSBmYWxsYmFjaywgcmV0dXJuIHRoZSBlbnRpcmUgYml0bWFzay5cblxuXG4gICAgICByZXR1cm4gbGFuZXM7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TmV4dExhbmVzKHJvb3QsIHdpcExhbmVzKSB7XG4gIC8vIEVhcmx5IGJhaWxvdXQgaWYgdGhlcmUncyBubyBwZW5kaW5nIHdvcmsgbGVmdC5cbiAgdmFyIHBlbmRpbmdMYW5lcyA9IHJvb3QucGVuZGluZ0xhbmVzO1xuXG4gIGlmIChwZW5kaW5nTGFuZXMgPT09IE5vTGFuZXMpIHtcbiAgICByZXR1cm4gTm9MYW5lcztcbiAgfVxuXG4gIHZhciBuZXh0TGFuZXMgPSBOb0xhbmVzO1xuICB2YXIgc3VzcGVuZGVkTGFuZXMgPSByb290LnN1c3BlbmRlZExhbmVzO1xuICB2YXIgcGluZ2VkTGFuZXMgPSByb290LnBpbmdlZExhbmVzOyAvLyBEbyBub3Qgd29yayBvbiBhbnkgaWRsZSB3b3JrIHVudGlsIGFsbCB0aGUgbm9uLWlkbGUgd29yayBoYXMgZmluaXNoZWQsXG4gIC8vIGV2ZW4gaWYgdGhlIHdvcmsgaXMgc3VzcGVuZGVkLlxuXG4gIHZhciBub25JZGxlUGVuZGluZ0xhbmVzID0gcGVuZGluZ0xhbmVzICYgTm9uSWRsZUxhbmVzO1xuXG4gIGlmIChub25JZGxlUGVuZGluZ0xhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgdmFyIG5vbklkbGVVbmJsb2NrZWRMYW5lcyA9IG5vbklkbGVQZW5kaW5nTGFuZXMgJiB+c3VzcGVuZGVkTGFuZXM7XG5cbiAgICBpZiAobm9uSWRsZVVuYmxvY2tlZExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhub25JZGxlVW5ibG9ja2VkTGFuZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbm9uSWRsZVBpbmdlZExhbmVzID0gbm9uSWRsZVBlbmRpbmdMYW5lcyAmIHBpbmdlZExhbmVzO1xuXG4gICAgICBpZiAobm9uSWRsZVBpbmdlZExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICAgIG5leHRMYW5lcyA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmVzKG5vbklkbGVQaW5nZWRMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoZSBvbmx5IHJlbWFpbmluZyB3b3JrIGlzIElkbGUuXG4gICAgdmFyIHVuYmxvY2tlZExhbmVzID0gcGVuZGluZ0xhbmVzICYgfnN1c3BlbmRlZExhbmVzO1xuXG4gICAgaWYgKHVuYmxvY2tlZExhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyh1bmJsb2NrZWRMYW5lcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwaW5nZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICBuZXh0TGFuZXMgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhwaW5nZWRMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKG5leHRMYW5lcyA9PT0gTm9MYW5lcykge1xuICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgcmVhY2hhYmxlIGlmIHdlJ3JlIHN1c3BlbmRlZFxuICAgIC8vIFRPRE86IENvbnNpZGVyIHdhcm5pbmcgaW4gdGhpcyBwYXRoIGlmIGEgZmFsbGJhY2sgdGltZXIgaXMgbm90IHNjaGVkdWxlZC5cbiAgICByZXR1cm4gTm9MYW5lcztcbiAgfSAvLyBJZiB3ZSdyZSBhbHJlYWR5IGluIHRoZSBtaWRkbGUgb2YgYSByZW5kZXIsIHN3aXRjaGluZyBsYW5lcyB3aWxsIGludGVycnVwdFxuICAvLyBpdCBhbmQgd2UnbGwgbG9zZSBvdXIgcHJvZ3Jlc3MuIFdlIHNob3VsZCBvbmx5IGRvIHRoaXMgaWYgdGhlIG5ldyBsYW5lcyBhcmVcbiAgLy8gaGlnaGVyIHByaW9yaXR5LlxuXG5cbiAgaWYgKHdpcExhbmVzICE9PSBOb0xhbmVzICYmIHdpcExhbmVzICE9PSBuZXh0TGFuZXMgJiYgLy8gSWYgd2UgYWxyZWFkeSBzdXNwZW5kZWQgd2l0aCBhIGRlbGF5LCB0aGVuIGludGVycnVwdGluZyBpcyBmaW5lLiBEb24ndFxuICAvLyBib3RoZXIgd2FpdGluZyB1bnRpbCB0aGUgcm9vdCBpcyBjb21wbGV0ZS5cbiAgKHdpcExhbmVzICYgc3VzcGVuZGVkTGFuZXMpID09PSBOb0xhbmVzKSB7XG4gICAgdmFyIG5leHRMYW5lID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShuZXh0TGFuZXMpO1xuICAgIHZhciB3aXBMYW5lID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZSh3aXBMYW5lcyk7XG5cbiAgICBpZiAoIC8vIFRlc3RzIHdoZXRoZXIgdGhlIG5leHQgbGFuZSBpcyBlcXVhbCBvciBsb3dlciBwcmlvcml0eSB0aGFuIHRoZSB3aXBcbiAgICAvLyBvbmUuIFRoaXMgd29ya3MgYmVjYXVzZSB0aGUgYml0cyBkZWNyZWFzZSBpbiBwcmlvcml0eSBhcyB5b3UgZ28gbGVmdC5cbiAgICBuZXh0TGFuZSA+PSB3aXBMYW5lIHx8IC8vIERlZmF1bHQgcHJpb3JpdHkgdXBkYXRlcyBzaG91bGQgbm90IGludGVycnVwdCB0cmFuc2l0aW9uIHVwZGF0ZXMuIFRoZVxuICAgIC8vIG9ubHkgZGlmZmVyZW5jZSBiZXR3ZWVuIGRlZmF1bHQgdXBkYXRlcyBhbmQgdHJhbnNpdGlvbiB1cGRhdGVzIGlzIHRoYXRcbiAgICAvLyBkZWZhdWx0IHVwZGF0ZXMgZG8gbm90IHN1cHBvcnQgcmVmcmVzaCB0cmFuc2l0aW9ucy5cbiAgICBuZXh0TGFuZSA9PT0gRGVmYXVsdExhbmUgJiYgKHdpcExhbmUgJiBUcmFuc2l0aW9uTGFuZXMpICE9PSBOb0xhbmVzKSB7XG4gICAgICAvLyBLZWVwIHdvcmtpbmcgb24gdGhlIGV4aXN0aW5nIGluLXByb2dyZXNzIHRyZWUuIERvIG5vdCBpbnRlcnJ1cHQuXG4gICAgICByZXR1cm4gd2lwTGFuZXM7XG4gICAgfVxuICB9XG5cbiAgaWYgKChuZXh0TGFuZXMgJiBJbnB1dENvbnRpbnVvdXNMYW5lKSAhPT0gTm9MYW5lcykge1xuICAgIC8vIFdoZW4gdXBkYXRlcyBhcmUgc3luYyBieSBkZWZhdWx0LCB3ZSBlbnRhbmdsZSBjb250aW51b3VzIHByaW9yaXR5IHVwZGF0ZXNcbiAgICAvLyBhbmQgZGVmYXVsdCB1cGRhdGVzLCBzbyB0aGV5IHJlbmRlciBpbiB0aGUgc2FtZSBiYXRjaC4gVGhlIG9ubHkgcmVhc29uXG4gICAgLy8gdGhleSB1c2Ugc2VwYXJhdGUgbGFuZXMgaXMgYmVjYXVzZSBjb250aW51b3VzIHVwZGF0ZXMgc2hvdWxkIGludGVycnVwdFxuICAgIC8vIHRyYW5zaXRpb25zLCBidXQgZGVmYXVsdCB1cGRhdGVzIHNob3VsZCBub3QuXG4gICAgbmV4dExhbmVzIHw9IHBlbmRpbmdMYW5lcyAmIERlZmF1bHRMYW5lO1xuICB9IC8vIENoZWNrIGZvciBlbnRhbmdsZWQgbGFuZXMgYW5kIGFkZCB0aGVtIHRvIHRoZSBiYXRjaC5cbiAgLy9cbiAgLy8gQSBsYW5lIGlzIHNhaWQgdG8gYmUgZW50YW5nbGVkIHdpdGggYW5vdGhlciB3aGVuIGl0J3Mgbm90IGFsbG93ZWQgdG8gcmVuZGVyXG4gIC8vIGluIGEgYmF0Y2ggdGhhdCBkb2VzIG5vdCBhbHNvIGluY2x1ZGUgdGhlIG90aGVyIGxhbmUuIFR5cGljYWxseSB3ZSBkbyB0aGlzXG4gIC8vIHdoZW4gbXVsdGlwbGUgdXBkYXRlcyBoYXZlIHRoZSBzYW1lIHNvdXJjZSwgYW5kIHdlIG9ubHkgd2FudCB0byByZXNwb25kIHRvXG4gIC8vIHRoZSBtb3N0IHJlY2VudCBldmVudCBmcm9tIHRoYXQgc291cmNlLlxuICAvL1xuICAvLyBOb3RlIHRoYXQgd2UgYXBwbHkgZW50YW5nbGVtZW50cyAqYWZ0ZXIqIGNoZWNraW5nIGZvciBwYXJ0aWFsIHdvcmsgYWJvdmUuXG4gIC8vIFRoaXMgbWVhbnMgdGhhdCBpZiBhIGxhbmUgaXMgZW50YW5nbGVkIGR1cmluZyBhbiBpbnRlcmxlYXZlZCBldmVudCB3aGlsZVxuICAvLyBpdCdzIGFscmVhZHkgcmVuZGVyaW5nLCB3ZSB3b24ndCBpbnRlcnJ1cHQgaXQuIFRoaXMgaXMgaW50ZW50aW9uYWwsIHNpbmNlXG4gIC8vIGVudGFuZ2xlbWVudCBpcyB1c3VhbGx5IFwiYmVzdCBlZmZvcnRcIjogd2UnbGwgdHJ5IG91ciBiZXN0IHRvIHJlbmRlciB0aGVcbiAgLy8gbGFuZXMgaW4gdGhlIHNhbWUgYmF0Y2gsIGJ1dCBpdCdzIG5vdCB3b3J0aCB0aHJvd2luZyBvdXQgcGFydGlhbGx5XG4gIC8vIGNvbXBsZXRlZCB3b3JrIGluIG9yZGVyIHRvIGRvIGl0LlxuICAvLyBUT0RPOiBSZWNvbnNpZGVyIHRoaXMuIFRoZSBjb3VudGVyLWFyZ3VtZW50IGlzIHRoYXQgdGhlIHBhcnRpYWwgd29ya1xuICAvLyByZXByZXNlbnRzIGFuIGludGVybWVkaWF0ZSBzdGF0ZSwgd2hpY2ggd2UgZG9uJ3Qgd2FudCB0byBzaG93IHRvIHRoZSB1c2VyLlxuICAvLyBBbmQgYnkgc3BlbmRpbmcgZXh0cmEgdGltZSBmaW5pc2hpbmcgaXQsIHdlJ3JlIGluY3JlYXNpbmcgdGhlIGFtb3VudCBvZlxuICAvLyB0aW1lIGl0IHRha2VzIHRvIHNob3cgdGhlIGZpbmFsIHN0YXRlLCB3aGljaCBpcyB3aGF0IHRoZXkgYXJlIGFjdHVhbGx5XG4gIC8vIHdhaXRpbmcgZm9yLlxuICAvL1xuICAvLyBGb3IgdGhvc2UgZXhjZXB0aW9ucyB3aGVyZSBlbnRhbmdsZW1lbnQgaXMgc2VtYW50aWNhbGx5IGltcG9ydGFudCwgbGlrZVxuICAvLyB1c2VNdXRhYmxlU291cmNlLCB3ZSBzaG91bGQgZW5zdXJlIHRoYXQgdGhlcmUgaXMgbm8gcGFydGlhbCB3b3JrIGF0IHRoZVxuICAvLyB0aW1lIHdlIGFwcGx5IHRoZSBlbnRhbmdsZW1lbnQuXG5cblxuICB2YXIgZW50YW5nbGVkTGFuZXMgPSByb290LmVudGFuZ2xlZExhbmVzO1xuXG4gIGlmIChlbnRhbmdsZWRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgIHZhciBlbnRhbmdsZW1lbnRzID0gcm9vdC5lbnRhbmdsZW1lbnRzO1xuICAgIHZhciBsYW5lcyA9IG5leHRMYW5lcyAmIGVudGFuZ2xlZExhbmVzO1xuXG4gICAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgICBuZXh0TGFuZXMgfD0gZW50YW5nbGVtZW50c1tpbmRleF07XG4gICAgICBsYW5lcyAmPSB+bGFuZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV4dExhbmVzO1xufVxuZnVuY3Rpb24gZ2V0TW9zdFJlY2VudEV2ZW50VGltZShyb290LCBsYW5lcykge1xuICB2YXIgZXZlbnRUaW1lcyA9IHJvb3QuZXZlbnRUaW1lcztcbiAgdmFyIG1vc3RSZWNlbnRFdmVudFRpbWUgPSBOb1RpbWVzdGFtcDtcblxuICB3aGlsZSAobGFuZXMgPiAwKSB7XG4gICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIHZhciBldmVudFRpbWUgPSBldmVudFRpbWVzW2luZGV4XTtcblxuICAgIGlmIChldmVudFRpbWUgPiBtb3N0UmVjZW50RXZlbnRUaW1lKSB7XG4gICAgICBtb3N0UmVjZW50RXZlbnRUaW1lID0gZXZlbnRUaW1lO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG5cbiAgcmV0dXJuIG1vc3RSZWNlbnRFdmVudFRpbWU7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVFeHBpcmF0aW9uVGltZShsYW5lLCBjdXJyZW50VGltZSkge1xuICBzd2l0Y2ggKGxhbmUpIHtcbiAgICBjYXNlIFN5bmNMYW5lOlxuICAgIGNhc2UgSW5wdXRDb250aW51b3VzSHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIElucHV0Q29udGludW91c0xhbmU6XG4gICAgICAvLyBVc2VyIGludGVyYWN0aW9ucyBzaG91bGQgZXhwaXJlIHNsaWdodGx5IG1vcmUgcXVpY2tseS5cbiAgICAgIC8vXG4gICAgICAvLyBOT1RFOiBUaGlzIGlzIHNldCB0byB0aGUgY29ycmVzcG9uZGluZyBjb25zdGFudCBhcyBpbiBTY2hlZHVsZXIuanMuXG4gICAgICAvLyBXaGVuIHdlIG1hZGUgaXQgbGFyZ2VyLCBhIHByb2R1Y3QgbWV0cmljIGluIHd3dyByZWdyZXNzZWQsIHN1Z2dlc3RpbmdcbiAgICAgIC8vIHRoZXJlJ3MgYSB1c2VyIGludGVyYWN0aW9uIHRoYXQncyBiZWluZyBzdGFydmVkIGJ5IGEgc2VyaWVzIG9mXG4gICAgICAvLyBzeW5jaHJvbm91cyB1cGRhdGVzLiBJZiB0aGF0IHRoZW9yeSBpcyBjb3JyZWN0LCB0aGUgcHJvcGVyIHNvbHV0aW9uIGlzXG4gICAgICAvLyB0byBmaXggdGhlIHN0YXJ2YXRpb24uIEhvd2V2ZXIsIHRoaXMgc2NlbmFyaW8gc3VwcG9ydHMgdGhlIGlkZWEgdGhhdFxuICAgICAgLy8gZXhwaXJhdGlvbiB0aW1lcyBhcmUgYW4gaW1wb3J0YW50IHNhZmVndWFyZCB3aGVuIHN0YXJ2YXRpb25cbiAgICAgIC8vIGRvZXMgaGFwcGVuLlxuICAgICAgcmV0dXJuIGN1cnJlbnRUaW1lICsgMjUwO1xuXG4gICAgY2FzZSBEZWZhdWx0SHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIERlZmF1bHRMYW5lOlxuICAgIGNhc2UgVHJhbnNpdGlvbkh5ZHJhdGlvbkxhbmU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTQ6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTY6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTc6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTg6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTk6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEwOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTI6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTEzOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTU6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE2OlxuICAgICAgcmV0dXJuIGN1cnJlbnRUaW1lICsgNTAwMDtcblxuICAgIGNhc2UgUmV0cnlMYW5lMTpcbiAgICBjYXNlIFJldHJ5TGFuZTI6XG4gICAgY2FzZSBSZXRyeUxhbmUzOlxuICAgIGNhc2UgUmV0cnlMYW5lNDpcbiAgICBjYXNlIFJldHJ5TGFuZTU6XG4gICAgICAvLyBUT0RPOiBSZXRyaWVzIHNob3VsZCBiZSBhbGxvd2VkIHRvIGV4cGlyZSBpZiB0aGV5IGFyZSBDUFUgYm91bmQgZm9yXG4gICAgICAvLyB0b28gbG9uZywgYnV0IHdoZW4gSSBtYWRlIHRoaXMgY2hhbmdlIGl0IGNhdXNlZCBhIHNwaWtlIGluIGJyb3dzZXJcbiAgICAgIC8vIGNyYXNoZXMuIFRoZXJlIG11c3QgYmUgc29tZSBvdGhlciB1bmRlcmx5aW5nIGJ1Zzsgbm90IHN1cGVyIHVyZ2VudCBidXRcbiAgICAgIC8vIGlkZWFsbHkgc2hvdWxkIGZpZ3VyZSBvdXQgd2h5IGFuZCBmaXggaXQuIFVuZm9ydHVuYXRlbHkgd2UgZG9uJ3QgaGF2ZVxuICAgICAgLy8gYSByZXBybyBmb3IgdGhlIGNyYXNoZXMsIG9ubHkgZGV0ZWN0ZWQgdmlhIHByb2R1Y3Rpb24gbWV0cmljcy5cbiAgICAgIHJldHVybiBOb1RpbWVzdGFtcDtcblxuICAgIGNhc2UgU2VsZWN0aXZlSHlkcmF0aW9uTGFuZTpcbiAgICBjYXNlIElkbGVIeWRyYXRpb25MYW5lOlxuICAgIGNhc2UgSWRsZUxhbmU6XG4gICAgY2FzZSBPZmZzY3JlZW5MYW5lOlxuICAgICAgLy8gQW55dGhpbmcgaWRsZSBwcmlvcml0eSBvciBsb3dlciBzaG91bGQgbmV2ZXIgZXhwaXJlLlxuICAgICAgcmV0dXJuIE5vVGltZXN0YW1wO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHtcbiAgICAgICAgZXJyb3IoJ1Nob3VsZCBoYXZlIGZvdW5kIG1hdGNoaW5nIGxhbmVzLiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gTm9UaW1lc3RhbXA7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWFya1N0YXJ2ZWRMYW5lc0FzRXhwaXJlZChyb290LCBjdXJyZW50VGltZSkge1xuICAvLyBUT0RPOiBUaGlzIGdldHMgY2FsbGVkIGV2ZXJ5IHRpbWUgd2UgeWllbGQuIFdlIGNhbiBvcHRpbWl6ZSBieSBzdG9yaW5nXG4gIC8vIHRoZSBlYXJsaWVzdCBleHBpcmF0aW9uIHRpbWUgb24gdGhlIHJvb3QuIFRoZW4gdXNlIHRoYXQgdG8gcXVpY2tseSBiYWlsIG91dFxuICAvLyBvZiB0aGlzIGZ1bmN0aW9uLlxuICB2YXIgcGVuZGluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXM7XG4gIHZhciBzdXNwZW5kZWRMYW5lcyA9IHJvb3Quc3VzcGVuZGVkTGFuZXM7XG4gIHZhciBwaW5nZWRMYW5lcyA9IHJvb3QucGluZ2VkTGFuZXM7XG4gIHZhciBleHBpcmF0aW9uVGltZXMgPSByb290LmV4cGlyYXRpb25UaW1lczsgLy8gSXRlcmF0ZSB0aHJvdWdoIHRoZSBwZW5kaW5nIGxhbmVzIGFuZCBjaGVjayBpZiB3ZSd2ZSByZWFjaGVkIHRoZWlyXG4gIC8vIGV4cGlyYXRpb24gdGltZS4gSWYgc28sIHdlJ2xsIGFzc3VtZSB0aGUgdXBkYXRlIGlzIGJlaW5nIHN0YXJ2ZWQgYW5kIG1hcmtcbiAgLy8gaXQgYXMgZXhwaXJlZCB0byBmb3JjZSBpdCB0byBmaW5pc2guXG5cbiAgdmFyIGxhbmVzID0gcGVuZGluZ0xhbmVzO1xuXG4gIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICB2YXIgaW5kZXggPSBwaWNrQXJiaXRyYXJ5TGFuZUluZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgdmFyIGV4cGlyYXRpb25UaW1lID0gZXhwaXJhdGlvblRpbWVzW2luZGV4XTtcblxuICAgIGlmIChleHBpcmF0aW9uVGltZSA9PT0gTm9UaW1lc3RhbXApIHtcbiAgICAgIC8vIEZvdW5kIGEgcGVuZGluZyBsYW5lIHdpdGggbm8gZXhwaXJhdGlvbiB0aW1lLiBJZiBpdCdzIG5vdCBzdXNwZW5kZWQsIG9yXG4gICAgICAvLyBpZiBpdCdzIHBpbmdlZCwgYXNzdW1lIGl0J3MgQ1BVLWJvdW5kLiBDb21wdXRlIGEgbmV3IGV4cGlyYXRpb24gdGltZVxuICAgICAgLy8gdXNpbmcgdGhlIGN1cnJlbnQgdGltZS5cbiAgICAgIGlmICgobGFuZSAmIHN1c3BlbmRlZExhbmVzKSA9PT0gTm9MYW5lcyB8fCAobGFuZSAmIHBpbmdlZExhbmVzKSAhPT0gTm9MYW5lcykge1xuICAgICAgICAvLyBBc3N1bWVzIHRpbWVzdGFtcHMgYXJlIG1vbm90b25pY2FsbHkgaW5jcmVhc2luZy5cbiAgICAgICAgZXhwaXJhdGlvblRpbWVzW2luZGV4XSA9IGNvbXB1dGVFeHBpcmF0aW9uVGltZShsYW5lLCBjdXJyZW50VGltZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChleHBpcmF0aW9uVGltZSA8PSBjdXJyZW50VGltZSkge1xuICAgICAgLy8gVGhpcyBsYW5lIGV4cGlyZWRcbiAgICAgIHJvb3QuZXhwaXJlZExhbmVzIHw9IGxhbmU7XG4gICAgfVxuXG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn0gLy8gVGhpcyByZXR1cm5zIHRoZSBoaWdoZXN0IHByaW9yaXR5IHBlbmRpbmcgbGFuZXMgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZXlcbi8vIGFyZSBzdXNwZW5kZWQuXG5cbmZ1bmN0aW9uIGdldEhpZ2hlc3RQcmlvcml0eVBlbmRpbmdMYW5lcyhyb290KSB7XG4gIHJldHVybiBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lcyhyb290LnBlbmRpbmdMYW5lcyk7XG59XG5mdW5jdGlvbiBnZXRMYW5lc1RvUmV0cnlTeW5jaHJvbm91c2x5T25FcnJvcihyb290KSB7XG4gIHZhciBldmVyeXRoaW5nQnV0T2Zmc2NyZWVuID0gcm9vdC5wZW5kaW5nTGFuZXMgJiB+T2Zmc2NyZWVuTGFuZTtcblxuICBpZiAoZXZlcnl0aGluZ0J1dE9mZnNjcmVlbiAhPT0gTm9MYW5lcykge1xuICAgIHJldHVybiBldmVyeXRoaW5nQnV0T2Zmc2NyZWVuO1xuICB9XG5cbiAgaWYgKGV2ZXJ5dGhpbmdCdXRPZmZzY3JlZW4gJiBPZmZzY3JlZW5MYW5lKSB7XG4gICAgcmV0dXJuIE9mZnNjcmVlbkxhbmU7XG4gIH1cblxuICByZXR1cm4gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzU3luY0xhbmUobGFuZXMpIHtcbiAgcmV0dXJuIChsYW5lcyAmIFN5bmNMYW5lKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzTm9uSWRsZVdvcmsobGFuZXMpIHtcbiAgcmV0dXJuIChsYW5lcyAmIE5vbklkbGVMYW5lcykgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc09ubHlSZXRyaWVzKGxhbmVzKSB7XG4gIHJldHVybiAobGFuZXMgJiBSZXRyeUxhbmVzKSA9PT0gbGFuZXM7XG59XG5mdW5jdGlvbiBpbmNsdWRlc09ubHlOb25VcmdlbnRMYW5lcyhsYW5lcykge1xuICB2YXIgVXJnZW50TGFuZXMgPSBTeW5jTGFuZSB8IElucHV0Q29udGludW91c0xhbmUgfCBEZWZhdWx0TGFuZTtcbiAgcmV0dXJuIChsYW5lcyAmIFVyZ2VudExhbmVzKSA9PT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzT25seVRyYW5zaXRpb25zKGxhbmVzKSB7XG4gIHJldHVybiAobGFuZXMgJiBUcmFuc2l0aW9uTGFuZXMpID09PSBsYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIGxhbmVzKSB7XG5cbiAgdmFyIFN5bmNEZWZhdWx0TGFuZXMgPSBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lIHwgSW5wdXRDb250aW51b3VzTGFuZSB8IERlZmF1bHRIeWRyYXRpb25MYW5lIHwgRGVmYXVsdExhbmU7XG4gIHJldHVybiAobGFuZXMgJiBTeW5jRGVmYXVsdExhbmVzKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGluY2x1ZGVzRXhwaXJlZExhbmUocm9vdCwgbGFuZXMpIHtcbiAgLy8gVGhpcyBpcyBhIHNlcGFyYXRlIGNoZWNrIGZyb20gaW5jbHVkZXNCbG9ja2luZ0xhbmUgYmVjYXVzZSBhIGxhbmUgY2FuXG4gIC8vIGV4cGlyZSBhZnRlciBhIHJlbmRlciBoYXMgYWxyZWFkeSBzdGFydGVkLlxuICByZXR1cm4gKGxhbmVzICYgcm9vdC5leHBpcmVkTGFuZXMpICE9PSBOb0xhbmVzO1xufVxuZnVuY3Rpb24gaXNUcmFuc2l0aW9uTGFuZShsYW5lKSB7XG4gIHJldHVybiAobGFuZSAmIFRyYW5zaXRpb25MYW5lcykgIT09IE5vTGFuZXM7XG59XG5mdW5jdGlvbiBjbGFpbU5leHRUcmFuc2l0aW9uTGFuZSgpIHtcbiAgLy8gQ3ljbGUgdGhyb3VnaCB0aGUgbGFuZXMsIGFzc2lnbmluZyBlYWNoIG5ldyB0cmFuc2l0aW9uIHRvIHRoZSBuZXh0IGxhbmUuXG4gIC8vIEluIG1vc3QgY2FzZXMsIHRoaXMgbWVhbnMgZXZlcnkgdHJhbnNpdGlvbiBnZXRzIGl0cyBvd24gbGFuZSwgdW50aWwgd2VcbiAgLy8gcnVuIG91dCBvZiBsYW5lcyBhbmQgY3ljbGUgYmFjayB0byB0aGUgYmVnaW5uaW5nLlxuICB2YXIgbGFuZSA9IG5leHRUcmFuc2l0aW9uTGFuZTtcbiAgbmV4dFRyYW5zaXRpb25MYW5lIDw8PSAxO1xuXG4gIGlmICgobmV4dFRyYW5zaXRpb25MYW5lICYgVHJhbnNpdGlvbkxhbmVzKSA9PT0gTm9MYW5lcykge1xuICAgIG5leHRUcmFuc2l0aW9uTGFuZSA9IFRyYW5zaXRpb25MYW5lMTtcbiAgfVxuXG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gY2xhaW1OZXh0UmV0cnlMYW5lKCkge1xuICB2YXIgbGFuZSA9IG5leHRSZXRyeUxhbmU7XG4gIG5leHRSZXRyeUxhbmUgPDw9IDE7XG5cbiAgaWYgKChuZXh0UmV0cnlMYW5lICYgUmV0cnlMYW5lcykgPT09IE5vTGFuZXMpIHtcbiAgICBuZXh0UmV0cnlMYW5lID0gUmV0cnlMYW5lMTtcbiAgfVxuXG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShsYW5lcykge1xuICByZXR1cm4gbGFuZXMgJiAtbGFuZXM7XG59XG5mdW5jdGlvbiBwaWNrQXJiaXRyYXJ5TGFuZShsYW5lcykge1xuICAvLyBUaGlzIHdyYXBwZXIgZnVuY3Rpb24gZ2V0cyBpbmxpbmVkLiBPbmx5IGV4aXN0cyBzbyB0byBjb21tdW5pY2F0ZSB0aGF0IGl0XG4gIC8vIGRvZXNuJ3QgbWF0dGVyIHdoaWNoIGJpdCBpcyBzZWxlY3RlZDsgeW91IGNhbiBwaWNrIGFueSBiaXQgd2l0aG91dFxuICAvLyBhZmZlY3RpbmcgdGhlIGFsZ29yaXRobXMgd2hlcmUgaXRzIHVzZWQuIEhlcmUgSSdtIHVzaW5nXG4gIC8vIGdldEhpZ2hlc3RQcmlvcml0eUxhbmUgYmVjYXVzZSBpdCByZXF1aXJlcyB0aGUgZmV3ZXN0IG9wZXJhdGlvbnMuXG4gIHJldHVybiBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lKGxhbmVzKTtcbn1cblxuZnVuY3Rpb24gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcykge1xuICByZXR1cm4gMzEgLSBjbHozMihsYW5lcyk7XG59XG5cbmZ1bmN0aW9uIGxhbmVUb0luZGV4KGxhbmUpIHtcbiAgcmV0dXJuIHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZSk7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzU29tZUxhbmUoYSwgYikge1xuICByZXR1cm4gKGEgJiBiKSAhPT0gTm9MYW5lcztcbn1cbmZ1bmN0aW9uIGlzU3Vic2V0T2ZMYW5lcyhzZXQsIHN1YnNldCkge1xuICByZXR1cm4gKHNldCAmIHN1YnNldCkgPT09IHN1YnNldDtcbn1cbmZ1bmN0aW9uIG1lcmdlTGFuZXMoYSwgYikge1xuICByZXR1cm4gYSB8IGI7XG59XG5mdW5jdGlvbiByZW1vdmVMYW5lcyhzZXQsIHN1YnNldCkge1xuICByZXR1cm4gc2V0ICYgfnN1YnNldDtcbn1cbmZ1bmN0aW9uIGludGVyc2VjdExhbmVzKGEsIGIpIHtcbiAgcmV0dXJuIGEgJiBiO1xufSAvLyBTZWVtcyByZWR1bmRhbnQsIGJ1dCBpdCBjaGFuZ2VzIHRoZSB0eXBlIGZyb20gYSBzaW5nbGUgbGFuZSAodXNlZCBmb3Jcbi8vIHVwZGF0ZXMpIHRvIGEgZ3JvdXAgb2YgbGFuZXMgKHVzZWQgZm9yIGZsdXNoaW5nIHdvcmspLlxuXG5mdW5jdGlvbiBsYW5lVG9MYW5lcyhsYW5lKSB7XG4gIHJldHVybiBsYW5lO1xufVxuZnVuY3Rpb24gaGlnaGVyUHJpb3JpdHlMYW5lKGEsIGIpIHtcbiAgLy8gVGhpcyB3b3JrcyBiZWNhdXNlIHRoZSBiaXQgcmFuZ2VzIGRlY3JlYXNlIGluIHByaW9yaXR5IGFzIHlvdSBnbyBsZWZ0LlxuICByZXR1cm4gYSAhPT0gTm9MYW5lICYmIGEgPCBiID8gYSA6IGI7XG59XG5mdW5jdGlvbiBjcmVhdGVMYW5lTWFwKGluaXRpYWwpIHtcbiAgLy8gSW50ZW50aW9uYWxseSBwdXNoaW5nIG9uZSBieSBvbmUuXG4gIC8vIGh0dHBzOi8vdjguZGV2L2Jsb2cvZWxlbWVudHMta2luZHMjYXZvaWQtY3JlYXRpbmctaG9sZXNcbiAgdmFyIGxhbmVNYXAgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IFRvdGFsTGFuZXM7IGkrKykge1xuICAgIGxhbmVNYXAucHVzaChpbml0aWFsKTtcbiAgfVxuXG4gIHJldHVybiBsYW5lTWFwO1xufVxuZnVuY3Rpb24gbWFya1Jvb3RVcGRhdGVkKHJvb3QsIHVwZGF0ZUxhbmUsIGV2ZW50VGltZSkge1xuICByb290LnBlbmRpbmdMYW5lcyB8PSB1cGRhdGVMYW5lOyAvLyBJZiB0aGVyZSBhcmUgYW55IHN1c3BlbmRlZCB0cmFuc2l0aW9ucywgaXQncyBwb3NzaWJsZSB0aGlzIG5ldyB1cGRhdGVcbiAgLy8gY291bGQgdW5ibG9jayB0aGVtLiBDbGVhciB0aGUgc3VzcGVuZGVkIGxhbmVzIHNvIHRoYXQgd2UgY2FuIHRyeSByZW5kZXJpbmdcbiAgLy8gdGhlbSBhZ2Fpbi5cbiAgLy9cbiAgLy8gVE9ETzogV2UgcmVhbGx5IG9ubHkgbmVlZCB0byB1bnN1c3BlbmQgb25seSBsYW5lcyB0aGF0IGFyZSBpbiB0aGVcbiAgLy8gYHN1YnRyZWVMYW5lc2Agb2YgdGhlIHVwZGF0ZWQgZmliZXIsIG9yIHRoZSB1cGRhdGUgbGFuZXMgb2YgdGhlIHJldHVyblxuICAvLyBwYXRoLiBUaGlzIHdvdWxkIGV4Y2x1ZGUgc3VzcGVuZGVkIHVwZGF0ZXMgaW4gYW4gdW5yZWxhdGVkIHNpYmxpbmcgdHJlZSxcbiAgLy8gc2luY2UgdGhlcmUncyBubyB3YXkgZm9yIHRoaXMgdXBkYXRlIHRvIHVuYmxvY2sgaXQuXG4gIC8vXG4gIC8vIFdlIGRvbid0IGRvIHRoaXMgaWYgdGhlIGluY29taW5nIHVwZGF0ZSBpcyBpZGxlLCBiZWNhdXNlIHdlIG5ldmVyIHByb2Nlc3NcbiAgLy8gaWRsZSB1cGRhdGVzIHVudGlsIGFmdGVyIGFsbCB0aGUgcmVndWxhciB1cGRhdGVzIGhhdmUgZmluaXNoZWQ7IHRoZXJlJ3Mgbm9cbiAgLy8gd2F5IGl0IGNvdWxkIHVuYmxvY2sgYSB0cmFuc2l0aW9uLlxuXG4gIGlmICh1cGRhdGVMYW5lICE9PSBJZGxlTGFuZSkge1xuICAgIHJvb3Quc3VzcGVuZGVkTGFuZXMgPSBOb0xhbmVzO1xuICAgIHJvb3QucGluZ2VkTGFuZXMgPSBOb0xhbmVzO1xuICB9XG5cbiAgdmFyIGV2ZW50VGltZXMgPSByb290LmV2ZW50VGltZXM7XG4gIHZhciBpbmRleCA9IGxhbmVUb0luZGV4KHVwZGF0ZUxhbmUpOyAvLyBXZSBjYW4gYWx3YXlzIG92ZXJ3cml0ZSBhbiBleGlzdGluZyB0aW1lc3RhbXAgYmVjYXVzZSB3ZSBwcmVmZXIgdGhlIG1vc3RcbiAgLy8gcmVjZW50IGV2ZW50LCBhbmQgd2UgYXNzdW1lIHRpbWUgaXMgbW9ub3RvbmljYWxseSBpbmNyZWFzaW5nLlxuXG4gIGV2ZW50VGltZXNbaW5kZXhdID0gZXZlbnRUaW1lO1xufVxuZnVuY3Rpb24gbWFya1Jvb3RTdXNwZW5kZWQocm9vdCwgc3VzcGVuZGVkTGFuZXMpIHtcbiAgcm9vdC5zdXNwZW5kZWRMYW5lcyB8PSBzdXNwZW5kZWRMYW5lcztcbiAgcm9vdC5waW5nZWRMYW5lcyAmPSB+c3VzcGVuZGVkTGFuZXM7IC8vIFRoZSBzdXNwZW5kZWQgbGFuZXMgYXJlIG5vIGxvbmdlciBDUFUtYm91bmQuIENsZWFyIHRoZWlyIGV4cGlyYXRpb24gdGltZXMuXG5cbiAgdmFyIGV4cGlyYXRpb25UaW1lcyA9IHJvb3QuZXhwaXJhdGlvblRpbWVzO1xuICB2YXIgbGFuZXMgPSBzdXNwZW5kZWRMYW5lcztcblxuICB3aGlsZSAobGFuZXMgPiAwKSB7XG4gICAgdmFyIGluZGV4ID0gcGlja0FyYml0cmFyeUxhbmVJbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIGV4cGlyYXRpb25UaW1lc1tpbmRleF0gPSBOb1RpbWVzdGFtcDtcbiAgICBsYW5lcyAmPSB+bGFuZTtcbiAgfVxufVxuZnVuY3Rpb24gbWFya1Jvb3RQaW5nZWQocm9vdCwgcGluZ2VkTGFuZXMsIGV2ZW50VGltZSkge1xuICByb290LnBpbmdlZExhbmVzIHw9IHJvb3Quc3VzcGVuZGVkTGFuZXMgJiBwaW5nZWRMYW5lcztcbn1cbmZ1bmN0aW9uIG1hcmtSb290RmluaXNoZWQocm9vdCwgcmVtYWluaW5nTGFuZXMpIHtcbiAgdmFyIG5vTG9uZ2VyUGVuZGluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXMgJiB+cmVtYWluaW5nTGFuZXM7XG4gIHJvb3QucGVuZGluZ0xhbmVzID0gcmVtYWluaW5nTGFuZXM7IC8vIExldCdzIHRyeSBldmVyeXRoaW5nIGFnYWluXG5cbiAgcm9vdC5zdXNwZW5kZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHJvb3QucGluZ2VkTGFuZXMgPSBOb0xhbmVzO1xuICByb290LmV4cGlyZWRMYW5lcyAmPSByZW1haW5pbmdMYW5lcztcbiAgcm9vdC5tdXRhYmxlUmVhZExhbmVzICY9IHJlbWFpbmluZ0xhbmVzO1xuICByb290LmVudGFuZ2xlZExhbmVzICY9IHJlbWFpbmluZ0xhbmVzO1xuICB2YXIgZW50YW5nbGVtZW50cyA9IHJvb3QuZW50YW5nbGVtZW50cztcbiAgdmFyIGV2ZW50VGltZXMgPSByb290LmV2ZW50VGltZXM7XG4gIHZhciBleHBpcmF0aW9uVGltZXMgPSByb290LmV4cGlyYXRpb25UaW1lczsgLy8gQ2xlYXIgdGhlIGxhbmVzIHRoYXQgbm8gbG9uZ2VyIGhhdmUgcGVuZGluZyB3b3JrXG5cbiAgdmFyIGxhbmVzID0gbm9Mb25nZXJQZW5kaW5nTGFuZXM7XG5cbiAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgIHZhciBpbmRleCA9IHBpY2tBcmJpdHJhcnlMYW5lSW5kZXgobGFuZXMpO1xuICAgIHZhciBsYW5lID0gMSA8PCBpbmRleDtcbiAgICBlbnRhbmdsZW1lbnRzW2luZGV4XSA9IE5vTGFuZXM7XG4gICAgZXZlbnRUaW1lc1tpbmRleF0gPSBOb1RpbWVzdGFtcDtcbiAgICBleHBpcmF0aW9uVGltZXNbaW5kZXhdID0gTm9UaW1lc3RhbXA7XG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtSb290RW50YW5nbGVkKHJvb3QsIGVudGFuZ2xlZExhbmVzKSB7XG4gIC8vIEluIGFkZGl0aW9uIHRvIGVudGFuZ2xpbmcgZWFjaCBvZiB0aGUgZ2l2ZW4gbGFuZXMgd2l0aCBlYWNoIG90aGVyLCB3ZSBhbHNvXG4gIC8vIGhhdmUgdG8gY29uc2lkZXIgX3RyYW5zaXRpdmVfIGVudGFuZ2xlbWVudHMuIEZvciBlYWNoIGxhbmUgdGhhdCBpcyBhbHJlYWR5XG4gIC8vIGVudGFuZ2xlZCB3aXRoICphbnkqIG9mIHRoZSBnaXZlbiBsYW5lcywgdGhhdCBsYW5lIGlzIG5vdyB0cmFuc2l0aXZlbHlcbiAgLy8gZW50YW5nbGVkIHdpdGggKmFsbCogdGhlIGdpdmVuIGxhbmVzLlxuICAvL1xuICAvLyBUcmFuc2xhdGVkOiBJZiBDIGlzIGVudGFuZ2xlZCB3aXRoIEEsIHRoZW4gZW50YW5nbGluZyBBIHdpdGggQiBhbHNvXG4gIC8vIGVudGFuZ2xlcyBDIHdpdGggQi5cbiAgLy9cbiAgLy8gSWYgdGhpcyBpcyBoYXJkIHRvIGdyYXNwLCBpdCBtaWdodCBoZWxwIHRvIGludGVudGlvbmFsbHkgYnJlYWsgdGhpc1xuICAvLyBmdW5jdGlvbiBhbmQgbG9vayBhdCB0aGUgdGVzdHMgdGhhdCBmYWlsIGluIFJlYWN0VHJhbnNpdGlvbi10ZXN0LmpzLiBUcnlcbiAgLy8gY29tbWVudGluZyBvdXQgb25lIG9mIHRoZSBjb25kaXRpb25zIGJlbG93LlxuICB2YXIgcm9vdEVudGFuZ2xlZExhbmVzID0gcm9vdC5lbnRhbmdsZWRMYW5lcyB8PSBlbnRhbmdsZWRMYW5lcztcbiAgdmFyIGVudGFuZ2xlbWVudHMgPSByb290LmVudGFuZ2xlbWVudHM7XG4gIHZhciBsYW5lcyA9IHJvb3RFbnRhbmdsZWRMYW5lcztcblxuICB3aGlsZSAobGFuZXMpIHtcbiAgICB2YXIgaW5kZXggPSBwaWNrQXJiaXRyYXJ5TGFuZUluZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG5cbiAgICBpZiAoIC8vIElzIHRoaXMgb25lIG9mIHRoZSBuZXdseSBlbnRhbmdsZWQgbGFuZXM/XG4gICAgbGFuZSAmIGVudGFuZ2xlZExhbmVzIHwgLy8gSXMgdGhpcyBsYW5lIHRyYW5zaXRpdmVseSBlbnRhbmdsZWQgd2l0aCB0aGUgbmV3bHkgZW50YW5nbGVkIGxhbmVzP1xuICAgIGVudGFuZ2xlbWVudHNbaW5kZXhdICYgZW50YW5nbGVkTGFuZXMpIHtcbiAgICAgIGVudGFuZ2xlbWVudHNbaW5kZXhdIHw9IGVudGFuZ2xlZExhbmVzO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59XG5mdW5jdGlvbiBnZXRCdW1wZWRMYW5lRm9ySHlkcmF0aW9uKHJvb3QsIHJlbmRlckxhbmVzKSB7XG4gIHZhciByZW5kZXJMYW5lID0gZ2V0SGlnaGVzdFByaW9yaXR5TGFuZShyZW5kZXJMYW5lcyk7XG4gIHZhciBsYW5lO1xuXG4gIHN3aXRjaCAocmVuZGVyTGFuZSkge1xuICAgIGNhc2UgSW5wdXRDb250aW51b3VzTGFuZTpcbiAgICAgIGxhbmUgPSBJbnB1dENvbnRpbnVvdXNIeWRyYXRpb25MYW5lO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIERlZmF1bHRMYW5lOlxuICAgICAgbGFuZSA9IERlZmF1bHRIeWRyYXRpb25MYW5lO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNDpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lNzpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lODpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lOTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTA6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTExOlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxMjpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTM6XG4gICAgY2FzZSBUcmFuc2l0aW9uTGFuZTE0OlxuICAgIGNhc2UgVHJhbnNpdGlvbkxhbmUxNTpcbiAgICBjYXNlIFRyYW5zaXRpb25MYW5lMTY6XG4gICAgY2FzZSBSZXRyeUxhbmUxOlxuICAgIGNhc2UgUmV0cnlMYW5lMjpcbiAgICBjYXNlIFJldHJ5TGFuZTM6XG4gICAgY2FzZSBSZXRyeUxhbmU0OlxuICAgIGNhc2UgUmV0cnlMYW5lNTpcbiAgICAgIGxhbmUgPSBUcmFuc2l0aW9uSHlkcmF0aW9uTGFuZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBJZGxlTGFuZTpcbiAgICAgIGxhbmUgPSBJZGxlSHlkcmF0aW9uTGFuZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpcyBhbHJlYWR5IGVpdGhlciBhIGh5ZHJhdGlvbiBsYW5lLCBvciBzaG91bGRuJ3RcbiAgICAgIC8vIGJlIHJldHJpZWQgYXQgYSBoeWRyYXRpb24gbGFuZS5cbiAgICAgIGxhbmUgPSBOb0xhbmU7XG4gICAgICBicmVhaztcbiAgfSAvLyBDaGVjayBpZiB0aGUgbGFuZSB3ZSBjaG9zZSBpcyBzdXNwZW5kZWQuIElmIHNvLCB0aGF0IGluZGljYXRlcyB0aGF0IHdlXG4gIC8vIGFscmVhZHkgYXR0ZW1wdGVkIGFuZCBmYWlsZWQgdG8gaHlkcmF0ZSBhdCB0aGF0IGxldmVsLiBBbHNvIGNoZWNrIGlmIHdlJ3JlXG4gIC8vIGFscmVhZHkgcmVuZGVyaW5nIHRoYXQgbGFuZSwgd2hpY2ggaXMgcmFyZSBidXQgY291bGQgaGFwcGVuLlxuXG5cbiAgaWYgKChsYW5lICYgKHJvb3Quc3VzcGVuZGVkTGFuZXMgfCByZW5kZXJMYW5lcykpICE9PSBOb0xhbmUpIHtcbiAgICAvLyBHaXZlIHVwIHRyeWluZyB0byBoeWRyYXRlIGFuZCBmYWxsIGJhY2sgdG8gY2xpZW50IHJlbmRlci5cbiAgICByZXR1cm4gTm9MYW5lO1xuICB9XG5cbiAgcmV0dXJuIGxhbmU7XG59XG5mdW5jdGlvbiBhZGRGaWJlclRvTGFuZXNNYXAocm9vdCwgZmliZXIsIGxhbmVzKSB7XG5cbiAgaWYgKCFpc0RldlRvb2xzUHJlc2VudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwZW5kaW5nVXBkYXRlcnNMYW5lTWFwID0gcm9vdC5wZW5kaW5nVXBkYXRlcnNMYW5lTWFwO1xuXG4gIHdoaWxlIChsYW5lcyA+IDApIHtcbiAgICB2YXIgaW5kZXggPSBsYW5lVG9JbmRleChsYW5lcyk7XG4gICAgdmFyIGxhbmUgPSAxIDw8IGluZGV4O1xuICAgIHZhciB1cGRhdGVycyA9IHBlbmRpbmdVcGRhdGVyc0xhbmVNYXBbaW5kZXhdO1xuICAgIHVwZGF0ZXJzLmFkZChmaWJlcik7XG4gICAgbGFuZXMgJj0gfmxhbmU7XG4gIH1cbn1cbmZ1bmN0aW9uIG1vdmVQZW5kaW5nRmliZXJzVG9NZW1vaXplZChyb290LCBsYW5lcykge1xuXG4gIGlmICghaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGVuZGluZ1VwZGF0ZXJzTGFuZU1hcCA9IHJvb3QucGVuZGluZ1VwZGF0ZXJzTGFuZU1hcDtcbiAgdmFyIG1lbW9pemVkVXBkYXRlcnMgPSByb290Lm1lbW9pemVkVXBkYXRlcnM7XG5cbiAgd2hpbGUgKGxhbmVzID4gMCkge1xuICAgIHZhciBpbmRleCA9IGxhbmVUb0luZGV4KGxhbmVzKTtcbiAgICB2YXIgbGFuZSA9IDEgPDwgaW5kZXg7XG4gICAgdmFyIHVwZGF0ZXJzID0gcGVuZGluZ1VwZGF0ZXJzTGFuZU1hcFtpbmRleF07XG5cbiAgICBpZiAodXBkYXRlcnMuc2l6ZSA+IDApIHtcbiAgICAgIHVwZGF0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIHZhciBhbHRlcm5hdGUgPSBmaWJlci5hbHRlcm5hdGU7XG5cbiAgICAgICAgaWYgKGFsdGVybmF0ZSA9PT0gbnVsbCB8fCAhbWVtb2l6ZWRVcGRhdGVycy5oYXMoYWx0ZXJuYXRlKSkge1xuICAgICAgICAgIG1lbW9pemVkVXBkYXRlcnMuYWRkKGZpYmVyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB1cGRhdGVycy5jbGVhcigpO1xuICAgIH1cblxuICAgIGxhbmVzICY9IH5sYW5lO1xuICB9XG59XG5mdW5jdGlvbiBnZXRUcmFuc2l0aW9uc0ZvckxhbmVzKHJvb3QsIGxhbmVzKSB7XG4gIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG52YXIgRGlzY3JldGVFdmVudFByaW9yaXR5ID0gU3luY0xhbmU7XG52YXIgQ29udGludW91c0V2ZW50UHJpb3JpdHkgPSBJbnB1dENvbnRpbnVvdXNMYW5lO1xudmFyIERlZmF1bHRFdmVudFByaW9yaXR5ID0gRGVmYXVsdExhbmU7XG52YXIgSWRsZUV2ZW50UHJpb3JpdHkgPSBJZGxlTGFuZTtcbnZhciBjdXJyZW50VXBkYXRlUHJpb3JpdHkgPSBOb0xhbmU7XG5mdW5jdGlvbiBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKSB7XG4gIHJldHVybiBjdXJyZW50VXBkYXRlUHJpb3JpdHk7XG59XG5mdW5jdGlvbiBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkobmV3UHJpb3JpdHkpIHtcbiAgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gbmV3UHJpb3JpdHk7XG59XG5mdW5jdGlvbiBydW5XaXRoUHJpb3JpdHkocHJpb3JpdHksIGZuKSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gY3VycmVudFVwZGF0ZVByaW9yaXR5O1xuXG4gIHRyeSB7XG4gICAgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gcHJpb3JpdHk7XG4gICAgcmV0dXJuIGZuKCk7XG4gIH0gZmluYWxseSB7XG4gICAgY3VycmVudFVwZGF0ZVByaW9yaXR5ID0gcHJldmlvdXNQcmlvcml0eTtcbiAgfVxufVxuZnVuY3Rpb24gaGlnaGVyRXZlbnRQcmlvcml0eShhLCBiKSB7XG4gIHJldHVybiBhICE9PSAwICYmIGEgPCBiID8gYSA6IGI7XG59XG5mdW5jdGlvbiBsb3dlckV2ZW50UHJpb3JpdHkoYSwgYikge1xuICByZXR1cm4gYSA9PT0gMCB8fCBhID4gYiA/IGEgOiBiO1xufVxuZnVuY3Rpb24gaXNIaWdoZXJFdmVudFByaW9yaXR5KGEsIGIpIHtcbiAgcmV0dXJuIGEgIT09IDAgJiYgYSA8IGI7XG59XG5mdW5jdGlvbiBsYW5lc1RvRXZlbnRQcmlvcml0eShsYW5lcykge1xuICB2YXIgbGFuZSA9IGdldEhpZ2hlc3RQcmlvcml0eUxhbmUobGFuZXMpO1xuXG4gIGlmICghaXNIaWdoZXJFdmVudFByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSwgbGFuZSkpIHtcbiAgICByZXR1cm4gRGlzY3JldGVFdmVudFByaW9yaXR5O1xuICB9XG5cbiAgaWYgKCFpc0hpZ2hlckV2ZW50UHJpb3JpdHkoQ29udGludW91c0V2ZW50UHJpb3JpdHksIGxhbmUpKSB7XG4gICAgcmV0dXJuIENvbnRpbnVvdXNFdmVudFByaW9yaXR5O1xuICB9XG5cbiAgaWYgKGluY2x1ZGVzTm9uSWRsZVdvcmsobGFuZSkpIHtcbiAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG4gIH1cblxuICByZXR1cm4gSWRsZUV2ZW50UHJpb3JpdHk7XG59XG5cbi8vIFRoaXMgaXMgaW1wb3J0ZWQgYnkgdGhlIGV2ZW50IHJlcGxheWluZyBpbXBsZW1lbnRhdGlvbiBpbiBSZWFjdCBET00uIEl0J3Ncbi8vIGluIGEgc2VwYXJhdGUgZmlsZSB0byBicmVhayBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgYmV0d2VlbiB0aGUgcmVuZGVyZXIgYW5kXG4vLyB0aGUgcmVjb25jaWxlci5cbmZ1bmN0aW9uIGlzUm9vdERlaHlkcmF0ZWQocm9vdCkge1xuICB2YXIgY3VycmVudFN0YXRlID0gcm9vdC5jdXJyZW50Lm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiBjdXJyZW50U3RhdGUuaXNEZWh5ZHJhdGVkO1xufVxuXG52YXIgX2F0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbjtcblxuZnVuY3Rpb24gc2V0QXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uKGZuKSB7XG4gIF9hdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24gPSBmbjtcbn1cbmZ1bmN0aW9uIGF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihmaWJlcikge1xuICBfYXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uKGZpYmVyKTtcbn1cbnZhciBhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbjtcbmZ1bmN0aW9uIHNldEF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uKGZuKSB7XG4gIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uID0gZm47XG59XG52YXIgYXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5O1xuZnVuY3Rpb24gc2V0QXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5KGZuKSB7XG4gIGF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eSA9IGZuO1xufVxudmFyIGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSQxO1xuZnVuY3Rpb24gc2V0R2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KGZuKSB7XG4gIGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSQxID0gZm47XG59XG52YXIgYXR0ZW1wdEh5ZHJhdGlvbkF0UHJpb3JpdHk7XG5mdW5jdGlvbiBzZXRBdHRlbXB0SHlkcmF0aW9uQXRQcmlvcml0eShmbikge1xuICBhdHRlbXB0SHlkcmF0aW9uQXRQcmlvcml0eSA9IGZuO1xufSAvLyBUT0RPOiBVcGdyYWRlIHRoaXMgZGVmaW5pdGlvbiBvbmNlIHdlJ3JlIG9uIGEgbmV3ZXIgdmVyc2lvbiBvZiBGbG93IHRoYXRcbi8vIGhhcyB0aGlzIGRlZmluaXRpb24gYnVpbHQtaW4uXG5cbnZhciBoYXNTY2hlZHVsZWRSZXBsYXlBdHRlbXB0ID0gZmFsc2U7IC8vIFRoZSBxdWV1ZSBvZiBkaXNjcmV0ZSBldmVudHMgdG8gYmUgcmVwbGF5ZWQuXG5cbnZhciBxdWV1ZWREaXNjcmV0ZUV2ZW50cyA9IFtdOyAvLyBJbmRpY2F0ZXMgaWYgYW55IGNvbnRpbnVvdXMgZXZlbnQgdGFyZ2V0cyBhcmUgbm9uLW51bGwgZm9yIGVhcmx5IGJhaWxvdXQuXG4vLyBpZiB0aGUgbGFzdCB0YXJnZXQgd2FzIGRlaHlkcmF0ZWQuXG5cbnZhciBxdWV1ZWRGb2N1cyA9IG51bGw7XG52YXIgcXVldWVkRHJhZyA9IG51bGw7XG52YXIgcXVldWVkTW91c2UgPSBudWxsOyAvLyBGb3IgcG9pbnRlciBldmVudHMgdGhlcmUgY2FuIGJlIG9uZSBsYXRlc3QgZXZlbnQgcGVyIHBvaW50ZXJJZC5cblxudmFyIHF1ZXVlZFBvaW50ZXJzID0gbmV3IE1hcCgpO1xudmFyIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcyA9IG5ldyBNYXAoKTsgLy8gV2UgY291bGQgY29uc2lkZXIgcmVwbGF5aW5nIHNlbGVjdGlvbmNoYW5nZSBhbmQgdG91Y2htb3ZlcyB0b28uXG5cbnZhciBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMgPSBbXTtcbnZhciBkaXNjcmV0ZVJlcGxheWFibGVFdmVudHMgPSBbJ21vdXNlZG93bicsICdtb3VzZXVwJywgJ3RvdWNoY2FuY2VsJywgJ3RvdWNoZW5kJywgJ3RvdWNoc3RhcnQnLCAnYXV4Y2xpY2snLCAnZGJsY2xpY2snLCAncG9pbnRlcmNhbmNlbCcsICdwb2ludGVyZG93bicsICdwb2ludGVydXAnLCAnZHJhZ2VuZCcsICdkcmFnc3RhcnQnLCAnZHJvcCcsICdjb21wb3NpdGlvbmVuZCcsICdjb21wb3NpdGlvbnN0YXJ0JywgJ2tleWRvd24nLCAna2V5cHJlc3MnLCAna2V5dXAnLCAnaW5wdXQnLCAndGV4dElucHV0JywgLy8gSW50ZW50aW9uYWxseSBjYW1lbENhc2Vcbidjb3B5JywgJ2N1dCcsICdwYXN0ZScsICdjbGljaycsICdjaGFuZ2UnLCAnY29udGV4dG1lbnUnLCAncmVzZXQnLCAnc3VibWl0J107XG5mdW5jdGlvbiBpc0Rpc2NyZXRlRXZlbnRUaGF0UmVxdWlyZXNIeWRyYXRpb24oZXZlbnRUeXBlKSB7XG4gIHJldHVybiBkaXNjcmV0ZVJlcGxheWFibGVFdmVudHMuaW5kZXhPZihldmVudFR5cGUpID4gLTE7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVF1ZXVlZFJlcGxheWFibGVFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICByZXR1cm4ge1xuICAgIGJsb2NrZWRPbjogYmxvY2tlZE9uLFxuICAgIGRvbUV2ZW50TmFtZTogZG9tRXZlbnROYW1lLFxuICAgIGV2ZW50U3lzdGVtRmxhZ3M6IGV2ZW50U3lzdGVtRmxhZ3MsXG4gICAgbmF0aXZlRXZlbnQ6IG5hdGl2ZUV2ZW50LFxuICAgIHRhcmdldENvbnRhaW5lcnM6IFt0YXJnZXRDb250YWluZXJdXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsZWFySWZDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkge1xuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgIGNhc2UgJ2ZvY3Vzb3V0JzpcbiAgICAgIHF1ZXVlZEZvY3VzID0gbnVsbDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICBjYXNlICdkcmFnbGVhdmUnOlxuICAgICAgcXVldWVkRHJhZyA9IG51bGw7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgY2FzZSAnbW91c2VvdXQnOlxuICAgICAgcXVldWVkTW91c2UgPSBudWxsO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdwb2ludGVyb3Zlcic6XG4gICAgY2FzZSAncG9pbnRlcm91dCc6XG4gICAgICB7XG4gICAgICAgIHZhciBwb2ludGVySWQgPSBuYXRpdmVFdmVudC5wb2ludGVySWQ7XG4gICAgICAgIHF1ZXVlZFBvaW50ZXJzLmRlbGV0ZShwb2ludGVySWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgJ2dvdHBvaW50ZXJjYXB0dXJlJzpcbiAgICBjYXNlICdsb3N0cG9pbnRlcmNhcHR1cmUnOlxuICAgICAge1xuICAgICAgICB2YXIgX3BvaW50ZXJJZCA9IG5hdGl2ZUV2ZW50LnBvaW50ZXJJZDtcbiAgICAgICAgcXVldWVkUG9pbnRlckNhcHR1cmVzLmRlbGV0ZShfcG9pbnRlcklkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChleGlzdGluZ1F1ZXVlZEV2ZW50LCBibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICBpZiAoZXhpc3RpbmdRdWV1ZWRFdmVudCA9PT0gbnVsbCB8fCBleGlzdGluZ1F1ZXVlZEV2ZW50Lm5hdGl2ZUV2ZW50ICE9PSBuYXRpdmVFdmVudCkge1xuICAgIHZhciBxdWV1ZWRFdmVudCA9IGNyZWF0ZVF1ZXVlZFJlcGxheWFibGVFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG5cbiAgICBpZiAoYmxvY2tlZE9uICE9PSBudWxsKSB7XG4gICAgICB2YXIgX2ZpYmVyMiA9IGdldEluc3RhbmNlRnJvbU5vZGUoYmxvY2tlZE9uKTtcblxuICAgICAgaWYgKF9maWJlcjIgIT09IG51bGwpIHtcbiAgICAgICAgLy8gQXR0ZW1wdCB0byBpbmNyZWFzZSB0aGUgcHJpb3JpdHkgb2YgdGhpcyB0YXJnZXQuXG4gICAgICAgIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uKF9maWJlcjIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBxdWV1ZWRFdmVudDtcbiAgfSAvLyBJZiB3ZSBoYXZlIGFscmVhZHkgcXVldWVkIHRoaXMgZXhhY3QgZXZlbnQsIHRoZW4gaXQncyBiZWNhdXNlXG4gIC8vIHRoZSBkaWZmZXJlbnQgZXZlbnQgc3lzdGVtcyBoYXZlIGRpZmZlcmVudCBET00gZXZlbnQgbGlzdGVuZXJzLlxuICAvLyBXZSBjYW4gYWNjdW11bGF0ZSB0aGUgZmxhZ3MsIGFuZCB0aGUgdGFyZ2V0Q29udGFpbmVycywgYW5kXG4gIC8vIHN0b3JlIGEgc2luZ2xlIGV2ZW50IHRvIGJlIHJlcGxheWVkLlxuXG5cbiAgZXhpc3RpbmdRdWV1ZWRFdmVudC5ldmVudFN5c3RlbUZsYWdzIHw9IGV2ZW50U3lzdGVtRmxhZ3M7XG4gIHZhciB0YXJnZXRDb250YWluZXJzID0gZXhpc3RpbmdRdWV1ZWRFdmVudC50YXJnZXRDb250YWluZXJzO1xuXG4gIGlmICh0YXJnZXRDb250YWluZXIgIT09IG51bGwgJiYgdGFyZ2V0Q29udGFpbmVycy5pbmRleE9mKHRhcmdldENvbnRhaW5lcikgPT09IC0xKSB7XG4gICAgdGFyZ2V0Q29udGFpbmVycy5wdXNoKHRhcmdldENvbnRhaW5lcik7XG4gIH1cblxuICByZXR1cm4gZXhpc3RpbmdRdWV1ZWRFdmVudDtcbn1cblxuZnVuY3Rpb24gcXVldWVJZkNvbnRpbnVvdXNFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICAvLyBUaGVzZSBzZXQgcmVsYXRlZFRhcmdldCB0byBudWxsIGJlY2F1c2UgdGhlIHJlcGxheWVkIGV2ZW50IHdpbGwgYmUgdHJlYXRlZCBhcyBpZiB3ZVxuICAvLyBtb3ZlZCBmcm9tIG91dHNpZGUgdGhlIHdpbmRvdyAobm8gdGFyZ2V0KSBvbnRvIHRoZSB0YXJnZXQgb25jZSBpdCBoeWRyYXRlcy5cbiAgLy8gSW5zdGVhZCBvZiBtdXRhdGluZyB3ZSBjb3VsZCBjbG9uZSB0aGUgZXZlbnQuXG4gIHN3aXRjaCAoZG9tRXZlbnROYW1lKSB7XG4gICAgY2FzZSAnZm9jdXNpbic6XG4gICAgICB7XG4gICAgICAgIHZhciBmb2N1c0V2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHF1ZXVlZEZvY3VzID0gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWRGb2N1cywgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgZm9jdXNFdmVudCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICAgIHtcbiAgICAgICAgdmFyIGRyYWdFdmVudCA9IG5hdGl2ZUV2ZW50O1xuICAgICAgICBxdWV1ZWREcmFnID0gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWREcmFnLCBibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBkcmFnRXZlbnQpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgICB7XG4gICAgICAgIHZhciBtb3VzZUV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHF1ZXVlZE1vdXNlID0gYWNjdW11bGF0ZU9yQ3JlYXRlQ29udGludW91c1F1ZXVlZFJlcGxheWFibGVFdmVudChxdWV1ZWRNb3VzZSwgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbW91c2VFdmVudCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgY2FzZSAncG9pbnRlcm92ZXInOlxuICAgICAge1xuICAgICAgICB2YXIgcG9pbnRlckV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgICAgIHZhciBwb2ludGVySWQgPSBwb2ludGVyRXZlbnQucG9pbnRlcklkO1xuICAgICAgICBxdWV1ZWRQb2ludGVycy5zZXQocG9pbnRlcklkLCBhY2N1bXVsYXRlT3JDcmVhdGVDb250aW51b3VzUXVldWVkUmVwbGF5YWJsZUV2ZW50KHF1ZXVlZFBvaW50ZXJzLmdldChwb2ludGVySWQpIHx8IG51bGwsIGJsb2NrZWRPbiwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIHBvaW50ZXJFdmVudCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ2dvdHBvaW50ZXJjYXB0dXJlJzpcbiAgICAgIHtcbiAgICAgICAgdmFyIF9wb2ludGVyRXZlbnQgPSBuYXRpdmVFdmVudDtcbiAgICAgICAgdmFyIF9wb2ludGVySWQyID0gX3BvaW50ZXJFdmVudC5wb2ludGVySWQ7XG4gICAgICAgIHF1ZXVlZFBvaW50ZXJDYXB0dXJlcy5zZXQoX3BvaW50ZXJJZDIsIGFjY3VtdWxhdGVPckNyZWF0ZUNvbnRpbnVvdXNRdWV1ZWRSZXBsYXlhYmxlRXZlbnQocXVldWVkUG9pbnRlckNhcHR1cmVzLmdldChfcG9pbnRlcklkMikgfHwgbnVsbCwgYmxvY2tlZE9uLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgX3BvaW50ZXJFdmVudCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn0gLy8gQ2hlY2sgaWYgdGhpcyB0YXJnZXQgaXMgdW5ibG9ja2VkLiBSZXR1cm5zIHRydWUgaWYgaXQncyB1bmJsb2NrZWQuXG5cbmZ1bmN0aW9uIGF0dGVtcHRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldChxdWV1ZWRUYXJnZXQpIHtcbiAgLy8gVE9ETzogVGhpcyBmdW5jdGlvbiBzaGFyZXMgYSBsb3Qgb2YgbG9naWMgd2l0aCBmaW5kSW5zdGFuY2VCbG9ja2luZ0V2ZW50LlxuICAvLyBUcnkgdG8gdW5pZnkgdGhlbS4gSXQncyBhIGJpdCB0cmlja3kgc2luY2UgaXQgd291bGQgcmVxdWlyZSB0d28gcmV0dXJuXG4gIC8vIHZhbHVlcy5cbiAgdmFyIHRhcmdldEluc3QgPSBnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZShxdWV1ZWRUYXJnZXQudGFyZ2V0KTtcblxuICBpZiAodGFyZ2V0SW5zdCAhPT0gbnVsbCkge1xuICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIodGFyZ2V0SW5zdCk7XG5cbiAgICBpZiAobmVhcmVzdE1vdW50ZWQgIT09IG51bGwpIHtcbiAgICAgIHZhciB0YWcgPSBuZWFyZXN0TW91bnRlZC50YWc7XG5cbiAgICAgIGlmICh0YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50KSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFN1c3BlbnNlSW5zdGFuY2VGcm9tRmliZXIobmVhcmVzdE1vdW50ZWQpO1xuXG4gICAgICAgIGlmIChpbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlJ3JlIGJsb2NrZWQgb24gaHlkcmF0aW5nIHRoaXMgYm91bmRhcnkuXG4gICAgICAgICAgLy8gSW5jcmVhc2UgaXRzIHByaW9yaXR5LlxuICAgICAgICAgIHF1ZXVlZFRhcmdldC5ibG9ja2VkT24gPSBpbnN0YW5jZTtcbiAgICAgICAgICBhdHRlbXB0SHlkcmF0aW9uQXRQcmlvcml0eShxdWV1ZWRUYXJnZXQucHJpb3JpdHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eShuZWFyZXN0TW91bnRlZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgICAgdmFyIHJvb3QgPSBuZWFyZXN0TW91bnRlZC5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKGlzUm9vdERlaHlkcmF0ZWQocm9vdCkpIHtcbiAgICAgICAgICBxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID0gZ2V0Q29udGFpbmVyRnJvbUZpYmVyKG5lYXJlc3RNb3VudGVkKTsgLy8gV2UgZG9uJ3QgY3VycmVudGx5IGhhdmUgYSB3YXkgdG8gaW5jcmVhc2UgdGhlIHByaW9yaXR5IG9mXG4gICAgICAgICAgLy8gYSByb290IG90aGVyIHRoYW4gc3luYy5cblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHF1ZXVlZFRhcmdldC5ibG9ja2VkT24gPSBudWxsO1xufVxuXG5mdW5jdGlvbiBxdWV1ZUV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0KHRhcmdldCkge1xuICAvLyBUT0RPOiBUaGlzIHdpbGwgcmVhZCB0aGUgcHJpb3JpdHkgaWYgaXQncyBkaXNwYXRjaGVkIGJ5IHRoZSBSZWFjdFxuICAvLyBldmVudCBzeXN0ZW0gYnV0IG5vdCBuYXRpdmUgZXZlbnRzLiBTaG91bGQgcmVhZCB3aW5kb3cuZXZlbnQudHlwZSwgbGlrZVxuICAvLyB3ZSBkbyBmb3IgdXBkYXRlcyAoZ2V0Q3VycmVudEV2ZW50UHJpb3JpdHkpLlxuICB2YXIgdXBkYXRlUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkkMSgpO1xuICB2YXIgcXVldWVkVGFyZ2V0ID0ge1xuICAgIGJsb2NrZWRPbjogbnVsbCxcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICBwcmlvcml0eTogdXBkYXRlUHJpb3JpdHlcbiAgfTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAoOyBpIDwgcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gU3RvcCBvbmNlIHdlIGhpdCB0aGUgZmlyc3QgdGFyZ2V0IHdpdGggbG93ZXIgcHJpb3JpdHkgdGhhblxuICAgIGlmICghaXNIaWdoZXJFdmVudFByaW9yaXR5KHVwZGF0ZVByaW9yaXR5LCBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHNbaV0ucHJpb3JpdHkpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMuc3BsaWNlKGksIDAsIHF1ZXVlZFRhcmdldCk7XG5cbiAgaWYgKGkgPT09IDApIHtcbiAgICBhdHRlbXB0RXhwbGljaXRIeWRyYXRpb25UYXJnZXQocXVldWVkVGFyZ2V0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZEV2ZW50KSB7XG4gIGlmIChxdWV1ZWRFdmVudC5ibG9ja2VkT24gIT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgdGFyZ2V0Q29udGFpbmVycyA9IHF1ZXVlZEV2ZW50LnRhcmdldENvbnRhaW5lcnM7XG5cbiAgd2hpbGUgKHRhcmdldENvbnRhaW5lcnMubGVuZ3RoID4gMCkge1xuICAgIHZhciB0YXJnZXRDb250YWluZXIgPSB0YXJnZXRDb250YWluZXJzWzBdO1xuICAgIHZhciBuZXh0QmxvY2tlZE9uID0gZmluZEluc3RhbmNlQmxvY2tpbmdFdmVudChxdWV1ZWRFdmVudC5kb21FdmVudE5hbWUsIHF1ZXVlZEV2ZW50LmV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgcXVldWVkRXZlbnQubmF0aXZlRXZlbnQpO1xuXG4gICAgaWYgKG5leHRCbG9ja2VkT24gPT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgdmFyIG5hdGl2ZUV2ZW50ID0gcXVldWVkRXZlbnQubmF0aXZlRXZlbnQ7XG4gICAgICAgIHZhciBuYXRpdmVFdmVudENsb25lID0gbmV3IG5hdGl2ZUV2ZW50LmNvbnN0cnVjdG9yKG5hdGl2ZUV2ZW50LnR5cGUsIG5hdGl2ZUV2ZW50KTtcbiAgICAgICAgc2V0UmVwbGF5aW5nRXZlbnQobmF0aXZlRXZlbnRDbG9uZSk7XG4gICAgICAgIG5hdGl2ZUV2ZW50LnRhcmdldC5kaXNwYXRjaEV2ZW50KG5hdGl2ZUV2ZW50Q2xvbmUpO1xuICAgICAgICByZXNldFJlcGxheWluZ0V2ZW50KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlJ3JlIHN0aWxsIGJsb2NrZWQuIFRyeSBhZ2FpbiBsYXRlci5cbiAgICAgIHZhciBfZmliZXIzID0gZ2V0SW5zdGFuY2VGcm9tTm9kZShuZXh0QmxvY2tlZE9uKTtcblxuICAgICAgaWYgKF9maWJlcjMgIT09IG51bGwpIHtcbiAgICAgICAgYXR0ZW1wdENvbnRpbnVvdXNIeWRyYXRpb24oX2ZpYmVyMyk7XG4gICAgICB9XG5cbiAgICAgIHF1ZXVlZEV2ZW50LmJsb2NrZWRPbiA9IG5leHRCbG9ja2VkT247XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSAvLyBUaGlzIHRhcmdldCBjb250YWluZXIgd2FzIHN1Y2Nlc3NmdWxseSBkaXNwYXRjaGVkLiBUcnkgdGhlIG5leHQuXG5cblxuICAgIHRhcmdldENvbnRhaW5lcnMuc2hpZnQoKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50SW5NYXAocXVldWVkRXZlbnQsIGtleSwgbWFwKSB7XG4gIGlmIChhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZEV2ZW50KSkge1xuICAgIG1hcC5kZWxldGUoa2V5KTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXBsYXlVbmJsb2NrZWRFdmVudHMoKSB7XG4gIGhhc1NjaGVkdWxlZFJlcGxheUF0dGVtcHQgPSBmYWxzZTtcblxuXG4gIGlmIChxdWV1ZWRGb2N1cyAhPT0gbnVsbCAmJiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZEZvY3VzKSkge1xuICAgIHF1ZXVlZEZvY3VzID0gbnVsbDtcbiAgfVxuXG4gIGlmIChxdWV1ZWREcmFnICE9PSBudWxsICYmIGF0dGVtcHRSZXBsYXlDb250aW51b3VzUXVldWVkRXZlbnQocXVldWVkRHJhZykpIHtcbiAgICBxdWV1ZWREcmFnID0gbnVsbDtcbiAgfVxuXG4gIGlmIChxdWV1ZWRNb3VzZSAhPT0gbnVsbCAmJiBhdHRlbXB0UmVwbGF5Q29udGludW91c1F1ZXVlZEV2ZW50KHF1ZXVlZE1vdXNlKSkge1xuICAgIHF1ZXVlZE1vdXNlID0gbnVsbDtcbiAgfVxuXG4gIHF1ZXVlZFBvaW50ZXJzLmZvckVhY2goYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudEluTWFwKTtcbiAgcXVldWVkUG9pbnRlckNhcHR1cmVzLmZvckVhY2goYXR0ZW1wdFJlcGxheUNvbnRpbnVvdXNRdWV1ZWRFdmVudEluTWFwKTtcbn1cblxuZnVuY3Rpb24gc2NoZWR1bGVDYWxsYmFja0lmVW5ibG9ja2VkKHF1ZXVlZEV2ZW50LCB1bmJsb2NrZWQpIHtcbiAgaWYgKHF1ZXVlZEV2ZW50LmJsb2NrZWRPbiA9PT0gdW5ibG9ja2VkKSB7XG4gICAgcXVldWVkRXZlbnQuYmxvY2tlZE9uID0gbnVsbDtcblxuICAgIGlmICghaGFzU2NoZWR1bGVkUmVwbGF5QXR0ZW1wdCkge1xuICAgICAgaGFzU2NoZWR1bGVkUmVwbGF5QXR0ZW1wdCA9IHRydWU7IC8vIFNjaGVkdWxlIGEgY2FsbGJhY2sgdG8gYXR0ZW1wdCByZXBsYXlpbmcgYXMgbWFueSBldmVudHMgYXMgYXJlXG4gICAgICAvLyBub3cgdW5ibG9ja2VkLiBUaGlzIGZpcnN0IG1pZ2h0IG5vdCBhY3R1YWxseSBiZSB1bmJsb2NrZWQgeWV0LlxuICAgICAgLy8gV2UgY291bGQgY2hlY2sgaXQgZWFybHkgdG8gYXZvaWQgc2NoZWR1bGluZyBhbiB1bm5lY2Vzc2FyeSBjYWxsYmFjay5cblxuICAgICAgU2NoZWR1bGVyLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2soU2NoZWR1bGVyLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5LCByZXBsYXlVbmJsb2NrZWRFdmVudHMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZXRyeUlmQmxvY2tlZE9uKHVuYmxvY2tlZCkge1xuICAvLyBNYXJrIGFueXRoaW5nIHRoYXQgd2FzIGJsb2NrZWQgb24gdGhpcyBhcyBubyBsb25nZXIgYmxvY2tlZFxuICAvLyBhbmQgZWxpZ2libGUgZm9yIGEgcmVwbGF5LlxuICBpZiAocXVldWVkRGlzY3JldGVFdmVudHMubGVuZ3RoID4gMCkge1xuICAgIHNjaGVkdWxlQ2FsbGJhY2tJZlVuYmxvY2tlZChxdWV1ZWREaXNjcmV0ZUV2ZW50c1swXSwgdW5ibG9ja2VkKTsgLy8gVGhpcyBpcyBhIGV4cG9uZW50aWFsIHNlYXJjaCBmb3IgZWFjaCBib3VuZGFyeSB0aGF0IGNvbW1pdHMuIEkgdGhpbmsgaXQnc1xuICAgIC8vIHdvcnRoIGl0IGJlY2F1c2Ugd2UgZXhwZWN0IHZlcnkgZmV3IGRpc2NyZXRlIGV2ZW50cyB0byBxdWV1ZSB1cCBhbmQgb25jZVxuICAgIC8vIHdlIGFyZSBhY3R1YWxseSBmdWxseSB1bmJsb2NrZWQgaXQgd2lsbCBiZSBmYXN0IHRvIHJlcGxheSB0aGVtLlxuXG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBxdWV1ZWREaXNjcmV0ZUV2ZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHF1ZXVlZEV2ZW50ID0gcXVldWVkRGlzY3JldGVFdmVudHNbaV07XG5cbiAgICAgIGlmIChxdWV1ZWRFdmVudC5ibG9ja2VkT24gPT09IHVuYmxvY2tlZCkge1xuICAgICAgICBxdWV1ZWRFdmVudC5ibG9ja2VkT24gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChxdWV1ZWRGb2N1cyAhPT0gbnVsbCkge1xuICAgIHNjaGVkdWxlQ2FsbGJhY2tJZlVuYmxvY2tlZChxdWV1ZWRGb2N1cywgdW5ibG9ja2VkKTtcbiAgfVxuXG4gIGlmIChxdWV1ZWREcmFnICE9PSBudWxsKSB7XG4gICAgc2NoZWR1bGVDYWxsYmFja0lmVW5ibG9ja2VkKHF1ZXVlZERyYWcsIHVuYmxvY2tlZCk7XG4gIH1cblxuICBpZiAocXVldWVkTW91c2UgIT09IG51bGwpIHtcbiAgICBzY2hlZHVsZUNhbGxiYWNrSWZVbmJsb2NrZWQocXVldWVkTW91c2UsIHVuYmxvY2tlZCk7XG4gIH1cblxuICB2YXIgdW5ibG9jayA9IGZ1bmN0aW9uIChxdWV1ZWRFdmVudCkge1xuICAgIHJldHVybiBzY2hlZHVsZUNhbGxiYWNrSWZVbmJsb2NrZWQocXVldWVkRXZlbnQsIHVuYmxvY2tlZCk7XG4gIH07XG5cbiAgcXVldWVkUG9pbnRlcnMuZm9yRWFjaCh1bmJsb2NrKTtcbiAgcXVldWVkUG9pbnRlckNhcHR1cmVzLmZvckVhY2godW5ibG9jayk7XG5cbiAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IHF1ZXVlZEV4cGxpY2l0SHlkcmF0aW9uVGFyZ2V0cy5sZW5ndGg7IF9pKyspIHtcbiAgICB2YXIgcXVldWVkVGFyZ2V0ID0gcXVldWVkRXhwbGljaXRIeWRyYXRpb25UYXJnZXRzW19pXTtcblxuICAgIGlmIChxdWV1ZWRUYXJnZXQuYmxvY2tlZE9uID09PSB1bmJsb2NrZWQpIHtcbiAgICAgIHF1ZXVlZFRhcmdldC5ibG9ja2VkT24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlIChxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMubGVuZ3RoID4gMCkge1xuICAgIHZhciBuZXh0RXhwbGljaXRUYXJnZXQgPSBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHNbMF07XG5cbiAgICBpZiAobmV4dEV4cGxpY2l0VGFyZ2V0LmJsb2NrZWRPbiAhPT0gbnVsbCkge1xuICAgICAgLy8gV2UncmUgc3RpbGwgYmxvY2tlZC5cbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBhdHRlbXB0RXhwbGljaXRIeWRyYXRpb25UYXJnZXQobmV4dEV4cGxpY2l0VGFyZ2V0KTtcblxuICAgICAgaWYgKG5leHRFeHBsaWNpdFRhcmdldC5ibG9ja2VkT24gPT09IG51bGwpIHtcbiAgICAgICAgLy8gV2UncmUgdW5ibG9ja2VkLlxuICAgICAgICBxdWV1ZWRFeHBsaWNpdEh5ZHJhdGlvblRhcmdldHMuc2hpZnQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50QmF0Y2hDb25maWc7IC8vIFRPRE86IGNhbiB3ZSBzdG9wIGV4cG9ydGluZyB0aGVzZT9cblxudmFyIF9lbmFibGVkID0gdHJ1ZTsgLy8gVGhpcyBpcyBleHBvcnRlZCBpbiBGQiBidWlsZHMgZm9yIHVzZSBieSBsZWdhY3kgRkIgbGF5ZXIgaW5mcmEuXG4vLyBXZSdkIGxpa2UgdG8gcmVtb3ZlIHRoaXMgYnV0IGl0J3Mgbm90IGNsZWFyIGlmIHRoaXMgaXMgc2FmZS5cblxuZnVuY3Rpb24gc2V0RW5hYmxlZChlbmFibGVkKSB7XG4gIF9lbmFibGVkID0gISFlbmFibGVkO1xufVxuZnVuY3Rpb24gaXNFbmFibGVkKCkge1xuICByZXR1cm4gX2VuYWJsZWQ7XG59XG5mdW5jdGlvbiBjcmVhdGVFdmVudExpc3RlbmVyV3JhcHBlcldpdGhQcmlvcml0eSh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncykge1xuICB2YXIgZXZlbnRQcmlvcml0eSA9IGdldEV2ZW50UHJpb3JpdHkoZG9tRXZlbnROYW1lKTtcbiAgdmFyIGxpc3RlbmVyV3JhcHBlcjtcblxuICBzd2l0Y2ggKGV2ZW50UHJpb3JpdHkpIHtcbiAgICBjYXNlIERpc2NyZXRlRXZlbnRQcmlvcml0eTpcbiAgICAgIGxpc3RlbmVyV3JhcHBlciA9IGRpc3BhdGNoRGlzY3JldGVFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250aW51b3VzRXZlbnRQcmlvcml0eTpcbiAgICAgIGxpc3RlbmVyV3JhcHBlciA9IGRpc3BhdGNoQ29udGludW91c0V2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIERlZmF1bHRFdmVudFByaW9yaXR5OlxuICAgIGRlZmF1bHQ6XG4gICAgICBsaXN0ZW5lcldyYXBwZXIgPSBkaXNwYXRjaEV2ZW50O1xuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gbGlzdGVuZXJXcmFwcGVyLmJpbmQobnVsbCwgZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaERpc2NyZXRlRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBjb250YWluZXIsIG5hdGl2ZUV2ZW50KSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBudWxsO1xuXG4gIHRyeSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgZGlzcGF0Y2hFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIGNvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBjb250YWluZXIsIG5hdGl2ZUV2ZW50KSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBudWxsO1xuXG4gIHRyeSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KENvbnRpbnVvdXNFdmVudFByaW9yaXR5KTtcbiAgICBkaXNwYXRjaEV2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgY29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG4gIH0gZmluYWxseSB7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICBpZiAoIV9lbmFibGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAge1xuICAgIGRpc3BhdGNoRXZlbnRXaXRoRW5hYmxlQ2FwdHVyZVBoYXNlU2VsZWN0aXZlSHlkcmF0aW9uV2l0aG91dERpc2NyZXRlRXZlbnRSZXBsYXkoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIG5hdGl2ZUV2ZW50KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50V2l0aEVuYWJsZUNhcHR1cmVQaGFzZVNlbGVjdGl2ZUh5ZHJhdGlvbldpdGhvdXREaXNjcmV0ZUV2ZW50UmVwbGF5KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkge1xuICB2YXIgYmxvY2tlZE9uID0gZmluZEluc3RhbmNlQmxvY2tpbmdFdmVudChkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lciwgbmF0aXZlRXZlbnQpO1xuXG4gIGlmIChibG9ja2VkT24gPT09IG51bGwpIHtcbiAgICBkaXNwYXRjaEV2ZW50Rm9yUGx1Z2luRXZlbnRTeXN0ZW0oZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgcmV0dXJuX3RhcmdldEluc3QsIHRhcmdldENvbnRhaW5lcik7XG4gICAgY2xlYXJJZkNvbnRpbnVvdXNFdmVudChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAocXVldWVJZkNvbnRpbnVvdXNFdmVudChibG9ja2VkT24sIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCkpIHtcbiAgICBuYXRpdmVFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICByZXR1cm47XG4gIH0gLy8gV2UgbmVlZCB0byBjbGVhciBvbmx5IGlmIHdlIGRpZG4ndCBxdWV1ZSBiZWNhdXNlXG4gIC8vIHF1ZXVlaW5nIGlzIGFjY3VtdWxhdGl2ZS5cblxuXG4gIGNsZWFySWZDb250aW51b3VzRXZlbnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCk7XG5cbiAgaWYgKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19DQVBUVVJFX1BIQVNFICYmIGlzRGlzY3JldGVFdmVudFRoYXRSZXF1aXJlc0h5ZHJhdGlvbihkb21FdmVudE5hbWUpKSB7XG4gICAgd2hpbGUgKGJsb2NrZWRPbiAhPT0gbnVsbCkge1xuICAgICAgdmFyIGZpYmVyID0gZ2V0SW5zdGFuY2VGcm9tTm9kZShibG9ja2VkT24pO1xuXG4gICAgICBpZiAoZmliZXIgIT09IG51bGwpIHtcbiAgICAgICAgYXR0ZW1wdFN5bmNocm9ub3VzSHlkcmF0aW9uKGZpYmVyKTtcbiAgICAgIH1cblxuICAgICAgdmFyIG5leHRCbG9ja2VkT24gPSBmaW5kSW5zdGFuY2VCbG9ja2luZ0V2ZW50KGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyLCBuYXRpdmVFdmVudCk7XG5cbiAgICAgIGlmIChuZXh0QmxvY2tlZE9uID09PSBudWxsKSB7XG4gICAgICAgIGRpc3BhdGNoRXZlbnRGb3JQbHVnaW5FdmVudFN5c3RlbShkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCByZXR1cm5fdGFyZ2V0SW5zdCwgdGFyZ2V0Q29udGFpbmVyKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5leHRCbG9ja2VkT24gPT09IGJsb2NrZWRPbikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgYmxvY2tlZE9uID0gbmV4dEJsb2NrZWRPbjtcbiAgICB9XG5cbiAgICBpZiAoYmxvY2tlZE9uICE9PSBudWxsKSB7XG4gICAgICBuYXRpdmVFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH0gLy8gVGhpcyBpcyBub3QgcmVwbGF5YWJsZSBzbyB3ZSdsbCBpbnZva2UgaXQgYnV0IHdpdGhvdXQgYSB0YXJnZXQsXG4gIC8vIGluIGNhc2UgdGhlIGV2ZW50IHN5c3RlbSBuZWVkcyB0byB0cmFjZSBpdC5cblxuXG4gIGRpc3BhdGNoRXZlbnRGb3JQbHVnaW5FdmVudFN5c3RlbShkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCBudWxsLCB0YXJnZXRDb250YWluZXIpO1xufVxuXG52YXIgcmV0dXJuX3RhcmdldEluc3QgPSBudWxsOyAvLyBSZXR1cm5zIGEgU3VzcGVuc2VJbnN0YW5jZSBvciBDb250YWluZXIgaWYgaXQncyBibG9ja2VkLlxuLy8gVGhlIHJldHVybl90YXJnZXRJbnN0IGZpZWxkIGFib3ZlIGlzIGNvbmNlcHR1YWxseSBwYXJ0IG9mIHRoZSByZXR1cm4gdmFsdWUuXG5cbmZ1bmN0aW9uIGZpbmRJbnN0YW5jZUJsb2NraW5nRXZlbnQoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIsIG5hdGl2ZUV2ZW50KSB7XG4gIC8vIFRPRE86IFdhcm4gaWYgX2VuYWJsZWQgaXMgZmFsc2UuXG4gIHJldHVybl90YXJnZXRJbnN0ID0gbnVsbDtcbiAgdmFyIG5hdGl2ZUV2ZW50VGFyZ2V0ID0gZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpO1xuICB2YXIgdGFyZ2V0SW5zdCA9IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICBpZiAodGFyZ2V0SW5zdCAhPT0gbnVsbCkge1xuICAgIHZhciBuZWFyZXN0TW91bnRlZCA9IGdldE5lYXJlc3RNb3VudGVkRmliZXIodGFyZ2V0SW5zdCk7XG5cbiAgICBpZiAobmVhcmVzdE1vdW50ZWQgPT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgdHJlZSBoYXMgYmVlbiB1bm1vdW50ZWQgYWxyZWFkeS4gRGlzcGF0Y2ggd2l0aG91dCBhIHRhcmdldC5cbiAgICAgIHRhcmdldEluc3QgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdGFnID0gbmVhcmVzdE1vdW50ZWQudGFnO1xuXG4gICAgICBpZiAodGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBnZXRTdXNwZW5zZUluc3RhbmNlRnJvbUZpYmVyKG5lYXJlc3RNb3VudGVkKTtcblxuICAgICAgICBpZiAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBRdWV1ZSB0aGUgZXZlbnQgdG8gYmUgcmVwbGF5ZWQgbGF0ZXIuIEFib3J0IGRpc3BhdGNoaW5nIHNpbmNlIHdlXG4gICAgICAgICAgLy8gZG9uJ3Qgd2FudCB0aGlzIGV2ZW50IGRpc3BhdGNoZWQgdHdpY2UgdGhyb3VnaCB0aGUgZXZlbnQgc3lzdGVtLlxuICAgICAgICAgIC8vIFRPRE86IElmIHRoaXMgaXMgdGhlIGZpcnN0IGRpc2NyZXRlIGV2ZW50IGluIHRoZSBxdWV1ZS4gU2NoZWR1bGUgYW4gaW5jcmVhc2VkXG4gICAgICAgICAgLy8gcHJpb3JpdHkgZm9yIHRoaXMgYm91bmRhcnkuXG4gICAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgICAgICB9IC8vIFRoaXMgc2hvdWxkbid0IGhhcHBlbiwgc29tZXRoaW5nIHdlbnQgd3JvbmcgYnV0IHRvIGF2b2lkIGJsb2NraW5nXG4gICAgICAgIC8vIHRoZSB3aG9sZSBzeXN0ZW0sIGRpc3BhdGNoIHRoZSBldmVudCB3aXRob3V0IGEgdGFyZ2V0LlxuICAgICAgICAvLyBUT0RPOiBXYXJuLlxuXG5cbiAgICAgICAgdGFyZ2V0SW5zdCA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKHRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgICAgdmFyIHJvb3QgPSBuZWFyZXN0TW91bnRlZC5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKGlzUm9vdERlaHlkcmF0ZWQocm9vdCkpIHtcbiAgICAgICAgICAvLyBJZiB0aGlzIGhhcHBlbnMgZHVyaW5nIGEgcmVwbGF5IHNvbWV0aGluZyB3ZW50IHdyb25nIGFuZCBpdCBtaWdodCBibG9ja1xuICAgICAgICAgIC8vIHRoZSB3aG9sZSBzeXN0ZW0uXG4gICAgICAgICAgcmV0dXJuIGdldENvbnRhaW5lckZyb21GaWJlcihuZWFyZXN0TW91bnRlZCk7XG4gICAgICAgIH1cblxuICAgICAgICB0YXJnZXRJbnN0ID0gbnVsbDtcbiAgICAgIH0gZWxzZSBpZiAobmVhcmVzdE1vdW50ZWQgIT09IHRhcmdldEluc3QpIHtcbiAgICAgICAgLy8gSWYgd2UgZ2V0IGFuIGV2ZW50IChleDogaW1nIG9ubG9hZCkgYmVmb3JlIGNvbW1pdHRpbmcgdGhhdFxuICAgICAgICAvLyBjb21wb25lbnQncyBtb3VudCwgaWdub3JlIGl0IGZvciBub3cgKHRoYXQgaXMsIHRyZWF0IGl0IGFzIGlmIGl0IHdhcyBhblxuICAgICAgICAvLyBldmVudCBvbiBhIG5vbi1SZWFjdCB0cmVlKS4gV2UgbWlnaHQgYWxzbyBjb25zaWRlciBxdWV1ZWluZyBldmVudHMgYW5kXG4gICAgICAgIC8vIGRpc3BhdGNoaW5nIHRoZW0gYWZ0ZXIgdGhlIG1vdW50LlxuICAgICAgICB0YXJnZXRJbnN0ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm5fdGFyZ2V0SW5zdCA9IHRhcmdldEluc3Q7IC8vIFdlJ3JlIG5vdCBibG9ja2VkIG9uIGFueXRoaW5nLlxuXG4gIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZ2V0RXZlbnRQcmlvcml0eShkb21FdmVudE5hbWUpIHtcbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICAvLyBVc2VkIGJ5IFNpbXBsZUV2ZW50UGx1Z2luOlxuICAgIGNhc2UgJ2NhbmNlbCc6XG4gICAgY2FzZSAnY2xpY2snOlxuICAgIGNhc2UgJ2Nsb3NlJzpcbiAgICBjYXNlICdjb250ZXh0bWVudSc6XG4gICAgY2FzZSAnY29weSc6XG4gICAgY2FzZSAnY3V0JzpcbiAgICBjYXNlICdhdXhjbGljayc6XG4gICAgY2FzZSAnZGJsY2xpY2snOlxuICAgIGNhc2UgJ2RyYWdlbmQnOlxuICAgIGNhc2UgJ2RyYWdzdGFydCc6XG4gICAgY2FzZSAnZHJvcCc6XG4gICAgY2FzZSAnZm9jdXNpbic6XG4gICAgY2FzZSAnZm9jdXNvdXQnOlxuICAgIGNhc2UgJ2lucHV0JzpcbiAgICBjYXNlICdpbnZhbGlkJzpcbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICBjYXNlICdrZXlwcmVzcyc6XG4gICAgY2FzZSAna2V5dXAnOlxuICAgIGNhc2UgJ21vdXNlZG93bic6XG4gICAgY2FzZSAnbW91c2V1cCc6XG4gICAgY2FzZSAncGFzdGUnOlxuICAgIGNhc2UgJ3BhdXNlJzpcbiAgICBjYXNlICdwbGF5JzpcbiAgICBjYXNlICdwb2ludGVyY2FuY2VsJzpcbiAgICBjYXNlICdwb2ludGVyZG93bic6XG4gICAgY2FzZSAncG9pbnRlcnVwJzpcbiAgICBjYXNlICdyYXRlY2hhbmdlJzpcbiAgICBjYXNlICdyZXNldCc6XG4gICAgY2FzZSAncmVzaXplJzpcbiAgICBjYXNlICdzZWVrZWQnOlxuICAgIGNhc2UgJ3N1Ym1pdCc6XG4gICAgY2FzZSAndG91Y2hjYW5jZWwnOlxuICAgIGNhc2UgJ3RvdWNoZW5kJzpcbiAgICBjYXNlICd0b3VjaHN0YXJ0JzpcbiAgICBjYXNlICd2b2x1bWVjaGFuZ2UnOiAvLyBVc2VkIGJ5IHBvbHlmaWxsczpcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgIGNhc2UgJ2NoYW5nZSc6XG4gICAgY2FzZSAnc2VsZWN0aW9uY2hhbmdlJzpcbiAgICBjYXNlICd0ZXh0SW5wdXQnOlxuICAgIGNhc2UgJ2NvbXBvc2l0aW9uc3RhcnQnOlxuICAgIGNhc2UgJ2NvbXBvc2l0aW9uZW5kJzpcbiAgICBjYXNlICdjb21wb3NpdGlvbnVwZGF0ZSc6IC8vIE9ubHkgZW5hYmxlQ3JlYXRlRXZlbnRIYW5kbGVBUEk6XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICBjYXNlICdiZWZvcmVibHVyJzpcbiAgICBjYXNlICdhZnRlcmJsdXInOiAvLyBOb3QgdXNlZCBieSBSZWFjdCBidXQgY291bGQgYmUgYnkgdXNlciBjb2RlOlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgY2FzZSAnYmVmb3JlaW5wdXQnOlxuICAgIGNhc2UgJ2JsdXInOlxuICAgIGNhc2UgJ2Z1bGxzY3JlZW5jaGFuZ2UnOlxuICAgIGNhc2UgJ2ZvY3VzJzpcbiAgICBjYXNlICdoYXNoY2hhbmdlJzpcbiAgICBjYXNlICdwb3BzdGF0ZSc6XG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICBjYXNlICdzZWxlY3RzdGFydCc6XG4gICAgICByZXR1cm4gRGlzY3JldGVFdmVudFByaW9yaXR5O1xuXG4gICAgY2FzZSAnZHJhZyc6XG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICBjYXNlICdkcmFnZXhpdCc6XG4gICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICBjYXNlICdkcmFnb3Zlcic6XG4gICAgY2FzZSAnbW91c2Vtb3ZlJzpcbiAgICBjYXNlICdtb3VzZW91dCc6XG4gICAgY2FzZSAnbW91c2VvdmVyJzpcbiAgICBjYXNlICdwb2ludGVybW92ZSc6XG4gICAgY2FzZSAncG9pbnRlcm91dCc6XG4gICAgY2FzZSAncG9pbnRlcm92ZXInOlxuICAgIGNhc2UgJ3Njcm9sbCc6XG4gICAgY2FzZSAndG9nZ2xlJzpcbiAgICBjYXNlICd0b3VjaG1vdmUnOlxuICAgIGNhc2UgJ3doZWVsJzogLy8gTm90IHVzZWQgYnkgUmVhY3QgYnV0IGNvdWxkIGJlIGJ5IHVzZXIgY29kZTpcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgIGNhc2UgJ21vdXNlZW50ZXInOlxuICAgIGNhc2UgJ21vdXNlbGVhdmUnOlxuICAgIGNhc2UgJ3BvaW50ZXJlbnRlcic6XG4gICAgY2FzZSAncG9pbnRlcmxlYXZlJzpcbiAgICAgIHJldHVybiBDb250aW51b3VzRXZlbnRQcmlvcml0eTtcblxuICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAge1xuICAgICAgICAvLyBXZSBtaWdodCBiZSBpbiB0aGUgU2NoZWR1bGVyIGNhbGxiYWNrLlxuICAgICAgICAvLyBFdmVudHVhbGx5IHRoaXMgbWVjaGFuaXNtIHdpbGwgYmUgcmVwbGFjZWQgYnkgYSBjaGVja1xuICAgICAgICAvLyBvZiB0aGUgY3VycmVudCBwcmlvcml0eSBvbiB0aGUgbmF0aXZlIHNjaGVkdWxlci5cbiAgICAgICAgdmFyIHNjaGVkdWxlclByaW9yaXR5ID0gZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwoKTtcblxuICAgICAgICBzd2l0Y2ggKHNjaGVkdWxlclByaW9yaXR5KSB7XG4gICAgICAgICAgY2FzZSBJbW1lZGlhdGVQcmlvcml0eTpcbiAgICAgICAgICAgIHJldHVybiBEaXNjcmV0ZUV2ZW50UHJpb3JpdHk7XG5cbiAgICAgICAgICBjYXNlIFVzZXJCbG9ja2luZ1ByaW9yaXR5OlxuICAgICAgICAgICAgcmV0dXJuIENvbnRpbnVvdXNFdmVudFByaW9yaXR5O1xuXG4gICAgICAgICAgY2FzZSBOb3JtYWxQcmlvcml0eTpcbiAgICAgICAgICBjYXNlIExvd1ByaW9yaXR5OlxuICAgICAgICAgICAgLy8gVE9ETzogSGFuZGxlIExvd1NjaGVkdWxlclByaW9yaXR5LCBzb21laG93LiBNYXliZSB0aGUgc2FtZSBsYW5lIGFzIGh5ZHJhdGlvbi5cbiAgICAgICAgICAgIHJldHVybiBEZWZhdWx0RXZlbnRQcmlvcml0eTtcblxuICAgICAgICAgIGNhc2UgSWRsZVByaW9yaXR5OlxuICAgICAgICAgICAgcmV0dXJuIElkbGVFdmVudFByaW9yaXR5O1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBEZWZhdWx0RXZlbnRQcmlvcml0eTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBEZWZhdWx0RXZlbnRQcmlvcml0eTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhZGRFdmVudEJ1YmJsZUxpc3RlbmVyKHRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lcikge1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCBmYWxzZSk7XG4gIHJldHVybiBsaXN0ZW5lcjtcbn1cbmZ1bmN0aW9uIGFkZEV2ZW50Q2FwdHVyZUxpc3RlbmVyKHRhcmdldCwgZXZlbnRUeXBlLCBsaXN0ZW5lcikge1xuICB0YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgcmV0dXJuIGxpc3RlbmVyO1xufVxuZnVuY3Rpb24gYWRkRXZlbnRDYXB0dXJlTGlzdGVuZXJXaXRoUGFzc2l2ZUZsYWcodGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBwYXNzaXZlKSB7XG4gIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIHtcbiAgICBjYXB0dXJlOiB0cnVlLFxuICAgIHBhc3NpdmU6IHBhc3NpdmVcbiAgfSk7XG4gIHJldHVybiBsaXN0ZW5lcjtcbn1cbmZ1bmN0aW9uIGFkZEV2ZW50QnViYmxlTGlzdGVuZXJXaXRoUGFzc2l2ZUZsYWcodGFyZ2V0LCBldmVudFR5cGUsIGxpc3RlbmVyLCBwYXNzaXZlKSB7XG4gIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIsIHtcbiAgICBwYXNzaXZlOiBwYXNzaXZlXG4gIH0pO1xuICByZXR1cm4gbGlzdGVuZXI7XG59XG5cbi8qKlxuICogVGhlc2UgdmFyaWFibGVzIHN0b3JlIGluZm9ybWF0aW9uIGFib3V0IHRleHQgY29udGVudCBvZiBhIHRhcmdldCBub2RlLFxuICogYWxsb3dpbmcgY29tcGFyaXNvbiBvZiBjb250ZW50IGJlZm9yZSBhbmQgYWZ0ZXIgYSBnaXZlbiBldmVudC5cbiAqXG4gKiBJZGVudGlmeSB0aGUgbm9kZSB3aGVyZSBzZWxlY3Rpb24gY3VycmVudGx5IGJlZ2lucywgdGhlbiBvYnNlcnZlXG4gKiBib3RoIGl0cyB0ZXh0IGNvbnRlbnQgYW5kIGl0cyBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSBET00uIFNpbmNlIHRoZVxuICogYnJvd3NlciBtYXkgbmF0aXZlbHkgcmVwbGFjZSB0aGUgdGFyZ2V0IG5vZGUgZHVyaW5nIGNvbXBvc2l0aW9uLCB3ZSBjYW5cbiAqIHVzZSBpdHMgcG9zaXRpb24gdG8gZmluZCBpdHMgcmVwbGFjZW1lbnQuXG4gKlxuICpcbiAqL1xudmFyIHJvb3QgPSBudWxsO1xudmFyIHN0YXJ0VGV4dCA9IG51bGw7XG52YXIgZmFsbGJhY2tUZXh0ID0gbnVsbDtcbmZ1bmN0aW9uIGluaXRpYWxpemUobmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgcm9vdCA9IG5hdGl2ZUV2ZW50VGFyZ2V0O1xuICBzdGFydFRleHQgPSBnZXRUZXh0KCk7XG4gIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gcmVzZXQoKSB7XG4gIHJvb3QgPSBudWxsO1xuICBzdGFydFRleHQgPSBudWxsO1xuICBmYWxsYmFja1RleHQgPSBudWxsO1xufVxuZnVuY3Rpb24gZ2V0RGF0YSgpIHtcbiAgaWYgKGZhbGxiYWNrVGV4dCkge1xuICAgIHJldHVybiBmYWxsYmFja1RleHQ7XG4gIH1cblxuICB2YXIgc3RhcnQ7XG4gIHZhciBzdGFydFZhbHVlID0gc3RhcnRUZXh0O1xuICB2YXIgc3RhcnRMZW5ndGggPSBzdGFydFZhbHVlLmxlbmd0aDtcbiAgdmFyIGVuZDtcbiAgdmFyIGVuZFZhbHVlID0gZ2V0VGV4dCgpO1xuICB2YXIgZW5kTGVuZ3RoID0gZW5kVmFsdWUubGVuZ3RoO1xuXG4gIGZvciAoc3RhcnQgPSAwOyBzdGFydCA8IHN0YXJ0TGVuZ3RoOyBzdGFydCsrKSB7XG4gICAgaWYgKHN0YXJ0VmFsdWVbc3RhcnRdICE9PSBlbmRWYWx1ZVtzdGFydF0pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBtaW5FbmQgPSBzdGFydExlbmd0aCAtIHN0YXJ0O1xuXG4gIGZvciAoZW5kID0gMTsgZW5kIDw9IG1pbkVuZDsgZW5kKyspIHtcbiAgICBpZiAoc3RhcnRWYWx1ZVtzdGFydExlbmd0aCAtIGVuZF0gIT09IGVuZFZhbHVlW2VuZExlbmd0aCAtIGVuZF0pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzbGljZVRhaWwgPSBlbmQgPiAxID8gMSAtIGVuZCA6IHVuZGVmaW5lZDtcbiAgZmFsbGJhY2tUZXh0ID0gZW5kVmFsdWUuc2xpY2Uoc3RhcnQsIHNsaWNlVGFpbCk7XG4gIHJldHVybiBmYWxsYmFja1RleHQ7XG59XG5mdW5jdGlvbiBnZXRUZXh0KCkge1xuICBpZiAoJ3ZhbHVlJyBpbiByb290KSB7XG4gICAgcmV0dXJuIHJvb3QudmFsdWU7XG4gIH1cblxuICByZXR1cm4gcm9vdC50ZXh0Q29udGVudDtcbn1cblxuLyoqXG4gKiBgY2hhckNvZGVgIHJlcHJlc2VudHMgdGhlIGFjdHVhbCBcImNoYXJhY3RlciBjb2RlXCIgYW5kIGlzIHNhZmUgdG8gdXNlIHdpdGhcbiAqIGBTdHJpbmcuZnJvbUNoYXJDb2RlYC4gQXMgc3VjaCwgb25seSBrZXlzIHRoYXQgY29ycmVzcG9uZCB0byBwcmludGFibGVcbiAqIGNoYXJhY3RlcnMgcHJvZHVjZSBhIHZhbGlkIGBjaGFyQ29kZWAsIHRoZSBvbmx5IGV4Y2VwdGlvbiB0byB0aGlzIGlzIEVudGVyLlxuICogVGhlIFRhYi1rZXkgaXMgY29uc2lkZXJlZCBub24tcHJpbnRhYmxlIGFuZCBkb2VzIG5vdCBoYXZlIGEgYGNoYXJDb2RlYCxcbiAqIHByZXN1bWFibHkgYmVjYXVzZSBpdCBkb2VzIG5vdCBwcm9kdWNlIGEgdGFiLWNoYXJhY3RlciBpbiBicm93c2Vycy5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE5vcm1hbGl6ZWQgYGNoYXJDb2RlYCBwcm9wZXJ0eS5cbiAqL1xuZnVuY3Rpb24gZ2V0RXZlbnRDaGFyQ29kZShuYXRpdmVFdmVudCkge1xuICB2YXIgY2hhckNvZGU7XG4gIHZhciBrZXlDb2RlID0gbmF0aXZlRXZlbnQua2V5Q29kZTtcblxuICBpZiAoJ2NoYXJDb2RlJyBpbiBuYXRpdmVFdmVudCkge1xuICAgIGNoYXJDb2RlID0gbmF0aXZlRXZlbnQuY2hhckNvZGU7IC8vIEZGIGRvZXMgbm90IHNldCBgY2hhckNvZGVgIGZvciB0aGUgRW50ZXIta2V5LCBjaGVjayBhZ2FpbnN0IGBrZXlDb2RlYC5cblxuICAgIGlmIChjaGFyQ29kZSA9PT0gMCAmJiBrZXlDb2RlID09PSAxMykge1xuICAgICAgY2hhckNvZGUgPSAxMztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSUU4IGRvZXMgbm90IGltcGxlbWVudCBgY2hhckNvZGVgLCBidXQgYGtleUNvZGVgIGhhcyB0aGUgY29ycmVjdCB2YWx1ZS5cbiAgICBjaGFyQ29kZSA9IGtleUNvZGU7XG4gIH0gLy8gSUUgYW5kIEVkZ2UgKG9uIFdpbmRvd3MpIGFuZCBDaHJvbWUgLyBTYWZhcmkgKG9uIFdpbmRvd3MgYW5kIExpbnV4KVxuICAvLyByZXBvcnQgRW50ZXIgYXMgY2hhckNvZGUgMTAgd2hlbiBjdHJsIGlzIHByZXNzZWQuXG5cblxuICBpZiAoY2hhckNvZGUgPT09IDEwKSB7XG4gICAgY2hhckNvZGUgPSAxMztcbiAgfSAvLyBTb21lIG5vbi1wcmludGFibGUga2V5cyBhcmUgcmVwb3J0ZWQgaW4gYGNoYXJDb2RlYC9ga2V5Q29kZWAsIGRpc2NhcmQgdGhlbS5cbiAgLy8gTXVzdCBub3QgZGlzY2FyZCB0aGUgKG5vbi0pcHJpbnRhYmxlIEVudGVyLWtleS5cblxuXG4gIGlmIChjaGFyQ29kZSA+PSAzMiB8fCBjaGFyQ29kZSA9PT0gMTMpIHtcbiAgICByZXR1cm4gY2hhckNvZGU7XG4gIH1cblxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gZnVuY3Rpb25UaGF0UmV0dXJuc1RydWUoKSB7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBmdW5jdGlvblRoYXRSZXR1cm5zRmFsc2UoKSB7XG4gIHJldHVybiBmYWxzZTtcbn0gLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGEgZmFjdG9yeSBzbyB0aGF0IHdlIGhhdmUgZGlmZmVyZW50IHJldHVybmVkIGNvbnN0cnVjdG9ycy5cbi8vIElmIHdlIGhhZCBhIHNpbmdsZSBjb25zdHJ1Y3RvciwgaXQgd291bGQgYmUgbWVnYW1vcnBoaWMgYW5kIGVuZ2luZXMgd291bGQgZGVvcHQuXG5cblxuZnVuY3Rpb24gY3JlYXRlU3ludGhldGljRXZlbnQoSW50ZXJmYWNlKSB7XG4gIC8qKlxuICAgKiBTeW50aGV0aWMgZXZlbnRzIGFyZSBkaXNwYXRjaGVkIGJ5IGV2ZW50IHBsdWdpbnMsIHR5cGljYWxseSBpbiByZXNwb25zZSB0byBhXG4gICAqIHRvcC1sZXZlbCBldmVudCBkZWxlZ2F0aW9uIGhhbmRsZXIuXG4gICAqXG4gICAqIFRoZXNlIHN5c3RlbXMgc2hvdWxkIGdlbmVyYWxseSB1c2UgcG9vbGluZyB0byByZWR1Y2UgdGhlIGZyZXF1ZW5jeSBvZiBnYXJiYWdlXG4gICAqIGNvbGxlY3Rpb24uIFRoZSBzeXN0ZW0gc2hvdWxkIGNoZWNrIGBpc1BlcnNpc3RlbnRgIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZVxuICAgKiBldmVudCBzaG91bGQgYmUgcmVsZWFzZWQgaW50byB0aGUgcG9vbCBhZnRlciBiZWluZyBkaXNwYXRjaGVkLiBVc2VycyB0aGF0XG4gICAqIG5lZWQgYSBwZXJzaXN0ZWQgZXZlbnQgc2hvdWxkIGludm9rZSBgcGVyc2lzdGAuXG4gICAqXG4gICAqIFN5bnRoZXRpYyBldmVudHMgKGFuZCBzdWJjbGFzc2VzKSBpbXBsZW1lbnQgdGhlIERPTSBMZXZlbCAzIEV2ZW50cyBBUEkgYnlcbiAgICogbm9ybWFsaXppbmcgYnJvd3NlciBxdWlya3MuIFN1YmNsYXNzZXMgZG8gbm90IG5lY2Vzc2FyaWx5IGhhdmUgdG8gaW1wbGVtZW50IGFcbiAgICogRE9NIGludGVyZmFjZTsgY3VzdG9tIGFwcGxpY2F0aW9uLXNwZWNpZmljIGV2ZW50cyBjYW4gYWxzbyBzdWJjbGFzcyB0aGlzLlxuICAgKi9cbiAgZnVuY3Rpb24gU3ludGhldGljQmFzZUV2ZW50KHJlYWN0TmFtZSwgcmVhY3RFdmVudFR5cGUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICAgIHRoaXMuX3JlYWN0TmFtZSA9IHJlYWN0TmFtZTtcbiAgICB0aGlzLl90YXJnZXRJbnN0ID0gdGFyZ2V0SW5zdDtcbiAgICB0aGlzLnR5cGUgPSByZWFjdEV2ZW50VHlwZTtcbiAgICB0aGlzLm5hdGl2ZUV2ZW50ID0gbmF0aXZlRXZlbnQ7XG4gICAgdGhpcy50YXJnZXQgPSBuYXRpdmVFdmVudFRhcmdldDtcbiAgICB0aGlzLmN1cnJlbnRUYXJnZXQgPSBudWxsO1xuXG4gICAgZm9yICh2YXIgX3Byb3BOYW1lIGluIEludGVyZmFjZSkge1xuICAgICAgaWYgKCFJbnRlcmZhY2UuaGFzT3duUHJvcGVydHkoX3Byb3BOYW1lKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIG5vcm1hbGl6ZSA9IEludGVyZmFjZVtfcHJvcE5hbWVdO1xuXG4gICAgICBpZiAobm9ybWFsaXplKSB7XG4gICAgICAgIHRoaXNbX3Byb3BOYW1lXSA9IG5vcm1hbGl6ZShuYXRpdmVFdmVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzW19wcm9wTmFtZV0gPSBuYXRpdmVFdmVudFtfcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBkZWZhdWx0UHJldmVudGVkID0gbmF0aXZlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCAhPSBudWxsID8gbmF0aXZlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCA6IG5hdGl2ZUV2ZW50LnJldHVyblZhbHVlID09PSBmYWxzZTtcblxuICAgIGlmIChkZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNUcnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNGYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gZnVuY3Rpb25UaGF0UmV0dXJuc0ZhbHNlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgYXNzaWduKFN5bnRoZXRpY0Jhc2VFdmVudC5wcm90b3R5cGUsIHtcbiAgICBwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24gKCkge1xuICAgICAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbiAgICAgIHZhciBldmVudCA9IHRoaXMubmF0aXZlRXZlbnQ7XG5cbiAgICAgIGlmICghZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gJEZsb3dGaXhNZSAtIGZsb3cgaXMgbm90IGF3YXJlIG9mIGB1bmtub3duYCBpbiBJRVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZXZlbnQucmV0dXJuVmFsdWUgIT09ICd1bmtub3duJykge1xuICAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IGZ1bmN0aW9uVGhhdFJldHVybnNUcnVlO1xuICAgIH0sXG4gICAgc3RvcFByb3BhZ2F0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgZXZlbnQgPSB0aGlzLm5hdGl2ZUV2ZW50O1xuXG4gICAgICBpZiAoIWV2ZW50KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LnN0b3BQcm9wYWdhdGlvbikge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgLy8gJEZsb3dGaXhNZSAtIGZsb3cgaXMgbm90IGF3YXJlIG9mIGB1bmtub3duYCBpbiBJRVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZXZlbnQuY2FuY2VsQnViYmxlICE9PSAndW5rbm93bicpIHtcbiAgICAgICAgLy8gVGhlIENoYW5nZUV2ZW50UGx1Z2luIHJlZ2lzdGVycyBhIFwicHJvcGVydHljaGFuZ2VcIiBldmVudCBmb3JcbiAgICAgICAgLy8gSUUuIFRoaXMgZXZlbnQgZG9lcyBub3Qgc3VwcG9ydCBidWJibGluZyBvciBjYW5jZWxsaW5nLCBhbmRcbiAgICAgICAgLy8gYW55IHJlZmVyZW5jZXMgdG8gY2FuY2VsQnViYmxlIHRocm93IFwiTWVtYmVyIG5vdCBmb3VuZFwiLiAgQVxuICAgICAgICAvLyB0eXBlb2YgY2hlY2sgb2YgXCJ1bmtub3duXCIgY2lyY3VtdmVudHMgdGhpcyBpc3N1ZSAoYW5kIGlzIGFsc29cbiAgICAgICAgLy8gSUUgc3BlY2lmaWMpLlxuICAgICAgICBldmVudC5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gZnVuY3Rpb25UaGF0UmV0dXJuc1RydWU7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFdlIHJlbGVhc2UgYWxsIGRpc3BhdGNoZWQgYFN5bnRoZXRpY0V2ZW50YHMgYWZ0ZXIgZWFjaCBldmVudCBsb29wLCBhZGRpbmdcbiAgICAgKiB0aGVtIGJhY2sgaW50byB0aGUgcG9vbC4gVGhpcyBhbGxvd3MgYSB3YXkgdG8gaG9sZCBvbnRvIGEgcmVmZXJlbmNlIHRoYXRcbiAgICAgKiB3b24ndCBiZSBhZGRlZCBiYWNrIGludG8gdGhlIHBvb2wuXG4gICAgICovXG4gICAgcGVyc2lzdDogZnVuY3Rpb24gKCkgey8vIE1vZGVybiBldmVudCBzeXN0ZW0gZG9lc24ndCB1c2UgcG9vbGluZy5cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoaXMgZXZlbnQgc2hvdWxkIGJlIHJlbGVhc2VkIGJhY2sgaW50byB0aGUgcG9vbC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhpcyBzaG91bGQgbm90IGJlIHJlbGVhc2VkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaXNQZXJzaXN0ZW50OiBmdW5jdGlvblRoYXRSZXR1cm5zVHJ1ZVxuICB9KTtcbiAgcmV0dXJuIFN5bnRoZXRpY0Jhc2VFdmVudDtcbn1cbi8qKlxuICogQGludGVyZmFjZSBFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMy1FdmVudHMvXG4gKi9cblxuXG52YXIgRXZlbnRJbnRlcmZhY2UgPSB7XG4gIGV2ZW50UGhhc2U6IDAsXG4gIGJ1YmJsZXM6IDAsXG4gIGNhbmNlbGFibGU6IDAsXG4gIHRpbWVTdGFtcDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuIGV2ZW50LnRpbWVTdGFtcCB8fCBEYXRlLm5vdygpO1xuICB9LFxuICBkZWZhdWx0UHJldmVudGVkOiAwLFxuICBpc1RydXN0ZWQ6IDBcbn07XG52YXIgU3ludGhldGljRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChFdmVudEludGVyZmFjZSk7XG5cbnZhciBVSUV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBFdmVudEludGVyZmFjZSwge1xuICB2aWV3OiAwLFxuICBkZXRhaWw6IDBcbn0pO1xuXG52YXIgU3ludGhldGljVUlFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KFVJRXZlbnRJbnRlcmZhY2UpO1xudmFyIGxhc3RNb3ZlbWVudFg7XG52YXIgbGFzdE1vdmVtZW50WTtcbnZhciBsYXN0TW91c2VFdmVudDtcblxuZnVuY3Rpb24gdXBkYXRlTW91c2VNb3ZlbWVudFBvbHlmaWxsU3RhdGUoZXZlbnQpIHtcbiAgaWYgKGV2ZW50ICE9PSBsYXN0TW91c2VFdmVudCkge1xuICAgIGlmIChsYXN0TW91c2VFdmVudCAmJiBldmVudC50eXBlID09PSAnbW91c2Vtb3ZlJykge1xuICAgICAgbGFzdE1vdmVtZW50WCA9IGV2ZW50LnNjcmVlblggLSBsYXN0TW91c2VFdmVudC5zY3JlZW5YO1xuICAgICAgbGFzdE1vdmVtZW50WSA9IGV2ZW50LnNjcmVlblkgLSBsYXN0TW91c2VFdmVudC5zY3JlZW5ZO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0TW92ZW1lbnRYID0gMDtcbiAgICAgIGxhc3RNb3ZlbWVudFkgPSAwO1xuICAgIH1cblxuICAgIGxhc3RNb3VzZUV2ZW50ID0gZXZlbnQ7XG4gIH1cbn1cbi8qKlxuICogQGludGVyZmFjZSBNb3VzZUV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG5cbnZhciBNb3VzZUV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIHNjcmVlblg6IDAsXG4gIHNjcmVlblk6IDAsXG4gIGNsaWVudFg6IDAsXG4gIGNsaWVudFk6IDAsXG4gIHBhZ2VYOiAwLFxuICBwYWdlWTogMCxcbiAgY3RybEtleTogMCxcbiAgc2hpZnRLZXk6IDAsXG4gIGFsdEtleTogMCxcbiAgbWV0YUtleTogMCxcbiAgZ2V0TW9kaWZpZXJTdGF0ZTogZ2V0RXZlbnRNb2RpZmllclN0YXRlLFxuICBidXR0b246IDAsXG4gIGJ1dHRvbnM6IDAsXG4gIHJlbGF0ZWRUYXJnZXQ6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChldmVudC5yZWxhdGVkVGFyZ2V0ID09PSB1bmRlZmluZWQpIHJldHVybiBldmVudC5mcm9tRWxlbWVudCA9PT0gZXZlbnQuc3JjRWxlbWVudCA/IGV2ZW50LnRvRWxlbWVudCA6IGV2ZW50LmZyb21FbGVtZW50O1xuICAgIHJldHVybiBldmVudC5yZWxhdGVkVGFyZ2V0O1xuICB9LFxuICBtb3ZlbWVudFg6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmICgnbW92ZW1lbnRYJyBpbiBldmVudCkge1xuICAgICAgcmV0dXJuIGV2ZW50Lm1vdmVtZW50WDtcbiAgICB9XG5cbiAgICB1cGRhdGVNb3VzZU1vdmVtZW50UG9seWZpbGxTdGF0ZShldmVudCk7XG4gICAgcmV0dXJuIGxhc3RNb3ZlbWVudFg7XG4gIH0sXG4gIG1vdmVtZW50WTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgaWYgKCdtb3ZlbWVudFknIGluIGV2ZW50KSB7XG4gICAgICByZXR1cm4gZXZlbnQubW92ZW1lbnRZO1xuICAgIH0gLy8gRG9uJ3QgbmVlZCB0byBjYWxsIHVwZGF0ZU1vdXNlTW92ZW1lbnRQb2x5ZmlsbFN0YXRlKCkgaGVyZVxuICAgIC8vIGJlY2F1c2UgaXQncyBndWFyYW50ZWVkIHRvIGhhdmUgYWxyZWFkeSBydW4gd2hlbiBtb3ZlbWVudFhcbiAgICAvLyB3YXMgY29waWVkLlxuXG5cbiAgICByZXR1cm4gbGFzdE1vdmVtZW50WTtcbiAgfVxufSk7XG5cbnZhciBTeW50aGV0aWNNb3VzZUV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoTW91c2VFdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgRHJhZ0V2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG52YXIgRHJhZ0V2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBNb3VzZUV2ZW50SW50ZXJmYWNlLCB7XG4gIGRhdGFUcmFuc2ZlcjogMFxufSk7XG5cbnZhciBTeW50aGV0aWNEcmFnRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChEcmFnRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEZvY3VzRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzL1xuICovXG5cbnZhciBGb2N1c0V2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIHJlbGF0ZWRUYXJnZXQ6IDBcbn0pO1xuXG52YXIgU3ludGhldGljRm9jdXNFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KEZvY3VzRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtYW5pbWF0aW9ucy8jQW5pbWF0aW9uRXZlbnQtaW50ZXJmYWNlXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9BbmltYXRpb25FdmVudFxuICovXG5cbnZhciBBbmltYXRpb25FdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgRXZlbnRJbnRlcmZhY2UsIHtcbiAgYW5pbWF0aW9uTmFtZTogMCxcbiAgZWxhcHNlZFRpbWU6IDAsXG4gIHBzZXVkb0VsZW1lbnQ6IDBcbn0pO1xuXG52YXIgU3ludGhldGljQW5pbWF0aW9uRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChBbmltYXRpb25FdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvY2xpcGJvYXJkLWFwaXMvXG4gKi9cblxudmFyIENsaXBib2FyZEV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBFdmVudEludGVyZmFjZSwge1xuICBjbGlwYm9hcmREYXRhOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICByZXR1cm4gJ2NsaXBib2FyZERhdGEnIGluIGV2ZW50ID8gZXZlbnQuY2xpcGJvYXJkRGF0YSA6IHdpbmRvdy5jbGlwYm9hcmREYXRhO1xuICB9XG59KTtcblxudmFyIFN5bnRoZXRpY0NsaXBib2FyZEV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoQ2xpcGJvYXJkRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8jZXZlbnRzLWNvbXBvc2l0aW9uZXZlbnRzXG4gKi9cblxudmFyIENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIEV2ZW50SW50ZXJmYWNlLCB7XG4gIGRhdGE6IDBcbn0pO1xuXG52YXIgU3ludGhldGljQ29tcG9zaXRpb25FdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMTMxMTA1XG4gKiAgICAgIC8jZXZlbnRzLWlucHV0ZXZlbnRzXG4gKi9cbi8vIEhhcHBlbnMgdG8gc2hhcmUgdGhlIHNhbWUgbGlzdCBmb3Igbm93LlxuXG52YXIgU3ludGhldGljSW5wdXRFdmVudCA9IFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQ7XG4vKipcbiAqIE5vcm1hbGl6YXRpb24gb2YgZGVwcmVjYXRlZCBIVE1MNSBga2V5YCB2YWx1ZXNcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0tleWJvYXJkRXZlbnQjS2V5X25hbWVzXG4gKi9cblxudmFyIG5vcm1hbGl6ZUtleSA9IHtcbiAgRXNjOiAnRXNjYXBlJyxcbiAgU3BhY2ViYXI6ICcgJyxcbiAgTGVmdDogJ0Fycm93TGVmdCcsXG4gIFVwOiAnQXJyb3dVcCcsXG4gIFJpZ2h0OiAnQXJyb3dSaWdodCcsXG4gIERvd246ICdBcnJvd0Rvd24nLFxuICBEZWw6ICdEZWxldGUnLFxuICBXaW46ICdPUycsXG4gIE1lbnU6ICdDb250ZXh0TWVudScsXG4gIEFwcHM6ICdDb250ZXh0TWVudScsXG4gIFNjcm9sbDogJ1Njcm9sbExvY2snLFxuICBNb3pQcmludGFibGVLZXk6ICdVbmlkZW50aWZpZWQnXG59O1xuLyoqXG4gKiBUcmFuc2xhdGlvbiBmcm9tIGxlZ2FjeSBga2V5Q29kZWAgdG8gSFRNTDUgYGtleWBcbiAqIE9ubHkgc3BlY2lhbCBrZXlzIHN1cHBvcnRlZCwgYWxsIG90aGVycyBkZXBlbmQgb24ga2V5Ym9hcmQgbGF5b3V0IG9yIGJyb3dzZXJcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0tleWJvYXJkRXZlbnQjS2V5X25hbWVzXG4gKi9cblxudmFyIHRyYW5zbGF0ZVRvS2V5ID0ge1xuICAnOCc6ICdCYWNrc3BhY2UnLFxuICAnOSc6ICdUYWInLFxuICAnMTInOiAnQ2xlYXInLFxuICAnMTMnOiAnRW50ZXInLFxuICAnMTYnOiAnU2hpZnQnLFxuICAnMTcnOiAnQ29udHJvbCcsXG4gICcxOCc6ICdBbHQnLFxuICAnMTknOiAnUGF1c2UnLFxuICAnMjAnOiAnQ2Fwc0xvY2snLFxuICAnMjcnOiAnRXNjYXBlJyxcbiAgJzMyJzogJyAnLFxuICAnMzMnOiAnUGFnZVVwJyxcbiAgJzM0JzogJ1BhZ2VEb3duJyxcbiAgJzM1JzogJ0VuZCcsXG4gICczNic6ICdIb21lJyxcbiAgJzM3JzogJ0Fycm93TGVmdCcsXG4gICczOCc6ICdBcnJvd1VwJyxcbiAgJzM5JzogJ0Fycm93UmlnaHQnLFxuICAnNDAnOiAnQXJyb3dEb3duJyxcbiAgJzQ1JzogJ0luc2VydCcsXG4gICc0Nic6ICdEZWxldGUnLFxuICAnMTEyJzogJ0YxJyxcbiAgJzExMyc6ICdGMicsXG4gICcxMTQnOiAnRjMnLFxuICAnMTE1JzogJ0Y0JyxcbiAgJzExNic6ICdGNScsXG4gICcxMTcnOiAnRjYnLFxuICAnMTE4JzogJ0Y3JyxcbiAgJzExOSc6ICdGOCcsXG4gICcxMjAnOiAnRjknLFxuICAnMTIxJzogJ0YxMCcsXG4gICcxMjInOiAnRjExJyxcbiAgJzEyMyc6ICdGMTInLFxuICAnMTQ0JzogJ051bUxvY2snLFxuICAnMTQ1JzogJ1Njcm9sbExvY2snLFxuICAnMjI0JzogJ01ldGEnXG59O1xuLyoqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnQgTmF0aXZlIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IE5vcm1hbGl6ZWQgYGtleWAgcHJvcGVydHkuXG4gKi9cblxuZnVuY3Rpb24gZ2V0RXZlbnRLZXkobmF0aXZlRXZlbnQpIHtcbiAgaWYgKG5hdGl2ZUV2ZW50LmtleSkge1xuICAgIC8vIE5vcm1hbGl6ZSBpbmNvbnNpc3RlbnQgdmFsdWVzIHJlcG9ydGVkIGJ5IGJyb3dzZXJzIGR1ZSB0b1xuICAgIC8vIGltcGxlbWVudGF0aW9ucyBvZiBhIHdvcmtpbmcgZHJhZnQgc3BlY2lmaWNhdGlvbi5cbiAgICAvLyBGaXJlRm94IGltcGxlbWVudHMgYGtleWAgYnV0IHJldHVybnMgYE1velByaW50YWJsZUtleWAgZm9yIGFsbFxuICAgIC8vIHByaW50YWJsZSBjaGFyYWN0ZXJzIChub3JtYWxpemVkIHRvIGBVbmlkZW50aWZpZWRgKSwgaWdub3JlIGl0LlxuICAgIHZhciBrZXkgPSBub3JtYWxpemVLZXlbbmF0aXZlRXZlbnQua2V5XSB8fCBuYXRpdmVFdmVudC5rZXk7XG5cbiAgICBpZiAoa2V5ICE9PSAnVW5pZGVudGlmaWVkJykge1xuICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG4gIH0gLy8gQnJvd3NlciBkb2VzIG5vdCBpbXBsZW1lbnQgYGtleWAsIHBvbHlmaWxsIGFzIG11Y2ggb2YgaXQgYXMgd2UgY2FuLlxuXG5cbiAgaWYgKG5hdGl2ZUV2ZW50LnR5cGUgPT09ICdrZXlwcmVzcycpIHtcbiAgICB2YXIgY2hhckNvZGUgPSBnZXRFdmVudENoYXJDb2RlKG5hdGl2ZUV2ZW50KTsgLy8gVGhlIGVudGVyLWtleSBpcyB0ZWNobmljYWxseSBib3RoIHByaW50YWJsZSBhbmQgbm9uLXByaW50YWJsZSBhbmQgY2FuXG4gICAgLy8gdGh1cyBiZSBjYXB0dXJlZCBieSBga2V5cHJlc3NgLCBubyBvdGhlciBub24tcHJpbnRhYmxlIGtleSBzaG91bGQuXG5cbiAgICByZXR1cm4gY2hhckNvZGUgPT09IDEzID8gJ0VudGVyJyA6IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUpO1xuICB9XG5cbiAgaWYgKG5hdGl2ZUV2ZW50LnR5cGUgPT09ICdrZXlkb3duJyB8fCBuYXRpdmVFdmVudC50eXBlID09PSAna2V5dXAnKSB7XG4gICAgLy8gV2hpbGUgdXNlciBrZXlib2FyZCBsYXlvdXQgZGV0ZXJtaW5lcyB0aGUgYWN0dWFsIG1lYW5pbmcgb2YgZWFjaFxuICAgIC8vIGBrZXlDb2RlYCB2YWx1ZSwgYWxtb3N0IGFsbCBmdW5jdGlvbiBrZXlzIGhhdmUgYSB1bml2ZXJzYWwgdmFsdWUuXG4gICAgcmV0dXJuIHRyYW5zbGF0ZVRvS2V5W25hdGl2ZUV2ZW50LmtleUNvZGVdIHx8ICdVbmlkZW50aWZpZWQnO1xuICB9XG5cbiAgcmV0dXJuICcnO1xufVxuLyoqXG4gKiBUcmFuc2xhdGlvbiBmcm9tIG1vZGlmaWVyIGtleSB0byB0aGUgYXNzb2NpYXRlZCBwcm9wZXJ0eSBpbiB0aGUgZXZlbnQuXG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy8ja2V5cy1Nb2RpZmllcnNcbiAqL1xuXG5cbnZhciBtb2RpZmllcktleVRvUHJvcCA9IHtcbiAgQWx0OiAnYWx0S2V5JyxcbiAgQ29udHJvbDogJ2N0cmxLZXknLFxuICBNZXRhOiAnbWV0YUtleScsXG4gIFNoaWZ0OiAnc2hpZnRLZXknXG59OyAvLyBPbGRlciBicm93c2VycyAoU2FmYXJpIDw9IDEwLCBpT1MgU2FmYXJpIDw9IDEwLjIpIGRvIG5vdCBzdXBwb3J0XG4vLyBnZXRNb2RpZmllclN0YXRlLiBJZiBnZXRNb2RpZmllclN0YXRlIGlzIG5vdCBzdXBwb3J0ZWQsIHdlIG1hcCBpdCB0byBhIHNldCBvZlxuLy8gbW9kaWZpZXIga2V5cyBleHBvc2VkIGJ5IHRoZSBldmVudC4gSW4gdGhpcyBjYXNlLCBMb2NrLWtleXMgYXJlIG5vdCBzdXBwb3J0ZWQuXG5cbmZ1bmN0aW9uIG1vZGlmaWVyU3RhdGVHZXR0ZXIoa2V5QXJnKSB7XG4gIHZhciBzeW50aGV0aWNFdmVudCA9IHRoaXM7XG4gIHZhciBuYXRpdmVFdmVudCA9IHN5bnRoZXRpY0V2ZW50Lm5hdGl2ZUV2ZW50O1xuXG4gIGlmIChuYXRpdmVFdmVudC5nZXRNb2RpZmllclN0YXRlKSB7XG4gICAgcmV0dXJuIG5hdGl2ZUV2ZW50LmdldE1vZGlmaWVyU3RhdGUoa2V5QXJnKTtcbiAgfVxuXG4gIHZhciBrZXlQcm9wID0gbW9kaWZpZXJLZXlUb1Byb3Bba2V5QXJnXTtcbiAgcmV0dXJuIGtleVByb3AgPyAhIW5hdGl2ZUV2ZW50W2tleVByb3BdIDogZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGdldEV2ZW50TW9kaWZpZXJTdGF0ZShuYXRpdmVFdmVudCkge1xuICByZXR1cm4gbW9kaWZpZXJTdGF0ZUdldHRlcjtcbn1cbi8qKlxuICogQGludGVyZmFjZSBLZXlib2FyZEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG5cbnZhciBLZXlib2FyZEV2ZW50SW50ZXJmYWNlID0gYXNzaWduKHt9LCBVSUV2ZW50SW50ZXJmYWNlLCB7XG4gIGtleTogZ2V0RXZlbnRLZXksXG4gIGNvZGU6IDAsXG4gIGxvY2F0aW9uOiAwLFxuICBjdHJsS2V5OiAwLFxuICBzaGlmdEtleTogMCxcbiAgYWx0S2V5OiAwLFxuICBtZXRhS2V5OiAwLFxuICByZXBlYXQ6IDAsXG4gIGxvY2FsZTogMCxcbiAgZ2V0TW9kaWZpZXJTdGF0ZTogZ2V0RXZlbnRNb2RpZmllclN0YXRlLFxuICAvLyBMZWdhY3kgSW50ZXJmYWNlXG4gIGNoYXJDb2RlOiBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAvLyBgY2hhckNvZGVgIGlzIHRoZSByZXN1bHQgb2YgYSBLZXlQcmVzcyBldmVudCBhbmQgcmVwcmVzZW50cyB0aGUgdmFsdWUgb2ZcbiAgICAvLyB0aGUgYWN0dWFsIHByaW50YWJsZSBjaGFyYWN0ZXIuXG4gICAgLy8gS2V5UHJlc3MgaXMgZGVwcmVjYXRlZCwgYnV0IGl0cyByZXBsYWNlbWVudCBpcyBub3QgeWV0IGZpbmFsIGFuZCBub3RcbiAgICAvLyBpbXBsZW1lbnRlZCBpbiBhbnkgbWFqb3IgYnJvd3Nlci4gT25seSBLZXlQcmVzcyBoYXMgY2hhckNvZGUuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdrZXlwcmVzcycpIHtcbiAgICAgIHJldHVybiBnZXRFdmVudENoYXJDb2RlKGV2ZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfSxcbiAga2V5Q29kZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYGtleUNvZGVgIGlzIHRoZSByZXN1bHQgb2YgYSBLZXlEb3duL1VwIGV2ZW50IGFuZCByZXByZXNlbnRzIHRoZSB2YWx1ZSBvZlxuICAgIC8vIHBoeXNpY2FsIGtleWJvYXJkIGtleS5cbiAgICAvLyBUaGUgYWN0dWFsIG1lYW5pbmcgb2YgdGhlIHZhbHVlIGRlcGVuZHMgb24gdGhlIHVzZXJzJyBrZXlib2FyZCBsYXlvdXRcbiAgICAvLyB3aGljaCBjYW5ub3QgYmUgZGV0ZWN0ZWQuIEFzc3VtaW5nIHRoYXQgaXQgaXMgYSBVUyBrZXlib2FyZCBsYXlvdXRcbiAgICAvLyBwcm92aWRlcyBhIHN1cnByaXNpbmdseSBhY2N1cmF0ZSBtYXBwaW5nIGZvciBVUyBhbmQgRXVyb3BlYW4gdXNlcnMuXG4gICAgLy8gRHVlIHRvIHRoaXMsIGl0IGlzIGxlZnQgdG8gdGhlIHVzZXIgdG8gaW1wbGVtZW50IGF0IHRoaXMgdGltZS5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleWRvd24nIHx8IGV2ZW50LnR5cGUgPT09ICdrZXl1cCcpIHtcbiAgICAgIHJldHVybiBldmVudC5rZXlDb2RlO1xuICAgIH1cblxuICAgIHJldHVybiAwO1xuICB9LFxuICB3aGljaDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gYHdoaWNoYCBpcyBhbiBhbGlhcyBmb3IgZWl0aGVyIGBrZXlDb2RlYCBvciBgY2hhckNvZGVgIGRlcGVuZGluZyBvbiB0aGVcbiAgICAvLyB0eXBlIG9mIHRoZSBldmVudC5cbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2tleXByZXNzJykge1xuICAgICAgcmV0dXJuIGdldEV2ZW50Q2hhckNvZGUoZXZlbnQpO1xuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSAna2V5ZG93bicgfHwgZXZlbnQudHlwZSA9PT0gJ2tleXVwJykge1xuICAgICAgcmV0dXJuIGV2ZW50LmtleUNvZGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIDA7XG4gIH1cbn0pO1xuXG52YXIgU3ludGhldGljS2V5Ym9hcmRFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KEtleWJvYXJkRXZlbnRJbnRlcmZhY2UpO1xuLyoqXG4gKiBAaW50ZXJmYWNlIFBvaW50ZXJFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9wb2ludGVyZXZlbnRzL1xuICovXG5cbnZhciBQb2ludGVyRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIE1vdXNlRXZlbnRJbnRlcmZhY2UsIHtcbiAgcG9pbnRlcklkOiAwLFxuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwLFxuICBwcmVzc3VyZTogMCxcbiAgdGFuZ2VudGlhbFByZXNzdXJlOiAwLFxuICB0aWx0WDogMCxcbiAgdGlsdFk6IDAsXG4gIHR3aXN0OiAwLFxuICBwb2ludGVyVHlwZTogMCxcbiAgaXNQcmltYXJ5OiAwXG59KTtcblxudmFyIFN5bnRoZXRpY1BvaW50ZXJFdmVudCA9IGNyZWF0ZVN5bnRoZXRpY0V2ZW50KFBvaW50ZXJFdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgVG91Y2hFdmVudFxuICogQHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi90b3VjaC1ldmVudHMvXG4gKi9cblxudmFyIFRvdWNoRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIFVJRXZlbnRJbnRlcmZhY2UsIHtcbiAgdG91Y2hlczogMCxcbiAgdGFyZ2V0VG91Y2hlczogMCxcbiAgY2hhbmdlZFRvdWNoZXM6IDAsXG4gIGFsdEtleTogMCxcbiAgbWV0YUtleTogMCxcbiAgY3RybEtleTogMCxcbiAgc2hpZnRLZXk6IDAsXG4gIGdldE1vZGlmaWVyU3RhdGU6IGdldEV2ZW50TW9kaWZpZXJTdGF0ZVxufSk7XG5cbnZhciBTeW50aGV0aWNUb3VjaEV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoVG91Y2hFdmVudEludGVyZmFjZSk7XG4vKipcbiAqIEBpbnRlcmZhY2UgRXZlbnRcbiAqIEBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvMjAwOS9XRC1jc3MzLXRyYW5zaXRpb25zLTIwMDkwMzIwLyN0cmFuc2l0aW9uLWV2ZW50cy1cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1RyYW5zaXRpb25FdmVudFxuICovXG5cbnZhciBUcmFuc2l0aW9uRXZlbnRJbnRlcmZhY2UgPSBhc3NpZ24oe30sIEV2ZW50SW50ZXJmYWNlLCB7XG4gIHByb3BlcnR5TmFtZTogMCxcbiAgZWxhcHNlZFRpbWU6IDAsXG4gIHBzZXVkb0VsZW1lbnQ6IDBcbn0pO1xuXG52YXIgU3ludGhldGljVHJhbnNpdGlvbkV2ZW50ID0gY3JlYXRlU3ludGhldGljRXZlbnQoVHJhbnNpdGlvbkV2ZW50SW50ZXJmYWNlKTtcbi8qKlxuICogQGludGVyZmFjZSBXaGVlbEV2ZW50XG4gKiBAc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0zLUV2ZW50cy9cbiAqL1xuXG52YXIgV2hlZWxFdmVudEludGVyZmFjZSA9IGFzc2lnbih7fSwgTW91c2VFdmVudEludGVyZmFjZSwge1xuICBkZWx0YVg6IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiAnZGVsdGFYJyBpbiBldmVudCA/IGV2ZW50LmRlbHRhWCA6IC8vIEZhbGxiYWNrIHRvIGB3aGVlbERlbHRhWGAgZm9yIFdlYmtpdCBhbmQgbm9ybWFsaXplIChyaWdodCBpcyBwb3NpdGl2ZSkuXG4gICAgJ3doZWVsRGVsdGFYJyBpbiBldmVudCA/IC1ldmVudC53aGVlbERlbHRhWCA6IDA7XG4gIH0sXG4gIGRlbHRhWTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgcmV0dXJuICdkZWx0YVknIGluIGV2ZW50ID8gZXZlbnQuZGVsdGFZIDogLy8gRmFsbGJhY2sgdG8gYHdoZWVsRGVsdGFZYCBmb3IgV2Via2l0IGFuZCBub3JtYWxpemUgKGRvd24gaXMgcG9zaXRpdmUpLlxuICAgICd3aGVlbERlbHRhWScgaW4gZXZlbnQgPyAtZXZlbnQud2hlZWxEZWx0YVkgOiAvLyBGYWxsYmFjayB0byBgd2hlZWxEZWx0YWAgZm9yIElFPDkgYW5kIG5vcm1hbGl6ZSAoZG93biBpcyBwb3NpdGl2ZSkuXG4gICAgJ3doZWVsRGVsdGEnIGluIGV2ZW50ID8gLWV2ZW50LndoZWVsRGVsdGEgOiAwO1xuICB9LFxuICBkZWx0YVo6IDAsXG4gIC8vIEJyb3dzZXJzIHdpdGhvdXQgXCJkZWx0YU1vZGVcIiBpcyByZXBvcnRpbmcgaW4gcmF3IHdoZWVsIGRlbHRhIHdoZXJlIG9uZVxuICAvLyBub3RjaCBvbiB0aGUgc2Nyb2xsIGlzIGFsd2F5cyArLy0gMTIwLCByb3VnaGx5IGVxdWl2YWxlbnQgdG8gcGl4ZWxzLlxuICAvLyBBIGdvb2QgYXBwcm94aW1hdGlvbiBvZiBET01fREVMVEFfTElORSAoMSkgaXMgNSUgb2Ygdmlld3BvcnQgc2l6ZSBvclxuICAvLyB+NDAgcGl4ZWxzLCBmb3IgRE9NX0RFTFRBX1NDUkVFTiAoMikgaXQgaXMgODcuNSUgb2Ygdmlld3BvcnQgc2l6ZS5cbiAgZGVsdGFNb2RlOiAwXG59KTtcblxudmFyIFN5bnRoZXRpY1doZWVsRXZlbnQgPSBjcmVhdGVTeW50aGV0aWNFdmVudChXaGVlbEV2ZW50SW50ZXJmYWNlKTtcblxudmFyIEVORF9LRVlDT0RFUyA9IFs5LCAxMywgMjcsIDMyXTsgLy8gVGFiLCBSZXR1cm4sIEVzYywgU3BhY2VcblxudmFyIFNUQVJUX0tFWUNPREUgPSAyMjk7XG52YXIgY2FuVXNlQ29tcG9zaXRpb25FdmVudCA9IGNhblVzZURPTSAmJiAnQ29tcG9zaXRpb25FdmVudCcgaW4gd2luZG93O1xudmFyIGRvY3VtZW50TW9kZSA9IG51bGw7XG5cbmlmIChjYW5Vc2VET00gJiYgJ2RvY3VtZW50TW9kZScgaW4gZG9jdW1lbnQpIHtcbiAgZG9jdW1lbnRNb2RlID0gZG9jdW1lbnQuZG9jdW1lbnRNb2RlO1xufSAvLyBXZWJraXQgb2ZmZXJzIGEgdmVyeSB1c2VmdWwgYHRleHRJbnB1dGAgZXZlbnQgdGhhdCBjYW4gYmUgdXNlZCB0b1xuLy8gZGlyZWN0bHkgcmVwcmVzZW50IGBiZWZvcmVJbnB1dGAuIFRoZSBJRSBgdGV4dGlucHV0YCBldmVudCBpcyBub3QgYXNcbi8vIHVzZWZ1bCwgc28gd2UgZG9uJ3QgdXNlIGl0LlxuXG5cbnZhciBjYW5Vc2VUZXh0SW5wdXRFdmVudCA9IGNhblVzZURPTSAmJiAnVGV4dEV2ZW50JyBpbiB3aW5kb3cgJiYgIWRvY3VtZW50TW9kZTsgLy8gSW4gSUU5Kywgd2UgaGF2ZSBhY2Nlc3MgdG8gY29tcG9zaXRpb24gZXZlbnRzLCBidXQgdGhlIGRhdGEgc3VwcGxpZWRcbi8vIGJ5IHRoZSBuYXRpdmUgY29tcG9zaXRpb25lbmQgZXZlbnQgbWF5IGJlIGluY29ycmVjdC4gSmFwYW5lc2UgaWRlb2dyYXBoaWNcbi8vIHNwYWNlcywgZm9yIGluc3RhbmNlIChcXHUzMDAwKSBhcmUgbm90IHJlY29yZGVkIGNvcnJlY3RseS5cblxudmFyIHVzZUZhbGxiYWNrQ29tcG9zaXRpb25EYXRhID0gY2FuVXNlRE9NICYmICghY2FuVXNlQ29tcG9zaXRpb25FdmVudCB8fCBkb2N1bWVudE1vZGUgJiYgZG9jdW1lbnRNb2RlID4gOCAmJiBkb2N1bWVudE1vZGUgPD0gMTEpO1xudmFyIFNQQUNFQkFSX0NPREUgPSAzMjtcbnZhciBTUEFDRUJBUl9DSEFSID0gU3RyaW5nLmZyb21DaGFyQ29kZShTUEFDRUJBUl9DT0RFKTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMoKSB7XG4gIHJlZ2lzdGVyVHdvUGhhc2VFdmVudCgnb25CZWZvcmVJbnB1dCcsIFsnY29tcG9zaXRpb25lbmQnLCAna2V5cHJlc3MnLCAndGV4dElucHV0JywgJ3Bhc3RlJ10pO1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQ29tcG9zaXRpb25FbmQnLCBbJ2NvbXBvc2l0aW9uZW5kJywgJ2ZvY3Vzb3V0JywgJ2tleWRvd24nLCAna2V5cHJlc3MnLCAna2V5dXAnLCAnbW91c2Vkb3duJ10pO1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQ29tcG9zaXRpb25TdGFydCcsIFsnY29tcG9zaXRpb25zdGFydCcsICdmb2N1c291dCcsICdrZXlkb3duJywgJ2tleXByZXNzJywgJ2tleXVwJywgJ21vdXNlZG93biddKTtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvbkNvbXBvc2l0aW9uVXBkYXRlJywgWydjb21wb3NpdGlvbnVwZGF0ZScsICdmb2N1c291dCcsICdrZXlkb3duJywgJ2tleXByZXNzJywgJ2tleXVwJywgJ21vdXNlZG93biddKTtcbn0gLy8gVHJhY2sgd2hldGhlciB3ZSd2ZSBldmVyIGhhbmRsZWQgYSBrZXlwcmVzcyBvbiB0aGUgc3BhY2Uga2V5LlxuXG5cbnZhciBoYXNTcGFjZUtleXByZXNzID0gZmFsc2U7XG4vKipcbiAqIFJldHVybiB3aGV0aGVyIGEgbmF0aXZlIGtleXByZXNzIGV2ZW50IGlzIGFzc3VtZWQgdG8gYmUgYSBjb21tYW5kLlxuICogVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIEZpcmVmb3ggZmlyZXMgYGtleXByZXNzYCBldmVudHMgZm9yIGtleSBjb21tYW5kc1xuICogKGN1dCwgY29weSwgc2VsZWN0LWFsbCwgZXRjLikgZXZlbiB0aG91Z2ggbm8gY2hhcmFjdGVyIGlzIGluc2VydGVkLlxuICovXG5cbmZ1bmN0aW9uIGlzS2V5cHJlc3NDb21tYW5kKG5hdGl2ZUV2ZW50KSB7XG4gIHJldHVybiAobmF0aXZlRXZlbnQuY3RybEtleSB8fCBuYXRpdmVFdmVudC5hbHRLZXkgfHwgbmF0aXZlRXZlbnQubWV0YUtleSkgJiYgLy8gY3RybEtleSAmJiBhbHRLZXkgaXMgZXF1aXZhbGVudCB0byBBbHRHciwgYW5kIGlzIG5vdCBhIGNvbW1hbmQuXG4gICEobmF0aXZlRXZlbnQuY3RybEtleSAmJiBuYXRpdmVFdmVudC5hbHRLZXkpO1xufVxuLyoqXG4gKiBUcmFuc2xhdGUgbmF0aXZlIHRvcCBsZXZlbCBldmVudHMgaW50byBldmVudCB0eXBlcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldENvbXBvc2l0aW9uRXZlbnRUeXBlKGRvbUV2ZW50TmFtZSkge1xuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2NvbXBvc2l0aW9uc3RhcnQnOlxuICAgICAgcmV0dXJuICdvbkNvbXBvc2l0aW9uU3RhcnQnO1xuXG4gICAgY2FzZSAnY29tcG9zaXRpb25lbmQnOlxuICAgICAgcmV0dXJuICdvbkNvbXBvc2l0aW9uRW5kJztcblxuICAgIGNhc2UgJ2NvbXBvc2l0aW9udXBkYXRlJzpcbiAgICAgIHJldHVybiAnb25Db21wb3NpdGlvblVwZGF0ZSc7XG4gIH1cbn1cbi8qKlxuICogRG9lcyBvdXIgZmFsbGJhY2sgYmVzdC1ndWVzcyBtb2RlbCB0aGluayB0aGlzIGV2ZW50IHNpZ25pZmllcyB0aGF0XG4gKiBjb21wb3NpdGlvbiBoYXMgYmVndW4/XG4gKi9cblxuXG5mdW5jdGlvbiBpc0ZhbGxiYWNrQ29tcG9zaXRpb25TdGFydChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSB7XG4gIHJldHVybiBkb21FdmVudE5hbWUgPT09ICdrZXlkb3duJyAmJiBuYXRpdmVFdmVudC5rZXlDb2RlID09PSBTVEFSVF9LRVlDT0RFO1xufVxuLyoqXG4gKiBEb2VzIG91ciBmYWxsYmFjayBtb2RlIHRoaW5rIHRoYXQgdGhpcyBldmVudCBpcyB0aGUgZW5kIG9mIGNvbXBvc2l0aW9uP1xuICovXG5cblxuZnVuY3Rpb24gaXNGYWxsYmFja0NvbXBvc2l0aW9uRW5kKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpIHtcbiAgc3dpdGNoIChkb21FdmVudE5hbWUpIHtcbiAgICBjYXNlICdrZXl1cCc6XG4gICAgICAvLyBDb21tYW5kIGtleXMgaW5zZXJ0IG9yIGNsZWFyIElNRSBpbnB1dC5cbiAgICAgIHJldHVybiBFTkRfS0VZQ09ERVMuaW5kZXhPZihuYXRpdmVFdmVudC5rZXlDb2RlKSAhPT0gLTE7XG5cbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICAgIC8vIEV4cGVjdCBJTUUga2V5Q29kZSBvbiBlYWNoIGtleWRvd24uIElmIHdlIGdldCBhbnkgb3RoZXJcbiAgICAgIC8vIGNvZGUgd2UgbXVzdCBoYXZlIGV4aXRlZCBlYXJsaWVyLlxuICAgICAgcmV0dXJuIG5hdGl2ZUV2ZW50LmtleUNvZGUgIT09IFNUQVJUX0tFWUNPREU7XG5cbiAgICBjYXNlICdrZXlwcmVzcyc6XG4gICAgY2FzZSAnbW91c2Vkb3duJzpcbiAgICBjYXNlICdmb2N1c291dCc6XG4gICAgICAvLyBFdmVudHMgYXJlIG5vdCBwb3NzaWJsZSB3aXRob3V0IGNhbmNlbGxpbmcgSU1FLlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4vKipcbiAqIEdvb2dsZSBJbnB1dCBUb29scyBwcm92aWRlcyBjb21wb3NpdGlvbiBkYXRhIHZpYSBhIEN1c3RvbUV2ZW50LFxuICogd2l0aCB0aGUgYGRhdGFgIHByb3BlcnR5IHBvcHVsYXRlZCBpbiB0aGUgYGRldGFpbGAgb2JqZWN0LiBJZiB0aGlzXG4gKiBpcyBhdmFpbGFibGUgb24gdGhlIGV2ZW50IG9iamVjdCwgdXNlIGl0LiBJZiBub3QsIHRoaXMgaXMgYSBwbGFpblxuICogY29tcG9zaXRpb24gZXZlbnQgYW5kIHdlIGhhdmUgbm90aGluZyBzcGVjaWFsIHRvIGV4dHJhY3QuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50XG4gKiBAcmV0dXJuIHs/c3RyaW5nfVxuICovXG5cblxuZnVuY3Rpb24gZ2V0RGF0YUZyb21DdXN0b21FdmVudChuYXRpdmVFdmVudCkge1xuICB2YXIgZGV0YWlsID0gbmF0aXZlRXZlbnQuZGV0YWlsO1xuXG4gIGlmICh0eXBlb2YgZGV0YWlsID09PSAnb2JqZWN0JyAmJiAnZGF0YScgaW4gZGV0YWlsKSB7XG4gICAgcmV0dXJuIGRldGFpbC5kYXRhO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4vKipcbiAqIENoZWNrIGlmIGEgY29tcG9zaXRpb24gZXZlbnQgd2FzIHRyaWdnZXJlZCBieSBLb3JlYW4gSU1FLlxuICogT3VyIGZhbGxiYWNrIG1vZGUgZG9lcyBub3Qgd29yayB3ZWxsIHdpdGggSUUncyBLb3JlYW4gSU1FLFxuICogc28ganVzdCB1c2UgbmF0aXZlIGNvbXBvc2l0aW9uIGV2ZW50cyB3aGVuIEtvcmVhbiBJTUUgaXMgdXNlZC5cbiAqIEFsdGhvdWdoIENvbXBvc2l0aW9uRXZlbnQubG9jYWxlIHByb3BlcnR5IGlzIGRlcHJlY2F0ZWQsXG4gKiBpdCBpcyBhdmFpbGFibGUgaW4gSUUsIHdoZXJlIG91ciBmYWxsYmFjayBtb2RlIGlzIGVuYWJsZWQuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG5hdGl2ZUV2ZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5cblxuZnVuY3Rpb24gaXNVc2luZ0tvcmVhbklNRShuYXRpdmVFdmVudCkge1xuICByZXR1cm4gbmF0aXZlRXZlbnQubG9jYWxlID09PSAna28nO1xufSAvLyBUcmFjayB0aGUgY3VycmVudCBJTUUgY29tcG9zaXRpb24gc3RhdHVzLCBpZiBhbnkuXG5cblxudmFyIGlzQ29tcG9zaW5nID0gZmFsc2U7XG4vKipcbiAqIEByZXR1cm4gez9vYmplY3R9IEEgU3ludGhldGljQ29tcG9zaXRpb25FdmVudC5cbiAqL1xuXG5mdW5jdGlvbiBleHRyYWN0Q29tcG9zaXRpb25FdmVudChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICB2YXIgZXZlbnRUeXBlO1xuICB2YXIgZmFsbGJhY2tEYXRhO1xuXG4gIGlmIChjYW5Vc2VDb21wb3NpdGlvbkV2ZW50KSB7XG4gICAgZXZlbnRUeXBlID0gZ2V0Q29tcG9zaXRpb25FdmVudFR5cGUoZG9tRXZlbnROYW1lKTtcbiAgfSBlbHNlIGlmICghaXNDb21wb3NpbmcpIHtcbiAgICBpZiAoaXNGYWxsYmFja0NvbXBvc2l0aW9uU3RhcnQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkpIHtcbiAgICAgIGV2ZW50VHlwZSA9ICdvbkNvbXBvc2l0aW9uU3RhcnQnO1xuICAgIH1cbiAgfSBlbHNlIGlmIChpc0ZhbGxiYWNrQ29tcG9zaXRpb25FbmQoZG9tRXZlbnROYW1lLCBuYXRpdmVFdmVudCkpIHtcbiAgICBldmVudFR5cGUgPSAnb25Db21wb3NpdGlvbkVuZCc7XG4gIH1cblxuICBpZiAoIWV2ZW50VHlwZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKHVzZUZhbGxiYWNrQ29tcG9zaXRpb25EYXRhICYmICFpc1VzaW5nS29yZWFuSU1FKG5hdGl2ZUV2ZW50KSkge1xuICAgIC8vIFRoZSBjdXJyZW50IGNvbXBvc2l0aW9uIGlzIHN0b3JlZCBzdGF0aWNhbGx5IGFuZCBtdXN0IG5vdCBiZVxuICAgIC8vIG92ZXJ3cml0dGVuIHdoaWxlIGNvbXBvc2l0aW9uIGNvbnRpbnVlcy5cbiAgICBpZiAoIWlzQ29tcG9zaW5nICYmIGV2ZW50VHlwZSA9PT0gJ29uQ29tcG9zaXRpb25TdGFydCcpIHtcbiAgICAgIGlzQ29tcG9zaW5nID0gaW5pdGlhbGl6ZShuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgfSBlbHNlIGlmIChldmVudFR5cGUgPT09ICdvbkNvbXBvc2l0aW9uRW5kJykge1xuICAgICAgaWYgKGlzQ29tcG9zaW5nKSB7XG4gICAgICAgIGZhbGxiYWNrRGF0YSA9IGdldERhdGEoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbGlzdGVuZXJzID0gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKHRhcmdldEluc3QsIGV2ZW50VHlwZSk7XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGV2ZW50ID0gbmV3IFN5bnRoZXRpY0NvbXBvc2l0aW9uRXZlbnQoZXZlbnRUeXBlLCBkb21FdmVudE5hbWUsIG51bGwsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgfSk7XG5cbiAgICBpZiAoZmFsbGJhY2tEYXRhKSB7XG4gICAgICAvLyBJbmplY3QgZGF0YSBnZW5lcmF0ZWQgZnJvbSBmYWxsYmFjayBwYXRoIGludG8gdGhlIHN5bnRoZXRpYyBldmVudC5cbiAgICAgIC8vIFRoaXMgbWF0Y2hlcyB0aGUgcHJvcGVydHkgb2YgbmF0aXZlIENvbXBvc2l0aW9uRXZlbnRJbnRlcmZhY2UuXG4gICAgICBldmVudC5kYXRhID0gZmFsbGJhY2tEYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY3VzdG9tRGF0YSA9IGdldERhdGFGcm9tQ3VzdG9tRXZlbnQobmF0aXZlRXZlbnQpO1xuXG4gICAgICBpZiAoY3VzdG9tRGF0YSAhPT0gbnVsbCkge1xuICAgICAgICBldmVudC5kYXRhID0gY3VzdG9tRGF0YTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TmF0aXZlQmVmb3JlSW5wdXRDaGFycyhkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSB7XG4gIHN3aXRjaCAoZG9tRXZlbnROYW1lKSB7XG4gICAgY2FzZSAnY29tcG9zaXRpb25lbmQnOlxuICAgICAgcmV0dXJuIGdldERhdGFGcm9tQ3VzdG9tRXZlbnQobmF0aXZlRXZlbnQpO1xuXG4gICAgY2FzZSAna2V5cHJlc3MnOlxuICAgICAgLyoqXG4gICAgICAgKiBJZiBuYXRpdmUgYHRleHRJbnB1dGAgZXZlbnRzIGFyZSBhdmFpbGFibGUsIG91ciBnb2FsIGlzIHRvIG1ha2VcbiAgICAgICAqIHVzZSBvZiB0aGVtLiBIb3dldmVyLCB0aGVyZSBpcyBhIHNwZWNpYWwgY2FzZTogdGhlIHNwYWNlYmFyIGtleS5cbiAgICAgICAqIEluIFdlYmtpdCwgcHJldmVudGluZyBkZWZhdWx0IG9uIGEgc3BhY2ViYXIgYHRleHRJbnB1dGAgZXZlbnRcbiAgICAgICAqIGNhbmNlbHMgY2hhcmFjdGVyIGluc2VydGlvbiwgYnV0IGl0ICphbHNvKiBjYXVzZXMgdGhlIGJyb3dzZXJcbiAgICAgICAqIHRvIGZhbGwgYmFjayB0byBpdHMgZGVmYXVsdCBzcGFjZWJhciBiZWhhdmlvciBvZiBzY3JvbGxpbmcgdGhlXG4gICAgICAgKiBwYWdlLlxuICAgICAgICpcbiAgICAgICAqIFRyYWNraW5nIGF0OlxuICAgICAgICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTM1NTEwM1xuICAgICAgICpcbiAgICAgICAqIFRvIGF2b2lkIHRoaXMgaXNzdWUsIHVzZSB0aGUga2V5cHJlc3MgZXZlbnQgYXMgaWYgbm8gYHRleHRJbnB1dGBcbiAgICAgICAqIGV2ZW50IGlzIGF2YWlsYWJsZS5cbiAgICAgICAqL1xuICAgICAgdmFyIHdoaWNoID0gbmF0aXZlRXZlbnQud2hpY2g7XG5cbiAgICAgIGlmICh3aGljaCAhPT0gU1BBQ0VCQVJfQ09ERSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaGFzU3BhY2VLZXlwcmVzcyA9IHRydWU7XG4gICAgICByZXR1cm4gU1BBQ0VCQVJfQ0hBUjtcblxuICAgIGNhc2UgJ3RleHRJbnB1dCc6XG4gICAgICAvLyBSZWNvcmQgdGhlIGNoYXJhY3RlcnMgdG8gYmUgYWRkZWQgdG8gdGhlIERPTS5cbiAgICAgIHZhciBjaGFycyA9IG5hdGl2ZUV2ZW50LmRhdGE7IC8vIElmIGl0J3MgYSBzcGFjZWJhciBjaGFyYWN0ZXIsIGFzc3VtZSB0aGF0IHdlIGhhdmUgYWxyZWFkeSBoYW5kbGVkXG4gICAgICAvLyBpdCBhdCB0aGUga2V5cHJlc3MgbGV2ZWwgYW5kIGJhaWwgaW1tZWRpYXRlbHkuIEFuZHJvaWQgQ2hyb21lXG4gICAgICAvLyBkb2Vzbid0IGdpdmUgdXMga2V5Y29kZXMsIHNvIHdlIG5lZWQgdG8gaWdub3JlIGl0LlxuXG4gICAgICBpZiAoY2hhcnMgPT09IFNQQUNFQkFSX0NIQVIgJiYgaGFzU3BhY2VLZXlwcmVzcykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNoYXJzO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIEZvciBvdGhlciBuYXRpdmUgZXZlbnQgdHlwZXMsIGRvIG5vdGhpbmcuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuLyoqXG4gKiBGb3IgYnJvd3NlcnMgdGhhdCBkbyBub3QgcHJvdmlkZSB0aGUgYHRleHRJbnB1dGAgZXZlbnQsIGV4dHJhY3QgdGhlXG4gKiBhcHByb3ByaWF0ZSBzdHJpbmcgdG8gdXNlIGZvciBTeW50aGV0aWNJbnB1dEV2ZW50LlxuICovXG5cblxuZnVuY3Rpb24gZ2V0RmFsbGJhY2tCZWZvcmVJbnB1dENoYXJzKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpIHtcbiAgLy8gSWYgd2UgYXJlIGN1cnJlbnRseSBjb21wb3NpbmcgKElNRSkgYW5kIHVzaW5nIGEgZmFsbGJhY2sgdG8gZG8gc28sXG4gIC8vIHRyeSB0byBleHRyYWN0IHRoZSBjb21wb3NlZCBjaGFyYWN0ZXJzIGZyb20gdGhlIGZhbGxiYWNrIG9iamVjdC5cbiAgLy8gSWYgY29tcG9zaXRpb24gZXZlbnQgaXMgYXZhaWxhYmxlLCB3ZSBleHRyYWN0IGEgc3RyaW5nIG9ubHkgYXRcbiAgLy8gY29tcG9zaXRpb25ldmVudCwgb3RoZXJ3aXNlIGV4dHJhY3QgaXQgYXQgZmFsbGJhY2sgZXZlbnRzLlxuICBpZiAoaXNDb21wb3NpbmcpIHtcbiAgICBpZiAoZG9tRXZlbnROYW1lID09PSAnY29tcG9zaXRpb25lbmQnIHx8ICFjYW5Vc2VDb21wb3NpdGlvbkV2ZW50ICYmIGlzRmFsbGJhY2tDb21wb3NpdGlvbkVuZChkb21FdmVudE5hbWUsIG5hdGl2ZUV2ZW50KSkge1xuICAgICAgdmFyIGNoYXJzID0gZ2V0RGF0YSgpO1xuICAgICAgcmVzZXQoKTtcbiAgICAgIGlzQ29tcG9zaW5nID0gZmFsc2U7XG4gICAgICByZXR1cm4gY2hhcnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ3Bhc3RlJzpcbiAgICAgIC8vIElmIGEgcGFzdGUgZXZlbnQgb2NjdXJzIGFmdGVyIGEga2V5cHJlc3MsIHRocm93IG91dCB0aGUgaW5wdXRcbiAgICAgIC8vIGNoYXJzLiBQYXN0ZSBldmVudHMgc2hvdWxkIG5vdCBsZWFkIHRvIEJlZm9yZUlucHV0IGV2ZW50cy5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSAna2V5cHJlc3MnOlxuICAgICAgLyoqXG4gICAgICAgKiBBcyBvZiB2MjcsIEZpcmVmb3ggbWF5IGZpcmUga2V5cHJlc3MgZXZlbnRzIGV2ZW4gd2hlbiBubyBjaGFyYWN0ZXJcbiAgICAgICAqIHdpbGwgYmUgaW5zZXJ0ZWQuIEEgZmV3IHBvc3NpYmlsaXRpZXM6XG4gICAgICAgKlxuICAgICAgICogLSBgd2hpY2hgIGlzIGAwYC4gQXJyb3cga2V5cywgRXNjIGtleSwgZXRjLlxuICAgICAgICpcbiAgICAgICAqIC0gYHdoaWNoYCBpcyB0aGUgcHJlc3NlZCBrZXkgY29kZSwgYnV0IG5vIGNoYXIgaXMgYXZhaWxhYmxlLlxuICAgICAgICogICBFeDogJ0FsdEdyICsgZGAgaW4gUG9saXNoLiBUaGVyZSBpcyBubyBtb2RpZmllZCBjaGFyYWN0ZXIgZm9yXG4gICAgICAgKiAgIHRoaXMga2V5IGNvbWJpbmF0aW9uIGFuZCBubyBjaGFyYWN0ZXIgaXMgaW5zZXJ0ZWQgaW50byB0aGVcbiAgICAgICAqICAgZG9jdW1lbnQsIGJ1dCBGRiBmaXJlcyB0aGUga2V5cHJlc3MgZm9yIGNoYXIgY29kZSBgMTAwYCBhbnl3YXkuXG4gICAgICAgKiAgIE5vIGBpbnB1dGAgZXZlbnQgd2lsbCBvY2N1ci5cbiAgICAgICAqXG4gICAgICAgKiAtIGB3aGljaGAgaXMgdGhlIHByZXNzZWQga2V5IGNvZGUsIGJ1dCBhIGNvbW1hbmQgY29tYmluYXRpb24gaXNcbiAgICAgICAqICAgYmVpbmcgdXNlZC4gRXg6IGBDbWQrQ2AuIE5vIGNoYXJhY3RlciBpcyBpbnNlcnRlZCwgYW5kIG5vXG4gICAgICAgKiAgIGBpbnB1dGAgZXZlbnQgd2lsbCBvY2N1ci5cbiAgICAgICAqL1xuICAgICAgaWYgKCFpc0tleXByZXNzQ29tbWFuZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgLy8gSUUgZmlyZXMgdGhlIGBrZXlwcmVzc2AgZXZlbnQgd2hlbiBhIHVzZXIgdHlwZXMgYW4gZW1vamkgdmlhXG4gICAgICAgIC8vIFRvdWNoIGtleWJvYXJkIG9mIFdpbmRvd3MuICBJbiBzdWNoIGEgY2FzZSwgdGhlIGBjaGFyYCBwcm9wZXJ0eVxuICAgICAgICAvLyBob2xkcyBhbiBlbW9qaSBjaGFyYWN0ZXIgbGlrZSBgXFx1RDgzRFxcdURFMEFgLiAgQmVjYXVzZSBpdHMgbGVuZ3RoXG4gICAgICAgIC8vIGlzIDIsIHRoZSBwcm9wZXJ0eSBgd2hpY2hgIGRvZXMgbm90IHJlcHJlc2VudCBhbiBlbW9qaSBjb3JyZWN0bHkuXG4gICAgICAgIC8vIEluIHN1Y2ggYSBjYXNlLCB3ZSBkaXJlY3RseSByZXR1cm4gdGhlIGBjaGFyYCBwcm9wZXJ0eSBpbnN0ZWFkIG9mXG4gICAgICAgIC8vIHVzaW5nIGB3aGljaGAuXG4gICAgICAgIGlmIChuYXRpdmVFdmVudC5jaGFyICYmIG5hdGl2ZUV2ZW50LmNoYXIubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHJldHVybiBuYXRpdmVFdmVudC5jaGFyO1xuICAgICAgICB9IGVsc2UgaWYgKG5hdGl2ZUV2ZW50LndoaWNoKSB7XG4gICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUobmF0aXZlRXZlbnQud2hpY2gpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSAnY29tcG9zaXRpb25lbmQnOlxuICAgICAgcmV0dXJuIHVzZUZhbGxiYWNrQ29tcG9zaXRpb25EYXRhICYmICFpc1VzaW5nS29yZWFuSU1FKG5hdGl2ZUV2ZW50KSA/IG51bGwgOiBuYXRpdmVFdmVudC5kYXRhO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG4vKipcbiAqIEV4dHJhY3QgYSBTeW50aGV0aWNJbnB1dEV2ZW50IGZvciBgYmVmb3JlSW5wdXRgLCBiYXNlZCBvbiBlaXRoZXIgbmF0aXZlXG4gKiBgdGV4dElucHV0YCBvciBmYWxsYmFjayBiZWhhdmlvci5cbiAqXG4gKiBAcmV0dXJuIHs/b2JqZWN0fSBBIFN5bnRoZXRpY0lucHV0RXZlbnQuXG4gKi9cblxuXG5mdW5jdGlvbiBleHRyYWN0QmVmb3JlSW5wdXRFdmVudChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCkge1xuICB2YXIgY2hhcnM7XG5cbiAgaWYgKGNhblVzZVRleHRJbnB1dEV2ZW50KSB7XG4gICAgY2hhcnMgPSBnZXROYXRpdmVCZWZvcmVJbnB1dENoYXJzKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpO1xuICB9IGVsc2Uge1xuICAgIGNoYXJzID0gZ2V0RmFsbGJhY2tCZWZvcmVJbnB1dENoYXJzKGRvbUV2ZW50TmFtZSwgbmF0aXZlRXZlbnQpO1xuICB9IC8vIElmIG5vIGNoYXJhY3RlcnMgYXJlIGJlaW5nIGluc2VydGVkLCBubyBCZWZvcmVJbnB1dCBldmVudCBzaG91bGRcbiAgLy8gYmUgZmlyZWQuXG5cblxuICBpZiAoIWNoYXJzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbGlzdGVuZXJzID0gYWNjdW11bGF0ZVR3b1BoYXNlTGlzdGVuZXJzKHRhcmdldEluc3QsICdvbkJlZm9yZUlucHV0Jyk7XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGV2ZW50ID0gbmV3IFN5bnRoZXRpY0lucHV0RXZlbnQoJ29uQmVmb3JlSW5wdXQnLCAnYmVmb3JlaW5wdXQnLCBudWxsLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICBldmVudDogZXZlbnQsXG4gICAgICBsaXN0ZW5lcnM6IGxpc3RlbmVyc1xuICAgIH0pO1xuICAgIGV2ZW50LmRhdGEgPSBjaGFycztcbiAgfVxufVxuLyoqXG4gKiBDcmVhdGUgYW4gYG9uQmVmb3JlSW5wdXRgIGV2ZW50IHRvIG1hdGNoXG4gKiBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDEzL1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDEzMTEwNS8jZXZlbnRzLWlucHV0ZXZlbnRzLlxuICpcbiAqIFRoaXMgZXZlbnQgcGx1Z2luIGlzIGJhc2VkIG9uIHRoZSBuYXRpdmUgYHRleHRJbnB1dGAgZXZlbnRcbiAqIGF2YWlsYWJsZSBpbiBDaHJvbWUsIFNhZmFyaSwgT3BlcmEsIGFuZCBJRS4gVGhpcyBldmVudCBmaXJlcyBhZnRlclxuICogYG9uS2V5UHJlc3NgIGFuZCBgb25Db21wb3NpdGlvbkVuZGAsIGJ1dCBiZWZvcmUgYG9uSW5wdXRgLlxuICpcbiAqIGBiZWZvcmVJbnB1dGAgaXMgc3BlYydkIGJ1dCBub3QgaW1wbGVtZW50ZWQgaW4gYW55IGJyb3dzZXJzLCBhbmRcbiAqIHRoZSBgaW5wdXRgIGV2ZW50IGRvZXMgbm90IHByb3ZpZGUgYW55IHVzZWZ1bCBpbmZvcm1hdGlvbiBhYm91dCB3aGF0IGhhc1xuICogYWN0dWFsbHkgYmVlbiBhZGRlZCwgY29udHJhcnkgdG8gdGhlIHNwZWMuIFRodXMsIGB0ZXh0SW5wdXRgIGlzIHRoZSBiZXN0XG4gKiBhdmFpbGFibGUgZXZlbnQgdG8gaWRlbnRpZnkgdGhlIGNoYXJhY3RlcnMgdGhhdCBoYXZlIGFjdHVhbGx5IGJlZW4gaW5zZXJ0ZWRcbiAqIGludG8gdGhlIHRhcmdldCBub2RlLlxuICpcbiAqIFRoaXMgcGx1Z2luIGlzIGFsc28gcmVzcG9uc2libGUgZm9yIGVtaXR0aW5nIGBjb21wb3NpdGlvbmAgZXZlbnRzLCB0aHVzXG4gKiBhbGxvd2luZyB1cyB0byBzaGFyZSBjb21wb3NpdGlvbiBmYWxsYmFjayBjb2RlIGZvciBib3RoIGBiZWZvcmVJbnB1dGAgYW5kXG4gKiBgY29tcG9zaXRpb25gIGV2ZW50IHR5cGVzLlxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyhkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIGV4dHJhY3RDb21wb3NpdGlvbkV2ZW50KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgZXh0cmFjdEJlZm9yZUlucHV0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xufVxuXG4vKipcbiAqIEBzZWUgaHR0cDovL3d3dy53aGF0d2cub3JnL3NwZWNzL3dlYi1hcHBzL2N1cnJlbnQtd29yay9tdWx0aXBhZ2UvdGhlLWlucHV0LWVsZW1lbnQuaHRtbCNpbnB1dC10eXBlLWF0dHItc3VtbWFyeVxuICovXG52YXIgc3VwcG9ydGVkSW5wdXRUeXBlcyA9IHtcbiAgY29sb3I6IHRydWUsXG4gIGRhdGU6IHRydWUsXG4gIGRhdGV0aW1lOiB0cnVlLFxuICAnZGF0ZXRpbWUtbG9jYWwnOiB0cnVlLFxuICBlbWFpbDogdHJ1ZSxcbiAgbW9udGg6IHRydWUsXG4gIG51bWJlcjogdHJ1ZSxcbiAgcGFzc3dvcmQ6IHRydWUsXG4gIHJhbmdlOiB0cnVlLFxuICBzZWFyY2g6IHRydWUsXG4gIHRlbDogdHJ1ZSxcbiAgdGV4dDogdHJ1ZSxcbiAgdGltZTogdHJ1ZSxcbiAgdXJsOiB0cnVlLFxuICB3ZWVrOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBpc1RleHRJbnB1dEVsZW1lbnQoZWxlbSkge1xuICB2YXIgbm9kZU5hbWUgPSBlbGVtICYmIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmIChub2RlTmFtZSA9PT0gJ2lucHV0Jykge1xuICAgIHJldHVybiAhIXN1cHBvcnRlZElucHV0VHlwZXNbZWxlbS50eXBlXTtcbiAgfVxuXG4gIGlmIChub2RlTmFtZSA9PT0gJ3RleHRhcmVhJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBldmVudCBpcyBzdXBwb3J0ZWQgaW4gdGhlIGN1cnJlbnQgZXhlY3V0aW9uIGVudmlyb25tZW50LlxuICpcbiAqIE5PVEU6IFRoaXMgd2lsbCBub3Qgd29yayBjb3JyZWN0bHkgZm9yIG5vbi1nZW5lcmljIGV2ZW50cyBzdWNoIGFzIGBjaGFuZ2VgLFxuICogYHJlc2V0YCwgYGxvYWRgLCBgZXJyb3JgLCBhbmQgYHNlbGVjdGAuXG4gKlxuICogQm9ycm93cyBmcm9tIE1vZGVybml6ci5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lU3VmZml4IEV2ZW50IG5hbWUsIGUuZy4gXCJjbGlja1wiLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgaXMgc3VwcG9ydGVkLlxuICogQGludGVybmFsXG4gKiBAbGljZW5zZSBNb2Rlcm5penIgMy4wLjBwcmUgKEN1c3RvbSBCdWlsZCkgfCBNSVRcbiAqL1xuXG5mdW5jdGlvbiBpc0V2ZW50U3VwcG9ydGVkKGV2ZW50TmFtZVN1ZmZpeCkge1xuICBpZiAoIWNhblVzZURPTSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBldmVudE5hbWUgPSAnb24nICsgZXZlbnROYW1lU3VmZml4O1xuICB2YXIgaXNTdXBwb3J0ZWQgPSAoZXZlbnROYW1lIGluIGRvY3VtZW50KTtcblxuICBpZiAoIWlzU3VwcG9ydGVkKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShldmVudE5hbWUsICdyZXR1cm47Jyk7XG4gICAgaXNTdXBwb3J0ZWQgPSB0eXBlb2YgZWxlbWVudFtldmVudE5hbWVdID09PSAnZnVuY3Rpb24nO1xuICB9XG5cbiAgcmV0dXJuIGlzU3VwcG9ydGVkO1xufVxuXG5mdW5jdGlvbiByZWdpc3RlckV2ZW50cyQxKCkge1xuICByZWdpc3RlclR3b1BoYXNlRXZlbnQoJ29uQ2hhbmdlJywgWydjaGFuZ2UnLCAnY2xpY2snLCAnZm9jdXNpbicsICdmb2N1c291dCcsICdpbnB1dCcsICdrZXlkb3duJywgJ2tleXVwJywgJ3NlbGVjdGlvbmNoYW5nZSddKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQW5kQWNjdW11bGF0ZUNoYW5nZUV2ZW50KGRpc3BhdGNoUXVldWUsIGluc3QsIG5hdGl2ZUV2ZW50LCB0YXJnZXQpIHtcbiAgLy8gRmxhZyB0aGlzIGV2ZW50IGxvb3AgYXMgbmVlZGluZyBzdGF0ZSByZXN0b3JlLlxuICBlbnF1ZXVlU3RhdGVSZXN0b3JlKHRhcmdldCk7XG4gIHZhciBsaXN0ZW5lcnMgPSBhY2N1bXVsYXRlVHdvUGhhc2VMaXN0ZW5lcnMoaW5zdCwgJ29uQ2hhbmdlJyk7XG5cbiAgaWYgKGxpc3RlbmVycy5sZW5ndGggPiAwKSB7XG4gICAgdmFyIGV2ZW50ID0gbmV3IFN5bnRoZXRpY0V2ZW50KCdvbkNoYW5nZScsICdjaGFuZ2UnLCBudWxsLCBuYXRpdmVFdmVudCwgdGFyZ2V0KTtcbiAgICBkaXNwYXRjaFF1ZXVlLnB1c2goe1xuICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgICB9KTtcbiAgfVxufVxuLyoqXG4gKiBGb3IgSUUgc2hpbXNcbiAqL1xuXG5cbnZhciBhY3RpdmVFbGVtZW50ID0gbnVsbDtcbnZhciBhY3RpdmVFbGVtZW50SW5zdCA9IG51bGw7XG4vKipcbiAqIFNFQ1RJT046IGhhbmRsZSBgY2hhbmdlYCBldmVudFxuICovXG5cbmZ1bmN0aW9uIHNob3VsZFVzZUNoYW5nZUV2ZW50KGVsZW0pIHtcbiAgdmFyIG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBub2RlTmFtZSA9PT0gJ3NlbGVjdCcgfHwgbm9kZU5hbWUgPT09ICdpbnB1dCcgJiYgZWxlbS50eXBlID09PSAnZmlsZSc7XG59XG5cbmZ1bmN0aW9uIG1hbnVhbERpc3BhdGNoQ2hhbmdlRXZlbnQobmF0aXZlRXZlbnQpIHtcbiAgdmFyIGRpc3BhdGNoUXVldWUgPSBbXTtcbiAgY3JlYXRlQW5kQWNjdW11bGF0ZUNoYW5nZUV2ZW50KGRpc3BhdGNoUXVldWUsIGFjdGl2ZUVsZW1lbnRJbnN0LCBuYXRpdmVFdmVudCwgZ2V0RXZlbnRUYXJnZXQobmF0aXZlRXZlbnQpKTsgLy8gSWYgY2hhbmdlIGFuZCBwcm9wZXJ0eWNoYW5nZSBidWJibGVkLCB3ZSdkIGp1c3QgYmluZCB0byBpdCBsaWtlIGFsbCB0aGVcbiAgLy8gb3RoZXIgZXZlbnRzIGFuZCBoYXZlIGl0IGdvIHRocm91Z2ggUmVhY3RCcm93c2VyRXZlbnRFbWl0dGVyLiBTaW5jZSBpdFxuICAvLyBkb2Vzbid0LCB3ZSBtYW51YWxseSBsaXN0ZW4gZm9yIHRoZSBldmVudHMgYW5kIHNvIHdlIGhhdmUgdG8gZW5xdWV1ZSBhbmRcbiAgLy8gcHJvY2VzcyB0aGUgYWJzdHJhY3QgZXZlbnQgbWFudWFsbHkuXG4gIC8vXG4gIC8vIEJhdGNoaW5nIGlzIG5lY2Vzc2FyeSBoZXJlIGluIG9yZGVyIHRvIGVuc3VyZSB0aGF0IGFsbCBldmVudCBoYW5kbGVycyBydW5cbiAgLy8gYmVmb3JlIHRoZSBuZXh0IHJlcmVuZGVyIChpbmNsdWRpbmcgZXZlbnQgaGFuZGxlcnMgYXR0YWNoZWQgdG8gYW5jZXN0b3JcbiAgLy8gZWxlbWVudHMgaW5zdGVhZCBvZiBkaXJlY3RseSBvbiB0aGUgaW5wdXQpLiBXaXRob3V0IHRoaXMsIGNvbnRyb2xsZWRcbiAgLy8gY29tcG9uZW50cyBkb24ndCB3b3JrIHByb3Blcmx5IGluIGNvbmp1bmN0aW9uIHdpdGggZXZlbnQgYnViYmxpbmcgYmVjYXVzZVxuICAvLyB0aGUgY29tcG9uZW50IGlzIHJlcmVuZGVyZWQgYW5kIHRoZSB2YWx1ZSByZXZlcnRlZCBiZWZvcmUgYWxsIHRoZSBldmVudFxuICAvLyBoYW5kbGVycyBjYW4gcnVuLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy83MDguXG5cbiAgYmF0Y2hlZFVwZGF0ZXMocnVuRXZlbnRJbkJhdGNoLCBkaXNwYXRjaFF1ZXVlKTtcbn1cblxuZnVuY3Rpb24gcnVuRXZlbnRJbkJhdGNoKGRpc3BhdGNoUXVldWUpIHtcbiAgcHJvY2Vzc0Rpc3BhdGNoUXVldWUoZGlzcGF0Y2hRdWV1ZSwgMCk7XG59XG5cbmZ1bmN0aW9uIGdldEluc3RJZlZhbHVlQ2hhbmdlZCh0YXJnZXRJbnN0KSB7XG4gIHZhciB0YXJnZXROb2RlID0gZ2V0Tm9kZUZyb21JbnN0YW5jZSh0YXJnZXRJbnN0KTtcblxuICBpZiAodXBkYXRlVmFsdWVJZkNoYW5nZWQodGFyZ2V0Tm9kZSkpIHtcbiAgICByZXR1cm4gdGFyZ2V0SW5zdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9yQ2hhbmdlRXZlbnQoZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0KSB7XG4gIGlmIChkb21FdmVudE5hbWUgPT09ICdjaGFuZ2UnKSB7XG4gICAgcmV0dXJuIHRhcmdldEluc3Q7XG4gIH1cbn1cbi8qKlxuICogU0VDVElPTjogaGFuZGxlIGBpbnB1dGAgZXZlbnRcbiAqL1xuXG5cbnZhciBpc0lucHV0RXZlbnRTdXBwb3J0ZWQgPSBmYWxzZTtcblxuaWYgKGNhblVzZURPTSkge1xuICAvLyBJRTkgY2xhaW1zIHRvIHN1cHBvcnQgdGhlIGlucHV0IGV2ZW50IGJ1dCBmYWlscyB0byB0cmlnZ2VyIGl0IHdoZW5cbiAgLy8gZGVsZXRpbmcgdGV4dCwgc28gd2UgaWdub3JlIGl0cyBpbnB1dCBldmVudHMuXG4gIGlzSW5wdXRFdmVudFN1cHBvcnRlZCA9IGlzRXZlbnRTdXBwb3J0ZWQoJ2lucHV0JykgJiYgKCFkb2N1bWVudC5kb2N1bWVudE1vZGUgfHwgZG9jdW1lbnQuZG9jdW1lbnRNb2RlID4gOSk7XG59XG4vKipcbiAqIChGb3IgSUUgPD05KSBTdGFydHMgdHJhY2tpbmcgcHJvcGVydHljaGFuZ2UgZXZlbnRzIG9uIHRoZSBwYXNzZWQtaW4gZWxlbWVudFxuICogYW5kIG92ZXJyaWRlIHRoZSB2YWx1ZSBwcm9wZXJ0eSBzbyB0aGF0IHdlIGNhbiBkaXN0aW5ndWlzaCB1c2VyIGV2ZW50cyBmcm9tXG4gKiB2YWx1ZSBjaGFuZ2VzIGluIEpTLlxuICovXG5cblxuZnVuY3Rpb24gc3RhcnRXYXRjaGluZ0ZvclZhbHVlQ2hhbmdlKHRhcmdldCwgdGFyZ2V0SW5zdCkge1xuICBhY3RpdmVFbGVtZW50ID0gdGFyZ2V0O1xuICBhY3RpdmVFbGVtZW50SW5zdCA9IHRhcmdldEluc3Q7XG4gIGFjdGl2ZUVsZW1lbnQuYXR0YWNoRXZlbnQoJ29ucHJvcGVydHljaGFuZ2UnLCBoYW5kbGVQcm9wZXJ0eUNoYW5nZSk7XG59XG4vKipcbiAqIChGb3IgSUUgPD05KSBSZW1vdmVzIHRoZSBldmVudCBsaXN0ZW5lcnMgZnJvbSB0aGUgY3VycmVudGx5LXRyYWNrZWQgZWxlbWVudCxcbiAqIGlmIGFueSBleGlzdHMuXG4gKi9cblxuXG5mdW5jdGlvbiBzdG9wV2F0Y2hpbmdGb3JWYWx1ZUNoYW5nZSgpIHtcbiAgaWYgKCFhY3RpdmVFbGVtZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgYWN0aXZlRWxlbWVudC5kZXRhY2hFdmVudCgnb25wcm9wZXJ0eWNoYW5nZScsIGhhbmRsZVByb3BlcnR5Q2hhbmdlKTtcbiAgYWN0aXZlRWxlbWVudCA9IG51bGw7XG4gIGFjdGl2ZUVsZW1lbnRJbnN0ID0gbnVsbDtcbn1cbi8qKlxuICogKEZvciBJRSA8PTkpIEhhbmRsZXMgYSBwcm9wZXJ0eWNoYW5nZSBldmVudCwgc2VuZGluZyBhIGBjaGFuZ2VgIGV2ZW50IGlmXG4gKiB0aGUgdmFsdWUgb2YgdGhlIGFjdGl2ZSBlbGVtZW50IGhhcyBjaGFuZ2VkLlxuICovXG5cblxuZnVuY3Rpb24gaGFuZGxlUHJvcGVydHlDaGFuZ2UobmF0aXZlRXZlbnQpIHtcbiAgaWYgKG5hdGl2ZUV2ZW50LnByb3BlcnR5TmFtZSAhPT0gJ3ZhbHVlJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChnZXRJbnN0SWZWYWx1ZUNoYW5nZWQoYWN0aXZlRWxlbWVudEluc3QpKSB7XG4gICAgbWFudWFsRGlzcGF0Y2hDaGFuZ2VFdmVudChuYXRpdmVFdmVudCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlRXZlbnRzRm9ySW5wdXRFdmVudFBvbHlmaWxsKGRvbUV2ZW50TmFtZSwgdGFyZ2V0LCB0YXJnZXRJbnN0KSB7XG4gIGlmIChkb21FdmVudE5hbWUgPT09ICdmb2N1c2luJykge1xuICAgIC8vIEluIElFOSwgcHJvcGVydHljaGFuZ2UgZmlyZXMgZm9yIG1vc3QgaW5wdXQgZXZlbnRzIGJ1dCBpcyBidWdneSBhbmRcbiAgICAvLyBkb2Vzbid0IGZpcmUgd2hlbiB0ZXh0IGlzIGRlbGV0ZWQsIGJ1dCBjb252ZW5pZW50bHksIHNlbGVjdGlvbmNoYW5nZVxuICAgIC8vIGFwcGVhcnMgdG8gZmlyZSBpbiBhbGwgb2YgdGhlIHJlbWFpbmluZyBjYXNlcyBzbyB3ZSBjYXRjaCB0aG9zZSBhbmRcbiAgICAvLyBmb3J3YXJkIHRoZSBldmVudCBpZiB0aGUgdmFsdWUgaGFzIGNoYW5nZWRcbiAgICAvLyBJbiBlaXRoZXIgY2FzZSwgd2UgZG9uJ3Qgd2FudCB0byBjYWxsIHRoZSBldmVudCBoYW5kbGVyIGlmIHRoZSB2YWx1ZVxuICAgIC8vIGlzIGNoYW5nZWQgZnJvbSBKUyBzbyB3ZSByZWRlZmluZSBhIHNldHRlciBmb3IgYC52YWx1ZWAgdGhhdCB1cGRhdGVzXG4gICAgLy8gb3VyIGFjdGl2ZUVsZW1lbnRWYWx1ZSB2YXJpYWJsZSwgYWxsb3dpbmcgdXMgdG8gaWdub3JlIHRob3NlIGNoYW5nZXNcbiAgICAvL1xuICAgIC8vIHN0b3BXYXRjaGluZygpIHNob3VsZCBiZSBhIG5vb3AgaGVyZSBidXQgd2UgY2FsbCBpdCBqdXN0IGluIGNhc2Ugd2VcbiAgICAvLyBtaXNzZWQgYSBibHVyIGV2ZW50IHNvbWVob3cuXG4gICAgc3RvcFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UoKTtcbiAgICBzdGFydFdhdGNoaW5nRm9yVmFsdWVDaGFuZ2UodGFyZ2V0LCB0YXJnZXRJbnN0KTtcbiAgfSBlbHNlIGlmIChkb21FdmVudE5hbWUgPT09ICdmb2N1c291dCcpIHtcbiAgICBzdG9wV2F0Y2hpbmdGb3JWYWx1ZUNoYW5nZSgpO1xuICB9XG59IC8vIEZvciBJRTggYW5kIElFOS5cblxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRFdmVudFBvbHlmaWxsKGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnc2VsZWN0aW9uY2hhbmdlJyB8fCBkb21FdmVudE5hbWUgPT09ICdrZXl1cCcgfHwgZG9tRXZlbnROYW1lID09PSAna2V5ZG93bicpIHtcbiAgICAvLyBPbiB0aGUgc2VsZWN0aW9uY2hhbmdlIGV2ZW50LCB0aGUgdGFyZ2V0IGlzIGp1c3QgZG9jdW1lbnQgd2hpY2ggaXNuJ3RcbiAgICAvLyBoZWxwZnVsIGZvciB1cyBzbyBqdXN0IGNoZWNrIGFjdGl2ZUVsZW1lbnQgaW5zdGVhZC5cbiAgICAvL1xuICAgIC8vIDk5JSBvZiB0aGUgdGltZSwga2V5ZG93biBhbmQga2V5dXAgYXJlbid0IG5lY2Vzc2FyeS4gSUU4IGZhaWxzIHRvIGZpcmVcbiAgICAvLyBwcm9wZXJ0eWNoYW5nZSBvbiB0aGUgZmlyc3QgaW5wdXQgZXZlbnQgYWZ0ZXIgc2V0dGluZyBgdmFsdWVgIGZyb20gYVxuICAgIC8vIHNjcmlwdCBhbmQgZmlyZXMgb25seSBrZXlkb3duLCBrZXlwcmVzcywga2V5dXAuIENhdGNoaW5nIGtleXVwIHVzdWFsbHlcbiAgICAvLyBnZXRzIGl0IGFuZCBjYXRjaGluZyBrZXlkb3duIGxldHMgdXMgZmlyZSBhbiBldmVudCBmb3IgdGhlIGZpcnN0XG4gICAgLy8ga2V5c3Ryb2tlIGlmIHVzZXIgZG9lcyBhIGtleSByZXBlYXQgKGl0J2xsIGJlIGEgbGl0dGxlIGRlbGF5ZWQ6IHJpZ2h0XG4gICAgLy8gYmVmb3JlIHRoZSBzZWNvbmQga2V5c3Ryb2tlKS4gT3RoZXIgaW5wdXQgbWV0aG9kcyAoZS5nLiwgcGFzdGUpIHNlZW0gdG9cbiAgICAvLyBmaXJlIHNlbGVjdGlvbmNoYW5nZSBub3JtYWxseS5cbiAgICByZXR1cm4gZ2V0SW5zdElmVmFsdWVDaGFuZ2VkKGFjdGl2ZUVsZW1lbnRJbnN0KTtcbiAgfVxufVxuLyoqXG4gKiBTRUNUSU9OOiBoYW5kbGUgYGNsaWNrYCBldmVudFxuICovXG5cblxuZnVuY3Rpb24gc2hvdWxkVXNlQ2xpY2tFdmVudChlbGVtKSB7XG4gIC8vIFVzZSB0aGUgYGNsaWNrYCBldmVudCB0byBkZXRlY3QgY2hhbmdlcyB0byBjaGVja2JveCBhbmQgcmFkaW8gaW5wdXRzLlxuICAvLyBUaGlzIGFwcHJvYWNoIHdvcmtzIGFjcm9zcyBhbGwgYnJvd3NlcnMsIHdoZXJlYXMgYGNoYW5nZWAgZG9lcyBub3QgZmlyZVxuICAvLyB1bnRpbCBgYmx1cmAgaW4gSUU4LlxuICB2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lO1xuICByZXR1cm4gbm9kZU5hbWUgJiYgbm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ2lucHV0JyAmJiAoZWxlbS50eXBlID09PSAnY2hlY2tib3gnIHx8IGVsZW0udHlwZSA9PT0gJ3JhZGlvJyk7XG59XG5cbmZ1bmN0aW9uIGdldFRhcmdldEluc3RGb3JDbGlja0V2ZW50KGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnY2xpY2snKSB7XG4gICAgcmV0dXJuIGdldEluc3RJZlZhbHVlQ2hhbmdlZCh0YXJnZXRJbnN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRPckNoYW5nZUV2ZW50KGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCkge1xuICBpZiAoZG9tRXZlbnROYW1lID09PSAnaW5wdXQnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ2NoYW5nZScpIHtcbiAgICByZXR1cm4gZ2V0SW5zdElmVmFsdWVDaGFuZ2VkKHRhcmdldEluc3QpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZUNvbnRyb2xsZWRJbnB1dEJsdXIobm9kZSkge1xuICB2YXIgc3RhdGUgPSBub2RlLl93cmFwcGVyU3RhdGU7XG5cbiAgaWYgKCFzdGF0ZSB8fCAhc3RhdGUuY29udHJvbGxlZCB8fCBub2RlLnR5cGUgIT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAge1xuICAgIC8vIElmIGNvbnRyb2xsZWQsIGFzc2lnbiB0aGUgdmFsdWUgYXR0cmlidXRlIHRvIHRoZSBjdXJyZW50IHZhbHVlIG9uIGJsdXJcbiAgICBzZXREZWZhdWx0VmFsdWUobm9kZSwgJ251bWJlcicsIG5vZGUudmFsdWUpO1xuICB9XG59XG4vKipcbiAqIFRoaXMgcGx1Z2luIGNyZWF0ZXMgYW4gYG9uQ2hhbmdlYCBldmVudCB0aGF0IG5vcm1hbGl6ZXMgY2hhbmdlIGV2ZW50c1xuICogYWNyb3NzIGZvcm0gZWxlbWVudHMuIFRoaXMgZXZlbnQgZmlyZXMgYXQgYSB0aW1lIHdoZW4gaXQncyBwb3NzaWJsZSB0b1xuICogY2hhbmdlIHRoZSBlbGVtZW50J3MgdmFsdWUgd2l0aG91dCBzZWVpbmcgYSBmbGlja2VyLlxuICpcbiAqIFN1cHBvcnRlZCBlbGVtZW50cyBhcmU6XG4gKiAtIGlucHV0IChzZWUgYGlzVGV4dElucHV0RWxlbWVudGApXG4gKiAtIHRleHRhcmVhXG4gKiAtIHNlbGVjdFxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyQxKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpIHtcbiAgdmFyIHRhcmdldE5vZGUgPSB0YXJnZXRJbnN0ID8gZ2V0Tm9kZUZyb21JbnN0YW5jZSh0YXJnZXRJbnN0KSA6IHdpbmRvdztcbiAgdmFyIGdldFRhcmdldEluc3RGdW5jLCBoYW5kbGVFdmVudEZ1bmM7XG5cbiAgaWYgKHNob3VsZFVzZUNoYW5nZUV2ZW50KHRhcmdldE5vZGUpKSB7XG4gICAgZ2V0VGFyZ2V0SW5zdEZ1bmMgPSBnZXRUYXJnZXRJbnN0Rm9yQ2hhbmdlRXZlbnQ7XG4gIH0gZWxzZSBpZiAoaXNUZXh0SW5wdXRFbGVtZW50KHRhcmdldE5vZGUpKSB7XG4gICAgaWYgKGlzSW5wdXRFdmVudFN1cHBvcnRlZCkge1xuICAgICAgZ2V0VGFyZ2V0SW5zdEZ1bmMgPSBnZXRUYXJnZXRJbnN0Rm9ySW5wdXRPckNoYW5nZUV2ZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBnZXRUYXJnZXRJbnN0RnVuYyA9IGdldFRhcmdldEluc3RGb3JJbnB1dEV2ZW50UG9seWZpbGw7XG4gICAgICBoYW5kbGVFdmVudEZ1bmMgPSBoYW5kbGVFdmVudHNGb3JJbnB1dEV2ZW50UG9seWZpbGw7XG4gICAgfVxuICB9IGVsc2UgaWYgKHNob3VsZFVzZUNsaWNrRXZlbnQodGFyZ2V0Tm9kZSkpIHtcbiAgICBnZXRUYXJnZXRJbnN0RnVuYyA9IGdldFRhcmdldEluc3RGb3JDbGlja0V2ZW50O1xuICB9XG5cbiAgaWYgKGdldFRhcmdldEluc3RGdW5jKSB7XG4gICAgdmFyIGluc3QgPSBnZXRUYXJnZXRJbnN0RnVuYyhkb21FdmVudE5hbWUsIHRhcmdldEluc3QpO1xuXG4gICAgaWYgKGluc3QpIHtcbiAgICAgIGNyZWF0ZUFuZEFjY3VtdWxhdGVDaGFuZ2VFdmVudChkaXNwYXRjaFF1ZXVlLCBpbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmIChoYW5kbGVFdmVudEZ1bmMpIHtcbiAgICBoYW5kbGVFdmVudEZ1bmMoZG9tRXZlbnROYW1lLCB0YXJnZXROb2RlLCB0YXJnZXRJbnN0KTtcbiAgfSAvLyBXaGVuIGJsdXJyaW5nLCBzZXQgdGhlIHZhbHVlIGF0dHJpYnV0ZSBmb3IgbnVtYmVyIGlucHV0c1xuXG5cbiAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ2ZvY3Vzb3V0Jykge1xuICAgIGhhbmRsZUNvbnRyb2xsZWRJbnB1dEJsdXIodGFyZ2V0Tm9kZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMkMigpIHtcbiAgcmVnaXN0ZXJEaXJlY3RFdmVudCgnb25Nb3VzZUVudGVyJywgWydtb3VzZW91dCcsICdtb3VzZW92ZXInXSk7XG4gIHJlZ2lzdGVyRGlyZWN0RXZlbnQoJ29uTW91c2VMZWF2ZScsIFsnbW91c2VvdXQnLCAnbW91c2VvdmVyJ10pO1xuICByZWdpc3RlckRpcmVjdEV2ZW50KCdvblBvaW50ZXJFbnRlcicsIFsncG9pbnRlcm91dCcsICdwb2ludGVyb3ZlciddKTtcbiAgcmVnaXN0ZXJEaXJlY3RFdmVudCgnb25Qb2ludGVyTGVhdmUnLCBbJ3BvaW50ZXJvdXQnLCAncG9pbnRlcm92ZXInXSk7XG59XG4vKipcbiAqIEZvciBhbG1vc3QgZXZlcnkgaW50ZXJhY3Rpb24gd2UgY2FyZSBhYm91dCwgdGhlcmUgd2lsbCBiZSBib3RoIGEgdG9wLWxldmVsXG4gKiBgbW91c2VvdmVyYCBhbmQgYG1vdXNlb3V0YCBldmVudCB0aGF0IG9jY3Vycy4gT25seSB1c2UgYG1vdXNlb3V0YCBzbyB0aGF0XG4gKiB3ZSBkbyBub3QgZXh0cmFjdCBkdXBsaWNhdGUgZXZlbnRzLiBIb3dldmVyLCBtb3ZpbmcgdGhlIG1vdXNlIGludG8gdGhlXG4gKiBicm93c2VyIGZyb20gb3V0c2lkZSB3aWxsIG5vdCBmaXJlIGEgYG1vdXNlb3V0YCBldmVudC4gSW4gdGhpcyBjYXNlLCB3ZSB1c2VcbiAqIHRoZSBgbW91c2VvdmVyYCB0b3AtbGV2ZWwgZXZlbnQuXG4gKi9cblxuXG5mdW5jdGlvbiBleHRyYWN0RXZlbnRzJDIoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lcikge1xuICB2YXIgaXNPdmVyRXZlbnQgPSBkb21FdmVudE5hbWUgPT09ICdtb3VzZW92ZXInIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3BvaW50ZXJvdmVyJztcbiAgdmFyIGlzT3V0RXZlbnQgPSBkb21FdmVudE5hbWUgPT09ICdtb3VzZW91dCcgfHwgZG9tRXZlbnROYW1lID09PSAncG9pbnRlcm91dCc7XG5cbiAgaWYgKGlzT3ZlckV2ZW50ICYmICFpc1JlcGxheWluZ0V2ZW50KG5hdGl2ZUV2ZW50KSkge1xuICAgIC8vIElmIHRoaXMgaXMgYW4gb3ZlciBldmVudCB3aXRoIGEgdGFyZ2V0LCB3ZSBtaWdodCBoYXZlIGFscmVhZHkgZGlzcGF0Y2hlZFxuICAgIC8vIHRoZSBldmVudCBpbiB0aGUgb3V0IGV2ZW50IG9mIHRoZSBvdGhlciB0YXJnZXQuIElmIHRoaXMgaXMgcmVwbGF5ZWQsXG4gICAgLy8gdGhlbiBpdCdzIGJlY2F1c2Ugd2UgY291bGRuJ3QgZGlzcGF0Y2ggYWdhaW5zdCB0aGlzIHRhcmdldCBwcmV2aW91c2x5XG4gICAgLy8gc28gd2UgaGF2ZSB0byBkbyBpdCBub3cgaW5zdGVhZC5cbiAgICB2YXIgcmVsYXRlZCA9IG5hdGl2ZUV2ZW50LnJlbGF0ZWRUYXJnZXQgfHwgbmF0aXZlRXZlbnQuZnJvbUVsZW1lbnQ7XG5cbiAgICBpZiAocmVsYXRlZCkge1xuICAgICAgLy8gSWYgdGhlIHJlbGF0ZWQgbm9kZSBpcyBtYW5hZ2VkIGJ5IFJlYWN0LCB3ZSBjYW4gYXNzdW1lIHRoYXQgd2UgaGF2ZVxuICAgICAgLy8gYWxyZWFkeSBkaXNwYXRjaGVkIHRoZSBjb3JyZXNwb25kaW5nIGV2ZW50cyBkdXJpbmcgaXRzIG1vdXNlb3V0LlxuICAgICAgaWYgKGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlKHJlbGF0ZWQpIHx8IGlzQ29udGFpbmVyTWFya2VkQXNSb290KHJlbGF0ZWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIWlzT3V0RXZlbnQgJiYgIWlzT3ZlckV2ZW50KSB7XG4gICAgLy8gTXVzdCBub3QgYmUgYSBtb3VzZSBvciBwb2ludGVyIGluIG9yIG91dCAtIGlnbm9yaW5nLlxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB3aW47IC8vIFRPRE86IHdoeSBpcyB0aGlzIG51bGxhYmxlIGluIHRoZSB0eXBlcyBidXQgd2UgcmVhZCBmcm9tIGl0P1xuXG4gIGlmIChuYXRpdmVFdmVudFRhcmdldC53aW5kb3cgPT09IG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gICAgLy8gYG5hdGl2ZUV2ZW50VGFyZ2V0YCBpcyBwcm9iYWJseSBhIHdpbmRvdyBvYmplY3QuXG4gICAgd2luID0gbmF0aXZlRXZlbnRUYXJnZXQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gVE9ETzogRmlndXJlIG91dCB3aHkgYG93bmVyRG9jdW1lbnRgIGlzIHNvbWV0aW1lcyB1bmRlZmluZWQgaW4gSUU4LlxuICAgIHZhciBkb2MgPSBuYXRpdmVFdmVudFRhcmdldC5vd25lckRvY3VtZW50O1xuXG4gICAgaWYgKGRvYykge1xuICAgICAgd2luID0gZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3c7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbiA9IHdpbmRvdztcbiAgICB9XG4gIH1cblxuICB2YXIgZnJvbTtcbiAgdmFyIHRvO1xuXG4gIGlmIChpc091dEV2ZW50KSB7XG4gICAgdmFyIF9yZWxhdGVkID0gbmF0aXZlRXZlbnQucmVsYXRlZFRhcmdldCB8fCBuYXRpdmVFdmVudC50b0VsZW1lbnQ7XG5cbiAgICBmcm9tID0gdGFyZ2V0SW5zdDtcbiAgICB0byA9IF9yZWxhdGVkID8gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUoX3JlbGF0ZWQpIDogbnVsbDtcblxuICAgIGlmICh0byAhPT0gbnVsbCkge1xuICAgICAgdmFyIG5lYXJlc3RNb3VudGVkID0gZ2V0TmVhcmVzdE1vdW50ZWRGaWJlcih0byk7XG5cbiAgICAgIGlmICh0byAhPT0gbmVhcmVzdE1vdW50ZWQgfHwgdG8udGFnICE9PSBIb3N0Q29tcG9uZW50ICYmIHRvLnRhZyAhPT0gSG9zdFRleHQpIHtcbiAgICAgICAgdG8gPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBNb3ZpbmcgdG8gYSBub2RlIGZyb20gb3V0c2lkZSB0aGUgd2luZG93LlxuICAgIGZyb20gPSBudWxsO1xuICAgIHRvID0gdGFyZ2V0SW5zdDtcbiAgfVxuXG4gIGlmIChmcm9tID09PSB0bykge1xuICAgIC8vIE5vdGhpbmcgcGVydGFpbnMgdG8gb3VyIG1hbmFnZWQgY29tcG9uZW50cy5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljTW91c2VFdmVudDtcbiAgdmFyIGxlYXZlRXZlbnRUeXBlID0gJ29uTW91c2VMZWF2ZSc7XG4gIHZhciBlbnRlckV2ZW50VHlwZSA9ICdvbk1vdXNlRW50ZXInO1xuICB2YXIgZXZlbnRUeXBlUHJlZml4ID0gJ21vdXNlJztcblxuICBpZiAoZG9tRXZlbnROYW1lID09PSAncG9pbnRlcm91dCcgfHwgZG9tRXZlbnROYW1lID09PSAncG9pbnRlcm92ZXInKSB7XG4gICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljUG9pbnRlckV2ZW50O1xuICAgIGxlYXZlRXZlbnRUeXBlID0gJ29uUG9pbnRlckxlYXZlJztcbiAgICBlbnRlckV2ZW50VHlwZSA9ICdvblBvaW50ZXJFbnRlcic7XG4gICAgZXZlbnRUeXBlUHJlZml4ID0gJ3BvaW50ZXInO1xuICB9XG5cbiAgdmFyIGZyb21Ob2RlID0gZnJvbSA9PSBudWxsID8gd2luIDogZ2V0Tm9kZUZyb21JbnN0YW5jZShmcm9tKTtcbiAgdmFyIHRvTm9kZSA9IHRvID09IG51bGwgPyB3aW4gOiBnZXROb2RlRnJvbUluc3RhbmNlKHRvKTtcbiAgdmFyIGxlYXZlID0gbmV3IFN5bnRoZXRpY0V2ZW50Q3RvcihsZWF2ZUV2ZW50VHlwZSwgZXZlbnRUeXBlUHJlZml4ICsgJ2xlYXZlJywgZnJvbSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgbGVhdmUudGFyZ2V0ID0gZnJvbU5vZGU7XG4gIGxlYXZlLnJlbGF0ZWRUYXJnZXQgPSB0b05vZGU7XG4gIHZhciBlbnRlciA9IG51bGw7IC8vIFdlIHNob3VsZCBvbmx5IHByb2Nlc3MgdGhpcyBuYXRpdmVFdmVudCBpZiB3ZSBhcmUgcHJvY2Vzc2luZ1xuICAvLyB0aGUgZmlyc3QgYW5jZXN0b3IuIE5leHQgdGltZSwgd2Ugd2lsbCBpZ25vcmUgdGhlIGV2ZW50LlxuXG4gIHZhciBuYXRpdmVUYXJnZXRJbnN0ID0gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUobmF0aXZlRXZlbnRUYXJnZXQpO1xuXG4gIGlmIChuYXRpdmVUYXJnZXRJbnN0ID09PSB0YXJnZXRJbnN0KSB7XG4gICAgdmFyIGVudGVyRXZlbnQgPSBuZXcgU3ludGhldGljRXZlbnRDdG9yKGVudGVyRXZlbnRUeXBlLCBldmVudFR5cGVQcmVmaXggKyAnZW50ZXInLCB0bywgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBlbnRlckV2ZW50LnRhcmdldCA9IHRvTm9kZTtcbiAgICBlbnRlckV2ZW50LnJlbGF0ZWRUYXJnZXQgPSBmcm9tTm9kZTtcbiAgICBlbnRlciA9IGVudGVyRXZlbnQ7XG4gIH1cblxuICBhY2N1bXVsYXRlRW50ZXJMZWF2ZVR3b1BoYXNlTGlzdGVuZXJzKGRpc3BhdGNoUXVldWUsIGxlYXZlLCBlbnRlciwgZnJvbSwgdG8pO1xufVxuXG4vKipcbiAqIGlubGluZWQgT2JqZWN0LmlzIHBvbHlmaWxsIHRvIGF2b2lkIHJlcXVpcmluZyBjb25zdW1lcnMgc2hpcCB0aGVpciBvd25cbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9pc1xuICovXG5mdW5jdGlvbiBpcyh4LCB5KSB7XG4gIHJldHVybiB4ID09PSB5ICYmICh4ICE9PSAwIHx8IDEgLyB4ID09PSAxIC8geSkgfHwgeCAhPT0geCAmJiB5ICE9PSB5IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIDtcbn1cblxudmFyIG9iamVjdElzID0gdHlwZW9mIE9iamVjdC5pcyA9PT0gJ2Z1bmN0aW9uJyA/IE9iamVjdC5pcyA6IGlzO1xuXG4vKipcbiAqIFBlcmZvcm1zIGVxdWFsaXR5IGJ5IGl0ZXJhdGluZyB0aHJvdWdoIGtleXMgb24gYW4gb2JqZWN0IGFuZCByZXR1cm5pbmcgZmFsc2VcbiAqIHdoZW4gYW55IGtleSBoYXMgdmFsdWVzIHdoaWNoIGFyZSBub3Qgc3RyaWN0bHkgZXF1YWwgYmV0d2VlbiB0aGUgYXJndW1lbnRzLlxuICogUmV0dXJucyB0cnVlIHdoZW4gdGhlIHZhbHVlcyBvZiBhbGwga2V5cyBhcmUgc3RyaWN0bHkgZXF1YWwuXG4gKi9cblxuZnVuY3Rpb24gc2hhbGxvd0VxdWFsKG9iakEsIG9iakIpIHtcbiAgaWYgKG9iamVjdElzKG9iakEsIG9iakIpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iakEgIT09ICdvYmplY3QnIHx8IG9iakEgPT09IG51bGwgfHwgdHlwZW9mIG9iakIgIT09ICdvYmplY3QnIHx8IG9iakIgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIga2V5c0EgPSBPYmplY3Qua2V5cyhvYmpBKTtcbiAgdmFyIGtleXNCID0gT2JqZWN0LmtleXMob2JqQik7XG5cbiAgaWYgKGtleXNBLmxlbmd0aCAhPT0ga2V5c0IubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIFRlc3QgZm9yIEEncyBrZXlzIGRpZmZlcmVudCBmcm9tIEIuXG5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXNBLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGN1cnJlbnRLZXkgPSBrZXlzQVtpXTtcblxuICAgIGlmICghaGFzT3duUHJvcGVydHkuY2FsbChvYmpCLCBjdXJyZW50S2V5KSB8fCAhb2JqZWN0SXMob2JqQVtjdXJyZW50S2V5XSwgb2JqQltjdXJyZW50S2V5XSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBHaXZlbiBhbnkgbm9kZSByZXR1cm4gdGhlIGZpcnN0IGxlYWYgbm9kZSB3aXRob3V0IGNoaWxkcmVuLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHJldHVybiB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX1cbiAqL1xuXG5mdW5jdGlvbiBnZXRMZWFmTm9kZShub2RlKSB7XG4gIHdoaWxlIChub2RlICYmIG5vZGUuZmlyc3RDaGlsZCkge1xuICAgIG5vZGUgPSBub2RlLmZpcnN0Q2hpbGQ7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn1cbi8qKlxuICogR2V0IHRoZSBuZXh0IHNpYmxpbmcgd2l0aGluIGEgY29udGFpbmVyLiBUaGlzIHdpbGwgd2FsayB1cCB0aGVcbiAqIERPTSBpZiBhIG5vZGUncyBzaWJsaW5ncyBoYXZlIGJlZW4gZXhoYXVzdGVkLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gbm9kZVxuICogQHJldHVybiB7P0RPTUVsZW1lbnR8RE9NVGV4dE5vZGV9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXRTaWJsaW5nTm9kZShub2RlKSB7XG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubmV4dFNpYmxpbmcpIHtcbiAgICAgIHJldHVybiBub2RlLm5leHRTaWJsaW5nO1xuICAgIH1cblxuICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gIH1cbn1cbi8qKlxuICogR2V0IG9iamVjdCBkZXNjcmliaW5nIHRoZSBub2RlcyB3aGljaCBjb250YWluIGNoYXJhY3RlcnMgYXQgb2Zmc2V0LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudHxET01UZXh0Tm9kZX0gcm9vdFxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybiB7P29iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldE5vZGVGb3JDaGFyYWN0ZXJPZmZzZXQocm9vdCwgb2Zmc2V0KSB7XG4gIHZhciBub2RlID0gZ2V0TGVhZk5vZGUocm9vdCk7XG4gIHZhciBub2RlU3RhcnQgPSAwO1xuICB2YXIgbm9kZUVuZCA9IDA7XG5cbiAgd2hpbGUgKG5vZGUpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSB7XG4gICAgICBub2RlRW5kID0gbm9kZVN0YXJ0ICsgbm9kZS50ZXh0Q29udGVudC5sZW5ndGg7XG5cbiAgICAgIGlmIChub2RlU3RhcnQgPD0gb2Zmc2V0ICYmIG5vZGVFbmQgPj0gb2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbm9kZTogbm9kZSxcbiAgICAgICAgICBvZmZzZXQ6IG9mZnNldCAtIG5vZGVTdGFydFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBub2RlU3RhcnQgPSBub2RlRW5kO1xuICAgIH1cblxuICAgIG5vZGUgPSBnZXRMZWFmTm9kZShnZXRTaWJsaW5nTm9kZShub2RlKSk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG91dGVyTm9kZVxuICogQHJldHVybiB7P29iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBnZXRPZmZzZXRzKG91dGVyTm9kZSkge1xuICB2YXIgb3duZXJEb2N1bWVudCA9IG91dGVyTm9kZS5vd25lckRvY3VtZW50O1xuICB2YXIgd2luID0gb3duZXJEb2N1bWVudCAmJiBvd25lckRvY3VtZW50LmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcbiAgdmFyIHNlbGVjdGlvbiA9IHdpbi5nZXRTZWxlY3Rpb24gJiYgd2luLmdldFNlbGVjdGlvbigpO1xuXG4gIGlmICghc2VsZWN0aW9uIHx8IHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgYW5jaG9yTm9kZSA9IHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgYW5jaG9yT2Zmc2V0ID0gc2VsZWN0aW9uLmFuY2hvck9mZnNldCxcbiAgICAgIGZvY3VzTm9kZSA9IHNlbGVjdGlvbi5mb2N1c05vZGUsXG4gICAgICBmb2N1c09mZnNldCA9IHNlbGVjdGlvbi5mb2N1c09mZnNldDsgLy8gSW4gRmlyZWZveCwgYW5jaG9yTm9kZSBhbmQgZm9jdXNOb2RlIGNhbiBiZSBcImFub255bW91cyBkaXZzXCIsIGUuZy4gdGhlXG4gIC8vIHVwL2Rvd24gYnV0dG9ucyBvbiBhbiA8aW5wdXQgdHlwZT1cIm51bWJlclwiPi4gQW5vbnltb3VzIGRpdnMgZG8gbm90IHNlZW0gdG9cbiAgLy8gZXhwb3NlIHByb3BlcnRpZXMsIHRyaWdnZXJpbmcgYSBcIlBlcm1pc3Npb24gZGVuaWVkIGVycm9yXCIgaWYgYW55IG9mIGl0c1xuICAvLyBwcm9wZXJ0aWVzIGFyZSBhY2Nlc3NlZC4gVGhlIG9ubHkgc2VlbWluZ2x5IHBvc3NpYmxlIHdheSB0byBhdm9pZCBlcnJvcmluZ1xuICAvLyBpcyB0byBhY2Nlc3MgYSBwcm9wZXJ0eSB0aGF0IHR5cGljYWxseSB3b3JrcyBmb3Igbm9uLWFub255bW91cyBkaXZzIGFuZFxuICAvLyBjYXRjaCBhbnkgZXJyb3IgdGhhdCBtYXkgb3RoZXJ3aXNlIGFyaXNlLiBTZWVcbiAgLy8gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjA4NDI3XG5cbiAgdHJ5IHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtZXhwcmVzc2lvbnMgKi9cbiAgICBhbmNob3JOb2RlLm5vZGVUeXBlO1xuICAgIGZvY3VzTm9kZS5ub2RlVHlwZTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLXVudXNlZC1leHByZXNzaW9ucyAqL1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gZ2V0TW9kZXJuT2Zmc2V0c0Zyb21Qb2ludHMob3V0ZXJOb2RlLCBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHtzdGFydCwgZW5kfSB3aGVyZSBgc3RhcnRgIGlzIHRoZSBjaGFyYWN0ZXIvY29kZXBvaW50IGluZGV4IG9mXG4gKiAoYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0KSB3aXRoaW4gdGhlIHRleHRDb250ZW50IG9mIGBvdXRlck5vZGVgLCBhbmRcbiAqIGBlbmRgIGlzIHRoZSBpbmRleCBvZiAoZm9jdXNOb2RlLCBmb2N1c09mZnNldCkuXG4gKlxuICogUmV0dXJucyBudWxsIGlmIHlvdSBwYXNzIGluIGdhcmJhZ2UgaW5wdXQgYnV0IHdlIHNob3VsZCBwcm9iYWJseSBqdXN0IGNyYXNoLlxuICpcbiAqIEV4cG9ydGVkIG9ubHkgZm9yIHRlc3RpbmcuXG4gKi9cblxuZnVuY3Rpb24gZ2V0TW9kZXJuT2Zmc2V0c0Zyb21Qb2ludHMob3V0ZXJOb2RlLCBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpIHtcbiAgdmFyIGxlbmd0aCA9IDA7XG4gIHZhciBzdGFydCA9IC0xO1xuICB2YXIgZW5kID0gLTE7XG4gIHZhciBpbmRleFdpdGhpbkFuY2hvciA9IDA7XG4gIHZhciBpbmRleFdpdGhpbkZvY3VzID0gMDtcbiAgdmFyIG5vZGUgPSBvdXRlck5vZGU7XG4gIHZhciBwYXJlbnROb2RlID0gbnVsbDtcblxuICBvdXRlcjogd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgbmV4dCA9IG51bGw7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKG5vZGUgPT09IGFuY2hvck5vZGUgJiYgKGFuY2hvck9mZnNldCA9PT0gMCB8fCBub2RlLm5vZGVUeXBlID09PSBURVhUX05PREUpKSB7XG4gICAgICAgIHN0YXJ0ID0gbGVuZ3RoICsgYW5jaG9yT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZSA9PT0gZm9jdXNOb2RlICYmIChmb2N1c09mZnNldCA9PT0gMCB8fCBub2RlLm5vZGVUeXBlID09PSBURVhUX05PREUpKSB7XG4gICAgICAgIGVuZCA9IGxlbmd0aCArIGZvY3VzT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSB7XG4gICAgICAgIGxlbmd0aCArPSBub2RlLm5vZGVWYWx1ZS5sZW5ndGg7XG4gICAgICB9XG5cbiAgICAgIGlmICgobmV4dCA9IG5vZGUuZmlyc3RDaGlsZCkgPT09IG51bGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IC8vIE1vdmluZyBmcm9tIGBub2RlYCB0byBpdHMgZmlyc3QgY2hpbGQgYG5leHRgLlxuXG5cbiAgICAgIHBhcmVudE5vZGUgPSBub2RlO1xuICAgICAgbm9kZSA9IG5leHQ7XG4gICAgfVxuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGlmIChub2RlID09PSBvdXRlck5vZGUpIHtcbiAgICAgICAgLy8gSWYgYG91dGVyTm9kZWAgaGFzIGNoaWxkcmVuLCB0aGlzIGlzIGFsd2F5cyB0aGUgc2Vjb25kIHRpbWUgdmlzaXRpbmdcbiAgICAgICAgLy8gaXQuIElmIGl0IGhhcyBubyBjaGlsZHJlbiwgdGhpcyBpcyBzdGlsbCB0aGUgZmlyc3QgbG9vcCwgYW5kIHRoZSBvbmx5XG4gICAgICAgIC8vIHZhbGlkIHNlbGVjdGlvbiBpcyBhbmNob3JOb2RlIGFuZCBmb2N1c05vZGUgYm90aCBlcXVhbCB0byB0aGlzIG5vZGVcbiAgICAgICAgLy8gYW5kIGJvdGggb2Zmc2V0cyAwLCBpbiB3aGljaCBjYXNlIHdlIHdpbGwgaGF2ZSBoYW5kbGVkIGFib3ZlLlxuICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudE5vZGUgPT09IGFuY2hvck5vZGUgJiYgKytpbmRleFdpdGhpbkFuY2hvciA9PT0gYW5jaG9yT2Zmc2V0KSB7XG4gICAgICAgIHN0YXJ0ID0gbGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICBpZiAocGFyZW50Tm9kZSA9PT0gZm9jdXNOb2RlICYmICsraW5kZXhXaXRoaW5Gb2N1cyA9PT0gZm9jdXNPZmZzZXQpIHtcbiAgICAgICAgZW5kID0gbGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICBpZiAoKG5leHQgPSBub2RlLm5leHRTaWJsaW5nKSAhPT0gbnVsbCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IHBhcmVudE5vZGU7XG4gICAgICBwYXJlbnROb2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH0gLy8gTW92aW5nIGZyb20gYG5vZGVgIHRvIGl0cyBuZXh0IHNpYmxpbmcgYG5leHRgLlxuXG5cbiAgICBub2RlID0gbmV4dDtcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gLTEgfHwgZW5kID09PSAtMSkge1xuICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbi4gKFdvdWxkIGhhcHBlbiBpZiB0aGUgYW5jaG9yL2ZvY3VzIG5vZGVzIGFyZW4ndFxuICAgIC8vIGFjdHVhbGx5IGluc2lkZSB0aGUgcGFzc2VkLWluIG5vZGUuKVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzdGFydDogc3RhcnQsXG4gICAgZW5kOiBlbmRcbiAgfTtcbn1cbi8qKlxuICogSW4gbW9kZXJuIG5vbi1JRSBicm93c2Vycywgd2UgY2FuIHN1cHBvcnQgYm90aCBmb3J3YXJkIGFuZCBiYWNrd2FyZFxuICogc2VsZWN0aW9ucy5cbiAqXG4gKiBOb3RlOiBJRTEwKyBzdXBwb3J0cyB0aGUgU2VsZWN0aW9uIG9iamVjdCwgYnV0IGl0IGRvZXMgbm90IHN1cHBvcnRcbiAqIHRoZSBgZXh0ZW5kYCBtZXRob2QsIHdoaWNoIG1lYW5zIHRoYXQgZXZlbiBpbiBtb2Rlcm4gSUUsIGl0J3Mgbm90IHBvc3NpYmxlXG4gKiB0byBwcm9ncmFtbWF0aWNhbGx5IGNyZWF0ZSBhIGJhY2t3YXJkIHNlbGVjdGlvbi4gVGh1cywgZm9yIGFsbCBJRVxuICogdmVyc2lvbnMsIHdlIHVzZSB0aGUgb2xkIElFIEFQSSB0byBjcmVhdGUgb3VyIHNlbGVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtET01FbGVtZW50fERPTVRleHROb2RlfSBub2RlXG4gKiBAcGFyYW0ge29iamVjdH0gb2Zmc2V0c1xuICovXG5cbmZ1bmN0aW9uIHNldE9mZnNldHMobm9kZSwgb2Zmc2V0cykge1xuICB2YXIgZG9jID0gbm9kZS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xuICB2YXIgd2luID0gZG9jICYmIGRvYy5kZWZhdWx0VmlldyB8fCB3aW5kb3c7IC8vIEVkZ2UgZmFpbHMgd2l0aCBcIk9iamVjdCBleHBlY3RlZFwiIGluIHNvbWUgc2NlbmFyaW9zLlxuICAvLyAoRm9yIGluc3RhbmNlOiBUaW55TUNFIGVkaXRvciB1c2VkIGluIGEgbGlzdCBjb21wb25lbnQgdGhhdCBzdXBwb3J0cyBwYXN0aW5nIHRvIGFkZCBtb3JlLFxuICAvLyBmYWlscyB3aGVuIHBhc3RpbmcgMTAwKyBpdGVtcylcblxuICBpZiAoIXdpbi5nZXRTZWxlY3Rpb24pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2VsZWN0aW9uID0gd2luLmdldFNlbGVjdGlvbigpO1xuICB2YXIgbGVuZ3RoID0gbm9kZS50ZXh0Q29udGVudC5sZW5ndGg7XG4gIHZhciBzdGFydCA9IE1hdGgubWluKG9mZnNldHMuc3RhcnQsIGxlbmd0aCk7XG4gIHZhciBlbmQgPSBvZmZzZXRzLmVuZCA9PT0gdW5kZWZpbmVkID8gc3RhcnQgOiBNYXRoLm1pbihvZmZzZXRzLmVuZCwgbGVuZ3RoKTsgLy8gSUUgMTEgdXNlcyBtb2Rlcm4gc2VsZWN0aW9uLCBidXQgZG9lc24ndCBzdXBwb3J0IHRoZSBleHRlbmQgbWV0aG9kLlxuICAvLyBGbGlwIGJhY2t3YXJkIHNlbGVjdGlvbnMsIHNvIHdlIGNhbiBzZXQgd2l0aCBhIHNpbmdsZSByYW5nZS5cblxuICBpZiAoIXNlbGVjdGlvbi5leHRlbmQgJiYgc3RhcnQgPiBlbmQpIHtcbiAgICB2YXIgdGVtcCA9IGVuZDtcbiAgICBlbmQgPSBzdGFydDtcbiAgICBzdGFydCA9IHRlbXA7XG4gIH1cblxuICB2YXIgc3RhcnRNYXJrZXIgPSBnZXROb2RlRm9yQ2hhcmFjdGVyT2Zmc2V0KG5vZGUsIHN0YXJ0KTtcbiAgdmFyIGVuZE1hcmtlciA9IGdldE5vZGVGb3JDaGFyYWN0ZXJPZmZzZXQobm9kZSwgZW5kKTtcblxuICBpZiAoc3RhcnRNYXJrZXIgJiYgZW5kTWFya2VyKSB7XG4gICAgaWYgKHNlbGVjdGlvbi5yYW5nZUNvdW50ID09PSAxICYmIHNlbGVjdGlvbi5hbmNob3JOb2RlID09PSBzdGFydE1hcmtlci5ub2RlICYmIHNlbGVjdGlvbi5hbmNob3JPZmZzZXQgPT09IHN0YXJ0TWFya2VyLm9mZnNldCAmJiBzZWxlY3Rpb24uZm9jdXNOb2RlID09PSBlbmRNYXJrZXIubm9kZSAmJiBzZWxlY3Rpb24uZm9jdXNPZmZzZXQgPT09IGVuZE1hcmtlci5vZmZzZXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICByYW5nZS5zZXRTdGFydChzdGFydE1hcmtlci5ub2RlLCBzdGFydE1hcmtlci5vZmZzZXQpO1xuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcblxuICAgIGlmIChzdGFydCA+IGVuZCkge1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcbiAgICAgIHNlbGVjdGlvbi5leHRlbmQoZW5kTWFya2VyLm5vZGUsIGVuZE1hcmtlci5vZmZzZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByYW5nZS5zZXRFbmQoZW5kTWFya2VyLm5vZGUsIGVuZE1hcmtlci5vZmZzZXQpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlICYmIG5vZGUubm9kZVR5cGUgPT09IFRFWFRfTk9ERTtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNOb2RlKG91dGVyTm9kZSwgaW5uZXJOb2RlKSB7XG4gIGlmICghb3V0ZXJOb2RlIHx8ICFpbm5lck5vZGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSBpZiAob3V0ZXJOb2RlID09PSBpbm5lck5vZGUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChpc1RleHROb2RlKG91dGVyTm9kZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gZWxzZSBpZiAoaXNUZXh0Tm9kZShpbm5lck5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5zTm9kZShvdXRlck5vZGUsIGlubmVyTm9kZS5wYXJlbnROb2RlKTtcbiAgfSBlbHNlIGlmICgnY29udGFpbnMnIGluIG91dGVyTm9kZSkge1xuICAgIHJldHVybiBvdXRlck5vZGUuY29udGFpbnMoaW5uZXJOb2RlKTtcbiAgfSBlbHNlIGlmIChvdXRlck5vZGUuY29tcGFyZURvY3VtZW50UG9zaXRpb24pIHtcbiAgICByZXR1cm4gISEob3V0ZXJOb2RlLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGlubmVyTm9kZSkgJiAxNik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzSW5Eb2N1bWVudChub2RlKSB7XG4gIHJldHVybiBub2RlICYmIG5vZGUub3duZXJEb2N1bWVudCAmJiBjb250YWluc05vZGUobm9kZS5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgbm9kZSk7XG59XG5cbmZ1bmN0aW9uIGlzU2FtZU9yaWdpbkZyYW1lKGlmcmFtZSkge1xuICB0cnkge1xuICAgIC8vIEFjY2Vzc2luZyB0aGUgY29udGVudERvY3VtZW50IG9mIGEgSFRNTElmcmFtZUVsZW1lbnQgY2FuIGNhdXNlIHRoZSBicm93c2VyXG4gICAgLy8gdG8gdGhyb3csIGUuZy4gaWYgaXQgaGFzIGEgY3Jvc3Mtb3JpZ2luIHNyYyBhdHRyaWJ1dGUuXG4gICAgLy8gU2FmYXJpIHdpbGwgc2hvdyBhbiBlcnJvciBpbiB0aGUgY29uc29sZSB3aGVuIHRoZSBhY2Nlc3MgcmVzdWx0cyBpbiBcIkJsb2NrZWQgYSBmcmFtZSB3aXRoIG9yaWdpblwiLiBlLmc6XG4gICAgLy8gaWZyYW1lLmNvbnRlbnREb2N1bWVudC5kZWZhdWx0VmlldztcbiAgICAvLyBBIHNhZmV0eSB3YXkgaXMgdG8gYWNjZXNzIG9uZSBvZiB0aGUgY3Jvc3Mgb3JpZ2luIHByb3BlcnRpZXM6IFdpbmRvdyBvciBMb2NhdGlvblxuICAgIC8vIFdoaWNoIG1pZ2h0IHJlc3VsdCBpbiBcIlNlY3VyaXR5RXJyb3JcIiBET00gRXhjZXB0aW9uIGFuZCBpdCBpcyBjb21wYXRpYmxlIHRvIFNhZmFyaS5cbiAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9icm93c2Vycy5odG1sI2ludGVncmF0aW9uLXdpdGgtaWRsXG4gICAgcmV0dXJuIHR5cGVvZiBpZnJhbWUuY29udGVudFdpbmRvdy5sb2NhdGlvbi5ocmVmID09PSAnc3RyaW5nJztcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldEFjdGl2ZUVsZW1lbnREZWVwKCkge1xuICB2YXIgd2luID0gd2luZG93O1xuICB2YXIgZWxlbWVudCA9IGdldEFjdGl2ZUVsZW1lbnQoKTtcblxuICB3aGlsZSAoZWxlbWVudCBpbnN0YW5jZW9mIHdpbi5IVE1MSUZyYW1lRWxlbWVudCkge1xuICAgIGlmIChpc1NhbWVPcmlnaW5GcmFtZShlbGVtZW50KSkge1xuICAgICAgd2luID0gZWxlbWVudC5jb250ZW50V2luZG93O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBlbGVtZW50ID0gZ2V0QWN0aXZlRWxlbWVudCh3aW4uZG9jdW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG4vKipcbiAqIEBSZWFjdElucHV0U2VsZWN0aW9uOiBSZWFjdCBpbnB1dCBzZWxlY3Rpb24gbW9kdWxlLiBCYXNlZCBvbiBTZWxlY3Rpb24uanMsXG4gKiBidXQgbW9kaWZpZWQgdG8gYmUgc3VpdGFibGUgZm9yIHJlYWN0IGFuZCBoYXMgYSBjb3VwbGUgb2YgYnVnIGZpeGVzIChkb2Vzbid0XG4gKiBhc3N1bWUgYnV0dG9ucyBoYXZlIHJhbmdlIHNlbGVjdGlvbnMgYWxsb3dlZCkuXG4gKiBJbnB1dCBzZWxlY3Rpb24gbW9kdWxlIGZvciBSZWFjdC5cbiAqL1xuXG4vKipcbiAqIEBoYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXM6IHdlIGdldCB0aGUgZWxlbWVudCB0eXBlcyB0aGF0IHN1cHBvcnQgc2VsZWN0aW9uXG4gKiBmcm9tIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2RvLW5vdC1hcHBseSwgbG9va2luZyBhdCBgc2VsZWN0aW9uU3RhcnRgXG4gKiBhbmQgYHNlbGVjdGlvbkVuZGAgcm93cy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGhhc1NlbGVjdGlvbkNhcGFiaWxpdGllcyhlbGVtKSB7XG4gIHZhciBub2RlTmFtZSA9IGVsZW0gJiYgZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBub2RlTmFtZSAmJiAobm9kZU5hbWUgPT09ICdpbnB1dCcgJiYgKGVsZW0udHlwZSA9PT0gJ3RleHQnIHx8IGVsZW0udHlwZSA9PT0gJ3NlYXJjaCcgfHwgZWxlbS50eXBlID09PSAndGVsJyB8fCBlbGVtLnR5cGUgPT09ICd1cmwnIHx8IGVsZW0udHlwZSA9PT0gJ3Bhc3N3b3JkJykgfHwgbm9kZU5hbWUgPT09ICd0ZXh0YXJlYScgfHwgZWxlbS5jb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyk7XG59XG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25JbmZvcm1hdGlvbigpIHtcbiAgdmFyIGZvY3VzZWRFbGVtID0gZ2V0QWN0aXZlRWxlbWVudERlZXAoKTtcbiAgcmV0dXJuIHtcbiAgICBmb2N1c2VkRWxlbTogZm9jdXNlZEVsZW0sXG4gICAgc2VsZWN0aW9uUmFuZ2U6IGhhc1NlbGVjdGlvbkNhcGFiaWxpdGllcyhmb2N1c2VkRWxlbSkgPyBnZXRTZWxlY3Rpb24oZm9jdXNlZEVsZW0pIDogbnVsbFxuICB9O1xufVxuLyoqXG4gKiBAcmVzdG9yZVNlbGVjdGlvbjogSWYgYW55IHNlbGVjdGlvbiBpbmZvcm1hdGlvbiB3YXMgcG90ZW50aWFsbHkgbG9zdCxcbiAqIHJlc3RvcmUgaXQuIFRoaXMgaXMgdXNlZnVsIHdoZW4gcGVyZm9ybWluZyBvcGVyYXRpb25zIHRoYXQgY291bGQgcmVtb3ZlIGRvbVxuICogbm9kZXMgYW5kIHBsYWNlIHRoZW0gYmFjayBpbiwgcmVzdWx0aW5nIGluIGZvY3VzIGJlaW5nIGxvc3QuXG4gKi9cblxuZnVuY3Rpb24gcmVzdG9yZVNlbGVjdGlvbihwcmlvclNlbGVjdGlvbkluZm9ybWF0aW9uKSB7XG4gIHZhciBjdXJGb2N1c2VkRWxlbSA9IGdldEFjdGl2ZUVsZW1lbnREZWVwKCk7XG4gIHZhciBwcmlvckZvY3VzZWRFbGVtID0gcHJpb3JTZWxlY3Rpb25JbmZvcm1hdGlvbi5mb2N1c2VkRWxlbTtcbiAgdmFyIHByaW9yU2VsZWN0aW9uUmFuZ2UgPSBwcmlvclNlbGVjdGlvbkluZm9ybWF0aW9uLnNlbGVjdGlvblJhbmdlO1xuXG4gIGlmIChjdXJGb2N1c2VkRWxlbSAhPT0gcHJpb3JGb2N1c2VkRWxlbSAmJiBpc0luRG9jdW1lbnQocHJpb3JGb2N1c2VkRWxlbSkpIHtcbiAgICBpZiAocHJpb3JTZWxlY3Rpb25SYW5nZSAhPT0gbnVsbCAmJiBoYXNTZWxlY3Rpb25DYXBhYmlsaXRpZXMocHJpb3JGb2N1c2VkRWxlbSkpIHtcbiAgICAgIHNldFNlbGVjdGlvbihwcmlvckZvY3VzZWRFbGVtLCBwcmlvclNlbGVjdGlvblJhbmdlKTtcbiAgICB9IC8vIEZvY3VzaW5nIGEgbm9kZSBjYW4gY2hhbmdlIHRoZSBzY3JvbGwgcG9zaXRpb24sIHdoaWNoIGlzIHVuZGVzaXJhYmxlXG5cblxuICAgIHZhciBhbmNlc3RvcnMgPSBbXTtcbiAgICB2YXIgYW5jZXN0b3IgPSBwcmlvckZvY3VzZWRFbGVtO1xuXG4gICAgd2hpbGUgKGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50Tm9kZSkge1xuICAgICAgaWYgKGFuY2VzdG9yLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgYW5jZXN0b3JzLnB1c2goe1xuICAgICAgICAgIGVsZW1lbnQ6IGFuY2VzdG9yLFxuICAgICAgICAgIGxlZnQ6IGFuY2VzdG9yLnNjcm9sbExlZnQsXG4gICAgICAgICAgdG9wOiBhbmNlc3Rvci5zY3JvbGxUb3BcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcmlvckZvY3VzZWRFbGVtLmZvY3VzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcmlvckZvY3VzZWRFbGVtLmZvY3VzKCk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbmNlc3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpbmZvID0gYW5jZXN0b3JzW2ldO1xuICAgICAgaW5mby5lbGVtZW50LnNjcm9sbExlZnQgPSBpbmZvLmxlZnQ7XG4gICAgICBpbmZvLmVsZW1lbnQuc2Nyb2xsVG9wID0gaW5mby50b3A7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBnZXRTZWxlY3Rpb246IEdldHMgdGhlIHNlbGVjdGlvbiBib3VuZHMgb2YgYSBmb2N1c2VkIHRleHRhcmVhLCBpbnB1dCBvclxuICogY29udGVudEVkaXRhYmxlIG5vZGUuXG4gKiAtQGlucHV0OiBMb29rIHVwIHNlbGVjdGlvbiBib3VuZHMgb2YgdGhpcyBpbnB1dFxuICogLUByZXR1cm4ge3N0YXJ0OiBzZWxlY3Rpb25TdGFydCwgZW5kOiBzZWxlY3Rpb25FbmR9XG4gKi9cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uKGlucHV0KSB7XG4gIHZhciBzZWxlY3Rpb247XG5cbiAgaWYgKCdzZWxlY3Rpb25TdGFydCcgaW4gaW5wdXQpIHtcbiAgICAvLyBNb2Rlcm4gYnJvd3NlciB3aXRoIGlucHV0IG9yIHRleHRhcmVhLlxuICAgIHNlbGVjdGlvbiA9IHtcbiAgICAgIHN0YXJ0OiBpbnB1dC5zZWxlY3Rpb25TdGFydCxcbiAgICAgIGVuZDogaW5wdXQuc2VsZWN0aW9uRW5kXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBDb250ZW50IGVkaXRhYmxlIG9yIG9sZCBJRSB0ZXh0YXJlYS5cbiAgICBzZWxlY3Rpb24gPSBnZXRPZmZzZXRzKGlucHV0KTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3Rpb24gfHwge1xuICAgIHN0YXJ0OiAwLFxuICAgIGVuZDogMFxuICB9O1xufVxuLyoqXG4gKiBAc2V0U2VsZWN0aW9uOiBTZXRzIHRoZSBzZWxlY3Rpb24gYm91bmRzIG9mIGEgdGV4dGFyZWEgb3IgaW5wdXQgYW5kIGZvY3VzZXNcbiAqIHRoZSBpbnB1dC5cbiAqIC1AaW5wdXQgICAgIFNldCBzZWxlY3Rpb24gYm91bmRzIG9mIHRoaXMgaW5wdXQgb3IgdGV4dGFyZWFcbiAqIC1Ab2Zmc2V0cyAgIE9iamVjdCBvZiBzYW1lIGZvcm0gdGhhdCBpcyByZXR1cm5lZCBmcm9tIGdldCpcbiAqL1xuXG5mdW5jdGlvbiBzZXRTZWxlY3Rpb24oaW5wdXQsIG9mZnNldHMpIHtcbiAgdmFyIHN0YXJ0ID0gb2Zmc2V0cy5zdGFydDtcbiAgdmFyIGVuZCA9IG9mZnNldHMuZW5kO1xuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuZCA9IHN0YXJ0O1xuICB9XG5cbiAgaWYgKCdzZWxlY3Rpb25TdGFydCcgaW4gaW5wdXQpIHtcbiAgICBpbnB1dC5zZWxlY3Rpb25TdGFydCA9IHN0YXJ0O1xuICAgIGlucHV0LnNlbGVjdGlvbkVuZCA9IE1hdGgubWluKGVuZCwgaW5wdXQudmFsdWUubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICBzZXRPZmZzZXRzKGlucHV0LCBvZmZzZXRzKTtcbiAgfVxufVxuXG52YXIgc2tpcFNlbGVjdGlvbkNoYW5nZUV2ZW50ID0gY2FuVXNlRE9NICYmICdkb2N1bWVudE1vZGUnIGluIGRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50TW9kZSA8PSAxMTtcblxuZnVuY3Rpb24gcmVnaXN0ZXJFdmVudHMkMygpIHtcbiAgcmVnaXN0ZXJUd29QaGFzZUV2ZW50KCdvblNlbGVjdCcsIFsnZm9jdXNvdXQnLCAnY29udGV4dG1lbnUnLCAnZHJhZ2VuZCcsICdmb2N1c2luJywgJ2tleWRvd24nLCAna2V5dXAnLCAnbW91c2Vkb3duJywgJ21vdXNldXAnLCAnc2VsZWN0aW9uY2hhbmdlJ10pO1xufVxuXG52YXIgYWN0aXZlRWxlbWVudCQxID0gbnVsbDtcbnZhciBhY3RpdmVFbGVtZW50SW5zdCQxID0gbnVsbDtcbnZhciBsYXN0U2VsZWN0aW9uID0gbnVsbDtcbnZhciBtb3VzZURvd24gPSBmYWxzZTtcbi8qKlxuICogR2V0IGFuIG9iamVjdCB3aGljaCBpcyBhIHVuaXF1ZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCBzZWxlY3Rpb24uXG4gKlxuICogVGhlIHJldHVybiB2YWx1ZSB3aWxsIG5vdCBiZSBjb25zaXN0ZW50IGFjcm9zcyBub2RlcyBvciBicm93c2VycywgYnV0XG4gKiB0d28gaWRlbnRpY2FsIHNlbGVjdGlvbnMgb24gdGhlIHNhbWUgbm9kZSB3aWxsIHJldHVybiBpZGVudGljYWwgb2JqZWN0cy5cbiAqL1xuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb24kMShub2RlKSB7XG4gIGlmICgnc2VsZWN0aW9uU3RhcnQnIGluIG5vZGUgJiYgaGFzU2VsZWN0aW9uQ2FwYWJpbGl0aWVzKG5vZGUpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXJ0OiBub2RlLnNlbGVjdGlvblN0YXJ0LFxuICAgICAgZW5kOiBub2RlLnNlbGVjdGlvbkVuZFxuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgdmFyIHdpbiA9IG5vZGUub3duZXJEb2N1bWVudCAmJiBub2RlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcgfHwgd2luZG93O1xuICAgIHZhciBzZWxlY3Rpb24gPSB3aW4uZ2V0U2VsZWN0aW9uKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFuY2hvck5vZGU6IHNlbGVjdGlvbi5hbmNob3JOb2RlLFxuICAgICAgYW5jaG9yT2Zmc2V0OiBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0LFxuICAgICAgZm9jdXNOb2RlOiBzZWxlY3Rpb24uZm9jdXNOb2RlLFxuICAgICAgZm9jdXNPZmZzZXQ6IHNlbGVjdGlvbi5mb2N1c09mZnNldFxuICAgIH07XG4gIH1cbn1cbi8qKlxuICogR2V0IGRvY3VtZW50IGFzc29jaWF0ZWQgd2l0aCB0aGUgZXZlbnQgdGFyZ2V0LlxuICovXG5cblxuZnVuY3Rpb24gZ2V0RXZlbnRUYXJnZXREb2N1bWVudChldmVudFRhcmdldCkge1xuICByZXR1cm4gZXZlbnRUYXJnZXQud2luZG93ID09PSBldmVudFRhcmdldCA/IGV2ZW50VGFyZ2V0LmRvY3VtZW50IDogZXZlbnRUYXJnZXQubm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUgPyBldmVudFRhcmdldCA6IGV2ZW50VGFyZ2V0Lm93bmVyRG9jdW1lbnQ7XG59XG4vKipcbiAqIFBvbGwgc2VsZWN0aW9uIHRvIHNlZSB3aGV0aGVyIGl0J3MgY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gbmF0aXZlRXZlbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBuYXRpdmVFdmVudFRhcmdldFxuICogQHJldHVybiB7P1N5bnRoZXRpY0V2ZW50fVxuICovXG5cblxuZnVuY3Rpb24gY29uc3RydWN0U2VsZWN0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gIC8vIEVuc3VyZSB3ZSBoYXZlIHRoZSByaWdodCBlbGVtZW50LCBhbmQgdGhhdCB0aGUgdXNlciBpcyBub3QgZHJhZ2dpbmcgYVxuICAvLyBzZWxlY3Rpb24gKHRoaXMgbWF0Y2hlcyBuYXRpdmUgYHNlbGVjdGAgZXZlbnQgYmVoYXZpb3IpLiBJbiBIVE1MNSwgc2VsZWN0XG4gIC8vIGZpcmVzIG9ubHkgb24gaW5wdXQgYW5kIHRleHRhcmVhIHRodXMgaWYgdGhlcmUncyBubyBmb2N1c2VkIGVsZW1lbnQgd2VcbiAgLy8gd29uJ3QgZGlzcGF0Y2guXG4gIHZhciBkb2MgPSBnZXRFdmVudFRhcmdldERvY3VtZW50KG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICBpZiAobW91c2VEb3duIHx8IGFjdGl2ZUVsZW1lbnQkMSA9PSBudWxsIHx8IGFjdGl2ZUVsZW1lbnQkMSAhPT0gZ2V0QWN0aXZlRWxlbWVudChkb2MpKSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIE9ubHkgZmlyZSB3aGVuIHNlbGVjdGlvbiBoYXMgYWN0dWFsbHkgY2hhbmdlZC5cblxuXG4gIHZhciBjdXJyZW50U2VsZWN0aW9uID0gZ2V0U2VsZWN0aW9uJDEoYWN0aXZlRWxlbWVudCQxKTtcblxuICBpZiAoIWxhc3RTZWxlY3Rpb24gfHwgIXNoYWxsb3dFcXVhbChsYXN0U2VsZWN0aW9uLCBjdXJyZW50U2VsZWN0aW9uKSkge1xuICAgIGxhc3RTZWxlY3Rpb24gPSBjdXJyZW50U2VsZWN0aW9uO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhY2N1bXVsYXRlVHdvUGhhc2VMaXN0ZW5lcnMoYWN0aXZlRWxlbWVudEluc3QkMSwgJ29uU2VsZWN0Jyk7XG5cbiAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciBldmVudCA9IG5ldyBTeW50aGV0aWNFdmVudCgnb25TZWxlY3QnLCAnc2VsZWN0JywgbnVsbCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICAgIGRpc3BhdGNoUXVldWUucHVzaCh7XG4gICAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgICAgbGlzdGVuZXJzOiBsaXN0ZW5lcnNcbiAgICAgIH0pO1xuICAgICAgZXZlbnQudGFyZ2V0ID0gYWN0aXZlRWxlbWVudCQxO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBUaGlzIHBsdWdpbiBjcmVhdGVzIGFuIGBvblNlbGVjdGAgZXZlbnQgdGhhdCBub3JtYWxpemVzIHNlbGVjdCBldmVudHNcbiAqIGFjcm9zcyBmb3JtIGVsZW1lbnRzLlxuICpcbiAqIFN1cHBvcnRlZCBlbGVtZW50cyBhcmU6XG4gKiAtIGlucHV0IChzZWUgYGlzVGV4dElucHV0RWxlbWVudGApXG4gKiAtIHRleHRhcmVhXG4gKiAtIGNvbnRlbnRFZGl0YWJsZVxuICpcbiAqIFRoaXMgZGlmZmVycyBmcm9tIG5hdGl2ZSBicm93c2VyIGltcGxlbWVudGF0aW9ucyBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKiAtIEZpcmVzIG9uIGNvbnRlbnRFZGl0YWJsZSBmaWVsZHMgYXMgd2VsbCBhcyBpbnB1dHMuXG4gKiAtIEZpcmVzIGZvciBjb2xsYXBzZWQgc2VsZWN0aW9uLlxuICogLSBGaXJlcyBhZnRlciB1c2VyIGlucHV0LlxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEV2ZW50cyQzKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzLCB0YXJnZXRDb250YWluZXIpIHtcbiAgdmFyIHRhcmdldE5vZGUgPSB0YXJnZXRJbnN0ID8gZ2V0Tm9kZUZyb21JbnN0YW5jZSh0YXJnZXRJbnN0KSA6IHdpbmRvdztcblxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIC8vIFRyYWNrIHRoZSBpbnB1dCBub2RlIHRoYXQgaGFzIGZvY3VzLlxuICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgICAgaWYgKGlzVGV4dElucHV0RWxlbWVudCh0YXJnZXROb2RlKSB8fCB0YXJnZXROb2RlLmNvbnRlbnRFZGl0YWJsZSA9PT0gJ3RydWUnKSB7XG4gICAgICAgIGFjdGl2ZUVsZW1lbnQkMSA9IHRhcmdldE5vZGU7XG4gICAgICAgIGFjdGl2ZUVsZW1lbnRJbnN0JDEgPSB0YXJnZXRJbnN0O1xuICAgICAgICBsYXN0U2VsZWN0aW9uID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdmb2N1c291dCc6XG4gICAgICBhY3RpdmVFbGVtZW50JDEgPSBudWxsO1xuICAgICAgYWN0aXZlRWxlbWVudEluc3QkMSA9IG51bGw7XG4gICAgICBsYXN0U2VsZWN0aW9uID0gbnVsbDtcbiAgICAgIGJyZWFrO1xuICAgIC8vIERvbid0IGZpcmUgdGhlIGV2ZW50IHdoaWxlIHRoZSB1c2VyIGlzIGRyYWdnaW5nLiBUaGlzIG1hdGNoZXMgdGhlXG4gICAgLy8gc2VtYW50aWNzIG9mIHRoZSBuYXRpdmUgc2VsZWN0IGV2ZW50LlxuXG4gICAgY2FzZSAnbW91c2Vkb3duJzpcbiAgICAgIG1vdXNlRG93biA9IHRydWU7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2NvbnRleHRtZW51JzpcbiAgICBjYXNlICdtb3VzZXVwJzpcbiAgICBjYXNlICdkcmFnZW5kJzpcbiAgICAgIG1vdXNlRG93biA9IGZhbHNlO1xuICAgICAgY29uc3RydWN0U2VsZWN0RXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIENocm9tZSBhbmQgSUUgZmlyZSBub24tc3RhbmRhcmQgZXZlbnQgd2hlbiBzZWxlY3Rpb24gaXMgY2hhbmdlZCAoYW5kXG4gICAgLy8gc29tZXRpbWVzIHdoZW4gaXQgaGFzbid0KS4gSUUncyBldmVudCBmaXJlcyBvdXQgb2Ygb3JkZXIgd2l0aCByZXNwZWN0XG4gICAgLy8gdG8ga2V5IGFuZCBpbnB1dCBldmVudHMgb24gZGVsZXRpb24sIHNvIHdlIGRpc2NhcmQgaXQuXG4gICAgLy9cbiAgICAvLyBGaXJlZm94IGRvZXNuJ3Qgc3VwcG9ydCBzZWxlY3Rpb25jaGFuZ2UsIHNvIGNoZWNrIHNlbGVjdGlvbiBzdGF0dXNcbiAgICAvLyBhZnRlciBlYWNoIGtleSBlbnRyeS4gVGhlIHNlbGVjdGlvbiBjaGFuZ2VzIGFmdGVyIGtleWRvd24gYW5kIGJlZm9yZVxuICAgIC8vIGtleXVwLCBidXQgd2UgY2hlY2sgb24ga2V5ZG93biBhcyB3ZWxsIGluIHRoZSBjYXNlIG9mIGhvbGRpbmcgZG93biBhXG4gICAgLy8ga2V5LCB3aGVuIG11bHRpcGxlIGtleWRvd24gZXZlbnRzIGFyZSBmaXJlZCBidXQgb25seSBvbmUga2V5dXAgaXMuXG4gICAgLy8gVGhpcyBpcyBhbHNvIG91ciBhcHByb2FjaCBmb3IgSUUgaGFuZGxpbmcsIGZvciB0aGUgcmVhc29uIGFib3ZlLlxuXG4gICAgY2FzZSAnc2VsZWN0aW9uY2hhbmdlJzpcbiAgICAgIGlmIChza2lwU2VsZWN0aW9uQ2hhbmdlRXZlbnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAvLyBmYWxscyB0aHJvdWdoXG5cbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICBjYXNlICdrZXl1cCc6XG4gICAgICBjb25zdHJ1Y3RTZWxlY3RFdmVudChkaXNwYXRjaFF1ZXVlLCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBtYXBwaW5nIG9mIHN0YW5kYXJkIHZlbmRvciBwcmVmaXhlcyB1c2luZyB0aGUgZGVmaW5lZCBzdHlsZSBwcm9wZXJ0eSBhbmQgZXZlbnQgbmFtZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3R5bGVQcm9wXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICovXG5cbmZ1bmN0aW9uIG1ha2VQcmVmaXhNYXAoc3R5bGVQcm9wLCBldmVudE5hbWUpIHtcbiAgdmFyIHByZWZpeGVzID0ge307XG4gIHByZWZpeGVzW3N0eWxlUHJvcC50b0xvd2VyQ2FzZSgpXSA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpO1xuICBwcmVmaXhlc1snV2Via2l0JyArIHN0eWxlUHJvcF0gPSAnd2Via2l0JyArIGV2ZW50TmFtZTtcbiAgcHJlZml4ZXNbJ01veicgKyBzdHlsZVByb3BdID0gJ21veicgKyBldmVudE5hbWU7XG4gIHJldHVybiBwcmVmaXhlcztcbn1cbi8qKlxuICogQSBsaXN0IG9mIGV2ZW50IG5hbWVzIHRvIGEgY29uZmlndXJhYmxlIGxpc3Qgb2YgdmVuZG9yIHByZWZpeGVzLlxuICovXG5cblxudmFyIHZlbmRvclByZWZpeGVzID0ge1xuICBhbmltYXRpb25lbmQ6IG1ha2VQcmVmaXhNYXAoJ0FuaW1hdGlvbicsICdBbmltYXRpb25FbmQnKSxcbiAgYW5pbWF0aW9uaXRlcmF0aW9uOiBtYWtlUHJlZml4TWFwKCdBbmltYXRpb24nLCAnQW5pbWF0aW9uSXRlcmF0aW9uJyksXG4gIGFuaW1hdGlvbnN0YXJ0OiBtYWtlUHJlZml4TWFwKCdBbmltYXRpb24nLCAnQW5pbWF0aW9uU3RhcnQnKSxcbiAgdHJhbnNpdGlvbmVuZDogbWFrZVByZWZpeE1hcCgnVHJhbnNpdGlvbicsICdUcmFuc2l0aW9uRW5kJylcbn07XG4vKipcbiAqIEV2ZW50IG5hbWVzIHRoYXQgaGF2ZSBhbHJlYWR5IGJlZW4gZGV0ZWN0ZWQgYW5kIHByZWZpeGVkIChpZiBhcHBsaWNhYmxlKS5cbiAqL1xuXG52YXIgcHJlZml4ZWRFdmVudE5hbWVzID0ge307XG4vKipcbiAqIEVsZW1lbnQgdG8gY2hlY2sgZm9yIHByZWZpeGVzIG9uLlxuICovXG5cbnZhciBzdHlsZSA9IHt9O1xuLyoqXG4gKiBCb290c3RyYXAgaWYgYSBET00gZXhpc3RzLlxuICovXG5cbmlmIChjYW5Vc2VET00pIHtcbiAgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5zdHlsZTsgLy8gT24gc29tZSBwbGF0Zm9ybXMsIGluIHBhcnRpY3VsYXIgc29tZSByZWxlYXNlcyBvZiBBbmRyb2lkIDQueCxcbiAgLy8gdGhlIHVuLXByZWZpeGVkIFwiYW5pbWF0aW9uXCIgYW5kIFwidHJhbnNpdGlvblwiIHByb3BlcnRpZXMgYXJlIGRlZmluZWQgb24gdGhlXG4gIC8vIHN0eWxlIG9iamVjdCBidXQgdGhlIGV2ZW50cyB0aGF0IGZpcmUgd2lsbCBzdGlsbCBiZSBwcmVmaXhlZCwgc28gd2UgbmVlZFxuICAvLyB0byBjaGVjayBpZiB0aGUgdW4tcHJlZml4ZWQgZXZlbnRzIGFyZSB1c2FibGUsIGFuZCBpZiBub3QgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgbWFwLlxuXG4gIGlmICghKCdBbmltYXRpb25FdmVudCcgaW4gd2luZG93KSkge1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy5hbmltYXRpb25lbmQuYW5pbWF0aW9uO1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy5hbmltYXRpb25pdGVyYXRpb24uYW5pbWF0aW9uO1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy5hbmltYXRpb25zdGFydC5hbmltYXRpb247XG4gIH0gLy8gU2FtZSBhcyBhYm92ZVxuXG5cbiAgaWYgKCEoJ1RyYW5zaXRpb25FdmVudCcgaW4gd2luZG93KSkge1xuICAgIGRlbGV0ZSB2ZW5kb3JQcmVmaXhlcy50cmFuc2l0aW9uZW5kLnRyYW5zaXRpb247XG4gIH1cbn1cbi8qKlxuICogQXR0ZW1wdHMgdG8gZGV0ZXJtaW5lIHRoZSBjb3JyZWN0IHZlbmRvciBwcmVmaXhlZCBldmVudCBuYW1lLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cblxuXG5mdW5jdGlvbiBnZXRWZW5kb3JQcmVmaXhlZEV2ZW50TmFtZShldmVudE5hbWUpIHtcbiAgaWYgKHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdKSB7XG4gICAgcmV0dXJuIHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdO1xuICB9IGVsc2UgaWYgKCF2ZW5kb3JQcmVmaXhlc1tldmVudE5hbWVdKSB7XG4gICAgcmV0dXJuIGV2ZW50TmFtZTtcbiAgfVxuXG4gIHZhciBwcmVmaXhNYXAgPSB2ZW5kb3JQcmVmaXhlc1tldmVudE5hbWVdO1xuXG4gIGZvciAodmFyIHN0eWxlUHJvcCBpbiBwcmVmaXhNYXApIHtcbiAgICBpZiAocHJlZml4TWFwLmhhc093blByb3BlcnR5KHN0eWxlUHJvcCkgJiYgc3R5bGVQcm9wIGluIHN0eWxlKSB7XG4gICAgICByZXR1cm4gcHJlZml4ZWRFdmVudE5hbWVzW2V2ZW50TmFtZV0gPSBwcmVmaXhNYXBbc3R5bGVQcm9wXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXZlbnROYW1lO1xufVxuXG52YXIgQU5JTUFUSU9OX0VORCA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCdhbmltYXRpb25lbmQnKTtcbnZhciBBTklNQVRJT05fSVRFUkFUSU9OID0gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoJ2FuaW1hdGlvbml0ZXJhdGlvbicpO1xudmFyIEFOSU1BVElPTl9TVEFSVCA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCdhbmltYXRpb25zdGFydCcpO1xudmFyIFRSQU5TSVRJT05fRU5EID0gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoJ3RyYW5zaXRpb25lbmQnKTtcblxudmFyIHRvcExldmVsRXZlbnRzVG9SZWFjdE5hbWVzID0gbmV3IE1hcCgpOyAvLyBOT1RFOiBDYXBpdGFsaXphdGlvbiBpcyBpbXBvcnRhbnQgaW4gdGhpcyBsaXN0IVxuLy9cbi8vIEUuZy4gaXQgbmVlZHMgXCJwb2ludGVyRG93blwiLCBub3QgXCJwb2ludGVyZG93blwiLlxuLy8gVGhpcyBpcyBiZWNhdXNlIHdlIGRlcml2ZSBib3RoIFJlYWN0IG5hbWUgKFwib25Qb2ludGVyRG93blwiKVxuLy8gYW5kIERPTSBuYW1lIChcInBvaW50ZXJkb3duXCIpIGZyb20gdGhlIHNhbWUgbGlzdC5cbi8vXG4vLyBFeGNlcHRpb25zIHRoYXQgZG9uJ3QgbWF0Y2ggdGhpcyBjb252ZW50aW9uIGFyZSBsaXN0ZWQgc2VwYXJhdGVseS5cbi8vXG4vLyBwcmV0dGllci1pZ25vcmVcblxudmFyIHNpbXBsZUV2ZW50UGx1Z2luRXZlbnRzID0gWydhYm9ydCcsICdhdXhDbGljaycsICdjYW5jZWwnLCAnY2FuUGxheScsICdjYW5QbGF5VGhyb3VnaCcsICdjbGljaycsICdjbG9zZScsICdjb250ZXh0TWVudScsICdjb3B5JywgJ2N1dCcsICdkcmFnJywgJ2RyYWdFbmQnLCAnZHJhZ0VudGVyJywgJ2RyYWdFeGl0JywgJ2RyYWdMZWF2ZScsICdkcmFnT3ZlcicsICdkcmFnU3RhcnQnLCAnZHJvcCcsICdkdXJhdGlvbkNoYW5nZScsICdlbXB0aWVkJywgJ2VuY3J5cHRlZCcsICdlbmRlZCcsICdlcnJvcicsICdnb3RQb2ludGVyQ2FwdHVyZScsICdpbnB1dCcsICdpbnZhbGlkJywgJ2tleURvd24nLCAna2V5UHJlc3MnLCAna2V5VXAnLCAnbG9hZCcsICdsb2FkZWREYXRhJywgJ2xvYWRlZE1ldGFkYXRhJywgJ2xvYWRTdGFydCcsICdsb3N0UG9pbnRlckNhcHR1cmUnLCAnbW91c2VEb3duJywgJ21vdXNlTW92ZScsICdtb3VzZU91dCcsICdtb3VzZU92ZXInLCAnbW91c2VVcCcsICdwYXN0ZScsICdwYXVzZScsICdwbGF5JywgJ3BsYXlpbmcnLCAncG9pbnRlckNhbmNlbCcsICdwb2ludGVyRG93bicsICdwb2ludGVyTW92ZScsICdwb2ludGVyT3V0JywgJ3BvaW50ZXJPdmVyJywgJ3BvaW50ZXJVcCcsICdwcm9ncmVzcycsICdyYXRlQ2hhbmdlJywgJ3Jlc2V0JywgJ3Jlc2l6ZScsICdzZWVrZWQnLCAnc2Vla2luZycsICdzdGFsbGVkJywgJ3N1Ym1pdCcsICdzdXNwZW5kJywgJ3RpbWVVcGRhdGUnLCAndG91Y2hDYW5jZWwnLCAndG91Y2hFbmQnLCAndG91Y2hTdGFydCcsICd2b2x1bWVDaGFuZ2UnLCAnc2Nyb2xsJywgJ3RvZ2dsZScsICd0b3VjaE1vdmUnLCAnd2FpdGluZycsICd3aGVlbCddO1xuXG5mdW5jdGlvbiByZWdpc3RlclNpbXBsZUV2ZW50KGRvbUV2ZW50TmFtZSwgcmVhY3ROYW1lKSB7XG4gIHRvcExldmVsRXZlbnRzVG9SZWFjdE5hbWVzLnNldChkb21FdmVudE5hbWUsIHJlYWN0TmFtZSk7XG4gIHJlZ2lzdGVyVHdvUGhhc2VFdmVudChyZWFjdE5hbWUsIFtkb21FdmVudE5hbWVdKTtcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJTaW1wbGVFdmVudHMoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2ltcGxlRXZlbnRQbHVnaW5FdmVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZXZlbnROYW1lID0gc2ltcGxlRXZlbnRQbHVnaW5FdmVudHNbaV07XG4gICAgdmFyIGRvbUV2ZW50TmFtZSA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBjYXBpdGFsaXplZEV2ZW50ID0gZXZlbnROYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBldmVudE5hbWUuc2xpY2UoMSk7XG4gICAgcmVnaXN0ZXJTaW1wbGVFdmVudChkb21FdmVudE5hbWUsICdvbicgKyBjYXBpdGFsaXplZEV2ZW50KTtcbiAgfSAvLyBTcGVjaWFsIGNhc2VzIHdoZXJlIGV2ZW50IG5hbWVzIGRvbid0IG1hdGNoLlxuXG5cbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChBTklNQVRJT05fRU5ELCAnb25BbmltYXRpb25FbmQnKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChBTklNQVRJT05fSVRFUkFUSU9OLCAnb25BbmltYXRpb25JdGVyYXRpb24nKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudChBTklNQVRJT05fU1RBUlQsICdvbkFuaW1hdGlvblN0YXJ0Jyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoJ2RibGNsaWNrJywgJ29uRG91YmxlQ2xpY2snKTtcbiAgcmVnaXN0ZXJTaW1wbGVFdmVudCgnZm9jdXNpbicsICdvbkZvY3VzJyk7XG4gIHJlZ2lzdGVyU2ltcGxlRXZlbnQoJ2ZvY3Vzb3V0JywgJ29uQmx1cicpO1xuICByZWdpc3RlclNpbXBsZUV2ZW50KFRSQU5TSVRJT05fRU5ELCAnb25UcmFuc2l0aW9uRW5kJyk7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RFdmVudHMkNChkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCwgZXZlbnRTeXN0ZW1GbGFncywgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIHZhciByZWFjdE5hbWUgPSB0b3BMZXZlbEV2ZW50c1RvUmVhY3ROYW1lcy5nZXQoZG9tRXZlbnROYW1lKTtcblxuICBpZiAocmVhY3ROYW1lID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljRXZlbnQ7XG4gIHZhciByZWFjdEV2ZW50VHlwZSA9IGRvbUV2ZW50TmFtZTtcblxuICBzd2l0Y2ggKGRvbUV2ZW50TmFtZSkge1xuICAgIGNhc2UgJ2tleXByZXNzJzpcbiAgICAgIC8vIEZpcmVmb3ggY3JlYXRlcyBhIGtleXByZXNzIGV2ZW50IGZvciBmdW5jdGlvbiBrZXlzIHRvby4gVGhpcyByZW1vdmVzXG4gICAgICAvLyB0aGUgdW53YW50ZWQga2V5cHJlc3MgZXZlbnRzLiBFbnRlciBpcyBob3dldmVyIGJvdGggcHJpbnRhYmxlIGFuZFxuICAgICAgLy8gbm9uLXByaW50YWJsZS4gT25lIHdvdWxkIGV4cGVjdCBUYWIgdG8gYmUgYXMgd2VsbCAoYnV0IGl0IGlzbid0KS5cbiAgICAgIGlmIChnZXRFdmVudENoYXJDb2RlKG5hdGl2ZUV2ZW50KSA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAvKiBmYWxscyB0aHJvdWdoICovXG5cbiAgICBjYXNlICdrZXlkb3duJzpcbiAgICBjYXNlICdrZXl1cCc6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNLZXlib2FyZEV2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdmb2N1c2luJzpcbiAgICAgIHJlYWN0RXZlbnRUeXBlID0gJ2ZvY3VzJztcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0ZvY3VzRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2ZvY3Vzb3V0JzpcbiAgICAgIHJlYWN0RXZlbnRUeXBlID0gJ2JsdXInO1xuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljRm9jdXNFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnYmVmb3JlYmx1cic6XG4gICAgY2FzZSAnYWZ0ZXJibHVyJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0ZvY3VzRXZlbnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2NsaWNrJzpcbiAgICAgIC8vIEZpcmVmb3ggY3JlYXRlcyBhIGNsaWNrIGV2ZW50IG9uIHJpZ2h0IG1vdXNlIGNsaWNrcy4gVGhpcyByZW1vdmVzIHRoZVxuICAgICAgLy8gdW53YW50ZWQgY2xpY2sgZXZlbnRzLlxuICAgICAgaWYgKG5hdGl2ZUV2ZW50LmJ1dHRvbiA9PT0gMikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAvKiBmYWxscyB0aHJvdWdoICovXG5cbiAgICBjYXNlICdhdXhjbGljayc6XG4gICAgY2FzZSAnZGJsY2xpY2snOlxuICAgIGNhc2UgJ21vdXNlZG93bic6XG4gICAgY2FzZSAnbW91c2Vtb3ZlJzpcbiAgICBjYXNlICdtb3VzZXVwJzogLy8gVE9ETzogRGlzYWJsZWQgZWxlbWVudHMgc2hvdWxkIG5vdCByZXNwb25kIHRvIG1vdXNlIGV2ZW50c1xuXG4gICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuXG4gICAgY2FzZSAnbW91c2VvdXQnOlxuICAgIGNhc2UgJ21vdXNlb3Zlcic6XG4gICAgY2FzZSAnY29udGV4dG1lbnUnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljTW91c2VFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZHJhZyc6XG4gICAgY2FzZSAnZHJhZ2VuZCc6XG4gICAgY2FzZSAnZHJhZ2VudGVyJzpcbiAgICBjYXNlICdkcmFnZXhpdCc6XG4gICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICBjYXNlICdkcmFnb3Zlcic6XG4gICAgY2FzZSAnZHJhZ3N0YXJ0JzpcbiAgICBjYXNlICdkcm9wJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0RyYWdFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndG91Y2hjYW5jZWwnOlxuICAgIGNhc2UgJ3RvdWNoZW5kJzpcbiAgICBjYXNlICd0b3VjaG1vdmUnOlxuICAgIGNhc2UgJ3RvdWNoc3RhcnQnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljVG91Y2hFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBBTklNQVRJT05fRU5EOlxuICAgIGNhc2UgQU5JTUFUSU9OX0lURVJBVElPTjpcbiAgICBjYXNlIEFOSU1BVElPTl9TVEFSVDpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY0FuaW1hdGlvbkV2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFRSQU5TSVRJT05fRU5EOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljVHJhbnNpdGlvbkV2ZW50O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzY3JvbGwnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljVUlFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnd2hlZWwnOlxuICAgICAgU3ludGhldGljRXZlbnRDdG9yID0gU3ludGhldGljV2hlZWxFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnY29weSc6XG4gICAgY2FzZSAnY3V0JzpcbiAgICBjYXNlICdwYXN0ZSc6XG4gICAgICBTeW50aGV0aWNFdmVudEN0b3IgPSBTeW50aGV0aWNDbGlwYm9hcmRFdmVudDtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZ290cG9pbnRlcmNhcHR1cmUnOlxuICAgIGNhc2UgJ2xvc3Rwb2ludGVyY2FwdHVyZSc6XG4gICAgY2FzZSAncG9pbnRlcmNhbmNlbCc6XG4gICAgY2FzZSAncG9pbnRlcmRvd24nOlxuICAgIGNhc2UgJ3BvaW50ZXJtb3ZlJzpcbiAgICBjYXNlICdwb2ludGVyb3V0JzpcbiAgICBjYXNlICdwb2ludGVyb3Zlcic6XG4gICAgY2FzZSAncG9pbnRlcnVwJzpcbiAgICAgIFN5bnRoZXRpY0V2ZW50Q3RvciA9IFN5bnRoZXRpY1BvaW50ZXJFdmVudDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgdmFyIGluQ2FwdHVyZVBoYXNlID0gKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19DQVBUVVJFX1BIQVNFKSAhPT0gMDtcblxuICB7XG4gICAgLy8gU29tZSBldmVudHMgZG9uJ3QgYnViYmxlIGluIHRoZSBicm93c2VyLlxuICAgIC8vIEluIHRoZSBwYXN0LCBSZWFjdCBoYXMgYWx3YXlzIGJ1YmJsZWQgdGhlbSwgYnV0IHRoaXMgY2FuIGJlIHN1cnByaXNpbmcuXG4gICAgLy8gV2UncmUgZ29pbmcgdG8gdHJ5IGFsaWduaW5nIGNsb3NlciB0byB0aGUgYnJvd3NlciBiZWhhdmlvciBieSBub3QgYnViYmxpbmdcbiAgICAvLyB0aGVtIGluIFJlYWN0IGVpdGhlci4gV2UnbGwgc3RhcnQgYnkgbm90IGJ1YmJsaW5nIG9uU2Nyb2xsLCBhbmQgdGhlbiBleHBhbmQuXG4gICAgdmFyIGFjY3VtdWxhdGVUYXJnZXRPbmx5ID0gIWluQ2FwdHVyZVBoYXNlICYmIC8vIFRPRE86IGlkZWFsbHksIHdlJ2QgZXZlbnR1YWxseSBhZGQgYWxsIGV2ZW50cyBmcm9tXG4gICAgLy8gbm9uRGVsZWdhdGVkRXZlbnRzIGxpc3QgaW4gRE9NUGx1Z2luRXZlbnRTeXN0ZW0uXG4gICAgLy8gVGhlbiB3ZSBjYW4gcmVtb3ZlIHRoaXMgc3BlY2lhbCBsaXN0LlxuICAgIC8vIFRoaXMgaXMgYSBicmVha2luZyBjaGFuZ2UgdGhhdCBjYW4gd2FpdCB1bnRpbCBSZWFjdCAxOC5cbiAgICBkb21FdmVudE5hbWUgPT09ICdzY3JvbGwnO1xuXG4gICAgdmFyIF9saXN0ZW5lcnMgPSBhY2N1bXVsYXRlU2luZ2xlUGhhc2VMaXN0ZW5lcnModGFyZ2V0SW5zdCwgcmVhY3ROYW1lLCBuYXRpdmVFdmVudC50eXBlLCBpbkNhcHR1cmVQaGFzZSwgYWNjdW11bGF0ZVRhcmdldE9ubHkpO1xuXG4gICAgaWYgKF9saXN0ZW5lcnMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gSW50ZW50aW9uYWxseSBjcmVhdGUgZXZlbnQgbGF6aWx5LlxuICAgICAgdmFyIF9ldmVudCA9IG5ldyBTeW50aGV0aWNFdmVudEN0b3IocmVhY3ROYW1lLCByZWFjdEV2ZW50VHlwZSwgbnVsbCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcblxuICAgICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgICAgZXZlbnQ6IF9ldmVudCxcbiAgICAgICAgbGlzdGVuZXJzOiBfbGlzdGVuZXJzXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLy8gVE9ETzogcmVtb3ZlIHRvcC1sZXZlbCBzaWRlIGVmZmVjdC5cbnJlZ2lzdGVyU2ltcGxlRXZlbnRzKCk7XG5yZWdpc3RlckV2ZW50cyQyKCk7XG5yZWdpc3RlckV2ZW50cyQxKCk7XG5yZWdpc3RlckV2ZW50cyQzKCk7XG5yZWdpc3RlckV2ZW50cygpO1xuXG5mdW5jdGlvbiBleHRyYWN0RXZlbnRzJDUoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQsIGV2ZW50U3lzdGVtRmxhZ3MsIHRhcmdldENvbnRhaW5lcikge1xuICAvLyBUT0RPOiB3ZSBzaG91bGQgcmVtb3ZlIHRoZSBjb25jZXB0IG9mIGEgXCJTaW1wbGVFdmVudFBsdWdpblwiLlxuICAvLyBUaGlzIGlzIHRoZSBiYXNpYyBmdW5jdGlvbmFsaXR5IG9mIHRoZSBldmVudCBzeXN0ZW0uIEFsbFxuICAvLyB0aGUgb3RoZXIgcGx1Z2lucyBhcmUgZXNzZW50aWFsbHkgcG9seWZpbGxzLiBTbyB0aGUgcGx1Z2luXG4gIC8vIHNob3VsZCBwcm9iYWJseSBiZSBpbmxpbmVkIHNvbWV3aGVyZSBhbmQgaGF2ZSBpdHMgbG9naWNcbiAgLy8gYmUgY29yZSB0aGUgdG8gZXZlbnQgc3lzdGVtLiBUaGlzIHdvdWxkIHBvdGVudGlhbGx5IGFsbG93XG4gIC8vIHVzIHRvIHNoaXAgYnVpbGRzIG9mIFJlYWN0IHdpdGhvdXQgdGhlIHBvbHlmaWxsZWQgcGx1Z2lucyBiZWxvdy5cbiAgZXh0cmFjdEV2ZW50cyQ0KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzKTtcbiAgdmFyIHNob3VsZFByb2Nlc3NQb2x5ZmlsbFBsdWdpbnMgPSAoZXZlbnRTeXN0ZW1GbGFncyAmIFNIT1VMRF9OT1RfUFJPQ0VTU19QT0xZRklMTF9FVkVOVF9QTFVHSU5TKSA9PT0gMDsgLy8gV2UgZG9uJ3QgcHJvY2VzcyB0aGVzZSBldmVudHMgdW5sZXNzIHdlIGFyZSBpbiB0aGVcbiAgLy8gZXZlbnQncyBuYXRpdmUgXCJidWJibGVcIiBwaGFzZSwgd2hpY2ggbWVhbnMgdGhhdCB3ZSdyZVxuICAvLyBub3QgaW4gdGhlIGNhcHR1cmUgcGhhc2UuIFRoYXQncyBiZWNhdXNlIHdlIGVtdWxhdGVcbiAgLy8gdGhlIGNhcHR1cmUgcGhhc2UgaGVyZSBzdGlsbC4gVGhpcyBpcyBhIHRyYWRlLW9mZixcbiAgLy8gYmVjYXVzZSBpbiBhbiBpZGVhbCB3b3JsZCB3ZSB3b3VsZCBub3QgZW11bGF0ZSBhbmQgdXNlXG4gIC8vIHRoZSBwaGFzZXMgcHJvcGVybHksIGxpa2Ugd2UgZG8gd2l0aCB0aGUgU2ltcGxlRXZlbnRcbiAgLy8gcGx1Z2luLiBIb3dldmVyLCB0aGUgcGx1Z2lucyBiZWxvdyBlaXRoZXIgZXhwZWN0XG4gIC8vIGVtdWxhdGlvbiAoRW50ZXJMZWF2ZSkgb3IgdXNlIHN0YXRlIGxvY2FsaXplZCB0byB0aGF0XG4gIC8vIHBsdWdpbiAoQmVmb3JlSW5wdXQsIENoYW5nZSwgU2VsZWN0KS4gVGhlIHN0YXRlIGluXG4gIC8vIHRoZXNlIG1vZHVsZXMgY29tcGxpY2F0ZXMgdGhpbmdzLCBhcyB5b3UnbGwgZXNzZW50aWFsbHlcbiAgLy8gZ2V0IHRoZSBjYXNlIHdoZXJlIHRoZSBjYXB0dXJlIHBoYXNlIGV2ZW50IG1pZ2h0IGNoYW5nZVxuICAvLyBzdGF0ZSwgb25seSBmb3IgdGhlIGZvbGxvd2luZyBidWJibGUgZXZlbnQgdG8gY29tZSBpblxuICAvLyBsYXRlciBhbmQgbm90IHRyaWdnZXIgYW55dGhpbmcgYXMgdGhlIHN0YXRlIG5vd1xuICAvLyBpbnZhbGlkYXRlcyB0aGUgaGV1cmlzdGljcyBvZiB0aGUgZXZlbnQgcGx1Z2luLiBXZVxuICAvLyBjb3VsZCBhbHRlciBhbGwgdGhlc2UgcGx1Z2lucyB0byB3b3JrIGluIHN1Y2ggd2F5cywgYnV0XG4gIC8vIHRoYXQgbWlnaHQgY2F1c2Ugb3RoZXIgdW5rbm93biBzaWRlLWVmZmVjdHMgdGhhdCB3ZVxuICAvLyBjYW4ndCBmb3Jlc2VlIHJpZ2h0IG5vdy5cblxuICBpZiAoc2hvdWxkUHJvY2Vzc1BvbHlmaWxsUGx1Z2lucykge1xuICAgIGV4dHJhY3RFdmVudHMkMihkaXNwYXRjaFF1ZXVlLCBkb21FdmVudE5hbWUsIHRhcmdldEluc3QsIG5hdGl2ZUV2ZW50LCBuYXRpdmVFdmVudFRhcmdldCk7XG4gICAgZXh0cmFjdEV2ZW50cyQxKGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0KTtcbiAgICBleHRyYWN0RXZlbnRzJDMoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICAgIGV4dHJhY3RFdmVudHMoZGlzcGF0Y2hRdWV1ZSwgZG9tRXZlbnROYW1lLCB0YXJnZXRJbnN0LCBuYXRpdmVFdmVudCwgbmF0aXZlRXZlbnRUYXJnZXQpO1xuICB9XG59IC8vIExpc3Qgb2YgZXZlbnRzIHRoYXQgbmVlZCB0byBiZSBpbmRpdmlkdWFsbHkgYXR0YWNoZWQgdG8gbWVkaWEgZWxlbWVudHMuXG5cblxudmFyIG1lZGlhRXZlbnRUeXBlcyA9IFsnYWJvcnQnLCAnY2FucGxheScsICdjYW5wbGF5dGhyb3VnaCcsICdkdXJhdGlvbmNoYW5nZScsICdlbXB0aWVkJywgJ2VuY3J5cHRlZCcsICdlbmRlZCcsICdlcnJvcicsICdsb2FkZWRkYXRhJywgJ2xvYWRlZG1ldGFkYXRhJywgJ2xvYWRzdGFydCcsICdwYXVzZScsICdwbGF5JywgJ3BsYXlpbmcnLCAncHJvZ3Jlc3MnLCAncmF0ZWNoYW5nZScsICdyZXNpemUnLCAnc2Vla2VkJywgJ3NlZWtpbmcnLCAnc3RhbGxlZCcsICdzdXNwZW5kJywgJ3RpbWV1cGRhdGUnLCAndm9sdW1lY2hhbmdlJywgJ3dhaXRpbmcnXTsgLy8gV2Ugc2hvdWxkIG5vdCBkZWxlZ2F0ZSB0aGVzZSBldmVudHMgdG8gdGhlIGNvbnRhaW5lciwgYnV0IHJhdGhlclxuLy8gc2V0IHRoZW0gb24gdGhlIGFjdHVhbCB0YXJnZXQgZWxlbWVudCBpdHNlbGYuIFRoaXMgaXMgcHJpbWFyaWx5XG4vLyBiZWNhdXNlIHRoZXNlIGV2ZW50cyBkbyBub3QgY29uc2lzdGVudGx5IGJ1YmJsZSBpbiB0aGUgRE9NLlxuXG52YXIgbm9uRGVsZWdhdGVkRXZlbnRzID0gbmV3IFNldChbJ2NhbmNlbCcsICdjbG9zZScsICdpbnZhbGlkJywgJ2xvYWQnLCAnc2Nyb2xsJywgJ3RvZ2dsZSddLmNvbmNhdChtZWRpYUV2ZW50VHlwZXMpKTtcblxuZnVuY3Rpb24gZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBsaXN0ZW5lciwgY3VycmVudFRhcmdldCkge1xuICB2YXIgdHlwZSA9IGV2ZW50LnR5cGUgfHwgJ3Vua25vd24tZXZlbnQnO1xuICBldmVudC5jdXJyZW50VGFyZ2V0ID0gY3VycmVudFRhcmdldDtcbiAgaW52b2tlR3VhcmRlZENhbGxiYWNrQW5kQ2F0Y2hGaXJzdEVycm9yKHR5cGUsIGxpc3RlbmVyLCB1bmRlZmluZWQsIGV2ZW50KTtcbiAgZXZlbnQuY3VycmVudFRhcmdldCA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NEaXNwYXRjaFF1ZXVlSXRlbXNJbk9yZGVyKGV2ZW50LCBkaXNwYXRjaExpc3RlbmVycywgaW5DYXB0dXJlUGhhc2UpIHtcbiAgdmFyIHByZXZpb3VzSW5zdGFuY2U7XG5cbiAgaWYgKGluQ2FwdHVyZVBoYXNlKSB7XG4gICAgZm9yICh2YXIgaSA9IGRpc3BhdGNoTGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgX2Rpc3BhdGNoTGlzdGVuZXJzJGkgPSBkaXNwYXRjaExpc3RlbmVyc1tpXSxcbiAgICAgICAgICBpbnN0YW5jZSA9IF9kaXNwYXRjaExpc3RlbmVycyRpLmluc3RhbmNlLFxuICAgICAgICAgIGN1cnJlbnRUYXJnZXQgPSBfZGlzcGF0Y2hMaXN0ZW5lcnMkaS5jdXJyZW50VGFyZ2V0LFxuICAgICAgICAgIGxpc3RlbmVyID0gX2Rpc3BhdGNoTGlzdGVuZXJzJGkubGlzdGVuZXI7XG5cbiAgICAgIGlmIChpbnN0YW5jZSAhPT0gcHJldmlvdXNJbnN0YW5jZSAmJiBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZXhlY3V0ZURpc3BhdGNoKGV2ZW50LCBsaXN0ZW5lciwgY3VycmVudFRhcmdldCk7XG4gICAgICBwcmV2aW91c0luc3RhbmNlID0gaW5zdGFuY2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBkaXNwYXRjaExpc3RlbmVycy5sZW5ndGg7IF9pKyspIHtcbiAgICAgIHZhciBfZGlzcGF0Y2hMaXN0ZW5lcnMkX2kgPSBkaXNwYXRjaExpc3RlbmVyc1tfaV0sXG4gICAgICAgICAgX2luc3RhbmNlID0gX2Rpc3BhdGNoTGlzdGVuZXJzJF9pLmluc3RhbmNlLFxuICAgICAgICAgIF9jdXJyZW50VGFyZ2V0ID0gX2Rpc3BhdGNoTGlzdGVuZXJzJF9pLmN1cnJlbnRUYXJnZXQsXG4gICAgICAgICAgX2xpc3RlbmVyID0gX2Rpc3BhdGNoTGlzdGVuZXJzJF9pLmxpc3RlbmVyO1xuXG4gICAgICBpZiAoX2luc3RhbmNlICE9PSBwcmV2aW91c0luc3RhbmNlICYmIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBleGVjdXRlRGlzcGF0Y2goZXZlbnQsIF9saXN0ZW5lciwgX2N1cnJlbnRUYXJnZXQpO1xuICAgICAgcHJldmlvdXNJbnN0YW5jZSA9IF9pbnN0YW5jZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJvY2Vzc0Rpc3BhdGNoUXVldWUoZGlzcGF0Y2hRdWV1ZSwgZXZlbnRTeXN0ZW1GbGFncykge1xuICB2YXIgaW5DYXB0dXJlUGhhc2UgPSAoZXZlbnRTeXN0ZW1GbGFncyAmIElTX0NBUFRVUkVfUEhBU0UpICE9PSAwO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGlzcGF0Y2hRdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIHZhciBfZGlzcGF0Y2hRdWV1ZSRpID0gZGlzcGF0Y2hRdWV1ZVtpXSxcbiAgICAgICAgZXZlbnQgPSBfZGlzcGF0Y2hRdWV1ZSRpLmV2ZW50LFxuICAgICAgICBsaXN0ZW5lcnMgPSBfZGlzcGF0Y2hRdWV1ZSRpLmxpc3RlbmVycztcbiAgICBwcm9jZXNzRGlzcGF0Y2hRdWV1ZUl0ZW1zSW5PcmRlcihldmVudCwgbGlzdGVuZXJzLCBpbkNhcHR1cmVQaGFzZSk7IC8vICBldmVudCBzeXN0ZW0gZG9lc24ndCB1c2UgcG9vbGluZy5cbiAgfSAvLyBUaGlzIHdvdWxkIGJlIGEgZ29vZCB0aW1lIHRvIHJldGhyb3cgaWYgYW55IG9mIHRoZSBldmVudCBoYW5kbGVycyB0aHJldy5cblxuXG4gIHJldGhyb3dDYXVnaHRFcnJvcigpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaEV2ZW50c0ZvclBsdWdpbnMoZG9tRXZlbnROYW1lLCBldmVudFN5c3RlbUZsYWdzLCBuYXRpdmVFdmVudCwgdGFyZ2V0SW5zdCwgdGFyZ2V0Q29udGFpbmVyKSB7XG4gIHZhciBuYXRpdmVFdmVudFRhcmdldCA9IGdldEV2ZW50VGFyZ2V0KG5hdGl2ZUV2ZW50KTtcbiAgdmFyIGRpc3BhdGNoUXVldWUgPSBbXTtcbiAgZXh0cmFjdEV2ZW50cyQ1KGRpc3BhdGNoUXVldWUsIGRvbUV2ZW50TmFtZSwgdGFyZ2V0SW5zdCwgbmF0aXZlRXZlbnQsIG5hdGl2ZUV2ZW50VGFyZ2V0LCBldmVudFN5c3RlbUZsYWdzKTtcbiAgcHJvY2Vzc0Rpc3BhdGNoUXVldWUoZGlzcGF0Y2hRdWV1ZSwgZXZlbnRTeXN0ZW1GbGFncyk7XG59XG5cbmZ1bmN0aW9uIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoZG9tRXZlbnROYW1lLCB0YXJnZXRFbGVtZW50KSB7XG4gIHtcbiAgICBpZiAoIW5vbkRlbGVnYXRlZEV2ZW50cy5oYXMoZG9tRXZlbnROYW1lKSkge1xuICAgICAgZXJyb3IoJ0RpZCBub3QgZXhwZWN0IGEgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgpIGNhbGwgZm9yIFwiJXNcIi4gJyArICdUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBkb21FdmVudE5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpc0NhcHR1cmVQaGFzZUxpc3RlbmVyID0gZmFsc2U7XG4gIHZhciBsaXN0ZW5lclNldCA9IGdldEV2ZW50TGlzdGVuZXJTZXQodGFyZ2V0RWxlbWVudCk7XG4gIHZhciBsaXN0ZW5lclNldEtleSA9IGdldExpc3RlbmVyU2V0S2V5KGRvbUV2ZW50TmFtZSwgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcik7XG5cbiAgaWYgKCFsaXN0ZW5lclNldC5oYXMobGlzdGVuZXJTZXRLZXkpKSB7XG4gICAgYWRkVHJhcHBlZEV2ZW50TGlzdGVuZXIodGFyZ2V0RWxlbWVudCwgZG9tRXZlbnROYW1lLCBJU19OT05fREVMRUdBVEVELCBpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKTtcbiAgICBsaXN0ZW5lclNldC5hZGQobGlzdGVuZXJTZXRLZXkpO1xuICB9XG59XG5mdW5jdGlvbiBsaXN0ZW5Ub05hdGl2ZUV2ZW50KGRvbUV2ZW50TmFtZSwgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lciwgdGFyZ2V0KSB7XG4gIHtcbiAgICBpZiAobm9uRGVsZWdhdGVkRXZlbnRzLmhhcyhkb21FdmVudE5hbWUpICYmICFpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKSB7XG4gICAgICBlcnJvcignRGlkIG5vdCBleHBlY3QgYSBsaXN0ZW5Ub05hdGl2ZUV2ZW50KCkgY2FsbCBmb3IgXCIlc1wiIGluIHRoZSBidWJibGUgcGhhc2UuICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZG9tRXZlbnROYW1lKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZXZlbnRTeXN0ZW1GbGFncyA9IDA7XG5cbiAgaWYgKGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIpIHtcbiAgICBldmVudFN5c3RlbUZsYWdzIHw9IElTX0NBUFRVUkVfUEhBU0U7XG4gIH1cblxuICBhZGRUcmFwcGVkRXZlbnRMaXN0ZW5lcih0YXJnZXQsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgaXNDYXB0dXJlUGhhc2VMaXN0ZW5lcik7XG59IC8vIFRoaXMgaXMgb25seSB1c2VkIGJ5IGNyZWF0ZUV2ZW50SGFuZGxlIHdoZW4gdGhlXG52YXIgbGlzdGVuaW5nTWFya2VyID0gJ19yZWFjdExpc3RlbmluZycgKyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtcbmZ1bmN0aW9uIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIGlmICghcm9vdENvbnRhaW5lckVsZW1lbnRbbGlzdGVuaW5nTWFya2VyXSkge1xuICAgIHJvb3RDb250YWluZXJFbGVtZW50W2xpc3RlbmluZ01hcmtlcl0gPSB0cnVlO1xuICAgIGFsbE5hdGl2ZUV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChkb21FdmVudE5hbWUpIHtcbiAgICAgIC8vIFdlIGhhbmRsZSBzZWxlY3Rpb25jaGFuZ2Ugc2VwYXJhdGVseSBiZWNhdXNlIGl0XG4gICAgICAvLyBkb2Vzbid0IGJ1YmJsZSBhbmQgbmVlZHMgdG8gYmUgb24gdGhlIGRvY3VtZW50LlxuICAgICAgaWYgKGRvbUV2ZW50TmFtZSAhPT0gJ3NlbGVjdGlvbmNoYW5nZScpIHtcbiAgICAgICAgaWYgKCFub25EZWxlZ2F0ZWRFdmVudHMuaGFzKGRvbUV2ZW50TmFtZSkpIHtcbiAgICAgICAgICBsaXN0ZW5Ub05hdGl2ZUV2ZW50KGRvbUV2ZW50TmFtZSwgZmFsc2UsIHJvb3RDb250YWluZXJFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxpc3RlblRvTmF0aXZlRXZlbnQoZG9tRXZlbnROYW1lLCB0cnVlLCByb290Q29udGFpbmVyRWxlbWVudCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdmFyIG93bmVyRG9jdW1lbnQgPSByb290Q29udGFpbmVyRWxlbWVudC5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSA/IHJvb3RDb250YWluZXJFbGVtZW50IDogcm9vdENvbnRhaW5lckVsZW1lbnQub3duZXJEb2N1bWVudDtcblxuICAgIGlmIChvd25lckRvY3VtZW50ICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGUgc2VsZWN0aW9uY2hhbmdlIGV2ZW50IGFsc28gbmVlZHMgZGVkdXBsaWNhdGlvblxuICAgICAgLy8gYnV0IGl0IGlzIGF0dGFjaGVkIHRvIHRoZSBkb2N1bWVudC5cbiAgICAgIGlmICghb3duZXJEb2N1bWVudFtsaXN0ZW5pbmdNYXJrZXJdKSB7XG4gICAgICAgIG93bmVyRG9jdW1lbnRbbGlzdGVuaW5nTWFya2VyXSA9IHRydWU7XG4gICAgICAgIGxpc3RlblRvTmF0aXZlRXZlbnQoJ3NlbGVjdGlvbmNoYW5nZScsIGZhbHNlLCBvd25lckRvY3VtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkVHJhcHBlZEV2ZW50TGlzdGVuZXIodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIGlzQ2FwdHVyZVBoYXNlTGlzdGVuZXIsIGlzRGVmZXJyZWRMaXN0ZW5lckZvckxlZ2FjeUZCU3VwcG9ydCkge1xuICB2YXIgbGlzdGVuZXIgPSBjcmVhdGVFdmVudExpc3RlbmVyV3JhcHBlcldpdGhQcmlvcml0eSh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncyk7IC8vIElmIHBhc3NpdmUgb3B0aW9uIGlzIG5vdCBzdXBwb3J0ZWQsIHRoZW4gdGhlIGV2ZW50IHdpbGwgYmVcbiAgLy8gYWN0aXZlIGFuZCBub3QgcGFzc2l2ZS5cblxuICB2YXIgaXNQYXNzaXZlTGlzdGVuZXIgPSB1bmRlZmluZWQ7XG5cbiAgaWYgKHBhc3NpdmVCcm93c2VyRXZlbnRzU3VwcG9ydGVkKSB7XG4gICAgLy8gQnJvd3NlcnMgaW50cm9kdWNlZCBhbiBpbnRlcnZlbnRpb24sIG1ha2luZyB0aGVzZSBldmVudHNcbiAgICAvLyBwYXNzaXZlIGJ5IGRlZmF1bHQgb24gZG9jdW1lbnQuIFJlYWN0IGRvZXNuJ3QgYmluZCB0aGVtXG4gICAgLy8gdG8gZG9jdW1lbnQgYW55bW9yZSwgYnV0IGNoYW5naW5nIHRoaXMgbm93IHdvdWxkIHVuZG9cbiAgICAvLyB0aGUgcGVyZm9ybWFuY2Ugd2lucyBmcm9tIHRoZSBjaGFuZ2UuIFNvIHdlIGVtdWxhdGVcbiAgICAvLyB0aGUgZXhpc3RpbmcgYmVoYXZpb3IgbWFudWFsbHkgb24gdGhlIHJvb3RzIG5vdy5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE5NjUxXG4gICAgaWYgKGRvbUV2ZW50TmFtZSA9PT0gJ3RvdWNoc3RhcnQnIHx8IGRvbUV2ZW50TmFtZSA9PT0gJ3RvdWNobW92ZScgfHwgZG9tRXZlbnROYW1lID09PSAnd2hlZWwnKSB7XG4gICAgICBpc1Bhc3NpdmVMaXN0ZW5lciA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgdGFyZ2V0Q29udGFpbmVyID0gIHRhcmdldENvbnRhaW5lcjtcbiAgdmFyIHVuc3Vic2NyaWJlTGlzdGVuZXI7IC8vIFdoZW4gbGVnYWN5RkJTdXBwb3J0IGlzIGVuYWJsZWQsIGl0J3MgZm9yIHdoZW4gd2VcblxuXG4gIGlmIChpc0NhcHR1cmVQaGFzZUxpc3RlbmVyKSB7XG4gICAgaWYgKGlzUGFzc2l2ZUxpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHVuc3Vic2NyaWJlTGlzdGVuZXIgPSBhZGRFdmVudENhcHR1cmVMaXN0ZW5lcldpdGhQYXNzaXZlRmxhZyh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgbGlzdGVuZXIsIGlzUGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5zdWJzY3JpYmVMaXN0ZW5lciA9IGFkZEV2ZW50Q2FwdHVyZUxpc3RlbmVyKHRhcmdldENvbnRhaW5lciwgZG9tRXZlbnROYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChpc1Bhc3NpdmVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB1bnN1YnNjcmliZUxpc3RlbmVyID0gYWRkRXZlbnRCdWJibGVMaXN0ZW5lcldpdGhQYXNzaXZlRmxhZyh0YXJnZXRDb250YWluZXIsIGRvbUV2ZW50TmFtZSwgbGlzdGVuZXIsIGlzUGFzc2l2ZUxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5zdWJzY3JpYmVMaXN0ZW5lciA9IGFkZEV2ZW50QnViYmxlTGlzdGVuZXIodGFyZ2V0Q29udGFpbmVyLCBkb21FdmVudE5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNNYXRjaGluZ1Jvb3RDb250YWluZXIoZ3JhbmRDb250YWluZXIsIHRhcmdldENvbnRhaW5lcikge1xuICByZXR1cm4gZ3JhbmRDb250YWluZXIgPT09IHRhcmdldENvbnRhaW5lciB8fCBncmFuZENvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFICYmIGdyYW5kQ29udGFpbmVyLnBhcmVudE5vZGUgPT09IHRhcmdldENvbnRhaW5lcjtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudEZvclBsdWdpbkV2ZW50U3lzdGVtKGRvbUV2ZW50TmFtZSwgZXZlbnRTeXN0ZW1GbGFncywgbmF0aXZlRXZlbnQsIHRhcmdldEluc3QsIHRhcmdldENvbnRhaW5lcikge1xuICB2YXIgYW5jZXN0b3JJbnN0ID0gdGFyZ2V0SW5zdDtcblxuICBpZiAoKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19FVkVOVF9IQU5ETEVfTk9OX01BTkFHRURfTk9ERSkgPT09IDAgJiYgKGV2ZW50U3lzdGVtRmxhZ3MgJiBJU19OT05fREVMRUdBVEVEKSA9PT0gMCkge1xuICAgIHZhciB0YXJnZXRDb250YWluZXJOb2RlID0gdGFyZ2V0Q29udGFpbmVyOyAvLyBJZiB3ZSBhcmUgdXNpbmcgdGhlIGxlZ2FjeSBGQiBzdXBwb3J0IGZsYWcsIHdlXG5cbiAgICBpZiAodGFyZ2V0SW5zdCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhlIGJlbG93IGxvZ2ljIGF0dGVtcHRzIHRvIHdvcmsgb3V0IGlmIHdlIG5lZWQgdG8gY2hhbmdlXG4gICAgICAvLyB0aGUgdGFyZ2V0IGZpYmVyIHRvIGEgZGlmZmVyZW50IGFuY2VzdG9yLiBXZSBoYWQgc2ltaWxhciBsb2dpY1xuICAgICAgLy8gaW4gdGhlIGxlZ2FjeSBldmVudCBzeXN0ZW0sIGV4Y2VwdCB0aGUgYmlnIGRpZmZlcmVuY2UgYmV0d2VlblxuICAgICAgLy8gc3lzdGVtcyBpcyB0aGF0IHRoZSBtb2Rlcm4gZXZlbnQgc3lzdGVtIG5vdyBoYXMgYW4gZXZlbnQgbGlzdGVuZXJcbiAgICAgIC8vIGF0dGFjaGVkIHRvIGVhY2ggUmVhY3QgUm9vdCBhbmQgUmVhY3QgUG9ydGFsIFJvb3QuIFRvZ2V0aGVyLFxuICAgICAgLy8gdGhlIERPTSBub2RlcyByZXByZXNlbnRpbmcgdGhlc2Ugcm9vdHMgYXJlIHRoZSBcInJvb3RDb250YWluZXJcIi5cbiAgICAgIC8vIFRvIGZpZ3VyZSBvdXQgd2hpY2ggYW5jZXN0b3IgaW5zdGFuY2Ugd2Ugc2hvdWxkIHVzZSwgd2UgdHJhdmVyc2VcbiAgICAgIC8vIHVwIHRoZSBmaWJlciB0cmVlIGZyb20gdGhlIHRhcmdldCBpbnN0YW5jZSBhbmQgYXR0ZW1wdCB0byBmaW5kXG4gICAgICAvLyByb290IGJvdW5kYXJpZXMgdGhhdCBtYXRjaCB0aGF0IG9mIG91ciBjdXJyZW50IFwicm9vdENvbnRhaW5lclwiLlxuICAgICAgLy8gSWYgd2UgZmluZCB0aGF0IFwicm9vdENvbnRhaW5lclwiLCB3ZSBmaW5kIHRoZSBwYXJlbnQgZmliZXJcbiAgICAgIC8vIHN1Yi10cmVlIGZvciB0aGF0IHJvb3QgYW5kIG1ha2UgdGhhdCBvdXIgYW5jZXN0b3IgaW5zdGFuY2UuXG4gICAgICB2YXIgbm9kZSA9IHRhcmdldEluc3Q7XG5cbiAgICAgIG1haW5Mb29wOiB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAobm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBub2RlVGFnID0gbm9kZS50YWc7XG5cbiAgICAgICAgaWYgKG5vZGVUYWcgPT09IEhvc3RSb290IHx8IG5vZGVUYWcgPT09IEhvc3RQb3J0YWwpIHtcbiAgICAgICAgICB2YXIgY29udGFpbmVyID0gbm9kZS5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcblxuICAgICAgICAgIGlmIChpc01hdGNoaW5nUm9vdENvbnRhaW5lcihjb250YWluZXIsIHRhcmdldENvbnRhaW5lck5vZGUpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobm9kZVRhZyA9PT0gSG9zdFBvcnRhbCkge1xuICAgICAgICAgICAgLy8gVGhlIHRhcmdldCBpcyBhIHBvcnRhbCwgYnV0IGl0J3Mgbm90IHRoZSByb290Q29udGFpbmVyIHdlJ3JlIGxvb2tpbmcgZm9yLlxuICAgICAgICAgICAgLy8gTm9ybWFsbHkgcG9ydGFscyBoYW5kbGUgdGhlaXIgb3duIGV2ZW50cyBhbGwgdGhlIHdheSBkb3duIHRvIHRoZSByb290LlxuICAgICAgICAgICAgLy8gU28gd2Ugc2hvdWxkIGJlIGFibGUgdG8gc3RvcCBub3cuIEhvd2V2ZXIsIHdlIGRvbid0IGtub3cgaWYgdGhpcyBwb3J0YWxcbiAgICAgICAgICAgIC8vIHdhcyBwYXJ0IG9mICpvdXIqIHJvb3QuXG4gICAgICAgICAgICB2YXIgZ3JhbmROb2RlID0gbm9kZS5yZXR1cm47XG5cbiAgICAgICAgICAgIHdoaWxlIChncmFuZE5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIGdyYW5kVGFnID0gZ3JhbmROb2RlLnRhZztcblxuICAgICAgICAgICAgICBpZiAoZ3JhbmRUYWcgPT09IEhvc3RSb290IHx8IGdyYW5kVGFnID09PSBIb3N0UG9ydGFsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGdyYW5kQ29udGFpbmVyID0gZ3JhbmROb2RlLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlzTWF0Y2hpbmdSb290Q29udGFpbmVyKGdyYW5kQ29udGFpbmVyLCB0YXJnZXRDb250YWluZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgcm9vdENvbnRhaW5lciB3ZSdyZSBsb29raW5nIGZvciBhbmQgd2UgZm91bmQgaXQgYXNcbiAgICAgICAgICAgICAgICAgIC8vIGEgcGFyZW50IG9mIHRoZSBQb3J0YWwuIFRoYXQgbWVhbnMgd2UgY2FuIGlnbm9yZSBpdCBiZWNhdXNlIHRoZVxuICAgICAgICAgICAgICAgICAgLy8gUG9ydGFsIHdpbGwgYnViYmxlIHRocm91Z2ggdG8gdXMuXG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgZ3JhbmROb2RlID0gZ3JhbmROb2RlLnJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IC8vIE5vdyB3ZSBuZWVkIHRvIGZpbmQgaXQncyBjb3JyZXNwb25kaW5nIGhvc3QgZmliZXIgaW4gdGhlIG90aGVyXG4gICAgICAgICAgLy8gdHJlZS4gVG8gZG8gdGhpcyB3ZSBjYW4gdXNlIGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlLCBidXQgd2VcbiAgICAgICAgICAvLyBuZWVkIHRvIHZhbGlkYXRlIHRoYXQgdGhlIGZpYmVyIGlzIGEgaG9zdCBpbnN0YW5jZSwgb3RoZXJ3aXNlXG4gICAgICAgICAgLy8gd2UgbmVlZCB0byB0cmF2ZXJzZSB1cCB0aHJvdWdoIHRoZSBET00gdGlsbCB3ZSBmaW5kIHRoZSBjb3JyZWN0XG4gICAgICAgICAgLy8gbm9kZSB0aGF0IGlzIGZyb20gdGhlIG90aGVyIHRyZWUuXG5cblxuICAgICAgICAgIHdoaWxlIChjb250YWluZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBwYXJlbnROb2RlID0gZ2V0Q2xvc2VzdEluc3RhbmNlRnJvbU5vZGUoY29udGFpbmVyKTtcblxuICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFyZW50VGFnID0gcGFyZW50Tm9kZS50YWc7XG5cbiAgICAgICAgICAgIGlmIChwYXJlbnRUYWcgPT09IEhvc3RDb21wb25lbnQgfHwgcGFyZW50VGFnID09PSBIb3N0VGV4dCkge1xuICAgICAgICAgICAgICBub2RlID0gYW5jZXN0b3JJbnN0ID0gcGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgY29udGludWUgbWFpbkxvb3A7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRhaW5lciA9IGNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBiYXRjaGVkVXBkYXRlcyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGRpc3BhdGNoRXZlbnRzRm9yUGx1Z2lucyhkb21FdmVudE5hbWUsIGV2ZW50U3lzdGVtRmxhZ3MsIG5hdGl2ZUV2ZW50LCBhbmNlc3Rvckluc3QpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGlzcGF0Y2hMaXN0ZW5lcihpbnN0YW5jZSwgbGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpIHtcbiAgcmV0dXJuIHtcbiAgICBpbnN0YW5jZTogaW5zdGFuY2UsXG4gICAgbGlzdGVuZXI6IGxpc3RlbmVyLFxuICAgIGN1cnJlbnRUYXJnZXQ6IGN1cnJlbnRUYXJnZXRcbiAgfTtcbn1cblxuZnVuY3Rpb24gYWNjdW11bGF0ZVNpbmdsZVBoYXNlTGlzdGVuZXJzKHRhcmdldEZpYmVyLCByZWFjdE5hbWUsIG5hdGl2ZUV2ZW50VHlwZSwgaW5DYXB0dXJlUGhhc2UsIGFjY3VtdWxhdGVUYXJnZXRPbmx5LCBuYXRpdmVFdmVudCkge1xuICB2YXIgY2FwdHVyZU5hbWUgPSByZWFjdE5hbWUgIT09IG51bGwgPyByZWFjdE5hbWUgKyAnQ2FwdHVyZScgOiBudWxsO1xuICB2YXIgcmVhY3RFdmVudE5hbWUgPSBpbkNhcHR1cmVQaGFzZSA/IGNhcHR1cmVOYW1lIDogcmVhY3ROYW1lO1xuICB2YXIgbGlzdGVuZXJzID0gW107XG4gIHZhciBpbnN0YW5jZSA9IHRhcmdldEZpYmVyO1xuICB2YXIgbGFzdEhvc3RDb21wb25lbnQgPSBudWxsOyAvLyBBY2N1bXVsYXRlIGFsbCBpbnN0YW5jZXMgYW5kIGxpc3RlbmVycyB2aWEgdGhlIHRhcmdldCAtPiByb290IHBhdGguXG5cbiAgd2hpbGUgKGluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgdmFyIF9pbnN0YW5jZTIgPSBpbnN0YW5jZSxcbiAgICAgICAgc3RhdGVOb2RlID0gX2luc3RhbmNlMi5zdGF0ZU5vZGUsXG4gICAgICAgIHRhZyA9IF9pbnN0YW5jZTIudGFnOyAvLyBIYW5kbGUgbGlzdGVuZXJzIHRoYXQgYXJlIG9uIEhvc3RDb21wb25lbnRzIChpLmUuIDxkaXY+KVxuXG4gICAgaWYgKHRhZyA9PT0gSG9zdENvbXBvbmVudCAmJiBzdGF0ZU5vZGUgIT09IG51bGwpIHtcbiAgICAgIGxhc3RIb3N0Q29tcG9uZW50ID0gc3RhdGVOb2RlOyAvLyBjcmVhdGVFdmVudEhhbmRsZSBsaXN0ZW5lcnNcblxuXG4gICAgICBpZiAocmVhY3RFdmVudE5hbWUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVyID0gZ2V0TGlzdGVuZXIoaW5zdGFuY2UsIHJlYWN0RXZlbnROYW1lKTtcblxuICAgICAgICBpZiAobGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGxpc3RlbmVyLCBsYXN0SG9zdENvbXBvbmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSAvLyBJZiB3ZSBhcmUgb25seSBhY2N1bXVsYXRpbmcgZXZlbnRzIGZvciB0aGUgdGFyZ2V0LCB0aGVuIHdlIGRvbid0XG4gICAgLy8gY29udGludWUgdG8gcHJvcGFnYXRlIHRocm91Z2ggdGhlIFJlYWN0IGZpYmVyIHRyZWUgdG8gZmluZCBvdGhlclxuICAgIC8vIGxpc3RlbmVycy5cblxuXG4gICAgaWYgKGFjY3VtdWxhdGVUYXJnZXRPbmx5KSB7XG4gICAgICBicmVhaztcbiAgICB9IC8vIElmIHdlIGFyZSBwcm9jZXNzaW5nIHRoZSBvbkJlZm9yZUJsdXIgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byB0YWtlXG5cbiAgICBpbnN0YW5jZSA9IGluc3RhbmNlLnJldHVybjtcbiAgfVxuXG4gIHJldHVybiBsaXN0ZW5lcnM7XG59IC8vIFdlIHNob3VsZCBvbmx5IHVzZSB0aGlzIGZ1bmN0aW9uIGZvcjpcbi8vIC0gQmVmb3JlSW5wdXRFdmVudFBsdWdpblxuLy8gLSBDaGFuZ2VFdmVudFBsdWdpblxuLy8gLSBTZWxlY3RFdmVudFBsdWdpblxuLy8gVGhpcyBpcyBiZWNhdXNlIHdlIG9ubHkgcHJvY2VzcyB0aGVzZSBwbHVnaW5zXG4vLyBpbiB0aGUgYnViYmxlIHBoYXNlLCBzbyB3ZSBuZWVkIHRvIGFjY3VtdWxhdGUgdHdvXG4vLyBwaGFzZSBldmVudCBsaXN0ZW5lcnMgKHZpYSBlbXVsYXRpb24pLlxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlVHdvUGhhc2VMaXN0ZW5lcnModGFyZ2V0RmliZXIsIHJlYWN0TmFtZSkge1xuICB2YXIgY2FwdHVyZU5hbWUgPSByZWFjdE5hbWUgKyAnQ2FwdHVyZSc7XG4gIHZhciBsaXN0ZW5lcnMgPSBbXTtcbiAgdmFyIGluc3RhbmNlID0gdGFyZ2V0RmliZXI7IC8vIEFjY3VtdWxhdGUgYWxsIGluc3RhbmNlcyBhbmQgbGlzdGVuZXJzIHZpYSB0aGUgdGFyZ2V0IC0+IHJvb3QgcGF0aC5cblxuICB3aGlsZSAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICB2YXIgX2luc3RhbmNlMyA9IGluc3RhbmNlLFxuICAgICAgICBzdGF0ZU5vZGUgPSBfaW5zdGFuY2UzLnN0YXRlTm9kZSxcbiAgICAgICAgdGFnID0gX2luc3RhbmNlMy50YWc7IC8vIEhhbmRsZSBsaXN0ZW5lcnMgdGhhdCBhcmUgb24gSG9zdENvbXBvbmVudHMgKGkuZS4gPGRpdj4pXG5cbiAgICBpZiAodGFnID09PSBIb3N0Q29tcG9uZW50ICYmIHN0YXRlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIGN1cnJlbnRUYXJnZXQgPSBzdGF0ZU5vZGU7XG4gICAgICB2YXIgY2FwdHVyZUxpc3RlbmVyID0gZ2V0TGlzdGVuZXIoaW5zdGFuY2UsIGNhcHR1cmVOYW1lKTtcblxuICAgICAgaWYgKGNhcHR1cmVMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgIGxpc3RlbmVycy51bnNoaWZ0KGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGNhcHR1cmVMaXN0ZW5lciwgY3VycmVudFRhcmdldCkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgYnViYmxlTGlzdGVuZXIgPSBnZXRMaXN0ZW5lcihpbnN0YW5jZSwgcmVhY3ROYW1lKTtcblxuICAgICAgaWYgKGJ1YmJsZUxpc3RlbmVyICE9IG51bGwpIHtcbiAgICAgICAgbGlzdGVuZXJzLnB1c2goY3JlYXRlRGlzcGF0Y2hMaXN0ZW5lcihpbnN0YW5jZSwgYnViYmxlTGlzdGVuZXIsIGN1cnJlbnRUYXJnZXQpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnN0YW5jZSA9IGluc3RhbmNlLnJldHVybjtcbiAgfVxuXG4gIHJldHVybiBsaXN0ZW5lcnM7XG59XG5cbmZ1bmN0aW9uIGdldFBhcmVudChpbnN0KSB7XG4gIGlmIChpbnN0ID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkbyB7XG4gICAgaW5zdCA9IGluc3QucmV0dXJuOyAvLyBUT0RPOiBJZiB0aGlzIGlzIGEgSG9zdFJvb3Qgd2UgbWlnaHQgd2FudCB0byBiYWlsIG91dC5cbiAgICAvLyBUaGF0IGlzIGRlcGVuZGluZyBvbiBpZiB3ZSB3YW50IG5lc3RlZCBzdWJ0cmVlcyAobGF5ZXJzKSB0byBidWJibGVcbiAgICAvLyBldmVudHMgdG8gdGhlaXIgcGFyZW50LiBXZSBjb3VsZCBhbHNvIGdvIHRocm91Z2ggcGFyZW50Tm9kZSBvbiB0aGVcbiAgICAvLyBob3N0IG5vZGUgYnV0IHRoYXQgd291bGRuJ3Qgd29yayBmb3IgUmVhY3QgTmF0aXZlIGFuZCBkb2Vzbid0IGxldCB1c1xuICAgIC8vIGRvIHRoZSBwb3J0YWwgZmVhdHVyZS5cbiAgfSB3aGlsZSAoaW5zdCAmJiBpbnN0LnRhZyAhPT0gSG9zdENvbXBvbmVudCk7XG5cbiAgaWYgKGluc3QpIHtcbiAgICByZXR1cm4gaW5zdDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuLyoqXG4gKiBSZXR1cm4gdGhlIGxvd2VzdCBjb21tb24gYW5jZXN0b3Igb2YgQSBhbmQgQiwgb3IgbnVsbCBpZiB0aGV5IGFyZSBpblxuICogZGlmZmVyZW50IHRyZWVzLlxuICovXG5cblxuZnVuY3Rpb24gZ2V0TG93ZXN0Q29tbW9uQW5jZXN0b3IoaW5zdEEsIGluc3RCKSB7XG4gIHZhciBub2RlQSA9IGluc3RBO1xuICB2YXIgbm9kZUIgPSBpbnN0QjtcbiAgdmFyIGRlcHRoQSA9IDA7XG5cbiAgZm9yICh2YXIgdGVtcEEgPSBub2RlQTsgdGVtcEE7IHRlbXBBID0gZ2V0UGFyZW50KHRlbXBBKSkge1xuICAgIGRlcHRoQSsrO1xuICB9XG5cbiAgdmFyIGRlcHRoQiA9IDA7XG5cbiAgZm9yICh2YXIgdGVtcEIgPSBub2RlQjsgdGVtcEI7IHRlbXBCID0gZ2V0UGFyZW50KHRlbXBCKSkge1xuICAgIGRlcHRoQisrO1xuICB9IC8vIElmIEEgaXMgZGVlcGVyLCBjcmF3bCB1cC5cblxuXG4gIHdoaWxlIChkZXB0aEEgLSBkZXB0aEIgPiAwKSB7XG4gICAgbm9kZUEgPSBnZXRQYXJlbnQobm9kZUEpO1xuICAgIGRlcHRoQS0tO1xuICB9IC8vIElmIEIgaXMgZGVlcGVyLCBjcmF3bCB1cC5cblxuXG4gIHdoaWxlIChkZXB0aEIgLSBkZXB0aEEgPiAwKSB7XG4gICAgbm9kZUIgPSBnZXRQYXJlbnQobm9kZUIpO1xuICAgIGRlcHRoQi0tO1xuICB9IC8vIFdhbGsgaW4gbG9ja3N0ZXAgdW50aWwgd2UgZmluZCBhIG1hdGNoLlxuXG5cbiAgdmFyIGRlcHRoID0gZGVwdGhBO1xuXG4gIHdoaWxlIChkZXB0aC0tKSB7XG4gICAgaWYgKG5vZGVBID09PSBub2RlQiB8fCBub2RlQiAhPT0gbnVsbCAmJiBub2RlQSA9PT0gbm9kZUIuYWx0ZXJuYXRlKSB7XG4gICAgICByZXR1cm4gbm9kZUE7XG4gICAgfVxuXG4gICAgbm9kZUEgPSBnZXRQYXJlbnQobm9kZUEpO1xuICAgIG5vZGVCID0gZ2V0UGFyZW50KG5vZGVCKTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlRW50ZXJMZWF2ZUxpc3RlbmVyc0ZvckV2ZW50KGRpc3BhdGNoUXVldWUsIGV2ZW50LCB0YXJnZXQsIGNvbW1vbiwgaW5DYXB0dXJlUGhhc2UpIHtcbiAgdmFyIHJlZ2lzdHJhdGlvbk5hbWUgPSBldmVudC5fcmVhY3ROYW1lO1xuICB2YXIgbGlzdGVuZXJzID0gW107XG4gIHZhciBpbnN0YW5jZSA9IHRhcmdldDtcblxuICB3aGlsZSAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICBpZiAoaW5zdGFuY2UgPT09IGNvbW1vbikge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdmFyIF9pbnN0YW5jZTQgPSBpbnN0YW5jZSxcbiAgICAgICAgYWx0ZXJuYXRlID0gX2luc3RhbmNlNC5hbHRlcm5hdGUsXG4gICAgICAgIHN0YXRlTm9kZSA9IF9pbnN0YW5jZTQuc3RhdGVOb2RlLFxuICAgICAgICB0YWcgPSBfaW5zdGFuY2U0LnRhZztcblxuICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwgJiYgYWx0ZXJuYXRlID09PSBjb21tb24pIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICh0YWcgPT09IEhvc3RDb21wb25lbnQgJiYgc3RhdGVOb2RlICE9PSBudWxsKSB7XG4gICAgICB2YXIgY3VycmVudFRhcmdldCA9IHN0YXRlTm9kZTtcblxuICAgICAgaWYgKGluQ2FwdHVyZVBoYXNlKSB7XG4gICAgICAgIHZhciBjYXB0dXJlTGlzdGVuZXIgPSBnZXRMaXN0ZW5lcihpbnN0YW5jZSwgcmVnaXN0cmF0aW9uTmFtZSk7XG5cbiAgICAgICAgaWYgKGNhcHR1cmVMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgICAgbGlzdGVuZXJzLnVuc2hpZnQoY3JlYXRlRGlzcGF0Y2hMaXN0ZW5lcihpbnN0YW5jZSwgY2FwdHVyZUxpc3RlbmVyLCBjdXJyZW50VGFyZ2V0KSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIWluQ2FwdHVyZVBoYXNlKSB7XG4gICAgICAgIHZhciBidWJibGVMaXN0ZW5lciA9IGdldExpc3RlbmVyKGluc3RhbmNlLCByZWdpc3RyYXRpb25OYW1lKTtcblxuICAgICAgICBpZiAoYnViYmxlTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgIGxpc3RlbmVycy5wdXNoKGNyZWF0ZURpc3BhdGNoTGlzdGVuZXIoaW5zdGFuY2UsIGJ1YmJsZUxpc3RlbmVyLCBjdXJyZW50VGFyZ2V0KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbnN0YW5jZSA9IGluc3RhbmNlLnJldHVybjtcbiAgfVxuXG4gIGlmIChsaXN0ZW5lcnMubGVuZ3RoICE9PSAwKSB7XG4gICAgZGlzcGF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgIGV2ZW50OiBldmVudCxcbiAgICAgIGxpc3RlbmVyczogbGlzdGVuZXJzXG4gICAgfSk7XG4gIH1cbn0gLy8gV2Ugc2hvdWxkIG9ubHkgdXNlIHRoaXMgZnVuY3Rpb24gZm9yOlxuLy8gLSBFbnRlckxlYXZlRXZlbnRQbHVnaW5cbi8vIFRoaXMgaXMgYmVjYXVzZSB3ZSBvbmx5IHByb2Nlc3MgdGhpcyBwbHVnaW5cbi8vIGluIHRoZSBidWJibGUgcGhhc2UsIHNvIHdlIG5lZWQgdG8gYWNjdW11bGF0ZSB0d29cbi8vIHBoYXNlIGV2ZW50IGxpc3RlbmVycy5cblxuXG5mdW5jdGlvbiBhY2N1bXVsYXRlRW50ZXJMZWF2ZVR3b1BoYXNlTGlzdGVuZXJzKGRpc3BhdGNoUXVldWUsIGxlYXZlRXZlbnQsIGVudGVyRXZlbnQsIGZyb20sIHRvKSB7XG4gIHZhciBjb21tb24gPSBmcm9tICYmIHRvID8gZ2V0TG93ZXN0Q29tbW9uQW5jZXN0b3IoZnJvbSwgdG8pIDogbnVsbDtcblxuICBpZiAoZnJvbSAhPT0gbnVsbCkge1xuICAgIGFjY3VtdWxhdGVFbnRlckxlYXZlTGlzdGVuZXJzRm9yRXZlbnQoZGlzcGF0Y2hRdWV1ZSwgbGVhdmVFdmVudCwgZnJvbSwgY29tbW9uLCBmYWxzZSk7XG4gIH1cblxuICBpZiAodG8gIT09IG51bGwgJiYgZW50ZXJFdmVudCAhPT0gbnVsbCkge1xuICAgIGFjY3VtdWxhdGVFbnRlckxlYXZlTGlzdGVuZXJzRm9yRXZlbnQoZGlzcGF0Y2hRdWV1ZSwgZW50ZXJFdmVudCwgdG8sIGNvbW1vbiwgdHJ1ZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGdldExpc3RlbmVyU2V0S2V5KGRvbUV2ZW50TmFtZSwgY2FwdHVyZSkge1xuICByZXR1cm4gZG9tRXZlbnROYW1lICsgXCJfX1wiICsgKGNhcHR1cmUgPyAnY2FwdHVyZScgOiAnYnViYmxlJyk7XG59XG5cbnZhciBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IGZhbHNlO1xudmFyIERBTkdFUk9VU0xZX1NFVF9JTk5FUl9IVE1MID0gJ2Rhbmdlcm91c2x5U2V0SW5uZXJIVE1MJztcbnZhciBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgPSAnc3VwcHJlc3NDb250ZW50RWRpdGFibGVXYXJuaW5nJztcbnZhciBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyA9ICdzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcnO1xudmFyIEFVVE9GT0NVUyA9ICdhdXRvRm9jdXMnO1xudmFyIENISUxEUkVOID0gJ2NoaWxkcmVuJztcbnZhciBTVFlMRSA9ICdzdHlsZSc7XG52YXIgSFRNTCQxID0gJ19faHRtbCc7XG52YXIgd2FybmVkVW5rbm93blRhZ3M7XG52YXIgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudDtcbnZhciB3YXJuRm9yUHJvcERpZmZlcmVuY2U7XG52YXIgd2FybkZvckV4dHJhQXR0cmlidXRlcztcbnZhciB3YXJuRm9ySW52YWxpZEV2ZW50TGlzdGVuZXI7XG52YXIgY2FuRGlmZlN0eWxlRm9ySHlkcmF0aW9uV2FybmluZztcbnZhciBub3JtYWxpemVIVE1MO1xuXG57XG4gIHdhcm5lZFVua25vd25UYWdzID0ge1xuICAgIC8vIFRoZXJlIGFyZSB3b3JraW5nIHBvbHlmaWxscyBmb3IgPGRpYWxvZz4uIExldCBwZW9wbGUgdXNlIGl0LlxuICAgIGRpYWxvZzogdHJ1ZSxcbiAgICAvLyBFbGVjdHJvbiBzaGlwcyBhIGN1c3RvbSA8d2Vidmlldz4gdGFnIHRvIGRpc3BsYXkgZXh0ZXJuYWwgd2ViIGNvbnRlbnQgaW5cbiAgICAvLyBhbiBpc29sYXRlZCBmcmFtZSBhbmQgcHJvY2Vzcy5cbiAgICAvLyBUaGlzIHRhZyBpcyBub3QgcHJlc2VudCBpbiBub24gRWxlY3Ryb24gZW52aXJvbm1lbnRzIHN1Y2ggYXMgSlNEb20gd2hpY2hcbiAgICAvLyBpcyBvZnRlbiB1c2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzLlxuICAgIC8vIEBzZWUgaHR0cHM6Ly9lbGVjdHJvbmpzLm9yZy9kb2NzL2FwaS93ZWJ2aWV3LXRhZ1xuICAgIHdlYnZpZXc6IHRydWVcbiAgfTtcblxuICB2YWxpZGF0ZVByb3BlcnRpZXNJbkRldmVsb3BtZW50ID0gZnVuY3Rpb24gKHR5cGUsIHByb3BzKSB7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzKHR5cGUsIHByb3BzKTtcbiAgICB2YWxpZGF0ZVByb3BlcnRpZXMkMSh0eXBlLCBwcm9wcyk7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzJDIodHlwZSwgcHJvcHMsIHtcbiAgICAgIHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXM6IHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMsXG4gICAgICBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzOiBwb3NzaWJsZVJlZ2lzdHJhdGlvbk5hbWVzXG4gICAgfSk7XG4gIH07IC8vIElFIDExIHBhcnNlcyAmIG5vcm1hbGl6ZXMgdGhlIHN0eWxlIGF0dHJpYnV0ZSBhcyBvcHBvc2VkIHRvIG90aGVyXG4gIC8vIGJyb3dzZXJzLiBJdCBhZGRzIHNwYWNlcyBhbmQgc29ydHMgdGhlIHByb3BlcnRpZXMgaW4gc29tZVxuICAvLyBub24tYWxwaGFiZXRpY2FsIG9yZGVyLiBIYW5kbGluZyB0aGF0IHdvdWxkIHJlcXVpcmUgc29ydGluZyBDU1NcbiAgLy8gcHJvcGVydGllcyBpbiB0aGUgY2xpZW50ICYgc2VydmVyIHZlcnNpb25zIG9yIGFwcGx5aW5nXG4gIC8vIGBleHBlY3RlZFN0eWxlYCB0byBhIHRlbXBvcmFyeSBET00gbm9kZSB0byByZWFkIGl0cyBgc3R5bGVgIGF0dHJpYnV0ZVxuICAvLyBub3JtYWxpemVkLiBTaW5jZSBpdCBvbmx5IGFmZmVjdHMgSUUsIHdlJ3JlIHNraXBwaW5nIHN0eWxlIHdhcm5pbmdzXG4gIC8vIGluIHRoYXQgYnJvd3NlciBjb21wbGV0ZWx5IGluIGZhdm9yIG9mIGRvaW5nIGFsbCB0aGF0IHdvcmsuXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzExODA3XG5cblxuICBjYW5EaWZmU3R5bGVGb3JIeWRyYXRpb25XYXJuaW5nID0gY2FuVXNlRE9NICYmICFkb2N1bWVudC5kb2N1bWVudE1vZGU7XG5cbiAgd2FybkZvclByb3BEaWZmZXJlbmNlID0gZnVuY3Rpb24gKHByb3BOYW1lLCBzZXJ2ZXJWYWx1ZSwgY2xpZW50VmFsdWUpIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbm9ybWFsaXplZENsaWVudFZhbHVlID0gbm9ybWFsaXplTWFya3VwRm9yVGV4dE9yQXR0cmlidXRlKGNsaWVudFZhbHVlKTtcbiAgICB2YXIgbm9ybWFsaXplZFNlcnZlclZhbHVlID0gbm9ybWFsaXplTWFya3VwRm9yVGV4dE9yQXR0cmlidXRlKHNlcnZlclZhbHVlKTtcblxuICAgIGlmIChub3JtYWxpemVkU2VydmVyVmFsdWUgPT09IG5vcm1hbGl6ZWRDbGllbnRWYWx1ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgIGVycm9yKCdQcm9wIGAlc2AgZGlkIG5vdCBtYXRjaC4gU2VydmVyOiAlcyBDbGllbnQ6ICVzJywgcHJvcE5hbWUsIEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWRTZXJ2ZXJWYWx1ZSksIEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWRDbGllbnRWYWx1ZSkpO1xuICB9O1xuXG4gIHdhcm5Gb3JFeHRyYUF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoYXR0cmlidXRlTmFtZXMpIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgYXR0cmlidXRlTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgICAgbmFtZXMucHVzaChuYW1lKTtcbiAgICB9KTtcblxuICAgIGVycm9yKCdFeHRyYSBhdHRyaWJ1dGVzIGZyb20gdGhlIHNlcnZlcjogJXMnLCBuYW1lcyk7XG4gIH07XG5cbiAgd2FybkZvckludmFsaWRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHJlZ2lzdHJhdGlvbk5hbWUsIGxpc3RlbmVyKSB7XG4gICAgaWYgKGxpc3RlbmVyID09PSBmYWxzZSkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIGAlc2AgbGlzdGVuZXIgdG8gYmUgYSBmdW5jdGlvbiwgaW5zdGVhZCBnb3QgYGZhbHNlYC5cXG5cXG4nICsgJ0lmIHlvdSB1c2VkIHRvIGNvbmRpdGlvbmFsbHkgb21pdCBpdCB3aXRoICVzPXtjb25kaXRpb24gJiYgdmFsdWV9LCAnICsgJ3Bhc3MgJXM9e2NvbmRpdGlvbiA/IHZhbHVlIDogdW5kZWZpbmVkfSBpbnN0ZWFkLicsIHJlZ2lzdHJhdGlvbk5hbWUsIHJlZ2lzdHJhdGlvbk5hbWUsIHJlZ2lzdHJhdGlvbk5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJvcignRXhwZWN0ZWQgYCVzYCBsaXN0ZW5lciB0byBiZSBhIGZ1bmN0aW9uLCBpbnN0ZWFkIGdvdCBhIHZhbHVlIG9mIGAlc2AgdHlwZS4nLCByZWdpc3RyYXRpb25OYW1lLCB0eXBlb2YgbGlzdGVuZXIpO1xuICAgIH1cbiAgfTsgLy8gUGFyc2UgdGhlIEhUTUwgYW5kIHJlYWQgaXQgYmFjayB0byBub3JtYWxpemUgdGhlIEhUTUwgc3RyaW5nIHNvIHRoYXQgaXRcbiAgLy8gY2FuIGJlIHVzZWQgZm9yIGNvbXBhcmlzb24uXG5cblxuICBub3JtYWxpemVIVE1MID0gZnVuY3Rpb24gKHBhcmVudCwgaHRtbCkge1xuICAgIC8vIFdlIGNvdWxkIGhhdmUgY3JlYXRlZCBhIHNlcGFyYXRlIGRvY3VtZW50IGhlcmUgdG8gYXZvaWRcbiAgICAvLyByZS1pbml0aWFsaXppbmcgY3VzdG9tIGVsZW1lbnRzIGlmIHRoZXkgZXhpc3QuIEJ1dCB0aGlzIGJyZWFrc1xuICAgIC8vIGhvdyA8bm9zY3JpcHQ+IGlzIGJlaW5nIGhhbmRsZWQuIFNvIHdlIHVzZSB0aGUgc2FtZSBkb2N1bWVudC5cbiAgICAvLyBTZWUgdGhlIGRpc2N1c3Npb24gaW4gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L3B1bGwvMTExNTcuXG4gICAgdmFyIHRlc3RFbGVtZW50ID0gcGFyZW50Lm5hbWVzcGFjZVVSSSA9PT0gSFRNTF9OQU1FU1BBQ0UgPyBwYXJlbnQub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KHBhcmVudC50YWdOYW1lKSA6IHBhcmVudC5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhwYXJlbnQubmFtZXNwYWNlVVJJLCBwYXJlbnQudGFnTmFtZSk7XG4gICAgdGVzdEVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICByZXR1cm4gdGVzdEVsZW1lbnQuaW5uZXJIVE1MO1xuICB9O1xufSAvLyBIVE1MIHBhcnNpbmcgbm9ybWFsaXplcyBDUiBhbmQgQ1JMRiB0byBMRi5cbi8vIEl0IGFsc28gY2FuIHR1cm4gXFx1MDAwMCBpbnRvIFxcdUZGRkQgaW5zaWRlIGF0dHJpYnV0ZXMuXG4vLyBodHRwczovL3d3dy53My5vcmcvVFIvaHRtbDUvc2luZ2xlLXBhZ2UuaHRtbCNwcmVwcm9jZXNzaW5nLXRoZS1pbnB1dC1zdHJlYW1cbi8vIElmIHdlIGhhdmUgYSBtaXNtYXRjaCwgaXQgbWlnaHQgYmUgY2F1c2VkIGJ5IHRoYXQuXG4vLyBXZSB3aWxsIHN0aWxsIHBhdGNoIHVwIGluIHRoaXMgY2FzZSBidXQgbm90IGZpcmUgdGhlIHdhcm5pbmcuXG5cblxudmFyIE5PUk1BTElaRV9ORVdMSU5FU19SRUdFWCA9IC9cXHJcXG4/L2c7XG52YXIgTk9STUFMSVpFX05VTExfQU5EX1JFUExBQ0VNRU5UX1JFR0VYID0gL1xcdTAwMDB8XFx1RkZGRC9nO1xuXG5mdW5jdGlvbiBub3JtYWxpemVNYXJrdXBGb3JUZXh0T3JBdHRyaWJ1dGUobWFya3VwKSB7XG4gIHtcbiAgICBjaGVja0h0bWxTdHJpbmdDb2VyY2lvbihtYXJrdXApO1xuICB9XG5cbiAgdmFyIG1hcmt1cFN0cmluZyA9IHR5cGVvZiBtYXJrdXAgPT09ICdzdHJpbmcnID8gbWFya3VwIDogJycgKyBtYXJrdXA7XG4gIHJldHVybiBtYXJrdXBTdHJpbmcucmVwbGFjZShOT1JNQUxJWkVfTkVXTElORVNfUkVHRVgsICdcXG4nKS5yZXBsYWNlKE5PUk1BTElaRV9OVUxMX0FORF9SRVBMQUNFTUVOVF9SRUdFWCwgJycpO1xufVxuXG5mdW5jdGlvbiBjaGVja0ZvclVubWF0Y2hlZFRleHQoc2VydmVyVGV4dCwgY2xpZW50VGV4dCwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldikge1xuICB2YXIgbm9ybWFsaXplZENsaWVudFRleHQgPSBub3JtYWxpemVNYXJrdXBGb3JUZXh0T3JBdHRyaWJ1dGUoY2xpZW50VGV4dCk7XG4gIHZhciBub3JtYWxpemVkU2VydmVyVGV4dCA9IG5vcm1hbGl6ZU1hcmt1cEZvclRleHRPckF0dHJpYnV0ZShzZXJ2ZXJUZXh0KTtcblxuICBpZiAobm9ybWFsaXplZFNlcnZlclRleHQgPT09IG5vcm1hbGl6ZWRDbGllbnRUZXh0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHNob3VsZFdhcm5EZXYpIHtcbiAgICB7XG4gICAgICBpZiAoIWRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgICAgICBlcnJvcignVGV4dCBjb250ZW50IGRpZCBub3QgbWF0Y2guIFNlcnZlcjogXCIlc1wiIENsaWVudDogXCIlc1wiJywgbm9ybWFsaXplZFNlcnZlclRleHQsIG5vcm1hbGl6ZWRDbGllbnRUZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoaXNDb25jdXJyZW50TW9kZSAmJiBlbmFibGVDbGllbnRSZW5kZXJGYWxsYmFja09uVGV4dE1pc21hdGNoKSB7XG4gICAgLy8gSW4gY29uY3VycmVudCByb290cywgd2UgdGhyb3cgd2hlbiB0aGVyZSdzIGEgdGV4dCBtaXNtYXRjaCBhbmQgcmV2ZXJ0IHRvXG4gICAgLy8gY2xpZW50IHJlbmRlcmluZywgdXAgdG8gdGhlIG5lYXJlc3QgU3VzcGVuc2UgYm91bmRhcnkuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdUZXh0IGNvbnRlbnQgZG9lcyBub3QgbWF0Y2ggc2VydmVyLXJlbmRlcmVkIEhUTUwuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0T3duZXJEb2N1bWVudEZyb21Sb290Q29udGFpbmVyKHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIHJldHVybiByb290Q29udGFpbmVyRWxlbWVudC5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSA/IHJvb3RDb250YWluZXJFbGVtZW50IDogcm9vdENvbnRhaW5lckVsZW1lbnQub3duZXJEb2N1bWVudDtcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbmZ1bmN0aW9uIHRyYXBDbGlja09uTm9uSW50ZXJhY3RpdmVFbGVtZW50KG5vZGUpIHtcbiAgLy8gTW9iaWxlIFNhZmFyaSBkb2VzIG5vdCBmaXJlIHByb3Blcmx5IGJ1YmJsZSBjbGljayBldmVudHMgb25cbiAgLy8gbm9uLWludGVyYWN0aXZlIGVsZW1lbnRzLCB3aGljaCBtZWFucyBkZWxlZ2F0ZWQgY2xpY2sgbGlzdGVuZXJzIGRvIG5vdFxuICAvLyBmaXJlLiBUaGUgd29ya2Fyb3VuZCBmb3IgdGhpcyBidWcgaW52b2x2ZXMgYXR0YWNoaW5nIGFuIGVtcHR5IGNsaWNrXG4gIC8vIGxpc3RlbmVyIG9uIHRoZSB0YXJnZXQgbm9kZS5cbiAgLy8gaHR0cHM6Ly93d3cucXVpcmtzbW9kZS5vcmcvYmxvZy9hcmNoaXZlcy8yMDEwLzA5L2NsaWNrX2V2ZW50X2RlbC5odG1sXG4gIC8vIEp1c3Qgc2V0IGl0IHVzaW5nIHRoZSBvbmNsaWNrIHByb3BlcnR5IHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSB0byBtYW5hZ2UgYW55XG4gIC8vIGJvb2trZWVwaW5nIGZvciBpdC4gTm90IHN1cmUgaWYgd2UgbmVlZCB0byBjbGVhciBpdCB3aGVuIHRoZSBsaXN0ZW5lciBpc1xuICAvLyByZW1vdmVkLlxuICAvLyBUT0RPOiBPbmx5IGRvIHRoaXMgZm9yIHRoZSByZWxldmFudCBTYWZhcmlzIG1heWJlP1xuICBub2RlLm9uY2xpY2sgPSBub29wO1xufVxuXG5mdW5jdGlvbiBzZXRJbml0aWFsRE9NUHJvcGVydGllcyh0YWcsIGRvbUVsZW1lbnQsIHJvb3RDb250YWluZXJFbGVtZW50LCBuZXh0UHJvcHMsIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSB7XG4gIGZvciAodmFyIHByb3BLZXkgaW4gbmV4dFByb3BzKSB7XG4gICAgaWYgKCFuZXh0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHZhciBuZXh0UHJvcCA9IG5leHRQcm9wc1twcm9wS2V5XTtcblxuICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAge1xuICAgICAgICBpZiAobmV4dFByb3ApIHtcbiAgICAgICAgICAvLyBGcmVlemUgdGhlIG5leHQgc3R5bGUgb2JqZWN0IHNvIHRoYXQgd2UgY2FuIGFzc3VtZSBpdCB3b24ndCBiZVxuICAgICAgICAgIC8vIG11dGF0ZWQuIFdlIGhhdmUgYWxyZWFkeSB3YXJuZWQgZm9yIHRoaXMgaW4gdGhlIHBhc3QuXG4gICAgICAgICAgT2JqZWN0LmZyZWV6ZShuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH0gLy8gUmVsaWVzIG9uIGB1cGRhdGVTdHlsZXNCeUlEYCBub3QgbXV0YXRpbmcgYHN0eWxlVXBkYXRlc2AuXG5cblxuICAgICAgc2V0VmFsdWVGb3JTdHlsZXMoZG9tRWxlbWVudCwgbmV4dFByb3ApO1xuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgIHZhciBuZXh0SHRtbCA9IG5leHRQcm9wID8gbmV4dFByb3BbSFRNTCQxXSA6IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKG5leHRIdG1sICE9IG51bGwpIHtcbiAgICAgICAgc2V0SW5uZXJIVE1MKGRvbUVsZW1lbnQsIG5leHRIdG1sKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IENISUxEUkVOKSB7XG4gICAgICBpZiAodHlwZW9mIG5leHRQcm9wID09PSAnc3RyaW5nJykge1xuICAgICAgICAvLyBBdm9pZCBzZXR0aW5nIGluaXRpYWwgdGV4dENvbnRlbnQgd2hlbiB0aGUgdGV4dCBpcyBlbXB0eS4gSW4gSUUxMSBzZXR0aW5nXG4gICAgICAgIC8vIHRleHRDb250ZW50IG9uIGEgPHRleHRhcmVhPiB3aWxsIGNhdXNlIHRoZSBwbGFjZWhvbGRlciB0byBub3RcbiAgICAgICAgLy8gc2hvdyB3aXRoaW4gdGhlIDx0ZXh0YXJlYT4gdW50aWwgaXQgaGFzIGJlZW4gZm9jdXNlZCBhbmQgYmx1cnJlZCBhZ2Fpbi5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy82NzMxI2lzc3VlY29tbWVudC0yNTQ4NzQ1NTNcbiAgICAgICAgdmFyIGNhblNldFRleHRDb250ZW50ID0gdGFnICE9PSAndGV4dGFyZWEnIHx8IG5leHRQcm9wICE9PSAnJztcblxuICAgICAgICBpZiAoY2FuU2V0VGV4dENvbnRlbnQpIHtcbiAgICAgICAgICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCBuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG5leHRQcm9wID09PSAnbnVtYmVyJykge1xuICAgICAgICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCAnJyArIG5leHRQcm9wKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IFNVUFBSRVNTX0NPTlRFTlRfRURJVEFCTEVfV0FSTklORyB8fCBwcm9wS2V5ID09PSBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORykgOyBlbHNlIGlmIChwcm9wS2V5ID09PSBBVVRPRk9DVVMpIDsgZWxzZSBpZiAocmVnaXN0cmF0aW9uTmFtZURlcGVuZGVuY2llcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSkge1xuICAgICAgaWYgKG5leHRQcm9wICE9IG51bGwpIHtcbiAgICAgICAgaWYgKCB0eXBlb2YgbmV4dFByb3AgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB3YXJuRm9ySW52YWxpZEV2ZW50TGlzdGVuZXIocHJvcEtleSwgbmV4dFByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHByb3BLZXkgPT09ICdvblNjcm9sbCcpIHtcbiAgICAgICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdzY3JvbGwnLCBkb21FbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobmV4dFByb3AgIT0gbnVsbCkge1xuICAgICAgc2V0VmFsdWVGb3JQcm9wZXJ0eShkb21FbGVtZW50LCBwcm9wS2V5LCBuZXh0UHJvcCwgaXNDdXN0b21Db21wb25lbnRUYWcpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVET01Qcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHVwZGF0ZVBheWxvYWQsIHdhc0N1c3RvbUNvbXBvbmVudFRhZywgaXNDdXN0b21Db21wb25lbnRUYWcpIHtcbiAgLy8gVE9ETzogSGFuZGxlIHdhc0N1c3RvbUNvbXBvbmVudFRhZ1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHVwZGF0ZVBheWxvYWQubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgcHJvcEtleSA9IHVwZGF0ZVBheWxvYWRbaV07XG4gICAgdmFyIHByb3BWYWx1ZSA9IHVwZGF0ZVBheWxvYWRbaSArIDFdO1xuXG4gICAgaWYgKHByb3BLZXkgPT09IFNUWUxFKSB7XG4gICAgICBzZXRWYWx1ZUZvclN0eWxlcyhkb21FbGVtZW50LCBwcm9wVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgIHNldElubmVySFRNTChkb21FbGVtZW50LCBwcm9wVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gQ0hJTERSRU4pIHtcbiAgICAgIHNldFRleHRDb250ZW50KGRvbUVsZW1lbnQsIHByb3BWYWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNldFZhbHVlRm9yUHJvcGVydHkoZG9tRWxlbWVudCwgcHJvcEtleSwgcHJvcFZhbHVlLCBpc0N1c3RvbUNvbXBvbmVudFRhZyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJFbGVtZW50LCBwYXJlbnROYW1lc3BhY2UpIHtcbiAgdmFyIGlzQ3VzdG9tQ29tcG9uZW50VGFnOyAvLyBXZSBjcmVhdGUgdGFncyBpbiB0aGUgbmFtZXNwYWNlIG9mIHRoZWlyIHBhcmVudCBjb250YWluZXIsIGV4Y2VwdCBIVE1MXG4gIC8vIHRhZ3MgZ2V0IG5vIG5hbWVzcGFjZS5cblxuICB2YXIgb3duZXJEb2N1bWVudCA9IGdldE93bmVyRG9jdW1lbnRGcm9tUm9vdENvbnRhaW5lcihyb290Q29udGFpbmVyRWxlbWVudCk7XG4gIHZhciBkb21FbGVtZW50O1xuICB2YXIgbmFtZXNwYWNlVVJJID0gcGFyZW50TmFtZXNwYWNlO1xuXG4gIGlmIChuYW1lc3BhY2VVUkkgPT09IEhUTUxfTkFNRVNQQUNFKSB7XG4gICAgbmFtZXNwYWNlVVJJID0gZ2V0SW50cmluc2ljTmFtZXNwYWNlKHR5cGUpO1xuICB9XG5cbiAgaWYgKG5hbWVzcGFjZVVSSSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICB7XG4gICAgICBpc0N1c3RvbUNvbXBvbmVudFRhZyA9IGlzQ3VzdG9tQ29tcG9uZW50KHR5cGUsIHByb3BzKTsgLy8gU2hvdWxkIHRoaXMgY2hlY2sgYmUgZ2F0ZWQgYnkgcGFyZW50IG5hbWVzcGFjZT8gTm90IHN1cmUgd2Ugd2FudCB0b1xuICAgICAgLy8gYWxsb3cgPFNWRz4gb3IgPG1BVEg+LlxuXG4gICAgICBpZiAoIWlzQ3VzdG9tQ29tcG9uZW50VGFnICYmIHR5cGUgIT09IHR5cGUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICBlcnJvcignPCVzIC8+IGlzIHVzaW5nIGluY29ycmVjdCBjYXNpbmcuICcgKyAnVXNlIFBhc2NhbENhc2UgZm9yIFJlYWN0IGNvbXBvbmVudHMsICcgKyAnb3IgbG93ZXJjYXNlIGZvciBIVE1MIGVsZW1lbnRzLicsIHR5cGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnc2NyaXB0Jykge1xuICAgICAgLy8gQ3JlYXRlIHRoZSBzY3JpcHQgdmlhIC5pbm5lckhUTUwgc28gaXRzIFwicGFyc2VyLWluc2VydGVkXCIgZmxhZyBpc1xuICAgICAgLy8gc2V0IHRvIHRydWUgYW5kIGl0IGRvZXMgbm90IGV4ZWN1dGVcbiAgICAgIHZhciBkaXYgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG4gICAgICBkaXYuaW5uZXJIVE1MID0gJzxzY3JpcHQ+PCcgKyAnL3NjcmlwdD4nOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgICAvLyBUaGlzIGlzIGd1YXJhbnRlZWQgdG8geWllbGQgYSBzY3JpcHQgZWxlbWVudC5cblxuICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBkaXYuZmlyc3RDaGlsZDtcbiAgICAgIGRvbUVsZW1lbnQgPSBkaXYucmVtb3ZlQ2hpbGQoZmlyc3RDaGlsZCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcHJvcHMuaXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyAkRmxvd0lzc3VlIGBjcmVhdGVFbGVtZW50YCBzaG91bGQgYmUgdXBkYXRlZCBmb3IgV2ViIENvbXBvbmVudHNcbiAgICAgIGRvbUVsZW1lbnQgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodHlwZSwge1xuICAgICAgICBpczogcHJvcHMuaXNcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTZXBhcmF0ZSBlbHNlIGJyYW5jaCBpbnN0ZWFkIG9mIHVzaW5nIGBwcm9wcy5pcyB8fCB1bmRlZmluZWRgIGFib3ZlIGJlY2F1c2Ugb2YgYSBGaXJlZm94IGJ1Zy5cbiAgICAgIC8vIFNlZSBkaXNjdXNzaW9uIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzY4OTZcbiAgICAgIC8vIGFuZCBkaXNjdXNzaW9uIGluIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTEyNzYyNDBcbiAgICAgIGRvbUVsZW1lbnQgPSBvd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodHlwZSk7IC8vIE5vcm1hbGx5IGF0dHJpYnV0ZXMgYXJlIGFzc2lnbmVkIGluIGBzZXRJbml0aWFsRE9NUHJvcGVydGllc2AsIGhvd2V2ZXIgdGhlIGBtdWx0aXBsZWAgYW5kIGBzaXplYFxuICAgICAgLy8gYXR0cmlidXRlcyBvbiBgc2VsZWN0YHMgbmVlZHMgdG8gYmUgYWRkZWQgYmVmb3JlIGBvcHRpb25gcyBhcmUgaW5zZXJ0ZWQuXG4gICAgICAvLyBUaGlzIHByZXZlbnRzOlxuICAgICAgLy8gLSBhIGJ1ZyB3aGVyZSB0aGUgYHNlbGVjdGAgZG9lcyBub3Qgc2Nyb2xsIHRvIHRoZSBjb3JyZWN0IG9wdGlvbiBiZWNhdXNlIHNpbmd1bGFyXG4gICAgICAvLyAgYHNlbGVjdGAgZWxlbWVudHMgYXV0b21hdGljYWxseSBwaWNrIHRoZSBmaXJzdCBpdGVtICMxMzIyMlxuICAgICAgLy8gLSBhIGJ1ZyB3aGVyZSB0aGUgYHNlbGVjdGAgc2V0IHRoZSBmaXJzdCBpdGVtIGFzIHNlbGVjdGVkIGRlc3BpdGUgdGhlIGBzaXplYCBhdHRyaWJ1dGUgIzE0MjM5XG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMzIyMlxuICAgICAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTQyMzlcblxuICAgICAgaWYgKHR5cGUgPT09ICdzZWxlY3QnKSB7XG4gICAgICAgIHZhciBub2RlID0gZG9tRWxlbWVudDtcblxuICAgICAgICBpZiAocHJvcHMubXVsdGlwbGUpIHtcbiAgICAgICAgICBub2RlLm11bHRpcGxlID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChwcm9wcy5zaXplKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBhIHNpemUgZ3JlYXRlciB0aGFuIDEgY2F1c2VzIGEgc2VsZWN0IHRvIGJlaGF2ZSBsaWtlIGBtdWx0aXBsZT10cnVlYCwgd2hlcmVcbiAgICAgICAgICAvLyBpdCBpcyBwb3NzaWJsZSB0aGF0IG5vIG9wdGlvbiBpcyBzZWxlY3RlZC5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIFRoaXMgaXMgb25seSBuZWNlc3Nhcnkgd2hlbiBhIHNlbGVjdCBpbiBcInNpbmdsZSBzZWxlY3Rpb24gbW9kZVwiLlxuICAgICAgICAgIG5vZGUuc2l6ZSA9IHByb3BzLnNpemU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZG9tRWxlbWVudCA9IG93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgdHlwZSk7XG4gIH1cblxuICB7XG4gICAgaWYgKG5hbWVzcGFjZVVSSSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICAgIGlmICghaXNDdXN0b21Db21wb25lbnRUYWcgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvbUVsZW1lbnQpID09PSAnW29iamVjdCBIVE1MVW5rbm93bkVsZW1lbnRdJyAmJiAhaGFzT3duUHJvcGVydHkuY2FsbCh3YXJuZWRVbmtub3duVGFncywgdHlwZSkpIHtcbiAgICAgICAgd2FybmVkVW5rbm93blRhZ3NbdHlwZV0gPSB0cnVlO1xuXG4gICAgICAgIGVycm9yKCdUaGUgdGFnIDwlcz4gaXMgdW5yZWNvZ25pemVkIGluIHRoaXMgYnJvd3Nlci4gJyArICdJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgUmVhY3QgY29tcG9uZW50LCBzdGFydCBpdHMgbmFtZSB3aXRoICcgKyAnYW4gdXBwZXJjYXNlIGxldHRlci4nLCB0eXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZG9tRWxlbWVudDtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVRleHROb2RlKHRleHQsIHJvb3RDb250YWluZXJFbGVtZW50KSB7XG4gIHJldHVybiBnZXRPd25lckRvY3VtZW50RnJvbVJvb3RDb250YWluZXIocm9vdENvbnRhaW5lckVsZW1lbnQpLmNyZWF0ZVRleHROb2RlKHRleHQpO1xufVxuZnVuY3Rpb24gc2V0SW5pdGlhbFByb3BlcnRpZXMoZG9tRWxlbWVudCwgdGFnLCByYXdQcm9wcywgcm9vdENvbnRhaW5lckVsZW1lbnQpIHtcbiAgdmFyIGlzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCByYXdQcm9wcyk7XG5cbiAge1xuICAgIHZhbGlkYXRlUHJvcGVydGllc0luRGV2ZWxvcG1lbnQodGFnLCByYXdQcm9wcyk7XG4gIH0gLy8gVE9ETzogTWFrZSBzdXJlIHRoYXQgd2UgY2hlY2sgaXNNb3VudGVkIGJlZm9yZSBmaXJpbmcgYW55IG9mIHRoZXNlIGV2ZW50cy5cblxuXG4gIHZhciBwcm9wcztcblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2RpYWxvZyc6XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdjYW5jZWwnLCBkb21FbGVtZW50KTtcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2Nsb3NlJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpZnJhbWUnOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgY2FzZSAnZW1iZWQnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGxvYWQgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdsb2FkJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd2aWRlbyc6XG4gICAgY2FzZSAnYXVkaW8nOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoZXNlIGV2ZW50cyBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciBhbGwgdGhlIG1lZGlhIGV2ZW50cy5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVkaWFFdmVudFR5cGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQobWVkaWFFdmVudFR5cGVzW2ldLCBkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnc291cmNlJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBlcnJvciBldmVudC5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2Vycm9yJywgZG9tRWxlbWVudCk7XG4gICAgICBwcm9wcyA9IHJhd1Byb3BzO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpbWcnOlxuICAgIGNhc2UgJ2ltYWdlJzpcbiAgICBjYXNlICdsaW5rJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGVzZSBldmVudHMgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgZXJyb3IgYW5kIGxvYWQgZXZlbnRzLlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnZXJyb3InLCBkb21FbGVtZW50KTtcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2xvYWQnLCBkb21FbGVtZW50KTtcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2RldGFpbHMnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIHRvZ2dsZSBldmVudC5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3RvZ2dsZScsIGRvbUVsZW1lbnQpO1xuICAgICAgcHJvcHMgPSByYXdQcm9wcztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgaW5pdFdyYXBwZXJTdGF0ZShkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBwcm9wcyA9IGdldEhvc3RQcm9wcyhkb21FbGVtZW50LCByYXdQcm9wcyk7IC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBpbnZhbGlkIGV2ZW50LlxuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdpbnZhbGlkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ29wdGlvbic6XG4gICAgICB2YWxpZGF0ZVByb3BzKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTtcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgcHJvcHMgPSBnZXRIb3N0UHJvcHMkMShkb21FbGVtZW50LCByYXdQcm9wcyk7IC8vIFdlIGxpc3RlbiB0byB0aGlzIGV2ZW50IGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIHRoZSBpbnZhbGlkIGV2ZW50LlxuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdpbnZhbGlkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3RleHRhcmVhJzpcbiAgICAgIGluaXRXcmFwcGVyU3RhdGUkMihkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBwcm9wcyA9IGdldEhvc3RQcm9wcyQyKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTsgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGludmFsaWQgZXZlbnQuXG5cbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2ludmFsaWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHByb3BzID0gcmF3UHJvcHM7XG4gIH1cblxuICBhc3NlcnRWYWxpZFByb3BzKHRhZywgcHJvcHMpO1xuICBzZXRJbml0aWFsRE9NUHJvcGVydGllcyh0YWcsIGRvbUVsZW1lbnQsIHJvb3RDb250YWluZXJFbGVtZW50LCBwcm9wcywgaXNDdXN0b21Db21wb25lbnRUYWcpO1xuXG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgLy8gVE9ETzogTWFrZSBzdXJlIHdlIGNoZWNrIGlmIHRoaXMgaXMgc3RpbGwgdW5tb3VudGVkIG9yIGRvIGFueSBjbGVhblxuICAgICAgLy8gdXAgbmVjZXNzYXJ5IHNpbmNlIHdlIG5ldmVyIHN0b3AgdHJhY2tpbmcgYW55bW9yZS5cbiAgICAgIHRyYWNrKGRvbUVsZW1lbnQpO1xuICAgICAgcG9zdE1vdW50V3JhcHBlcihkb21FbGVtZW50LCByYXdQcm9wcywgZmFsc2UpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgd2UgY2hlY2sgaWYgdGhpcyBpcyBzdGlsbCB1bm1vdW50ZWQgb3IgZG8gYW55IGNsZWFuXG4gICAgICAvLyB1cCBuZWNlc3Nhcnkgc2luY2Ugd2UgbmV2ZXIgc3RvcCB0cmFja2luZyBhbnltb3JlLlxuICAgICAgdHJhY2soZG9tRWxlbWVudCk7XG4gICAgICBwb3N0TW91bnRXcmFwcGVyJDMoZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ29wdGlvbic6XG4gICAgICBwb3N0TW91bnRXcmFwcGVyJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgcG9zdE1vdW50V3JhcHBlciQyKGRvbUVsZW1lbnQsIHJhd1Byb3BzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICh0eXBlb2YgcHJvcHMub25DbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gIH1cbn0gLy8gQ2FsY3VsYXRlIHRoZSBkaWZmIGJldHdlZW4gdGhlIHR3byBvYmplY3RzLlxuXG5mdW5jdGlvbiBkaWZmUHJvcGVydGllcyhkb21FbGVtZW50LCB0YWcsIGxhc3RSYXdQcm9wcywgbmV4dFJhd1Byb3BzLCByb290Q29udGFpbmVyRWxlbWVudCkge1xuICB7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudCh0YWcsIG5leHRSYXdQcm9wcyk7XG4gIH1cblxuICB2YXIgdXBkYXRlUGF5bG9hZCA9IG51bGw7XG4gIHZhciBsYXN0UHJvcHM7XG4gIHZhciBuZXh0UHJvcHM7XG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgICBsYXN0UHJvcHMgPSBnZXRIb3N0UHJvcHMoZG9tRWxlbWVudCwgbGFzdFJhd1Byb3BzKTtcbiAgICAgIG5leHRQcm9wcyA9IGdldEhvc3RQcm9wcyhkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgbGFzdFByb3BzID0gZ2V0SG9zdFByb3BzJDEoZG9tRWxlbWVudCwgbGFzdFJhd1Byb3BzKTtcbiAgICAgIG5leHRQcm9wcyA9IGdldEhvc3RQcm9wcyQxKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gICAgICB1cGRhdGVQYXlsb2FkID0gW107XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3RleHRhcmVhJzpcbiAgICAgIGxhc3RQcm9wcyA9IGdldEhvc3RQcm9wcyQyKGRvbUVsZW1lbnQsIGxhc3RSYXdQcm9wcyk7XG4gICAgICBuZXh0UHJvcHMgPSBnZXRIb3N0UHJvcHMkMihkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgbGFzdFByb3BzID0gbGFzdFJhd1Byb3BzO1xuICAgICAgbmV4dFByb3BzID0gbmV4dFJhd1Byb3BzO1xuXG4gICAgICBpZiAodHlwZW9mIGxhc3RQcm9wcy5vbkNsaWNrICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBuZXh0UHJvcHMub25DbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gIH1cblxuICBhc3NlcnRWYWxpZFByb3BzKHRhZywgbmV4dFByb3BzKTtcbiAgdmFyIHByb3BLZXk7XG4gIHZhciBzdHlsZU5hbWU7XG4gIHZhciBzdHlsZVVwZGF0ZXMgPSBudWxsO1xuXG4gIGZvciAocHJvcEtleSBpbiBsYXN0UHJvcHMpIHtcbiAgICBpZiAobmV4dFByb3BzLmhhc093blByb3BlcnR5KHByb3BLZXkpIHx8ICFsYXN0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkgfHwgbGFzdFByb3BzW3Byb3BLZXldID09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChwcm9wS2V5ID09PSBTVFlMRSkge1xuICAgICAgdmFyIGxhc3RTdHlsZSA9IGxhc3RQcm9wc1twcm9wS2V5XTtcblxuICAgICAgZm9yIChzdHlsZU5hbWUgaW4gbGFzdFN0eWxlKSB7XG4gICAgICAgIGlmIChsYXN0U3R5bGUuaGFzT3duUHJvcGVydHkoc3R5bGVOYW1lKSkge1xuICAgICAgICAgIGlmICghc3R5bGVVcGRhdGVzKSB7XG4gICAgICAgICAgICBzdHlsZVVwZGF0ZXMgPSB7fTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdHlsZVVwZGF0ZXNbc3R5bGVOYW1lXSA9ICcnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBEQU5HRVJPVVNMWV9TRVRfSU5ORVJfSFRNTCB8fCBwcm9wS2V5ID09PSBDSElMRFJFTikgOyBlbHNlIGlmIChwcm9wS2V5ID09PSBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgfHwgcHJvcEtleSA9PT0gU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkcpIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gQVVUT0ZPQ1VTKSA7IGVsc2UgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UuIElmIGFueSBsaXN0ZW5lciB1cGRhdGVzIHdlIG5lZWQgdG8gZW5zdXJlXG4gICAgICAvLyB0aGF0IHRoZSBcImN1cnJlbnRcIiBmaWJlciBwb2ludGVyIGdldHMgdXBkYXRlZCBzbyB3ZSBuZWVkIGEgY29tbWl0XG4gICAgICAvLyB0byB1cGRhdGUgdGhpcyBlbGVtZW50LlxuICAgICAgaWYgKCF1cGRhdGVQYXlsb2FkKSB7XG4gICAgICAgIHVwZGF0ZVBheWxvYWQgPSBbXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRm9yIGFsbCBvdGhlciBkZWxldGVkIHByb3BlcnRpZXMgd2UgYWRkIGl0IHRvIHRoZSBxdWV1ZS4gV2UgdXNlXG4gICAgICAvLyB0aGUgYWxsb3dlZCBwcm9wZXJ0eSBsaXN0IGluIHRoZSBjb21taXQgcGhhc2UgaW5zdGVhZC5cbiAgICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChwcm9wS2V5LCBudWxsKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHByb3BLZXkgaW4gbmV4dFByb3BzKSB7XG4gICAgdmFyIG5leHRQcm9wID0gbmV4dFByb3BzW3Byb3BLZXldO1xuICAgIHZhciBsYXN0UHJvcCA9IGxhc3RQcm9wcyAhPSBudWxsID8gbGFzdFByb3BzW3Byb3BLZXldIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFuZXh0UHJvcHMuaGFzT3duUHJvcGVydHkocHJvcEtleSkgfHwgbmV4dFByb3AgPT09IGxhc3RQcm9wIHx8IG5leHRQcm9wID09IG51bGwgJiYgbGFzdFByb3AgPT0gbnVsbCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHByb3BLZXkgPT09IFNUWUxFKSB7XG4gICAgICB7XG4gICAgICAgIGlmIChuZXh0UHJvcCkge1xuICAgICAgICAgIC8vIEZyZWV6ZSB0aGUgbmV4dCBzdHlsZSBvYmplY3Qgc28gdGhhdCB3ZSBjYW4gYXNzdW1lIGl0IHdvbid0IGJlXG4gICAgICAgICAgLy8gbXV0YXRlZC4gV2UgaGF2ZSBhbHJlYWR5IHdhcm5lZCBmb3IgdGhpcyBpbiB0aGUgcGFzdC5cbiAgICAgICAgICBPYmplY3QuZnJlZXplKG5leHRQcm9wKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobGFzdFByb3ApIHtcbiAgICAgICAgLy8gVW5zZXQgc3R5bGVzIG9uIGBsYXN0UHJvcGAgYnV0IG5vdCBvbiBgbmV4dFByb3BgLlxuICAgICAgICBmb3IgKHN0eWxlTmFtZSBpbiBsYXN0UHJvcCkge1xuICAgICAgICAgIGlmIChsYXN0UHJvcC5oYXNPd25Qcm9wZXJ0eShzdHlsZU5hbWUpICYmICghbmV4dFByb3AgfHwgIW5leHRQcm9wLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkpKSB7XG4gICAgICAgICAgICBpZiAoIXN0eWxlVXBkYXRlcykge1xuICAgICAgICAgICAgICBzdHlsZVVwZGF0ZXMgPSB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3R5bGVVcGRhdGVzW3N0eWxlTmFtZV0gPSAnJztcbiAgICAgICAgICB9XG4gICAgICAgIH0gLy8gVXBkYXRlIHN0eWxlcyB0aGF0IGNoYW5nZWQgc2luY2UgYGxhc3RQcm9wYC5cblxuXG4gICAgICAgIGZvciAoc3R5bGVOYW1lIGluIG5leHRQcm9wKSB7XG4gICAgICAgICAgaWYgKG5leHRQcm9wLmhhc093blByb3BlcnR5KHN0eWxlTmFtZSkgJiYgbGFzdFByb3Bbc3R5bGVOYW1lXSAhPT0gbmV4dFByb3Bbc3R5bGVOYW1lXSkge1xuICAgICAgICAgICAgaWYgKCFzdHlsZVVwZGF0ZXMpIHtcbiAgICAgICAgICAgICAgc3R5bGVVcGRhdGVzID0ge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0eWxlVXBkYXRlc1tzdHlsZU5hbWVdID0gbmV4dFByb3Bbc3R5bGVOYW1lXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlbGllcyBvbiBgdXBkYXRlU3R5bGVzQnlJRGAgbm90IG11dGF0aW5nIGBzdHlsZVVwZGF0ZXNgLlxuICAgICAgICBpZiAoIXN0eWxlVXBkYXRlcykge1xuICAgICAgICAgIGlmICghdXBkYXRlUGF5bG9hZCkge1xuICAgICAgICAgICAgdXBkYXRlUGF5bG9hZCA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHVwZGF0ZVBheWxvYWQucHVzaChwcm9wS2V5LCBzdHlsZVVwZGF0ZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3R5bGVVcGRhdGVzID0gbmV4dFByb3A7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSBEQU5HRVJPVVNMWV9TRVRfSU5ORVJfSFRNTCkge1xuICAgICAgdmFyIG5leHRIdG1sID0gbmV4dFByb3AgPyBuZXh0UHJvcFtIVE1MJDFdIDogdW5kZWZpbmVkO1xuICAgICAgdmFyIGxhc3RIdG1sID0gbGFzdFByb3AgPyBsYXN0UHJvcFtIVE1MJDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICBpZiAobmV4dEh0bWwgIT0gbnVsbCkge1xuICAgICAgICBpZiAobGFzdEh0bWwgIT09IG5leHRIdG1sKSB7XG4gICAgICAgICAgKHVwZGF0ZVBheWxvYWQgPSB1cGRhdGVQYXlsb2FkIHx8IFtdKS5wdXNoKHByb3BLZXksIG5leHRIdG1sKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gQ0hJTERSRU4pIHtcbiAgICAgIGlmICh0eXBlb2YgbmV4dFByb3AgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBuZXh0UHJvcCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgKHVwZGF0ZVBheWxvYWQgPSB1cGRhdGVQYXlsb2FkIHx8IFtdKS5wdXNoKHByb3BLZXksICcnICsgbmV4dFByb3ApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocHJvcEtleSA9PT0gU1VQUFJFU1NfQ09OVEVOVF9FRElUQUJMRV9XQVJOSU5HIHx8IHByb3BLZXkgPT09IFNVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HKSA7IGVsc2UgaWYgKHJlZ2lzdHJhdGlvbk5hbWVEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocHJvcEtleSkpIHtcbiAgICAgIGlmIChuZXh0UHJvcCAhPSBudWxsKSB7XG4gICAgICAgIC8vIFdlIGVhZ2VybHkgbGlzdGVuIHRvIHRoaXMgZXZlbiB0aG91Z2ggd2UgaGF2ZW4ndCBjb21taXR0ZWQgeWV0LlxuICAgICAgICBpZiAoIHR5cGVvZiBuZXh0UHJvcCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHdhcm5Gb3JJbnZhbGlkRXZlbnRMaXN0ZW5lcihwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcEtleSA9PT0gJ29uU2Nyb2xsJykge1xuICAgICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3Njcm9sbCcsIGRvbUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghdXBkYXRlUGF5bG9hZCAmJiBsYXN0UHJvcCAhPT0gbmV4dFByb3ApIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIHNwZWNpYWwgY2FzZS4gSWYgYW55IGxpc3RlbmVyIHVwZGF0ZXMgd2UgbmVlZCB0byBlbnN1cmVcbiAgICAgICAgLy8gdGhhdCB0aGUgXCJjdXJyZW50XCIgcHJvcHMgcG9pbnRlciBnZXRzIHVwZGF0ZWQgc28gd2UgbmVlZCBhIGNvbW1pdFxuICAgICAgICAvLyB0byB1cGRhdGUgdGhpcyBlbGVtZW50LlxuICAgICAgICB1cGRhdGVQYXlsb2FkID0gW107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEZvciBhbnkgb3RoZXIgcHJvcGVydHkgd2UgYWx3YXlzIGFkZCBpdCB0byB0aGUgcXVldWUgYW5kIHRoZW4gd2VcbiAgICAgIC8vIGZpbHRlciBpdCBvdXQgdXNpbmcgdGhlIGFsbG93ZWQgcHJvcGVydHkgbGlzdCBkdXJpbmcgdGhlIGNvbW1pdC5cbiAgICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0eWxlVXBkYXRlcykge1xuICAgIHtcbiAgICAgIHZhbGlkYXRlU2hvcnRoYW5kUHJvcGVydHlDb2xsaXNpb25JbkRldihzdHlsZVVwZGF0ZXMsIG5leHRQcm9wc1tTVFlMRV0pO1xuICAgIH1cblxuICAgICh1cGRhdGVQYXlsb2FkID0gdXBkYXRlUGF5bG9hZCB8fCBbXSkucHVzaChTVFlMRSwgc3R5bGVVcGRhdGVzKTtcbiAgfVxuXG4gIHJldHVybiB1cGRhdGVQYXlsb2FkO1xufSAvLyBBcHBseSB0aGUgZGlmZi5cblxuZnVuY3Rpb24gdXBkYXRlUHJvcGVydGllcyhkb21FbGVtZW50LCB1cGRhdGVQYXlsb2FkLCB0YWcsIGxhc3RSYXdQcm9wcywgbmV4dFJhd1Byb3BzKSB7XG4gIC8vIFVwZGF0ZSBjaGVja2VkICpiZWZvcmUqIG5hbWUuXG4gIC8vIEluIHRoZSBtaWRkbGUgb2YgYW4gdXBkYXRlLCBpdCBpcyBwb3NzaWJsZSB0byBoYXZlIG11bHRpcGxlIGNoZWNrZWQuXG4gIC8vIFdoZW4gYSBjaGVja2VkIHJhZGlvIHRyaWVzIHRvIGNoYW5nZSBuYW1lLCBicm93c2VyIG1ha2VzIGFub3RoZXIgcmFkaW8ncyBjaGVja2VkIGZhbHNlLlxuICBpZiAodGFnID09PSAnaW5wdXQnICYmIG5leHRSYXdQcm9wcy50eXBlID09PSAncmFkaW8nICYmIG5leHRSYXdQcm9wcy5uYW1lICE9IG51bGwpIHtcbiAgICB1cGRhdGVDaGVja2VkKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gIH1cblxuICB2YXIgd2FzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCBsYXN0UmF3UHJvcHMpO1xuICB2YXIgaXNDdXN0b21Db21wb25lbnRUYWcgPSBpc0N1c3RvbUNvbXBvbmVudCh0YWcsIG5leHRSYXdQcm9wcyk7IC8vIEFwcGx5IHRoZSBkaWZmLlxuXG4gIHVwZGF0ZURPTVByb3BlcnRpZXMoZG9tRWxlbWVudCwgdXBkYXRlUGF5bG9hZCwgd2FzQ3VzdG9tQ29tcG9uZW50VGFnLCBpc0N1c3RvbUNvbXBvbmVudFRhZyk7IC8vIFRPRE86IEVuc3VyZSB0aGF0IGFuIHVwZGF0ZSBnZXRzIHNjaGVkdWxlZCBpZiBhbnkgb2YgdGhlIHNwZWNpYWwgcHJvcHNcbiAgLy8gY2hhbmdlZC5cblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIC8vIFVwZGF0ZSB0aGUgd3JhcHBlciBhcm91bmQgaW5wdXRzICphZnRlciogdXBkYXRpbmcgcHJvcHMuIFRoaXMgaGFzIHRvXG4gICAgICAvLyBoYXBwZW4gYWZ0ZXIgYHVwZGF0ZURPTVByb3BlcnRpZXNgLiBPdGhlcndpc2UgSFRNTDUgaW5wdXQgdmFsaWRhdGlvbnNcbiAgICAgIC8vIHJhaXNlIHdhcm5pbmdzIGFuZCBwcmV2ZW50IHRoZSBuZXcgdmFsdWUgZnJvbSBiZWluZyBhc3NpZ25lZC5cbiAgICAgIHVwZGF0ZVdyYXBwZXIoZG9tRWxlbWVudCwgbmV4dFJhd1Byb3BzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgdXBkYXRlV3JhcHBlciQxKGRvbUVsZW1lbnQsIG5leHRSYXdQcm9wcyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICAvLyA8c2VsZWN0PiB2YWx1ZSB1cGRhdGUgbmVlZHMgdG8gb2NjdXIgYWZ0ZXIgPG9wdGlvbj4gY2hpbGRyZW5cbiAgICAgIC8vIHJlY29uY2lsaWF0aW9uXG4gICAgICBwb3N0VXBkYXRlV3JhcHBlcihkb21FbGVtZW50LCBuZXh0UmF3UHJvcHMpO1xuICAgICAgYnJlYWs7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0UG9zc2libGVTdGFuZGFyZE5hbWUocHJvcE5hbWUpIHtcbiAge1xuICAgIHZhciBsb3dlckNhc2VkTmFtZSA9IHByb3BOYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAoIXBvc3NpYmxlU3RhbmRhcmROYW1lcy5oYXNPd25Qcm9wZXJ0eShsb3dlckNhc2VkTmFtZSkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBwb3NzaWJsZVN0YW5kYXJkTmFtZXNbbG93ZXJDYXNlZE5hbWVdIHx8IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlmZkh5ZHJhdGVkUHJvcGVydGllcyhkb21FbGVtZW50LCB0YWcsIHJhd1Byb3BzLCBwYXJlbnROYW1lc3BhY2UsIHJvb3RDb250YWluZXJFbGVtZW50LCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KSB7XG4gIHZhciBpc0N1c3RvbUNvbXBvbmVudFRhZztcbiAgdmFyIGV4dHJhQXR0cmlidXRlTmFtZXM7XG5cbiAge1xuICAgIGlzQ3VzdG9tQ29tcG9uZW50VGFnID0gaXNDdXN0b21Db21wb25lbnQodGFnLCByYXdQcm9wcyk7XG4gICAgdmFsaWRhdGVQcm9wZXJ0aWVzSW5EZXZlbG9wbWVudCh0YWcsIHJhd1Byb3BzKTtcbiAgfSAvLyBUT0RPOiBNYWtlIHN1cmUgdGhhdCB3ZSBjaGVjayBpc01vdW50ZWQgYmVmb3JlIGZpcmluZyBhbnkgb2YgdGhlc2UgZXZlbnRzLlxuXG5cbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlICdkaWFsb2cnOlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnY2FuY2VsJywgZG9tRWxlbWVudCk7XG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdjbG9zZScsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpZnJhbWUnOlxuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgY2FzZSAnZW1iZWQnOlxuICAgICAgLy8gV2UgbGlzdGVuIHRvIHRoaXMgZXZlbnQgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgdGhlIGxvYWQgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdsb2FkJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3ZpZGVvJzpcbiAgICBjYXNlICdhdWRpbyc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhlc2UgZXZlbnRzIGluIGNhc2UgdG8gZW5zdXJlIGVtdWxhdGVkIGJ1YmJsZVxuICAgICAgLy8gbGlzdGVuZXJzIHN0aWxsIGZpcmUgZm9yIGFsbCB0aGUgbWVkaWEgZXZlbnRzLlxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZWRpYUV2ZW50VHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudChtZWRpYUV2ZW50VHlwZXNbaV0sIGRvbUVsZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NvdXJjZSc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgZXJyb3IgZXZlbnQuXG4gICAgICBsaXN0ZW5Ub05vbkRlbGVnYXRlZEV2ZW50KCdlcnJvcicsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdpbWcnOlxuICAgIGNhc2UgJ2ltYWdlJzpcbiAgICBjYXNlICdsaW5rJzpcbiAgICAgIC8vIFdlIGxpc3RlbiB0byB0aGVzZSBldmVudHMgaW4gY2FzZSB0byBlbnN1cmUgZW11bGF0ZWQgYnViYmxlXG4gICAgICAvLyBsaXN0ZW5lcnMgc3RpbGwgZmlyZSBmb3IgZXJyb3IgYW5kIGxvYWQgZXZlbnRzLlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnZXJyb3InLCBkb21FbGVtZW50KTtcbiAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ2xvYWQnLCBkb21FbGVtZW50KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnZGV0YWlscyc6XG4gICAgICAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgdG9nZ2xlIGV2ZW50LlxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgndG9nZ2xlJywgZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIGluaXRXcmFwcGVyU3RhdGUoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdvcHRpb24nOlxuICAgICAgdmFsaWRhdGVQcm9wcyhkb21FbGVtZW50LCByYXdQcm9wcyk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDEoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICBpbml0V3JhcHBlclN0YXRlJDIoZG9tRWxlbWVudCwgcmF3UHJvcHMpOyAvLyBXZSBsaXN0ZW4gdG8gdGhpcyBldmVudCBpbiBjYXNlIHRvIGVuc3VyZSBlbXVsYXRlZCBidWJibGVcbiAgICAgIC8vIGxpc3RlbmVycyBzdGlsbCBmaXJlIGZvciB0aGUgaW52YWxpZCBldmVudC5cblxuICAgICAgbGlzdGVuVG9Ob25EZWxlZ2F0ZWRFdmVudCgnaW52YWxpZCcsIGRvbUVsZW1lbnQpO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICBhc3NlcnRWYWxpZFByb3BzKHRhZywgcmF3UHJvcHMpO1xuXG4gIHtcbiAgICBleHRyYUF0dHJpYnV0ZU5hbWVzID0gbmV3IFNldCgpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gZG9tRWxlbWVudC5hdHRyaWJ1dGVzO1xuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgbmFtZSA9IGF0dHJpYnV0ZXNbX2ldLm5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICAgIC8vIENvbnRyb2xsZWQgYXR0cmlidXRlcyBhcmUgbm90IHZhbGlkYXRlZFxuICAgICAgICAvLyBUT0RPOiBPbmx5IGlnbm9yZSB0aGVtIG9uIGNvbnRyb2xsZWQgdGFncy5cbiAgICAgICAgY2FzZSAndmFsdWUnOlxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ2NoZWNrZWQnOlxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJ3NlbGVjdGVkJzpcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIEludGVudGlvbmFsbHkgdXNlIHRoZSBvcmlnaW5hbCBuYW1lLlxuICAgICAgICAgIC8vIFNlZSBkaXNjdXNzaW9uIGluIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzEwNjc2LlxuICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuYWRkKGF0dHJpYnV0ZXNbX2ldLm5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciB1cGRhdGVQYXlsb2FkID0gbnVsbDtcblxuICBmb3IgKHZhciBwcm9wS2V5IGluIHJhd1Byb3BzKSB7XG4gICAgaWYgKCFyYXdQcm9wcy5oYXNPd25Qcm9wZXJ0eShwcm9wS2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIG5leHRQcm9wID0gcmF3UHJvcHNbcHJvcEtleV07XG5cbiAgICBpZiAocHJvcEtleSA9PT0gQ0hJTERSRU4pIHtcbiAgICAgIC8vIEZvciB0ZXh0IGNvbnRlbnQgY2hpbGRyZW4gd2UgY29tcGFyZSBhZ2FpbnN0IHRleHRDb250ZW50LiBUaGlzXG4gICAgICAvLyBtaWdodCBtYXRjaCBhZGRpdGlvbmFsIEhUTUwgdGhhdCBpcyBoaWRkZW4gd2hlbiB3ZSByZWFkIGl0IHVzaW5nXG4gICAgICAvLyB0ZXh0Q29udGVudC4gRS5nLiBcImZvb1wiIHdpbGwgbWF0Y2ggXCJmPHNwYW4+b288L3NwYW4+XCIgYnV0IHRoYXQgc3RpbGxcbiAgICAgIC8vIHNhdGlzZmllcyBvdXIgcmVxdWlyZW1lbnQuIE91ciByZXF1aXJlbWVudCBpcyBub3QgdG8gcHJvZHVjZSBwZXJmZWN0XG4gICAgICAvLyBIVE1MIGFuZCBhdHRyaWJ1dGVzLiBJZGVhbGx5IHdlIHNob3VsZCBwcmVzZXJ2ZSBzdHJ1Y3R1cmUgYnV0IGl0J3NcbiAgICAgIC8vIG9rIG5vdCB0byBpZiB0aGUgdmlzaWJsZSBjb250ZW50IGlzIHN0aWxsIGVub3VnaCB0byBpbmRpY2F0ZSB3aGF0XG4gICAgICAvLyBldmVuIGxpc3RlbmVycyB0aGVzZSBub2RlcyBtaWdodCBiZSB3aXJlZCB1cCB0by5cbiAgICAgIC8vIFRPRE86IFdhcm4gaWYgdGhlcmUgaXMgbW9yZSB0aGFuIGEgc2luZ2xlIHRleHROb2RlIGFzIGEgY2hpbGQuXG4gICAgICAvLyBUT0RPOiBTaG91bGQgd2UgdXNlIGRvbUVsZW1lbnQuZmlyc3RDaGlsZC5ub2RlVmFsdWUgdG8gY29tcGFyZT9cbiAgICAgIGlmICh0eXBlb2YgbmV4dFByb3AgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChkb21FbGVtZW50LnRleHRDb250ZW50ICE9PSBuZXh0UHJvcCkge1xuICAgICAgICAgIGlmIChyYXdQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklOR10gIT09IHRydWUpIHtcbiAgICAgICAgICAgIGNoZWNrRm9yVW5tYXRjaGVkVGV4dChkb21FbGVtZW50LnRleHRDb250ZW50LCBuZXh0UHJvcCwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdXBkYXRlUGF5bG9hZCA9IFtDSElMRFJFTiwgbmV4dFByb3BdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBuZXh0UHJvcCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgaWYgKGRvbUVsZW1lbnQudGV4dENvbnRlbnQgIT09ICcnICsgbmV4dFByb3ApIHtcbiAgICAgICAgICBpZiAocmF3UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkddICE9PSB0cnVlKSB7XG4gICAgICAgICAgICBjaGVja0ZvclVubWF0Y2hlZFRleHQoZG9tRWxlbWVudC50ZXh0Q29udGVudCwgbmV4dFByb3AsIGlzQ29uY3VycmVudE1vZGUsIHNob3VsZFdhcm5EZXYpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHVwZGF0ZVBheWxvYWQgPSBbQ0hJTERSRU4sICcnICsgbmV4dFByb3BdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZWdpc3RyYXRpb25OYW1lRGVwZW5kZW5jaWVzLmhhc093blByb3BlcnR5KHByb3BLZXkpKSB7XG4gICAgICBpZiAobmV4dFByb3AgIT0gbnVsbCkge1xuICAgICAgICBpZiAoIHR5cGVvZiBuZXh0UHJvcCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHdhcm5Gb3JJbnZhbGlkRXZlbnRMaXN0ZW5lcihwcm9wS2V5LCBuZXh0UHJvcCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcEtleSA9PT0gJ29uU2Nyb2xsJykge1xuICAgICAgICAgIGxpc3RlblRvTm9uRGVsZWdhdGVkRXZlbnQoJ3Njcm9sbCcsIGRvbUVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzaG91bGRXYXJuRGV2ICYmIHRydWUgJiYgLy8gQ29udmluY2UgRmxvdyB3ZSd2ZSBjYWxjdWxhdGVkIGl0IChpdCdzIERFVi1vbmx5IGluIHRoaXMgbWV0aG9kLilcbiAgICB0eXBlb2YgaXNDdXN0b21Db21wb25lbnRUYWcgPT09ICdib29sZWFuJykge1xuICAgICAgLy8gVmFsaWRhdGUgdGhhdCB0aGUgcHJvcGVydGllcyBjb3JyZXNwb25kIHRvIHRoZWlyIGV4cGVjdGVkIHZhbHVlcy5cbiAgICAgIHZhciBzZXJ2ZXJWYWx1ZSA9IHZvaWQgMDtcbiAgICAgIHZhciBwcm9wZXJ0eUluZm8gPSBpc0N1c3RvbUNvbXBvbmVudFRhZyAmJiBlbmFibGVDdXN0b21FbGVtZW50UHJvcGVydHlTdXBwb3J0ID8gbnVsbCA6IGdldFByb3BlcnR5SW5mbyhwcm9wS2V5KTtcblxuICAgICAgaWYgKHJhd1Byb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HXSA9PT0gdHJ1ZSkgOyBlbHNlIGlmIChwcm9wS2V5ID09PSBTVVBQUkVTU19DT05URU5UX0VESVRBQkxFX1dBUk5JTkcgfHwgcHJvcEtleSA9PT0gU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkcgfHwgLy8gQ29udHJvbGxlZCBhdHRyaWJ1dGVzIGFyZSBub3QgdmFsaWRhdGVkXG4gICAgICAvLyBUT0RPOiBPbmx5IGlnbm9yZSB0aGVtIG9uIGNvbnRyb2xsZWQgdGFncy5cbiAgICAgIHByb3BLZXkgPT09ICd2YWx1ZScgfHwgcHJvcEtleSA9PT0gJ2NoZWNrZWQnIHx8IHByb3BLZXkgPT09ICdzZWxlY3RlZCcpIDsgZWxzZSBpZiAocHJvcEtleSA9PT0gREFOR0VST1VTTFlfU0VUX0lOTkVSX0hUTUwpIHtcbiAgICAgICAgdmFyIHNlcnZlckhUTUwgPSBkb21FbGVtZW50LmlubmVySFRNTDtcbiAgICAgICAgdmFyIG5leHRIdG1sID0gbmV4dFByb3AgPyBuZXh0UHJvcFtIVE1MJDFdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChuZXh0SHRtbCAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIGV4cGVjdGVkSFRNTCA9IG5vcm1hbGl6ZUhUTUwoZG9tRWxlbWVudCwgbmV4dEh0bWwpO1xuXG4gICAgICAgICAgaWYgKGV4cGVjdGVkSFRNTCAhPT0gc2VydmVySFRNTCkge1xuICAgICAgICAgICAgd2FybkZvclByb3BEaWZmZXJlbmNlKHByb3BLZXksIHNlcnZlckhUTUwsIGV4cGVjdGVkSFRNTCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09IFNUWUxFKSB7XG4gICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgZXh0cmFBdHRyaWJ1dGVOYW1lcy5kZWxldGUocHJvcEtleSk7XG5cbiAgICAgICAgaWYgKGNhbkRpZmZTdHlsZUZvckh5ZHJhdGlvbldhcm5pbmcpIHtcbiAgICAgICAgICB2YXIgZXhwZWN0ZWRTdHlsZSA9IGNyZWF0ZURhbmdlcm91c1N0cmluZ0ZvclN0eWxlcyhuZXh0UHJvcCk7XG4gICAgICAgICAgc2VydmVyVmFsdWUgPSBkb21FbGVtZW50LmdldEF0dHJpYnV0ZSgnc3R5bGUnKTtcblxuICAgICAgICAgIGlmIChleHBlY3RlZFN0eWxlICE9PSBzZXJ2ZXJWYWx1ZSkge1xuICAgICAgICAgICAgd2FybkZvclByb3BEaWZmZXJlbmNlKHByb3BLZXksIHNlcnZlclZhbHVlLCBleHBlY3RlZFN0eWxlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNDdXN0b21Db21wb25lbnRUYWcgJiYgIWVuYWJsZUN1c3RvbUVsZW1lbnRQcm9wZXJ0eVN1cHBvcnQpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZSAtIFNob3VsZCBiZSBpbmZlcnJlZCBhcyBub3QgdW5kZWZpbmVkLlxuICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmRlbGV0ZShwcm9wS2V5LnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICBzZXJ2ZXJWYWx1ZSA9IGdldFZhbHVlRm9yQXR0cmlidXRlKGRvbUVsZW1lbnQsIHByb3BLZXksIG5leHRQcm9wKTtcblxuICAgICAgICBpZiAobmV4dFByb3AgIT09IHNlcnZlclZhbHVlKSB7XG4gICAgICAgICAgd2FybkZvclByb3BEaWZmZXJlbmNlKHByb3BLZXksIHNlcnZlclZhbHVlLCBuZXh0UHJvcCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIXNob3VsZElnbm9yZUF0dHJpYnV0ZShwcm9wS2V5LCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSAmJiAhc2hvdWxkUmVtb3ZlQXR0cmlidXRlKHByb3BLZXksIG5leHRQcm9wLCBwcm9wZXJ0eUluZm8sIGlzQ3VzdG9tQ29tcG9uZW50VGFnKSkge1xuICAgICAgICB2YXIgaXNNaXNtYXRjaER1ZVRvQmFkQ2FzaW5nID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHByb3BlcnR5SW5mbyAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgICBleHRyYUF0dHJpYnV0ZU5hbWVzLmRlbGV0ZShwcm9wZXJ0eUluZm8uYXR0cmlidXRlTmFtZSk7XG4gICAgICAgICAgc2VydmVyVmFsdWUgPSBnZXRWYWx1ZUZvclByb3BlcnR5KGRvbUVsZW1lbnQsIHByb3BLZXksIG5leHRQcm9wLCBwcm9wZXJ0eUluZm8pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBvd25OYW1lc3BhY2UgPSBwYXJlbnROYW1lc3BhY2U7XG5cbiAgICAgICAgICBpZiAob3duTmFtZXNwYWNlID09PSBIVE1MX05BTUVTUEFDRSkge1xuICAgICAgICAgICAgb3duTmFtZXNwYWNlID0gZ2V0SW50cmluc2ljTmFtZXNwYWNlKHRhZyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG93bk5hbWVzcGFjZSA9PT0gSFRNTF9OQU1FU1BBQ0UpIHtcbiAgICAgICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuZGVsZXRlKHByb3BLZXkudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBzdGFuZGFyZE5hbWUgPSBnZXRQb3NzaWJsZVN0YW5kYXJkTmFtZShwcm9wS2V5KTtcblxuICAgICAgICAgICAgaWYgKHN0YW5kYXJkTmFtZSAhPT0gbnVsbCAmJiBzdGFuZGFyZE5hbWUgIT09IHByb3BLZXkpIHtcbiAgICAgICAgICAgICAgLy8gSWYgYW4gU1ZHIHByb3AgaXMgc3VwcGxpZWQgd2l0aCBiYWQgY2FzaW5nLCBpdCB3aWxsXG4gICAgICAgICAgICAgIC8vIGJlIHN1Y2Nlc3NmdWxseSBwYXJzZWQgZnJvbSBIVE1MLCBidXQgd2lsbCBwcm9kdWNlIGEgbWlzbWF0Y2hcbiAgICAgICAgICAgICAgLy8gKGFuZCB3b3VsZCBiZSBpbmNvcnJlY3RseSByZW5kZXJlZCBvbiB0aGUgY2xpZW50KS5cbiAgICAgICAgICAgICAgLy8gSG93ZXZlciwgd2UgYWxyZWFkeSB3YXJuIGFib3V0IGJhZCBjYXNpbmcgZWxzZXdoZXJlLlxuICAgICAgICAgICAgICAvLyBTbyB3ZSdsbCBza2lwIHRoZSBtaXNsZWFkaW5nIGV4dHJhIG1pc21hdGNoIHdhcm5pbmcgaW4gdGhpcyBjYXNlLlxuICAgICAgICAgICAgICBpc01pc21hdGNoRHVlVG9CYWRDYXNpbmcgPSB0cnVlOyAvLyAkRmxvd0ZpeE1lIC0gU2hvdWxkIGJlIGluZmVycmVkIGFzIG5vdCB1bmRlZmluZWQuXG5cbiAgICAgICAgICAgICAgZXh0cmFBdHRyaWJ1dGVOYW1lcy5kZWxldGUoc3RhbmRhcmROYW1lKTtcbiAgICAgICAgICAgIH0gLy8gJEZsb3dGaXhNZSAtIFNob3VsZCBiZSBpbmZlcnJlZCBhcyBub3QgdW5kZWZpbmVkLlxuXG5cbiAgICAgICAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuZGVsZXRlKHByb3BLZXkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHNlcnZlclZhbHVlID0gZ2V0VmFsdWVGb3JBdHRyaWJ1dGUoZG9tRWxlbWVudCwgcHJvcEtleSwgbmV4dFByb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRvbnRXYXJuQ3VzdG9tRWxlbWVudCA9IGVuYWJsZUN1c3RvbUVsZW1lbnRQcm9wZXJ0eVN1cHBvcnQgIDtcblxuICAgICAgICBpZiAoIWRvbnRXYXJuQ3VzdG9tRWxlbWVudCAmJiBuZXh0UHJvcCAhPT0gc2VydmVyVmFsdWUgJiYgIWlzTWlzbWF0Y2hEdWVUb0JhZENhc2luZykge1xuICAgICAgICAgIHdhcm5Gb3JQcm9wRGlmZmVyZW5jZShwcm9wS2V5LCBzZXJ2ZXJWYWx1ZSwgbmV4dFByb3ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAge1xuICAgIGlmIChzaG91bGRXYXJuRGV2KSB7XG4gICAgICBpZiAoIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgIGV4dHJhQXR0cmlidXRlTmFtZXMuc2l6ZSA+IDAgJiYgcmF3UHJvcHNbU1VQUFJFU1NfSFlEUkFUSU9OX1dBUk5JTkddICE9PSB0cnVlKSB7XG4gICAgICAgIC8vICRGbG93Rml4TWUgLSBTaG91bGQgYmUgaW5mZXJyZWQgYXMgbm90IHVuZGVmaW5lZC5cbiAgICAgICAgd2FybkZvckV4dHJhQXR0cmlidXRlcyhleHRyYUF0dHJpYnV0ZU5hbWVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgJ2lucHV0JzpcbiAgICAgIC8vIFRPRE86IE1ha2Ugc3VyZSB3ZSBjaGVjayBpZiB0aGlzIGlzIHN0aWxsIHVubW91bnRlZCBvciBkbyBhbnkgY2xlYW5cbiAgICAgIC8vIHVwIG5lY2Vzc2FyeSBzaW5jZSB3ZSBuZXZlciBzdG9wIHRyYWNraW5nIGFueW1vcmUuXG4gICAgICB0cmFjayhkb21FbGVtZW50KTtcbiAgICAgIHBvc3RNb3VudFdyYXBwZXIoZG9tRWxlbWVudCwgcmF3UHJvcHMsIHRydWUpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgd2UgY2hlY2sgaWYgdGhpcyBpcyBzdGlsbCB1bm1vdW50ZWQgb3IgZG8gYW55IGNsZWFuXG4gICAgICAvLyB1cCBuZWNlc3Nhcnkgc2luY2Ugd2UgbmV2ZXIgc3RvcCB0cmFja2luZyBhbnltb3JlLlxuICAgICAgdHJhY2soZG9tRWxlbWVudCk7XG4gICAgICBwb3N0TW91bnRXcmFwcGVyJDMoZG9tRWxlbWVudCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgIC8vIEZvciBpbnB1dCBhbmQgdGV4dGFyZWEgd2UgY3VycmVudCBhbHdheXMgc2V0IHRoZSB2YWx1ZSBwcm9wZXJ0eSBhdFxuICAgICAgLy8gcG9zdCBtb3VudCB0byBmb3JjZSBpdCB0byBkaXZlcmdlIGZyb20gYXR0cmlidXRlcy4gSG93ZXZlciwgZm9yXG4gICAgICAvLyBvcHRpb24gYW5kIHNlbGVjdCB3ZSBkb24ndCBxdWl0ZSBkbyB0aGUgc2FtZSB0aGluZyBhbmQgc2VsZWN0XG4gICAgICAvLyBpcyBub3QgcmVzaWxpZW50IHRvIHRoZSBET00gc3RhdGUgY2hhbmdpbmcgc28gd2UgZG9uJ3QgZG8gdGhhdCBoZXJlLlxuICAgICAgLy8gVE9ETzogQ29uc2lkZXIgbm90IGRvaW5nIHRoaXMgZm9yIGlucHV0IGFuZCB0ZXh0YXJlYS5cbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGlmICh0eXBlb2YgcmF3UHJvcHMub25DbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgICAgICB0cmFwQ2xpY2tPbk5vbkludGVyYWN0aXZlRWxlbWVudChkb21FbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gdXBkYXRlUGF5bG9hZDtcbn1cbmZ1bmN0aW9uIGRpZmZIeWRyYXRlZFRleHQodGV4dE5vZGUsIHRleHQsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAgdmFyIGlzRGlmZmVyZW50ID0gdGV4dE5vZGUubm9kZVZhbHVlICE9PSB0ZXh0O1xuICByZXR1cm4gaXNEaWZmZXJlbnQ7XG59XG5mdW5jdGlvbiB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVFbGVtZW50KHBhcmVudE5vZGUsIGNoaWxkKSB7XG4gIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICBlcnJvcignRGlkIG5vdCBleHBlY3Qgc2VydmVyIEhUTUwgdG8gY29udGFpbiBhIDwlcz4gaW4gPCVzPi4nLCBjaGlsZC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLCBwYXJlbnROb2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpO1xuICB9XG59XG5mdW5jdGlvbiB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVUZXh0KHBhcmVudE5vZGUsIGNoaWxkKSB7XG4gIHtcbiAgICBpZiAoZGlkV2FybkludmFsaWRIeWRyYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbiA9IHRydWU7XG5cbiAgICBlcnJvcignRGlkIG5vdCBleHBlY3Qgc2VydmVyIEhUTUwgdG8gY29udGFpbiB0aGUgdGV4dCBub2RlIFwiJXNcIiBpbiA8JXM+LicsIGNoaWxkLm5vZGVWYWx1ZSwgcGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gd2FybkZvckluc2VydGVkSHlkcmF0ZWRFbGVtZW50KHBhcmVudE5vZGUsIHRhZywgcHJvcHMpIHtcbiAge1xuICAgIGlmIChkaWRXYXJuSW52YWxpZEh5ZHJhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uID0gdHJ1ZTtcblxuICAgIGVycm9yKCdFeHBlY3RlZCBzZXJ2ZXIgSFRNTCB0byBjb250YWluIGEgbWF0Y2hpbmcgPCVzPiBpbiA8JXM+LicsIHRhZywgcGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudE5vZGUsIHRleHQpIHtcbiAge1xuICAgIGlmICh0ZXh0ID09PSAnJykge1xuICAgICAgLy8gV2UgZXhwZWN0IHRvIGluc2VydCBlbXB0eSB0ZXh0IG5vZGVzIHNpbmNlIHRoZXkncmUgbm90IHJlcHJlc2VudGVkIGluXG4gICAgICAvLyB0aGUgSFRNTC5cbiAgICAgIC8vIFRPRE86IFJlbW92ZSB0aGlzIHNwZWNpYWwgY2FzZSBpZiB3ZSBjYW4ganVzdCBhdm9pZCBpbnNlcnRpbmcgZW1wdHlcbiAgICAgIC8vIHRleHQgbm9kZXMuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGRpZFdhcm5JbnZhbGlkSHlkcmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZGlkV2FybkludmFsaWRIeWRyYXRpb24gPSB0cnVlO1xuXG4gICAgZXJyb3IoJ0V4cGVjdGVkIHNlcnZlciBIVE1MIHRvIGNvbnRhaW4gYSBtYXRjaGluZyB0ZXh0IG5vZGUgZm9yIFwiJXNcIiBpbiA8JXM+LicsIHRleHQsIHBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSk7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMyhkb21FbGVtZW50LCB0YWcsIHByb3BzKSB7XG4gIHN3aXRjaCAodGFnKSB7XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgICAgcmVzdG9yZUNvbnRyb2xsZWRTdGF0ZShkb21FbGVtZW50LCBwcm9wcyk7XG4gICAgICByZXR1cm47XG5cbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICByZXN0b3JlQ29udHJvbGxlZFN0YXRlJDIoZG9tRWxlbWVudCwgcHJvcHMpO1xuICAgICAgcmV0dXJuO1xuXG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgIHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMShkb21FbGVtZW50LCBwcm9wcyk7XG4gICAgICByZXR1cm47XG4gIH1cbn1cblxudmFyIHZhbGlkYXRlRE9NTmVzdGluZyA9IGZ1bmN0aW9uICgpIHt9O1xuXG52YXIgdXBkYXRlZEFuY2VzdG9ySW5mbyA9IGZ1bmN0aW9uICgpIHt9O1xuXG57XG4gIC8vIFRoaXMgdmFsaWRhdGlvbiBjb2RlIHdhcyB3cml0dGVuIGJhc2VkIG9uIHRoZSBIVE1MNSBwYXJzaW5nIHNwZWM6XG4gIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2hhcy1hbi1lbGVtZW50LWluLXNjb3BlXG4gIC8vXG4gIC8vIE5vdGU6IHRoaXMgZG9lcyBub3QgY2F0Y2ggYWxsIGludmFsaWQgbmVzdGluZywgbm9yIGRvZXMgaXQgdHJ5IHRvIChhcyBpdCdzXG4gIC8vIG5vdCBjbGVhciB3aGF0IHByYWN0aWNhbCBiZW5lZml0IGRvaW5nIHNvIHByb3ZpZGVzKTsgaW5zdGVhZCwgd2Ugd2FybiBvbmx5XG4gIC8vIGZvciBjYXNlcyB3aGVyZSB0aGUgcGFyc2VyIHdpbGwgZ2l2ZSBhIHBhcnNlIHRyZWUgZGlmZmVyaW5nIGZyb20gd2hhdCBSZWFjdFxuICAvLyBpbnRlbmRlZC4gRm9yIGV4YW1wbGUsIDxiPjxkaXY+PC9kaXY+PC9iPiBpcyBpbnZhbGlkIGJ1dCB3ZSBkb24ndCB3YXJuXG4gIC8vIGJlY2F1c2UgaXQgc3RpbGwgcGFyc2VzIGNvcnJlY3RseTsgd2UgZG8gd2FybiBmb3Igb3RoZXIgY2FzZXMgbGlrZSBuZXN0ZWRcbiAgLy8gPHA+IHRhZ3Mgd2hlcmUgdGhlIGJlZ2lubmluZyBvZiB0aGUgc2Vjb25kIGVsZW1lbnQgaW1wbGljaXRseSBjbG9zZXMgdGhlXG4gIC8vIGZpcnN0LCBjYXVzaW5nIGEgY29uZnVzaW5nIG1lc3MuXG4gIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3NwZWNpYWxcbiAgdmFyIHNwZWNpYWxUYWdzID0gWydhZGRyZXNzJywgJ2FwcGxldCcsICdhcmVhJywgJ2FydGljbGUnLCAnYXNpZGUnLCAnYmFzZScsICdiYXNlZm9udCcsICdiZ3NvdW5kJywgJ2Jsb2NrcXVvdGUnLCAnYm9keScsICdicicsICdidXR0b24nLCAnY2FwdGlvbicsICdjZW50ZXInLCAnY29sJywgJ2NvbGdyb3VwJywgJ2RkJywgJ2RldGFpbHMnLCAnZGlyJywgJ2RpdicsICdkbCcsICdkdCcsICdlbWJlZCcsICdmaWVsZHNldCcsICdmaWdjYXB0aW9uJywgJ2ZpZ3VyZScsICdmb290ZXInLCAnZm9ybScsICdmcmFtZScsICdmcmFtZXNldCcsICdoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNicsICdoZWFkJywgJ2hlYWRlcicsICdoZ3JvdXAnLCAnaHInLCAnaHRtbCcsICdpZnJhbWUnLCAnaW1nJywgJ2lucHV0JywgJ2lzaW5kZXgnLCAnbGknLCAnbGluaycsICdsaXN0aW5nJywgJ21haW4nLCAnbWFycXVlZScsICdtZW51JywgJ21lbnVpdGVtJywgJ21ldGEnLCAnbmF2JywgJ25vZW1iZWQnLCAnbm9mcmFtZXMnLCAnbm9zY3JpcHQnLCAnb2JqZWN0JywgJ29sJywgJ3AnLCAncGFyYW0nLCAncGxhaW50ZXh0JywgJ3ByZScsICdzY3JpcHQnLCAnc2VjdGlvbicsICdzZWxlY3QnLCAnc291cmNlJywgJ3N0eWxlJywgJ3N1bW1hcnknLCAndGFibGUnLCAndGJvZHknLCAndGQnLCAndGVtcGxhdGUnLCAndGV4dGFyZWEnLCAndGZvb3QnLCAndGgnLCAndGhlYWQnLCAndGl0bGUnLCAndHInLCAndHJhY2snLCAndWwnLCAnd2JyJywgJ3htcCddOyAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNoYXMtYW4tZWxlbWVudC1pbi1zY29wZVxuXG4gIHZhciBpblNjb3BlVGFncyA9IFsnYXBwbGV0JywgJ2NhcHRpb24nLCAnaHRtbCcsICd0YWJsZScsICd0ZCcsICd0aCcsICdtYXJxdWVlJywgJ29iamVjdCcsICd0ZW1wbGF0ZScsIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2h0bWwtaW50ZWdyYXRpb24tcG9pbnRcbiAgLy8gVE9ETzogRGlzdGluZ3Vpc2ggYnkgbmFtZXNwYWNlIGhlcmUgLS0gZm9yIDx0aXRsZT4sIGluY2x1ZGluZyBpdCBoZXJlXG4gIC8vIGVycnMgb24gdGhlIHNpZGUgb2YgZmV3ZXIgd2FybmluZ3NcbiAgJ2ZvcmVpZ25PYmplY3QnLCAnZGVzYycsICd0aXRsZSddOyAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNoYXMtYW4tZWxlbWVudC1pbi1idXR0b24tc2NvcGVcblxuICB2YXIgYnV0dG9uU2NvcGVUYWdzID0gaW5TY29wZVRhZ3MuY29uY2F0KFsnYnV0dG9uJ10pOyAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNnZW5lcmF0ZS1pbXBsaWVkLWVuZC10YWdzXG5cbiAgdmFyIGltcGxpZWRFbmRUYWdzID0gWydkZCcsICdkdCcsICdsaScsICdvcHRpb24nLCAnb3B0Z3JvdXAnLCAncCcsICdycCcsICdydCddO1xuICB2YXIgZW1wdHlBbmNlc3RvckluZm8gPSB7XG4gICAgY3VycmVudDogbnVsbCxcbiAgICBmb3JtVGFnOiBudWxsLFxuICAgIGFUYWdJblNjb3BlOiBudWxsLFxuICAgIGJ1dHRvblRhZ0luU2NvcGU6IG51bGwsXG4gICAgbm9iclRhZ0luU2NvcGU6IG51bGwsXG4gICAgcFRhZ0luQnV0dG9uU2NvcGU6IG51bGwsXG4gICAgbGlzdEl0ZW1UYWdBdXRvY2xvc2luZzogbnVsbCxcbiAgICBkbEl0ZW1UYWdBdXRvY2xvc2luZzogbnVsbFxuICB9O1xuXG4gIHVwZGF0ZWRBbmNlc3RvckluZm8gPSBmdW5jdGlvbiAob2xkSW5mbywgdGFnKSB7XG4gICAgdmFyIGFuY2VzdG9ySW5mbyA9IGFzc2lnbih7fSwgb2xkSW5mbyB8fCBlbXB0eUFuY2VzdG9ySW5mbyk7XG5cbiAgICB2YXIgaW5mbyA9IHtcbiAgICAgIHRhZzogdGFnXG4gICAgfTtcblxuICAgIGlmIChpblNjb3BlVGFncy5pbmRleE9mKHRhZykgIT09IC0xKSB7XG4gICAgICBhbmNlc3RvckluZm8uYVRhZ0luU2NvcGUgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLmJ1dHRvblRhZ0luU2NvcGUgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLm5vYnJUYWdJblNjb3BlID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoYnV0dG9uU2NvcGVUYWdzLmluZGV4T2YodGFnKSAhPT0gLTEpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5wVGFnSW5CdXR0b25TY29wZSA9IG51bGw7XG4gICAgfSAvLyBTZWUgcnVsZXMgZm9yICdsaScsICdkZCcsICdkdCcgc3RhcnQgdGFncyBpblxuICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmJvZHlcblxuXG4gICAgaWYgKHNwZWNpYWxUYWdzLmluZGV4T2YodGFnKSAhPT0gLTEgJiYgdGFnICE9PSAnYWRkcmVzcycgJiYgdGFnICE9PSAnZGl2JyAmJiB0YWcgIT09ICdwJykge1xuICAgICAgYW5jZXN0b3JJbmZvLmxpc3RJdGVtVGFnQXV0b2Nsb3NpbmcgPSBudWxsO1xuICAgICAgYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nID0gbnVsbDtcbiAgICB9XG5cbiAgICBhbmNlc3RvckluZm8uY3VycmVudCA9IGluZm87XG5cbiAgICBpZiAodGFnID09PSAnZm9ybScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5mb3JtVGFnID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnYScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5hVGFnSW5TY29wZSA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ2J1dHRvbicpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5idXR0b25UYWdJblNjb3BlID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnbm9icicpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5ub2JyVGFnSW5TY29wZSA9IGluZm87XG4gICAgfVxuXG4gICAgaWYgKHRhZyA9PT0gJ3AnKSB7XG4gICAgICBhbmNlc3RvckluZm8ucFRhZ0luQnV0dG9uU2NvcGUgPSBpbmZvO1xuICAgIH1cblxuICAgIGlmICh0YWcgPT09ICdsaScpIHtcbiAgICAgIGFuY2VzdG9ySW5mby5saXN0SXRlbVRhZ0F1dG9jbG9zaW5nID0gaW5mbztcbiAgICB9XG5cbiAgICBpZiAodGFnID09PSAnZGQnIHx8IHRhZyA9PT0gJ2R0Jykge1xuICAgICAgYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nID0gaW5mbztcbiAgICB9XG5cbiAgICByZXR1cm4gYW5jZXN0b3JJbmZvO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyXG4gICAqL1xuXG5cbiAgdmFyIGlzVGFnVmFsaWRXaXRoUGFyZW50ID0gZnVuY3Rpb24gKHRhZywgcGFyZW50VGFnKSB7XG4gICAgLy8gRmlyc3QsIGxldCdzIGNoZWNrIGlmIHdlJ3JlIGluIGFuIHVudXN1YWwgcGFyc2luZyBtb2RlLi4uXG4gICAgc3dpdGNoIChwYXJlbnRUYWcpIHtcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnNlbGVjdFxuICAgICAgY2FzZSAnc2VsZWN0JzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ29wdGlvbicgfHwgdGFnID09PSAnb3B0Z3JvdXAnIHx8IHRhZyA9PT0gJyN0ZXh0JztcblxuICAgICAgY2FzZSAnb3B0Z3JvdXAnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnb3B0aW9uJyB8fCB0YWcgPT09ICcjdGV4dCc7XG4gICAgICAvLyBTdHJpY3RseSBzcGVha2luZywgc2VlaW5nIGFuIDxvcHRpb24+IGRvZXNuJ3QgbWVhbiB3ZSdyZSBpbiBhIDxzZWxlY3Q+XG4gICAgICAvLyBidXRcblxuICAgICAgY2FzZSAnb3B0aW9uJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJyN0ZXh0JztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRkXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5jYXB0aW9uXG4gICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yIHNpbmNlIHRoZXNlIHJ1bGVzIGZhbGwgYmFjayB0byBcImluIGJvZHlcIiBtb2RlIGZvclxuICAgICAgLy8gYWxsIGV4Y2VwdCBzcGVjaWFsIHRhYmxlIG5vZGVzIHdoaWNoIGNhdXNlIGJhZCBwYXJzaW5nIGJlaGF2aW9yIGFueXdheS5cbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbnRyXG5cbiAgICAgIGNhc2UgJ3RyJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ3RoJyB8fCB0YWcgPT09ICd0ZCcgfHwgdGFnID09PSAnc3R5bGUnIHx8IHRhZyA9PT0gJ3NjcmlwdCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWludGJvZHlcblxuICAgICAgY2FzZSAndGJvZHknOlxuICAgICAgY2FzZSAndGhlYWQnOlxuICAgICAgY2FzZSAndGZvb3QnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAndHInIHx8IHRhZyA9PT0gJ3N0eWxlJyB8fCB0YWcgPT09ICdzY3JpcHQnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmNvbGdyb3VwXG5cbiAgICAgIGNhc2UgJ2NvbGdyb3VwJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2NvbCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjcGFyc2luZy1tYWluLWludGFibGVcblxuICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnY2FwdGlvbicgfHwgdGFnID09PSAnY29sZ3JvdXAnIHx8IHRhZyA9PT0gJ3Rib2R5JyB8fCB0YWcgPT09ICd0Zm9vdCcgfHwgdGFnID09PSAndGhlYWQnIHx8IHRhZyA9PT0gJ3N0eWxlJyB8fCB0YWcgPT09ICdzY3JpcHQnIHx8IHRhZyA9PT0gJ3RlbXBsYXRlJztcbiAgICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmhlYWRcblxuICAgICAgY2FzZSAnaGVhZCc6XG4gICAgICAgIHJldHVybiB0YWcgPT09ICdiYXNlJyB8fCB0YWcgPT09ICdiYXNlZm9udCcgfHwgdGFnID09PSAnYmdzb3VuZCcgfHwgdGFnID09PSAnbGluaycgfHwgdGFnID09PSAnbWV0YScgfHwgdGFnID09PSAndGl0bGUnIHx8IHRhZyA9PT0gJ25vc2NyaXB0JyB8fCB0YWcgPT09ICdub2ZyYW1lcycgfHwgdGFnID09PSAnc3R5bGUnIHx8IHRhZyA9PT0gJ3NjcmlwdCcgfHwgdGFnID09PSAndGVtcGxhdGUnO1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2VtYW50aWNzLmh0bWwjdGhlLWh0bWwtZWxlbWVudFxuXG4gICAgICBjYXNlICdodG1sJzpcbiAgICAgICAgcmV0dXJuIHRhZyA9PT0gJ2hlYWQnIHx8IHRhZyA9PT0gJ2JvZHknIHx8IHRhZyA9PT0gJ2ZyYW1lc2V0JztcblxuICAgICAgY2FzZSAnZnJhbWVzZXQnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnZnJhbWUnO1xuXG4gICAgICBjYXNlICcjZG9jdW1lbnQnOlxuICAgICAgICByZXR1cm4gdGFnID09PSAnaHRtbCc7XG4gICAgfSAvLyBQcm9iYWJseSBpbiB0aGUgXCJpbiBib2R5XCIgcGFyc2luZyBtb2RlLCBzbyB3ZSBvdXRsYXcgb25seSB0YWcgY29tYm9zXG4gICAgLy8gd2hlcmUgdGhlIHBhcnNpbmcgcnVsZXMgY2F1c2UgaW1wbGljaXQgb3BlbnMgb3IgY2xvc2VzIHRvIGJlIGFkZGVkLlxuICAgIC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmJvZHlcblxuXG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgJ2gxJzpcbiAgICAgIGNhc2UgJ2gyJzpcbiAgICAgIGNhc2UgJ2gzJzpcbiAgICAgIGNhc2UgJ2g0JzpcbiAgICAgIGNhc2UgJ2g1JzpcbiAgICAgIGNhc2UgJ2g2JzpcbiAgICAgICAgcmV0dXJuIHBhcmVudFRhZyAhPT0gJ2gxJyAmJiBwYXJlbnRUYWcgIT09ICdoMicgJiYgcGFyZW50VGFnICE9PSAnaDMnICYmIHBhcmVudFRhZyAhPT0gJ2g0JyAmJiBwYXJlbnRUYWcgIT09ICdoNScgJiYgcGFyZW50VGFnICE9PSAnaDYnO1xuXG4gICAgICBjYXNlICdycCc6XG4gICAgICBjYXNlICdydCc6XG4gICAgICAgIHJldHVybiBpbXBsaWVkRW5kVGFncy5pbmRleE9mKHBhcmVudFRhZykgPT09IC0xO1xuXG4gICAgICBjYXNlICdib2R5JzpcbiAgICAgIGNhc2UgJ2NhcHRpb24nOlxuICAgICAgY2FzZSAnY29sJzpcbiAgICAgIGNhc2UgJ2NvbGdyb3VwJzpcbiAgICAgIGNhc2UgJ2ZyYW1lc2V0JzpcbiAgICAgIGNhc2UgJ2ZyYW1lJzpcbiAgICAgIGNhc2UgJ2hlYWQnOlxuICAgICAgY2FzZSAnaHRtbCc6XG4gICAgICBjYXNlICd0Ym9keSc6XG4gICAgICBjYXNlICd0ZCc6XG4gICAgICBjYXNlICd0Zm9vdCc6XG4gICAgICBjYXNlICd0aCc6XG4gICAgICBjYXNlICd0aGVhZCc6XG4gICAgICBjYXNlICd0cic6XG4gICAgICAgIC8vIFRoZXNlIHRhZ3MgYXJlIG9ubHkgdmFsaWQgd2l0aCBhIGZldyBwYXJlbnRzIHRoYXQgaGF2ZSBzcGVjaWFsIGNoaWxkXG4gICAgICAgIC8vIHBhcnNpbmcgcnVsZXMgLS0gaWYgd2UncmUgZG93biBoZXJlLCB0aGVuIG5vbmUgb2YgdGhvc2UgbWF0Y2hlZCBhbmRcbiAgICAgICAgLy8gc28gd2UgYWxsb3cgaXQgb25seSBpZiB3ZSBkb24ndCBrbm93IHdoYXQgdGhlIHBhcmVudCBpcywgYXMgYWxsIG90aGVyXG4gICAgICAgIC8vIGNhc2VzIGFyZSBpbnZhbGlkLlxuICAgICAgICByZXR1cm4gcGFyZW50VGFnID09IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXJcbiAgICovXG5cblxuICB2YXIgZmluZEludmFsaWRBbmNlc3RvckZvclRhZyA9IGZ1bmN0aW9uICh0YWcsIGFuY2VzdG9ySW5mbykge1xuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlICdhZGRyZXNzJzpcbiAgICAgIGNhc2UgJ2FydGljbGUnOlxuICAgICAgY2FzZSAnYXNpZGUnOlxuICAgICAgY2FzZSAnYmxvY2txdW90ZSc6XG4gICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgY2FzZSAnZGV0YWlscyc6XG4gICAgICBjYXNlICdkaWFsb2cnOlxuICAgICAgY2FzZSAnZGlyJzpcbiAgICAgIGNhc2UgJ2Rpdic6XG4gICAgICBjYXNlICdkbCc6XG4gICAgICBjYXNlICdmaWVsZHNldCc6XG4gICAgICBjYXNlICdmaWdjYXB0aW9uJzpcbiAgICAgIGNhc2UgJ2ZpZ3VyZSc6XG4gICAgICBjYXNlICdmb290ZXInOlxuICAgICAgY2FzZSAnaGVhZGVyJzpcbiAgICAgIGNhc2UgJ2hncm91cCc6XG4gICAgICBjYXNlICdtYWluJzpcbiAgICAgIGNhc2UgJ21lbnUnOlxuICAgICAgY2FzZSAnbmF2JzpcbiAgICAgIGNhc2UgJ29sJzpcbiAgICAgIGNhc2UgJ3AnOlxuICAgICAgY2FzZSAnc2VjdGlvbic6XG4gICAgICBjYXNlICdzdW1tYXJ5JzpcbiAgICAgIGNhc2UgJ3VsJzpcbiAgICAgIGNhc2UgJ3ByZSc6XG4gICAgICBjYXNlICdsaXN0aW5nJzpcbiAgICAgIGNhc2UgJ3RhYmxlJzpcbiAgICAgIGNhc2UgJ2hyJzpcbiAgICAgIGNhc2UgJ3htcCc6XG4gICAgICBjYXNlICdoMSc6XG4gICAgICBjYXNlICdoMic6XG4gICAgICBjYXNlICdoMyc6XG4gICAgICBjYXNlICdoNCc6XG4gICAgICBjYXNlICdoNSc6XG4gICAgICBjYXNlICdoNic6XG4gICAgICAgIHJldHVybiBhbmNlc3RvckluZm8ucFRhZ0luQnV0dG9uU2NvcGU7XG5cbiAgICAgIGNhc2UgJ2Zvcm0nOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmZvcm1UYWcgfHwgYW5jZXN0b3JJbmZvLnBUYWdJbkJ1dHRvblNjb3BlO1xuXG4gICAgICBjYXNlICdsaSc6XG4gICAgICAgIHJldHVybiBhbmNlc3RvckluZm8ubGlzdEl0ZW1UYWdBdXRvY2xvc2luZztcblxuICAgICAgY2FzZSAnZGQnOlxuICAgICAgY2FzZSAnZHQnOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmRsSXRlbVRhZ0F1dG9jbG9zaW5nO1xuXG4gICAgICBjYXNlICdidXR0b24nOlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmJ1dHRvblRhZ0luU2NvcGU7XG5cbiAgICAgIGNhc2UgJ2EnOlxuICAgICAgICAvLyBTcGVjIHNheXMgc29tZXRoaW5nIGFib3V0IHN0b3JpbmcgYSBsaXN0IG9mIG1hcmtlcnMsIGJ1dCBpdCBzb3VuZHNcbiAgICAgICAgLy8gZXF1aXZhbGVudCB0byB0aGlzIGNoZWNrLlxuICAgICAgICByZXR1cm4gYW5jZXN0b3JJbmZvLmFUYWdJblNjb3BlO1xuXG4gICAgICBjYXNlICdub2JyJzpcbiAgICAgICAgcmV0dXJuIGFuY2VzdG9ySW5mby5ub2JyVGFnSW5TY29wZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB2YXIgZGlkV2FybiQxID0ge307XG5cbiAgdmFsaWRhdGVET01OZXN0aW5nID0gZnVuY3Rpb24gKGNoaWxkVGFnLCBjaGlsZFRleHQsIGFuY2VzdG9ySW5mbykge1xuICAgIGFuY2VzdG9ySW5mbyA9IGFuY2VzdG9ySW5mbyB8fCBlbXB0eUFuY2VzdG9ySW5mbztcbiAgICB2YXIgcGFyZW50SW5mbyA9IGFuY2VzdG9ySW5mby5jdXJyZW50O1xuICAgIHZhciBwYXJlbnRUYWcgPSBwYXJlbnRJbmZvICYmIHBhcmVudEluZm8udGFnO1xuXG4gICAgaWYgKGNoaWxkVGV4dCAhPSBudWxsKSB7XG4gICAgICBpZiAoY2hpbGRUYWcgIT0gbnVsbCkge1xuICAgICAgICBlcnJvcigndmFsaWRhdGVET01OZXN0aW5nOiB3aGVuIGNoaWxkVGV4dCBpcyBwYXNzZWQsIGNoaWxkVGFnIHNob3VsZCBiZSBudWxsJyk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkVGFnID0gJyN0ZXh0JztcbiAgICB9XG5cbiAgICB2YXIgaW52YWxpZFBhcmVudCA9IGlzVGFnVmFsaWRXaXRoUGFyZW50KGNoaWxkVGFnLCBwYXJlbnRUYWcpID8gbnVsbCA6IHBhcmVudEluZm87XG4gICAgdmFyIGludmFsaWRBbmNlc3RvciA9IGludmFsaWRQYXJlbnQgPyBudWxsIDogZmluZEludmFsaWRBbmNlc3RvckZvclRhZyhjaGlsZFRhZywgYW5jZXN0b3JJbmZvKTtcbiAgICB2YXIgaW52YWxpZFBhcmVudE9yQW5jZXN0b3IgPSBpbnZhbGlkUGFyZW50IHx8IGludmFsaWRBbmNlc3RvcjtcblxuICAgIGlmICghaW52YWxpZFBhcmVudE9yQW5jZXN0b3IpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYW5jZXN0b3JUYWcgPSBpbnZhbGlkUGFyZW50T3JBbmNlc3Rvci50YWc7XG4gICAgdmFyIHdhcm5LZXkgPSAhIWludmFsaWRQYXJlbnQgKyAnfCcgKyBjaGlsZFRhZyArICd8JyArIGFuY2VzdG9yVGFnO1xuXG4gICAgaWYgKGRpZFdhcm4kMVt3YXJuS2V5XSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRpZFdhcm4kMVt3YXJuS2V5XSA9IHRydWU7XG4gICAgdmFyIHRhZ0Rpc3BsYXlOYW1lID0gY2hpbGRUYWc7XG4gICAgdmFyIHdoaXRlc3BhY2VJbmZvID0gJyc7XG5cbiAgICBpZiAoY2hpbGRUYWcgPT09ICcjdGV4dCcpIHtcbiAgICAgIGlmICgvXFxTLy50ZXN0KGNoaWxkVGV4dCkpIHtcbiAgICAgICAgdGFnRGlzcGxheU5hbWUgPSAnVGV4dCBub2Rlcyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWdEaXNwbGF5TmFtZSA9ICdXaGl0ZXNwYWNlIHRleHQgbm9kZXMnO1xuICAgICAgICB3aGl0ZXNwYWNlSW5mbyA9IFwiIE1ha2Ugc3VyZSB5b3UgZG9uJ3QgaGF2ZSBhbnkgZXh0cmEgd2hpdGVzcGFjZSBiZXR3ZWVuIHRhZ3Mgb24gXCIgKyAnZWFjaCBsaW5lIG9mIHlvdXIgc291cmNlIGNvZGUuJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGFnRGlzcGxheU5hbWUgPSAnPCcgKyBjaGlsZFRhZyArICc+JztcbiAgICB9XG5cbiAgICBpZiAoaW52YWxpZFBhcmVudCkge1xuICAgICAgdmFyIGluZm8gPSAnJztcblxuICAgICAgaWYgKGFuY2VzdG9yVGFnID09PSAndGFibGUnICYmIGNoaWxkVGFnID09PSAndHInKSB7XG4gICAgICAgIGluZm8gKz0gJyBBZGQgYSA8dGJvZHk+LCA8dGhlYWQ+IG9yIDx0Zm9vdD4gdG8geW91ciBjb2RlIHRvIG1hdGNoIHRoZSBET00gdHJlZSBnZW5lcmF0ZWQgYnkgJyArICd0aGUgYnJvd3Nlci4nO1xuICAgICAgfVxuXG4gICAgICBlcnJvcigndmFsaWRhdGVET01OZXN0aW5nKC4uLik6ICVzIGNhbm5vdCBhcHBlYXIgYXMgYSBjaGlsZCBvZiA8JXM+LiVzJXMnLCB0YWdEaXNwbGF5TmFtZSwgYW5jZXN0b3JUYWcsIHdoaXRlc3BhY2VJbmZvLCBpbmZvKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3IoJ3ZhbGlkYXRlRE9NTmVzdGluZyguLi4pOiAlcyBjYW5ub3QgYXBwZWFyIGFzIGEgZGVzY2VuZGFudCBvZiAnICsgJzwlcz4uJywgdGFnRGlzcGxheU5hbWUsIGFuY2VzdG9yVGFnKTtcbiAgICB9XG4gIH07XG59XG5cbnZhciBTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyQxID0gJ3N1cHByZXNzSHlkcmF0aW9uV2FybmluZyc7XG52YXIgU1VTUEVOU0VfU1RBUlRfREFUQSA9ICckJztcbnZhciBTVVNQRU5TRV9FTkRfREFUQSA9ICcvJCc7XG52YXIgU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBID0gJyQ/JztcbnZhciBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBID0gJyQhJztcbnZhciBTVFlMRSQxID0gJ3N0eWxlJztcbnZhciBldmVudHNFbmFibGVkID0gbnVsbDtcbnZhciBzZWxlY3Rpb25JbmZvcm1hdGlvbiA9IG51bGw7XG5mdW5jdGlvbiBnZXRSb290SG9zdENvbnRleHQocm9vdENvbnRhaW5lckluc3RhbmNlKSB7XG4gIHZhciB0eXBlO1xuICB2YXIgbmFtZXNwYWNlO1xuICB2YXIgbm9kZVR5cGUgPSByb290Q29udGFpbmVySW5zdGFuY2Uubm9kZVR5cGU7XG5cbiAgc3dpdGNoIChub2RlVHlwZSkge1xuICAgIGNhc2UgRE9DVU1FTlRfTk9ERTpcbiAgICBjYXNlIERPQ1VNRU5UX0ZSQUdNRU5UX05PREU6XG4gICAgICB7XG4gICAgICAgIHR5cGUgPSBub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSA/ICcjZG9jdW1lbnQnIDogJyNmcmFnbWVudCc7XG4gICAgICAgIHZhciByb290ID0gcm9vdENvbnRhaW5lckluc3RhbmNlLmRvY3VtZW50RWxlbWVudDtcbiAgICAgICAgbmFtZXNwYWNlID0gcm9vdCA/IHJvb3QubmFtZXNwYWNlVVJJIDogZ2V0Q2hpbGROYW1lc3BhY2UobnVsbCwgJycpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHZhciBjb250YWluZXIgPSBub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFID8gcm9vdENvbnRhaW5lckluc3RhbmNlLnBhcmVudE5vZGUgOiByb290Q29udGFpbmVySW5zdGFuY2U7XG4gICAgICAgIHZhciBvd25OYW1lc3BhY2UgPSBjb250YWluZXIubmFtZXNwYWNlVVJJIHx8IG51bGw7XG4gICAgICAgIHR5cGUgPSBjb250YWluZXIudGFnTmFtZTtcbiAgICAgICAgbmFtZXNwYWNlID0gZ2V0Q2hpbGROYW1lc3BhY2Uob3duTmFtZXNwYWNlLCB0eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cblxuICB7XG4gICAgdmFyIHZhbGlkYXRlZFRhZyA9IHR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICB2YXIgYW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbyhudWxsLCB2YWxpZGF0ZWRUYWcpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZSxcbiAgICAgIGFuY2VzdG9ySW5mbzogYW5jZXN0b3JJbmZvXG4gICAgfTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0Q2hpbGRIb3N0Q29udGV4dChwYXJlbnRIb3N0Q29udGV4dCwgdHlwZSwgcm9vdENvbnRhaW5lckluc3RhbmNlKSB7XG4gIHtcbiAgICB2YXIgcGFyZW50SG9zdENvbnRleHREZXYgPSBwYXJlbnRIb3N0Q29udGV4dDtcbiAgICB2YXIgbmFtZXNwYWNlID0gZ2V0Q2hpbGROYW1lc3BhY2UocGFyZW50SG9zdENvbnRleHREZXYubmFtZXNwYWNlLCB0eXBlKTtcbiAgICB2YXIgYW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbyhwYXJlbnRIb3N0Q29udGV4dERldi5hbmNlc3RvckluZm8sIHR5cGUpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lc3BhY2U6IG5hbWVzcGFjZSxcbiAgICAgIGFuY2VzdG9ySW5mbzogYW5jZXN0b3JJbmZvXG4gICAgfTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0UHVibGljSW5zdGFuY2UoaW5zdGFuY2UpIHtcbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuZnVuY3Rpb24gcHJlcGFyZUZvckNvbW1pdChjb250YWluZXJJbmZvKSB7XG4gIGV2ZW50c0VuYWJsZWQgPSBpc0VuYWJsZWQoKTtcbiAgc2VsZWN0aW9uSW5mb3JtYXRpb24gPSBnZXRTZWxlY3Rpb25JbmZvcm1hdGlvbigpO1xuICB2YXIgYWN0aXZlSW5zdGFuY2UgPSBudWxsO1xuXG4gIHNldEVuYWJsZWQoZmFsc2UpO1xuICByZXR1cm4gYWN0aXZlSW5zdGFuY2U7XG59XG5mdW5jdGlvbiByZXNldEFmdGVyQ29tbWl0KGNvbnRhaW5lckluZm8pIHtcbiAgcmVzdG9yZVNlbGVjdGlvbihzZWxlY3Rpb25JbmZvcm1hdGlvbik7XG4gIHNldEVuYWJsZWQoZXZlbnRzRW5hYmxlZCk7XG4gIGV2ZW50c0VuYWJsZWQgPSBudWxsO1xuICBzZWxlY3Rpb25JbmZvcm1hdGlvbiA9IG51bGw7XG59XG5mdW5jdGlvbiBjcmVhdGVJbnN0YW5jZSh0eXBlLCBwcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBob3N0Q29udGV4dCwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICB2YXIgcGFyZW50TmFtZXNwYWNlO1xuXG4gIHtcbiAgICAvLyBUT0RPOiB0YWtlIG5hbWVzcGFjZSBpbnRvIGFjY291bnQgd2hlbiB2YWxpZGF0aW5nLlxuICAgIHZhciBob3N0Q29udGV4dERldiA9IGhvc3RDb250ZXh0O1xuICAgIHZhbGlkYXRlRE9NTmVzdGluZyh0eXBlLCBudWxsLCBob3N0Q29udGV4dERldi5hbmNlc3RvckluZm8pO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHByb3BzLmNoaWxkcmVuID09PSAnbnVtYmVyJykge1xuICAgICAgdmFyIHN0cmluZyA9ICcnICsgcHJvcHMuY2hpbGRyZW47XG4gICAgICB2YXIgb3duQW5jZXN0b3JJbmZvID0gdXBkYXRlZEFuY2VzdG9ySW5mbyhob3N0Q29udGV4dERldi5hbmNlc3RvckluZm8sIHR5cGUpO1xuICAgICAgdmFsaWRhdGVET01OZXN0aW5nKG51bGwsIHN0cmluZywgb3duQW5jZXN0b3JJbmZvKTtcbiAgICB9XG5cbiAgICBwYXJlbnROYW1lc3BhY2UgPSBob3N0Q29udGV4dERldi5uYW1lc3BhY2U7XG4gIH1cblxuICB2YXIgZG9tRWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgcGFyZW50TmFtZXNwYWNlKTtcbiAgcHJlY2FjaGVGaWJlck5vZGUoaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgZG9tRWxlbWVudCk7XG4gIHVwZGF0ZUZpYmVyUHJvcHMoZG9tRWxlbWVudCwgcHJvcHMpO1xuICByZXR1cm4gZG9tRWxlbWVudDtcbn1cbmZ1bmN0aW9uIGFwcGVuZEluaXRpYWxDaGlsZChwYXJlbnRJbnN0YW5jZSwgY2hpbGQpIHtcbiAgcGFyZW50SW5zdGFuY2UuYXBwZW5kQ2hpbGQoY2hpbGQpO1xufVxuZnVuY3Rpb24gZmluYWxpemVJbml0aWFsQ2hpbGRyZW4oZG9tRWxlbWVudCwgdHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQpIHtcbiAgc2V0SW5pdGlhbFByb3BlcnRpZXMoZG9tRWxlbWVudCwgdHlwZSwgcHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSk7XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYnV0dG9uJzpcbiAgICBjYXNlICdpbnB1dCc6XG4gICAgY2FzZSAnc2VsZWN0JzpcbiAgICBjYXNlICd0ZXh0YXJlYSc6XG4gICAgICByZXR1cm4gISFwcm9wcy5hdXRvRm9jdXM7XG5cbiAgICBjYXNlICdpbWcnOlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5mdW5jdGlvbiBwcmVwYXJlVXBkYXRlKGRvbUVsZW1lbnQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBob3N0Q29udGV4dCkge1xuICB7XG4gICAgdmFyIGhvc3RDb250ZXh0RGV2ID0gaG9zdENvbnRleHQ7XG5cbiAgICBpZiAodHlwZW9mIG5ld1Byb3BzLmNoaWxkcmVuICE9PSB0eXBlb2Ygb2xkUHJvcHMuY2hpbGRyZW4gJiYgKHR5cGVvZiBuZXdQcm9wcy5jaGlsZHJlbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIG5ld1Byb3BzLmNoaWxkcmVuID09PSAnbnVtYmVyJykpIHtcbiAgICAgIHZhciBzdHJpbmcgPSAnJyArIG5ld1Byb3BzLmNoaWxkcmVuO1xuICAgICAgdmFyIG93bkFuY2VzdG9ySW5mbyA9IHVwZGF0ZWRBbmNlc3RvckluZm8oaG9zdENvbnRleHREZXYuYW5jZXN0b3JJbmZvLCB0eXBlKTtcbiAgICAgIHZhbGlkYXRlRE9NTmVzdGluZyhudWxsLCBzdHJpbmcsIG93bkFuY2VzdG9ySW5mbyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRpZmZQcm9wZXJ0aWVzKGRvbUVsZW1lbnQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcyk7XG59XG5mdW5jdGlvbiBzaG91bGRTZXRUZXh0Q29udGVudCh0eXBlLCBwcm9wcykge1xuICByZXR1cm4gdHlwZSA9PT0gJ3RleHRhcmVhJyB8fCB0eXBlID09PSAnbm9zY3JpcHQnIHx8IHR5cGVvZiBwcm9wcy5jaGlsZHJlbiA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHByb3BzLmNoaWxkcmVuID09PSAnbnVtYmVyJyB8fCB0eXBlb2YgcHJvcHMuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgPT09ICdvYmplY3QnICYmIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MICE9PSBudWxsICYmIHByb3BzLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLl9faHRtbCAhPSBudWxsO1xufVxuZnVuY3Rpb24gY3JlYXRlVGV4dEluc3RhbmNlKHRleHQsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAge1xuICAgIHZhciBob3N0Q29udGV4dERldiA9IGhvc3RDb250ZXh0O1xuICAgIHZhbGlkYXRlRE9NTmVzdGluZyhudWxsLCB0ZXh0LCBob3N0Q29udGV4dERldi5hbmNlc3RvckluZm8pO1xuICB9XG5cbiAgdmFyIHRleHROb2RlID0gY3JlYXRlVGV4dE5vZGUodGV4dCwgcm9vdENvbnRhaW5lckluc3RhbmNlKTtcbiAgcHJlY2FjaGVGaWJlck5vZGUoaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgdGV4dE5vZGUpO1xuICByZXR1cm4gdGV4dE5vZGU7XG59XG5mdW5jdGlvbiBnZXRDdXJyZW50RXZlbnRQcmlvcml0eSgpIHtcbiAgdmFyIGN1cnJlbnRFdmVudCA9IHdpbmRvdy5ldmVudDtcblxuICBpZiAoY3VycmVudEV2ZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gRGVmYXVsdEV2ZW50UHJpb3JpdHk7XG4gIH1cblxuICByZXR1cm4gZ2V0RXZlbnRQcmlvcml0eShjdXJyZW50RXZlbnQudHlwZSk7XG59XG4vLyBpZiBhIGNvbXBvbmVudCBqdXN0IGltcG9ydHMgUmVhY3RET00gKGUuZy4gZm9yIGZpbmRET01Ob2RlKS5cbi8vIFNvbWUgZW52aXJvbm1lbnRzIG1pZ2h0IG5vdCBoYXZlIHNldFRpbWVvdXQgb3IgY2xlYXJUaW1lb3V0LlxuXG52YXIgc2NoZWR1bGVUaW1lb3V0ID0gdHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicgPyBzZXRUaW1lb3V0IDogdW5kZWZpbmVkO1xudmFyIGNhbmNlbFRpbWVvdXQgPSB0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nID8gY2xlYXJUaW1lb3V0IDogdW5kZWZpbmVkO1xudmFyIG5vVGltZW91dCA9IC0xO1xudmFyIGxvY2FsUHJvbWlzZSA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nID8gUHJvbWlzZSA6IHVuZGVmaW5lZDsgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLVxudmFyIHNjaGVkdWxlTWljcm90YXNrID0gdHlwZW9mIHF1ZXVlTWljcm90YXNrID09PSAnZnVuY3Rpb24nID8gcXVldWVNaWNyb3Rhc2sgOiB0eXBlb2YgbG9jYWxQcm9taXNlICE9PSAndW5kZWZpbmVkJyA/IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICByZXR1cm4gbG9jYWxQcm9taXNlLnJlc29sdmUobnVsbCkudGhlbihjYWxsYmFjaykuY2F0Y2goaGFuZGxlRXJyb3JJbk5leHRUaWNrKTtcbn0gOiBzY2hlZHVsZVRpbWVvdXQ7IC8vIFRPRE86IERldGVybWluZSB0aGUgYmVzdCBmYWxsYmFjayBoZXJlLlxuXG5mdW5jdGlvbiBoYW5kbGVFcnJvckluTmV4dFRpY2soZXJyb3IpIHtcbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH0pO1xufSAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBjb21taXRNb3VudChkb21FbGVtZW50LCB0eXBlLCBuZXdQcm9wcywgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICAvLyBEZXNwaXRlIHRoZSBuYW1pbmcgdGhhdCBtaWdodCBpbXBseSBvdGhlcndpc2UsIHRoaXMgbWV0aG9kIG9ubHlcbiAgLy8gZmlyZXMgaWYgdGhlcmUgaXMgYW4gYFVwZGF0ZWAgZWZmZWN0IHNjaGVkdWxlZCBkdXJpbmcgbW91bnRpbmcuXG4gIC8vIFRoaXMgaGFwcGVucyBpZiBgZmluYWxpemVJbml0aWFsQ2hpbGRyZW5gIHJldHVybnMgYHRydWVgICh3aGljaCBpdFxuICAvLyBkb2VzIHRvIGltcGxlbWVudCB0aGUgYGF1dG9Gb2N1c2AgYXR0cmlidXRlIG9uIHRoZSBjbGllbnQpLiBCdXRcbiAgLy8gdGhlcmUgYXJlIGFsc28gb3RoZXIgY2FzZXMgd2hlbiB0aGlzIG1pZ2h0IGhhcHBlbiAoc3VjaCBhcyBwYXRjaGluZ1xuICAvLyB1cCB0ZXh0IGNvbnRlbnQgZHVyaW5nIGh5ZHJhdGlvbiBtaXNtYXRjaCkuIFNvIHdlJ2xsIGNoZWNrIHRoaXMgYWdhaW4uXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2J1dHRvbic6XG4gICAgY2FzZSAnaW5wdXQnOlxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgY2FzZSAndGV4dGFyZWEnOlxuICAgICAgaWYgKG5ld1Byb3BzLmF1dG9Gb2N1cykge1xuICAgICAgICBkb21FbGVtZW50LmZvY3VzKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcblxuICAgIGNhc2UgJ2ltZyc6XG4gICAgICB7XG4gICAgICAgIGlmIChuZXdQcm9wcy5zcmMpIHtcbiAgICAgICAgICBkb21FbGVtZW50LnNyYyA9IG5ld1Byb3BzLnNyYztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gY29tbWl0VXBkYXRlKGRvbUVsZW1lbnQsIHVwZGF0ZVBheWxvYWQsIHR5cGUsIG9sZFByb3BzLCBuZXdQcm9wcywgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSkge1xuICAvLyBBcHBseSB0aGUgZGlmZiB0byB0aGUgRE9NIG5vZGUuXG4gIHVwZGF0ZVByb3BlcnRpZXMoZG9tRWxlbWVudCwgdXBkYXRlUGF5bG9hZCwgdHlwZSwgb2xkUHJvcHMsIG5ld1Byb3BzKTsgLy8gVXBkYXRlIHRoZSBwcm9wcyBoYW5kbGUgc28gdGhhdCB3ZSBrbm93IHdoaWNoIHByb3BzIGFyZSB0aGUgb25lcyB3aXRoXG4gIC8vIHdpdGggY3VycmVudCBldmVudCBoYW5kbGVycy5cblxuICB1cGRhdGVGaWJlclByb3BzKGRvbUVsZW1lbnQsIG5ld1Byb3BzKTtcbn1cbmZ1bmN0aW9uIHJlc2V0VGV4dENvbnRlbnQoZG9tRWxlbWVudCkge1xuICBzZXRUZXh0Q29udGVudChkb21FbGVtZW50LCAnJyk7XG59XG5mdW5jdGlvbiBjb21taXRUZXh0VXBkYXRlKHRleHRJbnN0YW5jZSwgb2xkVGV4dCwgbmV3VGV4dCkge1xuICB0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlID0gbmV3VGV4dDtcbn1cbmZ1bmN0aW9uIGFwcGVuZENoaWxkKHBhcmVudEluc3RhbmNlLCBjaGlsZCkge1xuICBwYXJlbnRJbnN0YW5jZS5hcHBlbmRDaGlsZChjaGlsZCk7XG59XG5mdW5jdGlvbiBhcHBlbmRDaGlsZFRvQ29udGFpbmVyKGNvbnRhaW5lciwgY2hpbGQpIHtcbiAgdmFyIHBhcmVudE5vZGU7XG5cbiAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgcGFyZW50Tm9kZSA9IGNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGNoaWxkLCBjb250YWluZXIpO1xuICB9IGVsc2Uge1xuICAgIHBhcmVudE5vZGUgPSBjb250YWluZXI7XG4gICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChjaGlsZCk7XG4gIH0gLy8gVGhpcyBjb250YWluZXIgbWlnaHQgYmUgdXNlZCBmb3IgYSBwb3J0YWwuXG4gIC8vIElmIHNvbWV0aGluZyBpbnNpZGUgYSBwb3J0YWwgaXMgY2xpY2tlZCwgdGhhdCBjbGljayBzaG91bGQgYnViYmxlXG4gIC8vIHRocm91Z2ggdGhlIFJlYWN0IHRyZWUuIEhvd2V2ZXIsIG9uIE1vYmlsZSBTYWZhcmkgdGhlIGNsaWNrIHdvdWxkXG4gIC8vIG5ldmVyIGJ1YmJsZSB0aHJvdWdoIHRoZSAqRE9NKiB0cmVlIHVubGVzcyBhbiBhbmNlc3RvciB3aXRoIG9uY2xpY2tcbiAgLy8gZXZlbnQgZXhpc3RzLiBTbyB3ZSB3b3VsZG4ndCBzZWUgaXQgYW5kIGRpc3BhdGNoIGl0LlxuICAvLyBUaGlzIGlzIHdoeSB3ZSBlbnN1cmUgdGhhdCBub24gUmVhY3Qgcm9vdCBjb250YWluZXJzIGhhdmUgaW5saW5lIG9uY2xpY2tcbiAgLy8gZGVmaW5lZC5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMTkxOFxuXG5cbiAgdmFyIHJlYWN0Um9vdENvbnRhaW5lciA9IGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyO1xuXG4gIGlmICgocmVhY3RSb290Q29udGFpbmVyID09PSBudWxsIHx8IHJlYWN0Um9vdENvbnRhaW5lciA9PT0gdW5kZWZpbmVkKSAmJiBwYXJlbnROb2RlLm9uY2xpY2sgPT09IG51bGwpIHtcbiAgICAvLyBUT0RPOiBUaGlzIGNhc3QgbWF5IG5vdCBiZSBzb3VuZCBmb3IgU1ZHLCBNYXRoTUwgb3IgY3VzdG9tIGVsZW1lbnRzLlxuICAgIHRyYXBDbGlja09uTm9uSW50ZXJhY3RpdmVFbGVtZW50KHBhcmVudE5vZGUpO1xuICB9XG59XG5mdW5jdGlvbiBpbnNlcnRCZWZvcmUocGFyZW50SW5zdGFuY2UsIGNoaWxkLCBiZWZvcmVDaGlsZCkge1xuICBwYXJlbnRJbnN0YW5jZS5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZUNoaWxkKTtcbn1cbmZ1bmN0aW9uIGluc2VydEluQ29udGFpbmVyQmVmb3JlKGNvbnRhaW5lciwgY2hpbGQsIGJlZm9yZUNoaWxkKSB7XG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgIGNvbnRhaW5lci5wYXJlbnROb2RlLmluc2VydEJlZm9yZShjaGlsZCwgYmVmb3JlQ2hpbGQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUoY2hpbGQsIGJlZm9yZUNoaWxkKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVDaGlsZChwYXJlbnRJbnN0YW5jZSwgY2hpbGQpIHtcbiAgcGFyZW50SW5zdGFuY2UucmVtb3ZlQ2hpbGQoY2hpbGQpO1xufVxuZnVuY3Rpb24gcmVtb3ZlQ2hpbGRGcm9tQ29udGFpbmVyKGNvbnRhaW5lciwgY2hpbGQpIHtcbiAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgY29udGFpbmVyLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICB9IGVsc2Uge1xuICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChjaGlsZCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGNsZWFyU3VzcGVuc2VCb3VuZGFyeShwYXJlbnRJbnN0YW5jZSwgc3VzcGVuc2VJbnN0YW5jZSkge1xuICB2YXIgbm9kZSA9IHN1c3BlbnNlSW5zdGFuY2U7IC8vIERlbGV0ZSBhbGwgbm9kZXMgd2l0aGluIHRoaXMgc3VzcGVuc2UgYm91bmRhcnkuXG4gIC8vIFRoZXJlIG1pZ2h0IGJlIG5lc3RlZCBub2RlcyBzbyB3ZSBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgaG93XG4gIC8vIGRlZXAgd2UgYXJlIGFuZCBvbmx5IGJyZWFrIG91dCB3aGVuIHdlJ3JlIGJhY2sgb24gdG9wLlxuXG4gIHZhciBkZXB0aCA9IDA7XG5cbiAgZG8ge1xuICAgIHZhciBuZXh0Tm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgcGFyZW50SW5zdGFuY2UucmVtb3ZlQ2hpbGQobm9kZSk7XG5cbiAgICBpZiAobmV4dE5vZGUgJiYgbmV4dE5vZGUubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIGRhdGEgPSBuZXh0Tm9kZS5kYXRhO1xuXG4gICAgICBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfRU5EX0RBVEEpIHtcbiAgICAgICAgaWYgKGRlcHRoID09PSAwKSB7XG4gICAgICAgICAgcGFyZW50SW5zdGFuY2UucmVtb3ZlQ2hpbGQobmV4dE5vZGUpOyAvLyBSZXRyeSBpZiBhbnkgZXZlbnQgcmVwbGF5aW5nIHdhcyBibG9ja2VkIG9uIHRoaXMuXG5cbiAgICAgICAgICByZXRyeUlmQmxvY2tlZE9uKHN1c3BlbnNlSW5zdGFuY2UpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRhdGEgPT09IFNVU1BFTlNFX1NUQVJUX0RBVEEgfHwgZGF0YSA9PT0gU1VTUEVOU0VfUEVORElOR19TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX0ZBTExCQUNLX1NUQVJUX0RBVEEpIHtcbiAgICAgICAgZGVwdGgrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gbmV4dE5vZGU7XG4gIH0gd2hpbGUgKG5vZGUpOyAvLyBUT0RPOiBXYXJuLCB3ZSBkaWRuJ3QgZmluZCB0aGUgZW5kIGNvbW1lbnQgYm91bmRhcnkuXG4gIC8vIFJldHJ5IGlmIGFueSBldmVudCByZXBsYXlpbmcgd2FzIGJsb2NrZWQgb24gdGhpcy5cblxuXG4gIHJldHJ5SWZCbG9ja2VkT24oc3VzcGVuc2VJbnN0YW5jZSk7XG59XG5mdW5jdGlvbiBjbGVhclN1c3BlbnNlQm91bmRhcnlGcm9tQ29udGFpbmVyKGNvbnRhaW5lciwgc3VzcGVuc2VJbnN0YW5jZSkge1xuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICBjbGVhclN1c3BlbnNlQm91bmRhcnkoY29udGFpbmVyLnBhcmVudE5vZGUsIHN1c3BlbnNlSW5zdGFuY2UpO1xuICB9IGVsc2UgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgY2xlYXJTdXNwZW5zZUJvdW5kYXJ5KGNvbnRhaW5lciwgc3VzcGVuc2VJbnN0YW5jZSk7XG4gIH0gLy8gUmV0cnkgaWYgYW55IGV2ZW50IHJlcGxheWluZyB3YXMgYmxvY2tlZCBvbiB0aGlzLlxuXG5cbiAgcmV0cnlJZkJsb2NrZWRPbihjb250YWluZXIpO1xufVxuZnVuY3Rpb24gaGlkZUluc3RhbmNlKGluc3RhbmNlKSB7XG4gIC8vIFRPRE86IERvZXMgdGhpcyB3b3JrIGZvciBhbGwgZWxlbWVudCB0eXBlcz8gV2hhdCBhYm91dCBNYXRoTUw/IFNob3VsZCB3ZVxuICAvLyBwYXNzIGhvc3QgY29udGV4dCB0byB0aGlzIG1ldGhvZD9cbiAgaW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgdmFyIHN0eWxlID0gaW5zdGFuY2Uuc3R5bGU7XG5cbiAgaWYgKHR5cGVvZiBzdHlsZS5zZXRQcm9wZXJ0eSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN0eWxlLnNldFByb3BlcnR5KCdkaXNwbGF5JywgJ25vbmUnLCAnaW1wb3J0YW50Jyk7XG4gIH0gZWxzZSB7XG4gICAgc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgfVxufVxuZnVuY3Rpb24gaGlkZVRleHRJbnN0YW5jZSh0ZXh0SW5zdGFuY2UpIHtcbiAgdGV4dEluc3RhbmNlLm5vZGVWYWx1ZSA9ICcnO1xufVxuZnVuY3Rpb24gdW5oaWRlSW5zdGFuY2UoaW5zdGFuY2UsIHByb3BzKSB7XG4gIGluc3RhbmNlID0gaW5zdGFuY2U7XG4gIHZhciBzdHlsZVByb3AgPSBwcm9wc1tTVFlMRSQxXTtcbiAgdmFyIGRpc3BsYXkgPSBzdHlsZVByb3AgIT09IHVuZGVmaW5lZCAmJiBzdHlsZVByb3AgIT09IG51bGwgJiYgc3R5bGVQcm9wLmhhc093blByb3BlcnR5KCdkaXNwbGF5JykgPyBzdHlsZVByb3AuZGlzcGxheSA6IG51bGw7XG4gIGluc3RhbmNlLnN0eWxlLmRpc3BsYXkgPSBkYW5nZXJvdXNTdHlsZVZhbHVlKCdkaXNwbGF5JywgZGlzcGxheSk7XG59XG5mdW5jdGlvbiB1bmhpZGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlLCB0ZXh0KSB7XG4gIHRleHRJbnN0YW5jZS5ub2RlVmFsdWUgPSB0ZXh0O1xufVxuZnVuY3Rpb24gY2xlYXJDb250YWluZXIoY29udGFpbmVyKSB7XG4gIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgIGNvbnRhaW5lci50ZXh0Q29udGVudCA9ICcnO1xuICB9IGVsc2UgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfTk9ERSkge1xuICAgIGlmIChjb250YWluZXIuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY29udGFpbmVyLmRvY3VtZW50RWxlbWVudCk7XG4gICAgfVxuICB9XG59IC8vIC0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGNhbkh5ZHJhdGVJbnN0YW5jZShpbnN0YW5jZSwgdHlwZSwgcHJvcHMpIHtcbiAgaWYgKGluc3RhbmNlLm5vZGVUeXBlICE9PSBFTEVNRU5UX05PREUgfHwgdHlwZS50b0xvd2VyQ2FzZSgpICE9PSBpbnN0YW5jZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gLy8gVGhpcyBoYXMgbm93IGJlZW4gcmVmaW5lZCB0byBhbiBlbGVtZW50IG5vZGUuXG5cblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5mdW5jdGlvbiBjYW5IeWRyYXRlVGV4dEluc3RhbmNlKGluc3RhbmNlLCB0ZXh0KSB7XG4gIGlmICh0ZXh0ID09PSAnJyB8fCBpbnN0YW5jZS5ub2RlVHlwZSAhPT0gVEVYVF9OT0RFKSB7XG4gICAgLy8gRW1wdHkgc3RyaW5ncyBhcmUgbm90IHBhcnNlZCBieSBIVE1MIHNvIHRoZXJlIHdvbid0IGJlIGEgY29ycmVjdCBtYXRjaCBoZXJlLlxuICAgIHJldHVybiBudWxsO1xuICB9IC8vIFRoaXMgaGFzIG5vdyBiZWVuIHJlZmluZWQgdG8gYSB0ZXh0IG5vZGUuXG5cblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5mdW5jdGlvbiBjYW5IeWRyYXRlU3VzcGVuc2VJbnN0YW5jZShpbnN0YW5jZSkge1xuICBpZiAoaW5zdGFuY2Uubm9kZVR5cGUgIT09IENPTU1FTlRfTk9ERSkge1xuICAgIC8vIEVtcHR5IHN0cmluZ3MgYXJlIG5vdCBwYXJzZWQgYnkgSFRNTCBzbyB0aGVyZSB3b24ndCBiZSBhIGNvcnJlY3QgbWF0Y2ggaGVyZS5cbiAgICByZXR1cm4gbnVsbDtcbiAgfSAvLyBUaGlzIGhhcyBub3cgYmVlbiByZWZpbmVkIHRvIGEgc3VzcGVuc2Ugbm9kZS5cblxuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cbmZ1bmN0aW9uIGlzU3VzcGVuc2VJbnN0YW5jZVBlbmRpbmcoaW5zdGFuY2UpIHtcbiAgcmV0dXJuIGluc3RhbmNlLmRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQTtcbn1cbmZ1bmN0aW9uIGlzU3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrKGluc3RhbmNlKSB7XG4gIHJldHVybiBpbnN0YW5jZS5kYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBO1xufVxuZnVuY3Rpb24gZ2V0U3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrRXJyb3JEZXRhaWxzKGluc3RhbmNlKSB7XG4gIHZhciBkYXRhc2V0ID0gaW5zdGFuY2UubmV4dFNpYmxpbmcgJiYgaW5zdGFuY2UubmV4dFNpYmxpbmcuZGF0YXNldDtcbiAgdmFyIGRpZ2VzdCwgbWVzc2FnZSwgc3RhY2s7XG5cbiAgaWYgKGRhdGFzZXQpIHtcbiAgICBkaWdlc3QgPSBkYXRhc2V0LmRnc3Q7XG5cbiAgICB7XG4gICAgICBtZXNzYWdlID0gZGF0YXNldC5tc2c7XG4gICAgICBzdGFjayA9IGRhdGFzZXQuc3RjaztcbiAgICB9XG4gIH1cblxuICB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICBkaWdlc3Q6IGRpZ2VzdCxcbiAgICAgIHN0YWNrOiBzdGFja1xuICAgIH07XG4gIH0gLy8gbGV0IHZhbHVlID0ge21lc3NhZ2U6IHVuZGVmaW5lZCwgaGFzaDogdW5kZWZpbmVkfTtcbiAgLy8gY29uc3QgbmV4dFNpYmxpbmcgPSBpbnN0YW5jZS5uZXh0U2libGluZztcbiAgLy8gaWYgKG5leHRTaWJsaW5nKSB7XG4gIC8vICAgY29uc3QgZGF0YXNldCA9ICgobmV4dFNpYmxpbmc6IGFueSk6IEhUTUxUZW1wbGF0ZUVsZW1lbnQpLmRhdGFzZXQ7XG4gIC8vICAgdmFsdWUubWVzc2FnZSA9IGRhdGFzZXQubXNnO1xuICAvLyAgIHZhbHVlLmhhc2ggPSBkYXRhc2V0Lmhhc2g7XG4gIC8vICAgaWYgKHRydWUpIHtcbiAgLy8gICAgIHZhbHVlLnN0YWNrID0gZGF0YXNldC5zdGFjaztcbiAgLy8gICB9XG4gIC8vIH1cbiAgLy8gcmV0dXJuIHZhbHVlO1xuXG59XG5mdW5jdGlvbiByZWdpc3RlclN1c3BlbnNlSW5zdGFuY2VSZXRyeShpbnN0YW5jZSwgY2FsbGJhY2spIHtcbiAgaW5zdGFuY2UuX3JlYWN0UmV0cnkgPSBjYWxsYmFjaztcbn1cblxuZnVuY3Rpb24gZ2V0TmV4dEh5ZHJhdGFibGUobm9kZSkge1xuICAvLyBTa2lwIG5vbi1oeWRyYXRhYmxlIG5vZGVzLlxuICBmb3IgKDsgbm9kZSAhPSBudWxsOyBub2RlID0gbm9kZS5uZXh0U2libGluZykge1xuICAgIHZhciBub2RlVHlwZSA9IG5vZGUubm9kZVR5cGU7XG5cbiAgICBpZiAobm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlVHlwZSA9PT0gVEVYVF9OT0RFKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAobm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIG5vZGVEYXRhID0gbm9kZS5kYXRhO1xuXG4gICAgICBpZiAobm9kZURhdGEgPT09IFNVU1BFTlNFX1NUQVJUX0RBVEEgfHwgbm9kZURhdGEgPT09IFNVU1BFTlNFX0ZBTExCQUNLX1NUQVJUX0RBVEEgfHwgbm9kZURhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGVEYXRhID09PSBTVVNQRU5TRV9FTkRfREFUQSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKGluc3RhbmNlKSB7XG4gIHJldHVybiBnZXROZXh0SHlkcmF0YWJsZShpbnN0YW5jZS5uZXh0U2libGluZyk7XG59XG5mdW5jdGlvbiBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZChwYXJlbnRJbnN0YW5jZSkge1xuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGUocGFyZW50SW5zdGFuY2UuZmlyc3RDaGlsZCk7XG59XG5mdW5jdGlvbiBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZFdpdGhpbkNvbnRhaW5lcihwYXJlbnRDb250YWluZXIpIHtcbiAgcmV0dXJuIGdldE5leHRIeWRyYXRhYmxlKHBhcmVudENvbnRhaW5lci5maXJzdENoaWxkKTtcbn1cbmZ1bmN0aW9uIGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkV2l0aGluU3VzcGVuc2VJbnN0YW5jZShwYXJlbnRJbnN0YW5jZSkge1xuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGUocGFyZW50SW5zdGFuY2UubmV4dFNpYmxpbmcpO1xufVxuZnVuY3Rpb24gaHlkcmF0ZUluc3RhbmNlKGluc3RhbmNlLCB0eXBlLCBwcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlLCBob3N0Q29udGV4dCwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgc2hvdWxkV2FybkRldikge1xuICBwcmVjYWNoZUZpYmVyTm9kZShpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCBpbnN0YW5jZSk7IC8vIFRPRE86IFBvc3NpYmx5IGRlZmVyIHRoaXMgdW50aWwgdGhlIGNvbW1pdCBwaGFzZSB3aGVyZSBhbGwgdGhlIGV2ZW50c1xuICAvLyBnZXQgYXR0YWNoZWQuXG5cbiAgdXBkYXRlRmliZXJQcm9wcyhpbnN0YW5jZSwgcHJvcHMpO1xuICB2YXIgcGFyZW50TmFtZXNwYWNlO1xuXG4gIHtcbiAgICB2YXIgaG9zdENvbnRleHREZXYgPSBob3N0Q29udGV4dDtcbiAgICBwYXJlbnROYW1lc3BhY2UgPSBob3N0Q29udGV4dERldi5uYW1lc3BhY2U7XG4gIH0gLy8gVE9ETzogVGVtcG9yYXJ5IGhhY2sgdG8gY2hlY2sgaWYgd2UncmUgaW4gYSBjb25jdXJyZW50IHJvb3QuIFdlIGNhbiBkZWxldGVcbiAgLy8gd2hlbiB0aGUgbGVnYWN5IHJvb3QgQVBJIGlzIHJlbW92ZWQuXG5cblxuICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChpbnRlcm5hbEluc3RhbmNlSGFuZGxlLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcbiAgcmV0dXJuIGRpZmZIeWRyYXRlZFByb3BlcnRpZXMoaW5zdGFuY2UsIHR5cGUsIHByb3BzLCBwYXJlbnROYW1lc3BhY2UsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaXNDb25jdXJyZW50TW9kZSwgc2hvdWxkV2FybkRldik7XG59XG5mdW5jdGlvbiBoeWRyYXRlVGV4dEluc3RhbmNlKHRleHRJbnN0YW5jZSwgdGV4dCwgaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgc2hvdWxkV2FybkRldikge1xuICBwcmVjYWNoZUZpYmVyTm9kZShpbnRlcm5hbEluc3RhbmNlSGFuZGxlLCB0ZXh0SW5zdGFuY2UpOyAvLyBUT0RPOiBUZW1wb3JhcnkgaGFjayB0byBjaGVjayBpZiB3ZSdyZSBpbiBhIGNvbmN1cnJlbnQgcm9vdC4gV2UgY2FuIGRlbGV0ZVxuICAvLyB3aGVuIHRoZSBsZWdhY3kgcm9vdCBBUEkgaXMgcmVtb3ZlZC5cblxuICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChpbnRlcm5hbEluc3RhbmNlSGFuZGxlLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcbiAgcmV0dXJuIGRpZmZIeWRyYXRlZFRleHQodGV4dEluc3RhbmNlLCB0ZXh0KTtcbn1cbmZ1bmN0aW9uIGh5ZHJhdGVTdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlSW5zdGFuY2UsIGludGVybmFsSW5zdGFuY2VIYW5kbGUpIHtcbiAgcHJlY2FjaGVGaWJlck5vZGUoaW50ZXJuYWxJbnN0YW5jZUhhbmRsZSwgc3VzcGVuc2VJbnN0YW5jZSk7XG59XG5mdW5jdGlvbiBnZXROZXh0SHlkcmF0YWJsZUluc3RhbmNlQWZ0ZXJTdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgdmFyIG5vZGUgPSBzdXNwZW5zZUluc3RhbmNlLm5leHRTaWJsaW5nOyAvLyBTa2lwIHBhc3QgYWxsIG5vZGVzIHdpdGhpbiB0aGlzIHN1c3BlbnNlIGJvdW5kYXJ5LlxuICAvLyBUaGVyZSBtaWdodCBiZSBuZXN0ZWQgbm9kZXMgc28gd2UgbmVlZCB0byBrZWVwIHRyYWNrIG9mIGhvd1xuICAvLyBkZWVwIHdlIGFyZSBhbmQgb25seSBicmVhayBvdXQgd2hlbiB3ZSdyZSBiYWNrIG9uIHRvcC5cblxuICB2YXIgZGVwdGggPSAwO1xuXG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkge1xuICAgICAgdmFyIGRhdGEgPSBub2RlLmRhdGE7XG5cbiAgICAgIGlmIChkYXRhID09PSBTVVNQRU5TRV9FTkRfREFUQSkge1xuICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKG5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfU1RBUlRfREFUQSB8fCBkYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSkge1xuICAgICAgICBkZXB0aCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIG5vZGUgPSBub2RlLm5leHRTaWJsaW5nO1xuICB9IC8vIFRPRE86IFdhcm4sIHdlIGRpZG4ndCBmaW5kIHRoZSBlbmQgY29tbWVudCBib3VuZGFyeS5cblxuXG4gIHJldHVybiBudWxsO1xufSAvLyBSZXR1cm5zIHRoZSBTdXNwZW5zZUluc3RhbmNlIGlmIHRoaXMgbm9kZSBpcyBhIGRpcmVjdCBjaGlsZCBvZiBhXG4vLyBTdXNwZW5zZUluc3RhbmNlLiBJLmUuIGlmIGl0cyBwcmV2aW91cyBzaWJsaW5nIGlzIGEgQ29tbWVudCB3aXRoXG4vLyBTVVNQRU5TRV94X1NUQVJUX0RBVEEuIE90aGVyd2lzZSwgbnVsbC5cblxuZnVuY3Rpb24gZ2V0UGFyZW50U3VzcGVuc2VJbnN0YW5jZSh0YXJnZXRJbnN0YW5jZSkge1xuICB2YXIgbm9kZSA9IHRhcmdldEluc3RhbmNlLnByZXZpb3VzU2libGluZzsgLy8gU2tpcCBwYXN0IGFsbCBub2RlcyB3aXRoaW4gdGhpcyBzdXNwZW5zZSBib3VuZGFyeS5cbiAgLy8gVGhlcmUgbWlnaHQgYmUgbmVzdGVkIG5vZGVzIHNvIHdlIG5lZWQgdG8ga2VlcCB0cmFjayBvZiBob3dcbiAgLy8gZGVlcCB3ZSBhcmUgYW5kIG9ubHkgYnJlYWsgb3V0IHdoZW4gd2UncmUgYmFjayBvbiB0b3AuXG5cbiAgdmFyIGRlcHRoID0gMDtcblxuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHtcbiAgICAgIHZhciBkYXRhID0gbm9kZS5kYXRhO1xuXG4gICAgICBpZiAoZGF0YSA9PT0gU1VTUEVOU0VfU1RBUlRfREFUQSB8fCBkYXRhID09PSBTVVNQRU5TRV9GQUxMQkFDS19TVEFSVF9EQVRBIHx8IGRhdGEgPT09IFNVU1BFTlNFX1BFTkRJTkdfU1RBUlRfREFUQSkge1xuICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRhdGEgPT09IFNVU1BFTlNFX0VORF9EQVRBKSB7XG4gICAgICAgIGRlcHRoKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBjb21taXRIeWRyYXRlZENvbnRhaW5lcihjb250YWluZXIpIHtcbiAgLy8gUmV0cnkgaWYgYW55IGV2ZW50IHJlcGxheWluZyB3YXMgYmxvY2tlZCBvbiB0aGlzLlxuICByZXRyeUlmQmxvY2tlZE9uKGNvbnRhaW5lcik7XG59XG5mdW5jdGlvbiBjb21taXRIeWRyYXRlZFN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSkge1xuICAvLyBSZXRyeSBpZiBhbnkgZXZlbnQgcmVwbGF5aW5nIHdhcyBibG9ja2VkIG9uIHRoaXMuXG4gIHJldHJ5SWZCbG9ja2VkT24oc3VzcGVuc2VJbnN0YW5jZSk7XG59XG5mdW5jdGlvbiBzaG91bGREZWxldGVVbmh5ZHJhdGVkVGFpbEluc3RhbmNlcyhwYXJlbnRUeXBlKSB7XG4gIHJldHVybiBwYXJlbnRUeXBlICE9PSAnaGVhZCcgJiYgcGFyZW50VHlwZSAhPT0gJ2JvZHknO1xufVxuZnVuY3Rpb24gZGlkTm90TWF0Y2hIeWRyYXRlZENvbnRhaW5lclRleHRJbnN0YW5jZShwYXJlbnRDb250YWluZXIsIHRleHRJbnN0YW5jZSwgdGV4dCwgaXNDb25jdXJyZW50TW9kZSkge1xuICB2YXIgc2hvdWxkV2FybkRldiA9IHRydWU7XG4gIGNoZWNrRm9yVW5tYXRjaGVkVGV4dCh0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KTtcbn1cbmZ1bmN0aW9uIGRpZE5vdE1hdGNoSHlkcmF0ZWRUZXh0SW5zdGFuY2UocGFyZW50VHlwZSwgcGFyZW50UHJvcHMsIHBhcmVudEluc3RhbmNlLCB0ZXh0SW5zdGFuY2UsIHRleHQsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAgaWYgKHBhcmVudFByb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HJDFdICE9PSB0cnVlKSB7XG4gICAgdmFyIHNob3VsZFdhcm5EZXYgPSB0cnVlO1xuICAgIGNoZWNrRm9yVW5tYXRjaGVkVGV4dCh0ZXh0SW5zdGFuY2Uubm9kZVZhbHVlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlLCBzaG91bGRXYXJuRGV2KTtcbiAgfVxufVxuZnVuY3Rpb24gZGlkTm90SHlkcmF0ZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgaW5zdGFuY2UpIHtcbiAge1xuICAgIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVFbGVtZW50KHBhcmVudENvbnRhaW5lciwgaW5zdGFuY2UpO1xuICAgIH0gZWxzZSBpZiAoaW5zdGFuY2Uubm9kZVR5cGUgPT09IENPTU1FTlRfTk9ERSkgOyBlbHNlIHtcbiAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZVRleHQocGFyZW50Q29udGFpbmVyLCBpbnN0YW5jZSk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHBhcmVudEluc3RhbmNlLCBpbnN0YW5jZSkge1xuICB7XG4gICAgLy8gJEZsb3dGaXhNZTogT25seSBFbGVtZW50IG9yIERvY3VtZW50IGNhbiBiZSBwYXJlbnQgbm9kZXMuXG4gICAgdmFyIHBhcmVudE5vZGUgPSBwYXJlbnRJbnN0YW5jZS5wYXJlbnROb2RlO1xuXG4gICAgaWYgKHBhcmVudE5vZGUgIT09IG51bGwpIHtcbiAgICAgIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHdhcm5Gb3JEZWxldGVkSHlkcmF0YWJsZUVsZW1lbnQocGFyZW50Tm9kZSwgaW5zdGFuY2UpO1xuICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSA7IGVsc2Uge1xuICAgICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVUZXh0KHBhcmVudE5vZGUsIGluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGRpZE5vdEh5ZHJhdGVJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIGluc3RhbmNlLCBpc0NvbmN1cnJlbnRNb2RlKSB7XG4gIHtcbiAgICBpZiAoaXNDb25jdXJyZW50TW9kZSB8fCBwYXJlbnRQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyQxXSAhPT0gdHJ1ZSkge1xuICAgICAgaWYgKGluc3RhbmNlLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgd2FybkZvckRlbGV0ZWRIeWRyYXRhYmxlRWxlbWVudChwYXJlbnRJbnN0YW5jZSwgaW5zdGFuY2UpO1xuICAgICAgfSBlbHNlIGlmIChpbnN0YW5jZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFKSA7IGVsc2Uge1xuICAgICAgICB3YXJuRm9yRGVsZXRlZEh5ZHJhdGFibGVUZXh0KHBhcmVudEluc3RhbmNlLCBpbnN0YW5jZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgdHlwZSwgcHJvcHMpIHtcbiAge1xuICAgIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkRWxlbWVudChwYXJlbnRDb250YWluZXIsIHR5cGUpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZVdpdGhpbkNvbnRhaW5lcihwYXJlbnRDb250YWluZXIsIHRleHQpIHtcbiAge1xuICAgIHdhcm5Gb3JJbnNlcnRlZEh5ZHJhdGVkVGV4dChwYXJlbnRDb250YWluZXIsIHRleHQpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluU3VzcGVuc2VJbnN0YW5jZShwYXJlbnRJbnN0YW5jZSwgdHlwZSwgcHJvcHMpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWU6IE9ubHkgRWxlbWVudCBvciBEb2N1bWVudCBjYW4gYmUgcGFyZW50IG5vZGVzLlxuICAgIHZhciBwYXJlbnROb2RlID0gcGFyZW50SW5zdGFuY2UucGFyZW50Tm9kZTtcbiAgICBpZiAocGFyZW50Tm9kZSAhPT0gbnVsbCkgd2FybkZvckluc2VydGVkSHlkcmF0ZWRFbGVtZW50KHBhcmVudE5vZGUsIHR5cGUpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZVdpdGhpblN1c3BlbnNlSW5zdGFuY2UocGFyZW50SW5zdGFuY2UsIHRleHQpIHtcbiAge1xuICAgIC8vICRGbG93Rml4TWU6IE9ubHkgRWxlbWVudCBvciBEb2N1bWVudCBjYW4gYmUgcGFyZW50IG5vZGVzLlxuICAgIHZhciBwYXJlbnROb2RlID0gcGFyZW50SW5zdGFuY2UucGFyZW50Tm9kZTtcbiAgICBpZiAocGFyZW50Tm9kZSAhPT0gbnVsbCkgd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudE5vZGUsIHRleHQpO1xuICB9XG59XG5mdW5jdGlvbiBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlKHBhcmVudFR5cGUsIHBhcmVudFByb3BzLCBwYXJlbnRJbnN0YW5jZSwgdHlwZSwgcHJvcHMsIGlzQ29uY3VycmVudE1vZGUpIHtcbiAge1xuICAgIGlmIChpc0NvbmN1cnJlbnRNb2RlIHx8IHBhcmVudFByb3BzW1NVUFBSRVNTX0hZRFJBVElPTl9XQVJOSU5HJDFdICE9PSB0cnVlKSB7XG4gICAgICB3YXJuRm9ySW5zZXJ0ZWRIeWRyYXRlZEVsZW1lbnQocGFyZW50SW5zdGFuY2UsIHR5cGUpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGlkTm90RmluZEh5ZHJhdGFibGVUZXh0SW5zdGFuY2UocGFyZW50VHlwZSwgcGFyZW50UHJvcHMsIHBhcmVudEluc3RhbmNlLCB0ZXh0LCBpc0NvbmN1cnJlbnRNb2RlKSB7XG4gIHtcbiAgICBpZiAoaXNDb25jdXJyZW50TW9kZSB8fCBwYXJlbnRQcm9wc1tTVVBQUkVTU19IWURSQVRJT05fV0FSTklORyQxXSAhPT0gdHJ1ZSkge1xuICAgICAgd2FybkZvckluc2VydGVkSHlkcmF0ZWRUZXh0KHBhcmVudEluc3RhbmNlLCB0ZXh0KTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGVycm9ySHlkcmF0aW5nQ29udGFpbmVyKHBhcmVudENvbnRhaW5lcikge1xuICB7XG4gICAgLy8gVE9ETzogVGhpcyBnZXRzIGxvZ2dlZCBieSBvblJlY292ZXJhYmxlRXJyb3IsIHRvbywgc28gd2Ugc2hvdWxkIGJlXG4gICAgLy8gYWJsZSB0byByZW1vdmUgaXQuXG4gICAgZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIGR1cmluZyBoeWRyYXRpb24uIFRoZSBzZXJ2ZXIgSFRNTCB3YXMgcmVwbGFjZWQgd2l0aCBjbGllbnQgY29udGVudCBpbiA8JXM+LicsIHBhcmVudENvbnRhaW5lci5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxufVxuZnVuY3Rpb24gcHJlcGFyZVBvcnRhbE1vdW50KHBvcnRhbEluc3RhbmNlKSB7XG4gIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHBvcnRhbEluc3RhbmNlKTtcbn1cblxudmFyIHJhbmRvbUtleSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpO1xudmFyIGludGVybmFsSW5zdGFuY2VLZXkgPSAnX19yZWFjdEZpYmVyJCcgKyByYW5kb21LZXk7XG52YXIgaW50ZXJuYWxQcm9wc0tleSA9ICdfX3JlYWN0UHJvcHMkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbENvbnRhaW5lckluc3RhbmNlS2V5ID0gJ19fcmVhY3RDb250YWluZXIkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbEV2ZW50SGFuZGxlcnNLZXkgPSAnX19yZWFjdEV2ZW50cyQnICsgcmFuZG9tS2V5O1xudmFyIGludGVybmFsRXZlbnRIYW5kbGVyTGlzdGVuZXJzS2V5ID0gJ19fcmVhY3RMaXN0ZW5lcnMkJyArIHJhbmRvbUtleTtcbnZhciBpbnRlcm5hbEV2ZW50SGFuZGxlc1NldEtleSA9ICdfX3JlYWN0SGFuZGxlcyQnICsgcmFuZG9tS2V5O1xuZnVuY3Rpb24gZGV0YWNoRGVsZXRlZEluc3RhbmNlKG5vZGUpIHtcbiAgLy8gVE9ETzogVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBvbiBob3N0IGNvbXBvbmVudHMuIEkgZG9uJ3QgdGhpbmsgYWxsIG9mXG4gIC8vIHRoZXNlIGZpZWxkcyBhcmUgcmVsZXZhbnQuXG4gIGRlbGV0ZSBub2RlW2ludGVybmFsSW5zdGFuY2VLZXldO1xuICBkZWxldGUgbm9kZVtpbnRlcm5hbFByb3BzS2V5XTtcbiAgZGVsZXRlIG5vZGVbaW50ZXJuYWxFdmVudEhhbmRsZXJzS2V5XTtcbiAgZGVsZXRlIG5vZGVbaW50ZXJuYWxFdmVudEhhbmRsZXJMaXN0ZW5lcnNLZXldO1xuICBkZWxldGUgbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlc1NldEtleV07XG59XG5mdW5jdGlvbiBwcmVjYWNoZUZpYmVyTm9kZShob3N0SW5zdCwgbm9kZSkge1xuICBub2RlW2ludGVybmFsSW5zdGFuY2VLZXldID0gaG9zdEluc3Q7XG59XG5mdW5jdGlvbiBtYXJrQ29udGFpbmVyQXNSb290KGhvc3RSb290LCBub2RlKSB7XG4gIG5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV0gPSBob3N0Um9vdDtcbn1cbmZ1bmN0aW9uIHVubWFya0NvbnRhaW5lckFzUm9vdChub2RlKSB7XG4gIG5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV0gPSBudWxsO1xufVxuZnVuY3Rpb24gaXNDb250YWluZXJNYXJrZWRBc1Jvb3Qobm9kZSkge1xuICByZXR1cm4gISFub2RlW2ludGVybmFsQ29udGFpbmVySW5zdGFuY2VLZXldO1xufSAvLyBHaXZlbiBhIERPTSBub2RlLCByZXR1cm4gdGhlIGNsb3Nlc3QgSG9zdENvbXBvbmVudCBvciBIb3N0VGV4dCBmaWJlciBhbmNlc3Rvci5cbi8vIElmIHRoZSB0YXJnZXQgbm9kZSBpcyBwYXJ0IG9mIGEgaHlkcmF0ZWQgb3Igbm90IHlldCByZW5kZXJlZCBzdWJ0cmVlLCB0aGVuXG4vLyB0aGlzIG1heSBhbHNvIHJldHVybiBhIFN1c3BlbnNlQ29tcG9uZW50IG9yIEhvc3RSb290IHRvIGluZGljYXRlIHRoYXQuXG4vLyBDb25jZXB0dWFsbHkgdGhlIEhvc3RSb290IGZpYmVyIGlzIGEgY2hpbGQgb2YgdGhlIENvbnRhaW5lciBub2RlLiBTbyBpZiB5b3Vcbi8vIHBhc3MgdGhlIENvbnRhaW5lciBub2RlIGFzIHRoZSB0YXJnZXROb2RlLCB5b3Ugd2lsbCBub3QgYWN0dWFsbHkgZ2V0IHRoZVxuLy8gSG9zdFJvb3QgYmFjay4gVG8gZ2V0IHRvIHRoZSBIb3N0Um9vdCwgeW91IG5lZWQgdG8gcGFzcyBhIGNoaWxkIG9mIGl0LlxuLy8gVGhlIHNhbWUgdGhpbmcgYXBwbGllcyB0byBTdXNwZW5zZSBib3VuZGFyaWVzLlxuXG5mdW5jdGlvbiBnZXRDbG9zZXN0SW5zdGFuY2VGcm9tTm9kZSh0YXJnZXROb2RlKSB7XG4gIHZhciB0YXJnZXRJbnN0ID0gdGFyZ2V0Tm9kZVtpbnRlcm5hbEluc3RhbmNlS2V5XTtcblxuICBpZiAodGFyZ2V0SW5zdCkge1xuICAgIC8vIERvbid0IHJldHVybiBIb3N0Um9vdCBvciBTdXNwZW5zZUNvbXBvbmVudCBoZXJlLlxuICAgIHJldHVybiB0YXJnZXRJbnN0O1xuICB9IC8vIElmIHRoZSBkaXJlY3QgZXZlbnQgdGFyZ2V0IGlzbid0IGEgUmVhY3Qgb3duZWQgRE9NIG5vZGUsIHdlIG5lZWQgdG8gbG9va1xuICAvLyB0byBzZWUgaWYgb25lIG9mIGl0cyBwYXJlbnRzIGlzIGEgUmVhY3Qgb3duZWQgRE9NIG5vZGUuXG5cblxuICB2YXIgcGFyZW50Tm9kZSA9IHRhcmdldE5vZGUucGFyZW50Tm9kZTtcblxuICB3aGlsZSAocGFyZW50Tm9kZSkge1xuICAgIC8vIFdlJ2xsIGNoZWNrIGlmIHRoaXMgaXMgYSBjb250YWluZXIgcm9vdCB0aGF0IGNvdWxkIGluY2x1ZGVcbiAgICAvLyBSZWFjdCBub2RlcyBpbiB0aGUgZnV0dXJlLiBXZSBuZWVkIHRvIGNoZWNrIHRoaXMgZmlyc3QgYmVjYXVzZVxuICAgIC8vIGlmIHdlJ3JlIGEgY2hpbGQgb2YgYSBkZWh5ZHJhdGVkIGNvbnRhaW5lciwgd2UgbmVlZCB0byBmaXJzdFxuICAgIC8vIGZpbmQgdGhhdCBpbm5lciBjb250YWluZXIgYmVmb3JlIG1vdmluZyBvbiB0byBmaW5kaW5nIHRoZSBwYXJlbnRcbiAgICAvLyBpbnN0YW5jZS4gTm90ZSB0aGF0IHdlIGRvbid0IGNoZWNrIHRoaXMgZmllbGQgb24gIHRoZSB0YXJnZXROb2RlXG4gICAgLy8gaXRzZWxmIGJlY2F1c2UgdGhlIGZpYmVycyBhcmUgY29uY2VwdHVhbGx5IGJldHdlZW4gdGhlIGNvbnRhaW5lclxuICAgIC8vIG5vZGUgYW5kIHRoZSBmaXJzdCBjaGlsZC4gSXQgaXNuJ3Qgc3Vycm91bmRpbmcgdGhlIGNvbnRhaW5lciBub2RlLlxuICAgIC8vIElmIGl0J3Mgbm90IGEgY29udGFpbmVyLCB3ZSBjaGVjayBpZiBpdCdzIGFuIGluc3RhbmNlLlxuICAgIHRhcmdldEluc3QgPSBwYXJlbnROb2RlW2ludGVybmFsQ29udGFpbmVySW5zdGFuY2VLZXldIHx8IHBhcmVudE5vZGVbaW50ZXJuYWxJbnN0YW5jZUtleV07XG5cbiAgICBpZiAodGFyZ2V0SW5zdCkge1xuICAgICAgLy8gU2luY2UgdGhpcyB3YXNuJ3QgdGhlIGRpcmVjdCB0YXJnZXQgb2YgdGhlIGV2ZW50LCB3ZSBtaWdodCBoYXZlXG4gICAgICAvLyBzdGVwcGVkIHBhc3QgZGVoeWRyYXRlZCBET00gbm9kZXMgdG8gZ2V0IGhlcmUuIEhvd2V2ZXIgdGhleSBjb3VsZFxuICAgICAgLy8gYWxzbyBoYXZlIGJlZW4gbm9uLVJlYWN0IG5vZGVzLiBXZSBuZWVkIHRvIGFuc3dlciB3aGljaCBvbmUuXG4gICAgICAvLyBJZiB3ZSB0aGUgaW5zdGFuY2UgZG9lc24ndCBoYXZlIGFueSBjaGlsZHJlbiwgdGhlbiB0aGVyZSBjYW4ndCBiZVxuICAgICAgLy8gYSBuZXN0ZWQgc3VzcGVuc2UgYm91bmRhcnkgd2l0aGluIGl0LiBTbyB3ZSBjYW4gdXNlIHRoaXMgYXMgYSBmYXN0XG4gICAgICAvLyBiYWlsb3V0LiBNb3N0IG9mIHRoZSB0aW1lLCB3aGVuIHBlb3BsZSBhZGQgbm9uLVJlYWN0IGNoaWxkcmVuIHRvXG4gICAgICAvLyB0aGUgdHJlZSwgaXQgaXMgdXNpbmcgYSByZWYgdG8gYSBjaGlsZC1sZXNzIERPTSBub2RlLlxuICAgICAgLy8gTm9ybWFsbHkgd2UnZCBvbmx5IG5lZWQgdG8gY2hlY2sgb25lIG9mIHRoZSBmaWJlcnMgYmVjYXVzZSBpZiBpdFxuICAgICAgLy8gaGFzIGV2ZXIgZ29uZSBmcm9tIGhhdmluZyBjaGlsZHJlbiB0byBkZWxldGluZyB0aGVtIG9yIHZpY2UgdmVyc2FcbiAgICAgIC8vIGl0IHdvdWxkIGhhdmUgZGVsZXRlZCB0aGUgZGVoeWRyYXRlZCBib3VuZGFyeSBuZXN0ZWQgaW5zaWRlIGFscmVhZHkuXG4gICAgICAvLyBIb3dldmVyLCBzaW5jZSB0aGUgSG9zdFJvb3Qgc3RhcnRzIG91dCB3aXRoIGFuIGFsdGVybmF0ZSBpdCBtaWdodFxuICAgICAgLy8gaGF2ZSBvbmUgb24gdGhlIGFsdGVybmF0ZSBzbyB3ZSBuZWVkIHRvIGNoZWNrIGluIGNhc2UgdGhpcyB3YXMgYVxuICAgICAgLy8gcm9vdC5cbiAgICAgIHZhciBhbHRlcm5hdGUgPSB0YXJnZXRJbnN0LmFsdGVybmF0ZTtcblxuICAgICAgaWYgKHRhcmdldEluc3QuY2hpbGQgIT09IG51bGwgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGFsdGVybmF0ZS5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBOZXh0IHdlIG5lZWQgdG8gZmlndXJlIG91dCBpZiB0aGUgbm9kZSB0aGF0IHNraXBwZWQgcGFzdCBpc1xuICAgICAgICAvLyBuZXN0ZWQgd2l0aGluIGEgZGVoeWRyYXRlZCBib3VuZGFyeSBhbmQgaWYgc28sIHdoaWNoIG9uZS5cbiAgICAgICAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBnZXRQYXJlbnRTdXNwZW5zZUluc3RhbmNlKHRhcmdldE5vZGUpO1xuXG4gICAgICAgIHdoaWxlIChzdXNwZW5zZUluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UgZm91bmQgYSBzdXNwZW5zZSBpbnN0YW5jZS4gVGhhdCBtZWFucyB0aGF0IHdlIGhhdmVuJ3RcbiAgICAgICAgICAvLyBoeWRyYXRlZCBpdCB5ZXQuIEV2ZW4gdGhvdWdoIHdlIGxlYXZlIHRoZSBjb21tZW50cyBpbiB0aGVcbiAgICAgICAgICAvLyBET00gYWZ0ZXIgaHlkcmF0aW5nLCBhbmQgdGhlcmUgYXJlIGJvdW5kYXJpZXMgaW4gdGhlIERPTVxuICAgICAgICAgIC8vIHRoYXQgY291bGQgYWxyZWFkeSBiZSBoeWRyYXRlZCwgd2Ugd291bGRuJ3QgaGF2ZSBmb3VuZCB0aGVtXG4gICAgICAgICAgLy8gdGhyb3VnaCB0aGlzIHBhc3Mgc2luY2UgaWYgdGhlIHRhcmdldCBpcyBoeWRyYXRlZCBpdCB3b3VsZFxuICAgICAgICAgIC8vIGhhdmUgaGFkIGFuIGludGVybmFsSW5zdGFuY2VLZXkgb24gaXQuXG4gICAgICAgICAgLy8gTGV0J3MgZ2V0IHRoZSBmaWJlciBhc3NvY2lhdGVkIHdpdGggdGhlIFN1c3BlbnNlQ29tcG9uZW50XG4gICAgICAgICAgLy8gYXMgdGhlIGRlZXBlc3QgaW5zdGFuY2UuXG4gICAgICAgICAgdmFyIHRhcmdldFN1c3BlbnNlSW5zdCA9IHN1c3BlbnNlSW5zdGFuY2VbaW50ZXJuYWxJbnN0YW5jZUtleV07XG5cbiAgICAgICAgICBpZiAodGFyZ2V0U3VzcGVuc2VJbnN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0U3VzcGVuc2VJbnN0O1xuICAgICAgICAgIH0gLy8gSWYgd2UgZG9uJ3QgZmluZCBhIEZpYmVyIG9uIHRoZSBjb21tZW50LCBpdCBtaWdodCBiZSBiZWNhdXNlXG4gICAgICAgICAgLy8gd2UgaGF2ZW4ndCBnb3R0ZW4gdG8gaHlkcmF0ZSBpdCB5ZXQuIFRoZXJlIG1pZ2h0IHN0aWxsIGJlIGFcbiAgICAgICAgICAvLyBwYXJlbnQgYm91bmRhcnkgdGhhdCBoYXNuJ3QgYWJvdmUgdGhpcyBvbmUgc28gd2UgbmVlZCB0byBmaW5kXG4gICAgICAgICAgLy8gdGhlIG91dGVyIG1vc3QgdGhhdCBpcyBrbm93bi5cblxuXG4gICAgICAgICAgc3VzcGVuc2VJbnN0YW5jZSA9IGdldFBhcmVudFN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSk7IC8vIElmIHdlIGRvbid0IGZpbmQgb25lLCB0aGVuIHRoYXQgc2hvdWxkIG1lYW4gdGhhdCB0aGUgcGFyZW50XG4gICAgICAgICAgLy8gaG9zdCBjb21wb25lbnQgYWxzbyBoYXNuJ3QgaHlkcmF0ZWQgeWV0LiBXZSBjYW4gcmV0dXJuIGl0XG4gICAgICAgICAgLy8gYmVsb3cgc2luY2UgaXQgd2lsbCBiYWlsIG91dCBvbiB0aGUgaXNNb3VudGVkIGNoZWNrIGxhdGVyLlxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0YXJnZXRJbnN0O1xuICAgIH1cblxuICAgIHRhcmdldE5vZGUgPSBwYXJlbnROb2RlO1xuICAgIHBhcmVudE5vZGUgPSB0YXJnZXROb2RlLnBhcmVudE5vZGU7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogR2l2ZW4gYSBET00gbm9kZSwgcmV0dXJuIHRoZSBSZWFjdERPTUNvbXBvbmVudCBvciBSZWFjdERPTVRleHRDb21wb25lbnRcbiAqIGluc3RhbmNlLCBvciBudWxsIGlmIHRoZSBub2RlIHdhcyBub3QgcmVuZGVyZWQgYnkgdGhpcyBSZWFjdC5cbiAqL1xuXG5mdW5jdGlvbiBnZXRJbnN0YW5jZUZyb21Ob2RlKG5vZGUpIHtcbiAgdmFyIGluc3QgPSBub2RlW2ludGVybmFsSW5zdGFuY2VLZXldIHx8IG5vZGVbaW50ZXJuYWxDb250YWluZXJJbnN0YW5jZUtleV07XG5cbiAgaWYgKGluc3QpIHtcbiAgICBpZiAoaW5zdC50YWcgPT09IEhvc3RDb21wb25lbnQgfHwgaW5zdC50YWcgPT09IEhvc3RUZXh0IHx8IGluc3QudGFnID09PSBTdXNwZW5zZUNvbXBvbmVudCB8fCBpbnN0LnRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgIHJldHVybiBpbnN0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogR2l2ZW4gYSBSZWFjdERPTUNvbXBvbmVudCBvciBSZWFjdERPTVRleHRDb21wb25lbnQsIHJldHVybiB0aGUgY29ycmVzcG9uZGluZ1xuICogRE9NIG5vZGUuXG4gKi9cblxuZnVuY3Rpb24gZ2V0Tm9kZUZyb21JbnN0YW5jZShpbnN0KSB7XG4gIGlmIChpbnN0LnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBpbnN0LnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICAvLyBJbiBGaWJlciB0aGlzLCBpcyBqdXN0IHRoZSBzdGF0ZSBub2RlIHJpZ2h0IG5vdy4gV2UgYXNzdW1lIGl0IHdpbGwgYmVcbiAgICAvLyBhIGhvc3QgY29tcG9uZW50IG9yIGhvc3QgdGV4dC5cbiAgICByZXR1cm4gaW5zdC5zdGF0ZU5vZGU7XG4gIH0gLy8gV2l0aG91dCB0aGlzIGZpcnN0IGludmFyaWFudCwgcGFzc2luZyBhIG5vbi1ET00tY29tcG9uZW50IHRyaWdnZXJzIHRoZSBuZXh0XG4gIC8vIGludmFyaWFudCBmb3IgYSBtaXNzaW5nIHBhcmVudCwgd2hpY2ggaXMgc3VwZXIgY29uZnVzaW5nLlxuXG5cbiAgdGhyb3cgbmV3IEVycm9yKCdnZXROb2RlRnJvbUluc3RhbmNlOiBJbnZhbGlkIGFyZ3VtZW50LicpO1xufVxuZnVuY3Rpb24gZ2V0RmliZXJDdXJyZW50UHJvcHNGcm9tTm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlW2ludGVybmFsUHJvcHNLZXldIHx8IG51bGw7XG59XG5mdW5jdGlvbiB1cGRhdGVGaWJlclByb3BzKG5vZGUsIHByb3BzKSB7XG4gIG5vZGVbaW50ZXJuYWxQcm9wc0tleV0gPSBwcm9wcztcbn1cbmZ1bmN0aW9uIGdldEV2ZW50TGlzdGVuZXJTZXQobm9kZSkge1xuICB2YXIgZWxlbWVudExpc3RlbmVyU2V0ID0gbm9kZVtpbnRlcm5hbEV2ZW50SGFuZGxlcnNLZXldO1xuXG4gIGlmIChlbGVtZW50TGlzdGVuZXJTZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVsZW1lbnRMaXN0ZW5lclNldCA9IG5vZGVbaW50ZXJuYWxFdmVudEhhbmRsZXJzS2V5XSA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50TGlzdGVuZXJTZXQ7XG59XG5cbnZhciBsb2dnZWRUeXBlRmFpbHVyZXMgPSB7fTtcbnZhciBSZWFjdERlYnVnQ3VycmVudEZyYW1lJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdERlYnVnQ3VycmVudEZyYW1lO1xuXG5mdW5jdGlvbiBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChlbGVtZW50KSB7XG4gIHtcbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgdmFyIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG4gICAgICB2YXIgc3RhY2sgPSBkZXNjcmliZVVua25vd25FbGVtZW50VHlwZUZyYW1lSW5ERVYoZWxlbWVudC50eXBlLCBlbGVtZW50Ll9zb3VyY2UsIG93bmVyID8gb3duZXIudHlwZSA6IG51bGwpO1xuICAgICAgUmVhY3REZWJ1Z0N1cnJlbnRGcmFtZSQxLnNldEV4dHJhU3RhY2tGcmFtZShzdGFjayk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFJlYWN0RGVidWdDdXJyZW50RnJhbWUkMS5zZXRFeHRyYVN0YWNrRnJhbWUobnVsbCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrUHJvcFR5cGVzKHR5cGVTcGVjcywgdmFsdWVzLCBsb2NhdGlvbiwgY29tcG9uZW50TmFtZSwgZWxlbWVudCkge1xuICB7XG4gICAgLy8gJEZsb3dGaXhNZSBUaGlzIGlzIG9rYXkgYnV0IEZsb3cgZG9lc24ndCBrbm93IGl0LlxuICAgIHZhciBoYXMgPSBGdW5jdGlvbi5jYWxsLmJpbmQoaGFzT3duUHJvcGVydHkpO1xuXG4gICAgZm9yICh2YXIgdHlwZVNwZWNOYW1lIGluIHR5cGVTcGVjcykge1xuICAgICAgaWYgKGhhcyh0eXBlU3BlY3MsIHR5cGVTcGVjTmFtZSkpIHtcbiAgICAgICAgdmFyIGVycm9yJDEgPSB2b2lkIDA7IC8vIFByb3AgdHlwZSB2YWxpZGF0aW9uIG1heSB0aHJvdy4gSW4gY2FzZSB0aGV5IGRvLCB3ZSBkb24ndCB3YW50IHRvXG4gICAgICAgIC8vIGZhaWwgdGhlIHJlbmRlciBwaGFzZSB3aGVyZSBpdCBkaWRuJ3QgZmFpbCBiZWZvcmUuIFNvIHdlIGxvZyBpdC5cbiAgICAgICAgLy8gQWZ0ZXIgdGhlc2UgaGF2ZSBiZWVuIGNsZWFuZWQgdXAsIHdlJ2xsIGxldCB0aGVtIHRocm93LlxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGFuIGludmFyaWFudCB0aGF0IGdldHMgY2F1Z2h0LiBJdCdzIHRoZSBzYW1lXG4gICAgICAgICAgLy8gYmVoYXZpb3IgYXMgd2l0aG91dCB0aGlzIHN0YXRlbWVudCBleGNlcHQgd2l0aCBhIGJldHRlciBtZXNzYWdlLlxuICAgICAgICAgIGlmICh0eXBlb2YgdHlwZVNwZWNzW3R5cGVTcGVjTmFtZV0gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICAgICAgICB2YXIgZXJyID0gRXJyb3IoKGNvbXBvbmVudE5hbWUgfHwgJ1JlYWN0IGNsYXNzJykgKyAnOiAnICsgbG9jYXRpb24gKyAnIHR5cGUgYCcgKyB0eXBlU3BlY05hbWUgKyAnYCBpcyBpbnZhbGlkOyAnICsgJ2l0IG11c3QgYmUgYSBmdW5jdGlvbiwgdXN1YWxseSBmcm9tIHRoZSBgcHJvcC10eXBlc2AgcGFja2FnZSwgYnV0IHJlY2VpdmVkIGAnICsgdHlwZW9mIHR5cGVTcGVjc1t0eXBlU3BlY05hbWVdICsgJ2AuJyArICdUaGlzIG9mdGVuIGhhcHBlbnMgYmVjYXVzZSBvZiB0eXBvcyBzdWNoIGFzIGBQcm9wVHlwZXMuZnVuY3Rpb25gIGluc3RlYWQgb2YgYFByb3BUeXBlcy5mdW5jYC4nKTtcbiAgICAgICAgICAgIGVyci5uYW1lID0gJ0ludmFyaWFudCBWaW9sYXRpb24nO1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGVycm9yJDEgPSB0eXBlU3BlY3NbdHlwZVNwZWNOYW1lXSh2YWx1ZXMsIHR5cGVTcGVjTmFtZSwgY29tcG9uZW50TmFtZSwgbG9jYXRpb24sIG51bGwsICdTRUNSRVRfRE9fTk9UX1BBU1NfVEhJU19PUl9ZT1VfV0lMTF9CRV9GSVJFRCcpO1xuICAgICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAgIGVycm9yJDEgPSBleDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvciQxICYmICEoZXJyb3IkMSBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpO1xuXG4gICAgICAgICAgZXJyb3IoJyVzOiB0eXBlIHNwZWNpZmljYXRpb24gb2YgJXMnICsgJyBgJXNgIGlzIGludmFsaWQ7IHRoZSB0eXBlIGNoZWNrZXIgJyArICdmdW5jdGlvbiBtdXN0IHJldHVybiBgbnVsbGAgb3IgYW4gYEVycm9yYCBidXQgcmV0dXJuZWQgYSAlcy4gJyArICdZb3UgbWF5IGhhdmUgZm9yZ290dGVuIHRvIHBhc3MgYW4gYXJndW1lbnQgdG8gdGhlIHR5cGUgY2hlY2tlciAnICsgJ2NyZWF0b3IgKGFycmF5T2YsIGluc3RhbmNlT2YsIG9iamVjdE9mLCBvbmVPZiwgb25lT2ZUeXBlLCBhbmQgJyArICdzaGFwZSBhbGwgcmVxdWlyZSBhbiBhcmd1bWVudCkuJywgY29tcG9uZW50TmFtZSB8fCAnUmVhY3QgY2xhc3MnLCBsb2NhdGlvbiwgdHlwZVNwZWNOYW1lLCB0eXBlb2YgZXJyb3IkMSk7XG5cbiAgICAgICAgICBzZXRDdXJyZW50bHlWYWxpZGF0aW5nRWxlbWVudChudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvciQxIGluc3RhbmNlb2YgRXJyb3IgJiYgIShlcnJvciQxLm1lc3NhZ2UgaW4gbG9nZ2VkVHlwZUZhaWx1cmVzKSkge1xuICAgICAgICAgIC8vIE9ubHkgbW9uaXRvciB0aGlzIGZhaWx1cmUgb25jZSBiZWNhdXNlIHRoZXJlIHRlbmRzIHRvIGJlIGEgbG90IG9mIHRoZVxuICAgICAgICAgIC8vIHNhbWUgZXJyb3IuXG4gICAgICAgICAgbG9nZ2VkVHlwZUZhaWx1cmVzW2Vycm9yJDEubWVzc2FnZV0gPSB0cnVlO1xuICAgICAgICAgIHNldEN1cnJlbnRseVZhbGlkYXRpbmdFbGVtZW50KGVsZW1lbnQpO1xuXG4gICAgICAgICAgZXJyb3IoJ0ZhaWxlZCAlcyB0eXBlOiAlcycsIGxvY2F0aW9uLCBlcnJvciQxLm1lc3NhZ2UpO1xuXG4gICAgICAgICAgc2V0Q3VycmVudGx5VmFsaWRhdGluZ0VsZW1lbnQobnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIHZhbHVlU3RhY2sgPSBbXTtcbnZhciBmaWJlclN0YWNrO1xuXG57XG4gIGZpYmVyU3RhY2sgPSBbXTtcbn1cblxudmFyIGluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNyZWF0ZUN1cnNvcihkZWZhdWx0VmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBjdXJyZW50OiBkZWZhdWx0VmFsdWVcbiAgfTtcbn1cblxuZnVuY3Rpb24gcG9wKGN1cnNvciwgZmliZXIpIHtcbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHtcbiAgICAgIGVycm9yKCdVbmV4cGVjdGVkIHBvcC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm47XG4gIH1cblxuICB7XG4gICAgaWYgKGZpYmVyICE9PSBmaWJlclN0YWNrW2luZGV4XSkge1xuICAgICAgZXJyb3IoJ1VuZXhwZWN0ZWQgRmliZXIgcG9wcGVkLicpO1xuICAgIH1cbiAgfVxuXG4gIGN1cnNvci5jdXJyZW50ID0gdmFsdWVTdGFja1tpbmRleF07XG4gIHZhbHVlU3RhY2tbaW5kZXhdID0gbnVsbDtcblxuICB7XG4gICAgZmliZXJTdGFja1tpbmRleF0gPSBudWxsO1xuICB9XG5cbiAgaW5kZXgtLTtcbn1cblxuZnVuY3Rpb24gcHVzaChjdXJzb3IsIHZhbHVlLCBmaWJlcikge1xuICBpbmRleCsrO1xuICB2YWx1ZVN0YWNrW2luZGV4XSA9IGN1cnNvci5jdXJyZW50O1xuXG4gIHtcbiAgICBmaWJlclN0YWNrW2luZGV4XSA9IGZpYmVyO1xuICB9XG5cbiAgY3Vyc29yLmN1cnJlbnQgPSB2YWx1ZTtcbn1cblxudmFyIHdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dDtcblxue1xuICB3YXJuZWRBYm91dE1pc3NpbmdHZXRDaGlsZENvbnRleHQgPSB7fTtcbn1cblxudmFyIGVtcHR5Q29udGV4dE9iamVjdCA9IHt9O1xuXG57XG4gIE9iamVjdC5mcmVlemUoZW1wdHlDb250ZXh0T2JqZWN0KTtcbn0gLy8gQSBjdXJzb3IgdG8gdGhlIGN1cnJlbnQgbWVyZ2VkIGNvbnRleHQgb2JqZWN0IG9uIHRoZSBzdGFjay5cblxuXG52YXIgY29udGV4dFN0YWNrQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKGVtcHR5Q29udGV4dE9iamVjdCk7IC8vIEEgY3Vyc29yIHRvIGEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbnRleHQgaGFzIGNoYW5nZWQuXG5cbnZhciBkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKGZhbHNlKTsgLy8gS2VlcCB0cmFjayBvZiB0aGUgcHJldmlvdXMgY29udGV4dCBvYmplY3QgdGhhdCB3YXMgb24gdGhlIHN0YWNrLlxuLy8gV2UgdXNlIHRoaXMgdG8gZ2V0IGFjY2VzcyB0byB0aGUgcGFyZW50IGNvbnRleHQgYWZ0ZXIgd2UgaGF2ZSBhbHJlYWR5XG4vLyBwdXNoZWQgdGhlIG5leHQgY29udGV4dCBwcm92aWRlciwgYW5kIG5vdyBuZWVkIHRvIG1lcmdlIHRoZWlyIGNvbnRleHRzLlxuXG52YXIgcHJldmlvdXNDb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuXG5mdW5jdGlvbiBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgZGlkUHVzaE93bkNvbnRleHRJZlByb3ZpZGVyKSB7XG4gIHtcbiAgICBpZiAoZGlkUHVzaE93bkNvbnRleHRJZlByb3ZpZGVyICYmIGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgIC8vIElmIHRoZSBmaWJlciBpcyBhIGNvbnRleHQgcHJvdmlkZXIgaXRzZWxmLCB3aGVuIHdlIHJlYWQgaXRzIGNvbnRleHRcbiAgICAgIC8vIHdlIG1heSBoYXZlIGFscmVhZHkgcHVzaGVkIGl0cyBvd24gY2hpbGQgY29udGV4dCBvbiB0aGUgc3RhY2suIEEgY29udGV4dFxuICAgICAgLy8gcHJvdmlkZXIgc2hvdWxkIG5vdCBcInNlZVwiIGl0cyBvd24gY2hpbGQgY29udGV4dC4gVGhlcmVmb3JlIHdlIHJlYWQgdGhlXG4gICAgICAvLyBwcmV2aW91cyAocGFyZW50KSBjb250ZXh0IGluc3RlYWQgZm9yIGEgY29udGV4dCBwcm92aWRlci5cbiAgICAgIHJldHVybiBwcmV2aW91c0NvbnRleHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHRTdGFja0N1cnNvci5jdXJyZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhY2hlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0LCBtYXNrZWRDb250ZXh0KSB7XG4gIHtcbiAgICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRVbm1hc2tlZENoaWxkQ29udGV4dCA9IHVubWFza2VkQ29udGV4dDtcbiAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1hc2tlZENoaWxkQ29udGV4dCA9IG1hc2tlZENvbnRleHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0KSB7XG4gIHtcbiAgICB2YXIgdHlwZSA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgdmFyIGNvbnRleHRUeXBlcyA9IHR5cGUuY29udGV4dFR5cGVzO1xuXG4gICAgaWYgKCFjb250ZXh0VHlwZXMpIHtcbiAgICAgIHJldHVybiBlbXB0eUNvbnRleHRPYmplY3Q7XG4gICAgfSAvLyBBdm9pZCByZWNyZWF0aW5nIG1hc2tlZCBjb250ZXh0IHVubGVzcyB1bm1hc2tlZCBjb250ZXh0IGhhcyBjaGFuZ2VkLlxuICAgIC8vIEZhaWxpbmcgdG8gZG8gdGhpcyB3aWxsIHJlc3VsdCBpbiB1bm5lY2Vzc2FyeSBjYWxscyB0byBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzLlxuICAgIC8vIFRoaXMgbWF5IHRyaWdnZXIgaW5maW5pdGUgbG9vcHMgaWYgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyBjYWxscyBzZXRTdGF0ZS5cblxuXG4gICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgaWYgKGluc3RhbmNlICYmIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkVW5tYXNrZWRDaGlsZENvbnRleHQgPT09IHVubWFza2VkQ29udGV4dCkge1xuICAgICAgcmV0dXJuIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWFza2VkQ2hpbGRDb250ZXh0O1xuICAgIH1cblxuICAgIHZhciBjb250ZXh0ID0ge307XG5cbiAgICBmb3IgKHZhciBrZXkgaW4gY29udGV4dFR5cGVzKSB7XG4gICAgICBjb250ZXh0W2tleV0gPSB1bm1hc2tlZENvbnRleHRba2V5XTtcbiAgICB9XG5cbiAgICB7XG4gICAgICB2YXIgbmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIod29ya0luUHJvZ3Jlc3MpIHx8ICdVbmtub3duJztcbiAgICAgIGNoZWNrUHJvcFR5cGVzKGNvbnRleHRUeXBlcywgY29udGV4dCwgJ2NvbnRleHQnLCBuYW1lKTtcbiAgICB9IC8vIENhY2hlIHVubWFza2VkIGNvbnRleHQgc28gd2UgY2FuIGF2b2lkIHJlY3JlYXRpbmcgbWFza2VkIGNvbnRleHQgdW5sZXNzIG5lY2Vzc2FyeS5cbiAgICAvLyBDb250ZXh0IGlzIGNyZWF0ZWQgYmVmb3JlIHRoZSBjbGFzcyBjb21wb25lbnQgaXMgaW5zdGFudGlhdGVkIHNvIGNoZWNrIGZvciBpbnN0YW5jZS5cblxuXG4gICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICBjYWNoZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHVubWFza2VkQ29udGV4dCwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFzQ29udGV4dENoYW5nZWQoKSB7XG4gIHtcbiAgICByZXR1cm4gZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvci5jdXJyZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ29udGV4dFByb3ZpZGVyKHR5cGUpIHtcbiAge1xuICAgIHZhciBjaGlsZENvbnRleHRUeXBlcyA9IHR5cGUuY2hpbGRDb250ZXh0VHlwZXM7XG4gICAgcmV0dXJuIGNoaWxkQ29udGV4dFR5cGVzICE9PSBudWxsICYmIGNoaWxkQ29udGV4dFR5cGVzICE9PSB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9wQ29udGV4dChmaWJlcikge1xuICB7XG4gICAgcG9wKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgICBwb3AoY29udGV4dFN0YWNrQ3Vyc29yLCBmaWJlcik7XG4gIH1cbn1cblxuZnVuY3Rpb24gcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGZpYmVyKSB7XG4gIHtcbiAgICBwb3AoZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgZmliZXIpO1xuICAgIHBvcChjb250ZXh0U3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwdXNoVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGZpYmVyLCBjb250ZXh0LCBkaWRDaGFuZ2UpIHtcbiAge1xuICAgIGlmIChjb250ZXh0U3RhY2tDdXJzb3IuY3VycmVudCAhPT0gZW1wdHlDb250ZXh0T2JqZWN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgY29udGV4dCBmb3VuZCBvbiBzdGFjay4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yLCBjb250ZXh0LCBmaWJlcik7XG4gICAgcHVzaChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCBkaWRDaGFuZ2UsIGZpYmVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9jZXNzQ2hpbGRDb250ZXh0KGZpYmVyLCB0eXBlLCBwYXJlbnRDb250ZXh0KSB7XG4gIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG4gICAgdmFyIGNoaWxkQ29udGV4dFR5cGVzID0gdHlwZS5jaGlsZENvbnRleHRUeXBlczsgLy8gVE9ETyAoYnZhdWdobikgUmVwbGFjZSB0aGlzIGJlaGF2aW9yIHdpdGggYW4gaW52YXJpYW50KCkgaW4gdGhlIGZ1dHVyZS5cbiAgICAvLyBJdCBoYXMgb25seSBiZWVuIGFkZGVkIGluIEZpYmVyIHRvIG1hdGNoIHRoZSAodW5pbnRlbnRpb25hbCkgYmVoYXZpb3IgaW4gU3RhY2suXG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldENoaWxkQ29udGV4dCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAge1xuICAgICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdVbmtub3duJztcblxuICAgICAgICBpZiAoIXdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dFtjb21wb25lbnROYW1lXSkge1xuICAgICAgICAgIHdhcm5lZEFib3V0TWlzc2luZ0dldENoaWxkQ29udGV4dFtjb21wb25lbnROYW1lXSA9IHRydWU7XG5cbiAgICAgICAgICBlcnJvcignJXMuY2hpbGRDb250ZXh0VHlwZXMgaXMgc3BlY2lmaWVkIGJ1dCB0aGVyZSBpcyBubyBnZXRDaGlsZENvbnRleHQoKSBtZXRob2QgJyArICdvbiB0aGUgaW5zdGFuY2UuIFlvdSBjYW4gZWl0aGVyIGRlZmluZSBnZXRDaGlsZENvbnRleHQoKSBvbiAlcyBvciByZW1vdmUgJyArICdjaGlsZENvbnRleHRUeXBlcyBmcm9tIGl0LicsIGNvbXBvbmVudE5hbWUsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJlbnRDb250ZXh0O1xuICAgIH1cblxuICAgIHZhciBjaGlsZENvbnRleHQgPSBpbnN0YW5jZS5nZXRDaGlsZENvbnRleHQoKTtcblxuICAgIGZvciAodmFyIGNvbnRleHRLZXkgaW4gY2hpbGRDb250ZXh0KSB7XG4gICAgICBpZiAoIShjb250ZXh0S2V5IGluIGNoaWxkQ29udGV4dFR5cGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdVbmtub3duJykgKyBcIi5nZXRDaGlsZENvbnRleHQoKToga2V5IFxcXCJcIiArIGNvbnRleHRLZXkgKyBcIlxcXCIgaXMgbm90IGRlZmluZWQgaW4gY2hpbGRDb250ZXh0VHlwZXMuXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHtcbiAgICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1Vua25vd24nO1xuICAgICAgY2hlY2tQcm9wVHlwZXMoY2hpbGRDb250ZXh0VHlwZXMsIGNoaWxkQ29udGV4dCwgJ2NoaWxkIGNvbnRleHQnLCBuYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNzaWduKHt9LCBwYXJlbnRDb250ZXh0LCBjaGlsZENvbnRleHQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1c2hDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MpIHtcbiAge1xuICAgIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTsgLy8gV2UgcHVzaCB0aGUgY29udGV4dCBhcyBlYXJseSBhcyBwb3NzaWJsZSB0byBlbnN1cmUgc3RhY2sgaW50ZWdyaXR5LlxuICAgIC8vIElmIHRoZSBpbnN0YW5jZSBkb2VzIG5vdCBleGlzdCB5ZXQsIHdlIHdpbGwgcHVzaCBudWxsIGF0IGZpcnN0LFxuICAgIC8vIGFuZCByZXBsYWNlIGl0IG9uIHRoZSBzdGFjayBsYXRlciB3aGVuIGludmFsaWRhdGluZyB0aGUgY29udGV4dC5cblxuICAgIHZhciBtZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dCA9IGluc3RhbmNlICYmIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0IHx8IGVtcHR5Q29udGV4dE9iamVjdDsgLy8gUmVtZW1iZXIgdGhlIHBhcmVudCBjb250ZXh0IHNvIHdlIGNhbiBtZXJnZSB3aXRoIGl0IGxhdGVyLlxuICAgIC8vIEluaGVyaXQgdGhlIHBhcmVudCdzIGRpZC1wZXJmb3JtLXdvcmsgdmFsdWUgdG8gYXZvaWQgaW5hZHZlcnRlbnRseSBibG9ja2luZyB1cGRhdGVzLlxuXG4gICAgcHJldmlvdXNDb250ZXh0ID0gY29udGV4dFN0YWNrQ3Vyc29yLmN1cnJlbnQ7XG4gICAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IsIG1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0LCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgcHVzaChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCBkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLmN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbnZhbGlkYXRlQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCB0eXBlLCBkaWRDaGFuZ2UpIHtcbiAge1xuICAgIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcblxuICAgIGlmICghaW5zdGFuY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gaGF2ZSBhbiBpbnN0YW5jZSBieSB0aGlzIHBvaW50LiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgaWYgKGRpZENoYW5nZSkge1xuICAgICAgLy8gTWVyZ2UgcGFyZW50IGFuZCBvd24gY29udGV4dC5cbiAgICAgIC8vIFNraXAgdGhpcyBpZiB3ZSdyZSBub3QgdXBkYXRpbmcgZHVlIHRvIHNDVS5cbiAgICAgIC8vIFRoaXMgYXZvaWRzIHVubmVjZXNzYXJpbHkgcmVjb21wdXRpbmcgbWVtb2l6ZWQgdmFsdWVzLlxuICAgICAgdmFyIG1lcmdlZENvbnRleHQgPSBwcm9jZXNzQ2hpbGRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB0eXBlLCBwcmV2aW91c0NvbnRleHQpO1xuICAgICAgaW5zdGFuY2UuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNZXJnZWRDaGlsZENvbnRleHQgPSBtZXJnZWRDb250ZXh0OyAvLyBSZXBsYWNlIHRoZSBvbGQgKG9yIGVtcHR5KSBjb250ZXh0IHdpdGggdGhlIG5ldyBvbmUuXG4gICAgICAvLyBJdCBpcyBpbXBvcnRhbnQgdG8gdW53aW5kIHRoZSBjb250ZXh0IGluIHRoZSByZXZlcnNlIG9yZGVyLlxuXG4gICAgICBwb3AoZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcG9wKGNvbnRleHRTdGFja0N1cnNvciwgd29ya0luUHJvZ3Jlc3MpOyAvLyBOb3cgcHVzaCB0aGUgbmV3IGNvbnRleHQgYW5kIG1hcmsgdGhhdCBpdCBoYXMgY2hhbmdlZC5cblxuICAgICAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IsIG1lcmdlZENvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHB1c2goZGlkUGVyZm9ybVdvcmtTdGFja0N1cnNvciwgZGlkQ2hhbmdlLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBvcChkaWRQZXJmb3JtV29ya1N0YWNrQ3Vyc29yLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBwdXNoKGRpZFBlcmZvcm1Xb3JrU3RhY2tDdXJzb3IsIGRpZENoYW5nZSwgd29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kQ3VycmVudFVubWFza2VkQ29udGV4dChmaWJlcikge1xuICB7XG4gICAgLy8gQ3VycmVudGx5IHRoaXMgaXMgb25seSB1c2VkIHdpdGggcmVuZGVyU3VidHJlZUludG9Db250YWluZXI7IG5vdCBzdXJlIGlmIGl0XG4gICAgLy8gbWFrZXMgc2Vuc2UgZWxzZXdoZXJlXG4gICAgaWYgKCFpc0ZpYmVyTW91bnRlZChmaWJlcikgfHwgZmliZXIudGFnICE9PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBzdWJ0cmVlIHBhcmVudCB0byBiZSBhIG1vdW50ZWQgY2xhc3MgY29tcG9uZW50LiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgfVxuXG4gICAgdmFyIG5vZGUgPSBmaWJlcjtcblxuICAgIGRvIHtcbiAgICAgIHN3aXRjaCAobm9kZS50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICByZXR1cm4gbm9kZS5zdGF0ZU5vZGUuY29udGV4dDtcblxuICAgICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBDb21wb25lbnQgPSBub2RlLnR5cGU7XG5cbiAgICAgICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBub2RlLnN0YXRlTm9kZS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgfSB3aGlsZSAobm9kZSAhPT0gbnVsbCk7XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIHVuZXhwZWN0ZWQgZGV0YWNoZWQgc3VidHJlZSBwYXJlbnQuICcgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxufVxuXG52YXIgTGVnYWN5Um9vdCA9IDA7XG52YXIgQ29uY3VycmVudFJvb3QgPSAxO1xuXG52YXIgc3luY1F1ZXVlID0gbnVsbDtcbnZhciBpbmNsdWRlc0xlZ2FjeVN5bmNDYWxsYmFja3MgPSBmYWxzZTtcbnZhciBpc0ZsdXNoaW5nU3luY1F1ZXVlID0gZmFsc2U7XG5mdW5jdGlvbiBzY2hlZHVsZVN5bmNDYWxsYmFjayhjYWxsYmFjaykge1xuICAvLyBQdXNoIHRoaXMgY2FsbGJhY2sgaW50byBhbiBpbnRlcm5hbCBxdWV1ZS4gV2UnbGwgZmx1c2ggdGhlc2UgZWl0aGVyIGluXG4gIC8vIHRoZSBuZXh0IHRpY2ssIG9yIGVhcmxpZXIgaWYgc29tZXRoaW5nIGNhbGxzIGBmbHVzaFN5bmNDYWxsYmFja1F1ZXVlYC5cbiAgaWYgKHN5bmNRdWV1ZSA9PT0gbnVsbCkge1xuICAgIHN5bmNRdWV1ZSA9IFtjYWxsYmFja107XG4gIH0gZWxzZSB7XG4gICAgLy8gUHVzaCBvbnRvIGV4aXN0aW5nIHF1ZXVlLiBEb24ndCBuZWVkIHRvIHNjaGVkdWxlIGEgY2FsbGJhY2sgYmVjYXVzZVxuICAgIC8vIHdlIGFscmVhZHkgc2NoZWR1bGVkIG9uZSB3aGVuIHdlIGNyZWF0ZWQgdGhlIHF1ZXVlLlxuICAgIHN5bmNRdWV1ZS5wdXNoKGNhbGxiYWNrKTtcbiAgfVxufVxuZnVuY3Rpb24gc2NoZWR1bGVMZWdhY3lTeW5jQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgaW5jbHVkZXNMZWdhY3lTeW5jQ2FsbGJhY2tzID0gdHJ1ZTtcbiAgc2NoZWR1bGVTeW5jQ2FsbGJhY2soY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gZmx1c2hTeW5jQ2FsbGJhY2tzT25seUluTGVnYWN5TW9kZSgpIHtcbiAgLy8gT25seSBmbHVzaGVzIHRoZSBxdWV1ZSBpZiB0aGVyZSdzIGEgbGVnYWN5IHN5bmMgY2FsbGJhY2sgc2NoZWR1bGVkLlxuICAvLyBUT0RPOiBUaGVyZSdzIG9ubHkgYSBzaW5nbGUgdHlwZSBvZiBjYWxsYmFjazogcGVyZm9ybVN5bmNPbldvcmtPblJvb3QuIFNvXG4gIC8vIGl0IG1pZ2h0IG1ha2UgbW9yZSBzZW5zZSBmb3IgdGhlIHF1ZXVlIHRvIGJlIGEgbGlzdCBvZiByb290cyBpbnN0ZWFkIG9mIGFcbiAgLy8gbGlzdCBvZiBnZW5lcmljIGNhbGxiYWNrcy4gVGhlbiB3ZSBjYW4gaGF2ZSB0d286IG9uZSBmb3IgbGVnYWN5IHJvb3RzLCBvbmVcbiAgLy8gZm9yIGNvbmN1cnJlbnQgcm9vdHMuIEFuZCB0aGlzIG1ldGhvZCB3b3VsZCBvbmx5IGZsdXNoIHRoZSBsZWdhY3kgb25lcy5cbiAgaWYgKGluY2x1ZGVzTGVnYWN5U3luY0NhbGxiYWNrcykge1xuICAgIGZsdXNoU3luY0NhbGxiYWNrcygpO1xuICB9XG59XG5mdW5jdGlvbiBmbHVzaFN5bmNDYWxsYmFja3MoKSB7XG4gIGlmICghaXNGbHVzaGluZ1N5bmNRdWV1ZSAmJiBzeW5jUXVldWUgIT09IG51bGwpIHtcbiAgICAvLyBQcmV2ZW50IHJlLWVudHJhbmNlLlxuICAgIGlzRmx1c2hpbmdTeW5jUXVldWUgPSB0cnVlO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcHJldmlvdXNVcGRhdGVQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBpc1N5bmMgPSB0cnVlO1xuICAgICAgdmFyIHF1ZXVlID0gc3luY1F1ZXVlOyAvLyBUT0RPOiBJcyB0aGlzIG5lY2Vzc2FyeSBhbnltb3JlPyBUaGUgb25seSB1c2VyIGNvZGUgdGhhdCBydW5zIGluIHRoaXNcbiAgICAgIC8vIHF1ZXVlIGlzIGluIHRoZSByZW5kZXIgb3IgY29tbWl0IHBoYXNlcy5cblxuICAgICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG5cbiAgICAgIGZvciAoOyBpIDwgcXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gcXVldWVbaV07XG5cbiAgICAgICAgZG8ge1xuICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2soaXNTeW5jKTtcbiAgICAgICAgfSB3aGlsZSAoY2FsbGJhY2sgIT09IG51bGwpO1xuICAgICAgfVxuXG4gICAgICBzeW5jUXVldWUgPSBudWxsO1xuICAgICAgaW5jbHVkZXNMZWdhY3lTeW5jQ2FsbGJhY2tzID0gZmFsc2U7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIElmIHNvbWV0aGluZyB0aHJvd3MsIGxlYXZlIHRoZSByZW1haW5pbmcgY2FsbGJhY2tzIG9uIHRoZSBxdWV1ZS5cbiAgICAgIGlmIChzeW5jUXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgc3luY1F1ZXVlID0gc3luY1F1ZXVlLnNsaWNlKGkgKyAxKTtcbiAgICAgIH0gLy8gUmVzdW1lIGZsdXNoaW5nIGluIHRoZSBuZXh0IHRpY2tcblxuXG4gICAgICBzY2hlZHVsZUNhbGxiYWNrKEltbWVkaWF0ZVByaW9yaXR5LCBmbHVzaFN5bmNDYWxsYmFja3MpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1VwZGF0ZVByaW9yaXR5KTtcbiAgICAgIGlzRmx1c2hpbmdTeW5jUXVldWUgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLy8gVE9ETzogVXNlIHRoZSB1bmlmaWVkIGZpYmVyIHN0YWNrIG1vZHVsZSBpbnN0ZWFkIG9mIHRoaXMgbG9jYWwgb25lP1xuLy8gSW50ZW50aW9uYWxseSBub3QgdXNpbmcgaXQgeWV0IHRvIGRlcmlzayB0aGUgaW5pdGlhbCBpbXBsZW1lbnRhdGlvbiwgYmVjYXVzZVxuLy8gdGhlIHdheSB3ZSBwdXNoL3BvcCB0aGVzZSB2YWx1ZXMgaXMgYSBiaXQgdW51c3VhbC4gSWYgdGhlcmUncyBhIG1pc3Rha2UsIEknZFxuLy8gcmF0aGVyIHRoZSBpZHMgYmUgd3JvbmcgdGhhbiBjcmFzaCB0aGUgd2hvbGUgcmVjb25jaWxlci5cbnZhciBmb3JrU3RhY2sgPSBbXTtcbnZhciBmb3JrU3RhY2tJbmRleCA9IDA7XG52YXIgdHJlZUZvcmtQcm92aWRlciA9IG51bGw7XG52YXIgdHJlZUZvcmtDb3VudCA9IDA7XG52YXIgaWRTdGFjayA9IFtdO1xudmFyIGlkU3RhY2tJbmRleCA9IDA7XG52YXIgdHJlZUNvbnRleHRQcm92aWRlciA9IG51bGw7XG52YXIgdHJlZUNvbnRleHRJZCA9IDE7XG52YXIgdHJlZUNvbnRleHRPdmVyZmxvdyA9ICcnO1xuZnVuY3Rpb24gaXNGb3JrZWRDaGlsZCh3b3JrSW5Qcm9ncmVzcykge1xuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgcmV0dXJuICh3b3JrSW5Qcm9ncmVzcy5mbGFncyAmIEZvcmtlZCkgIT09IE5vRmxhZ3M7XG59XG5mdW5jdGlvbiBnZXRGb3Jrc0F0TGV2ZWwod29ya0luUHJvZ3Jlc3MpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7XG4gIHJldHVybiB0cmVlRm9ya0NvdW50O1xufVxuZnVuY3Rpb24gZ2V0VHJlZUlkKCkge1xuICB2YXIgb3ZlcmZsb3cgPSB0cmVlQ29udGV4dE92ZXJmbG93O1xuICB2YXIgaWRXaXRoTGVhZGluZ0JpdCA9IHRyZWVDb250ZXh0SWQ7XG4gIHZhciBpZCA9IGlkV2l0aExlYWRpbmdCaXQgJiB+Z2V0TGVhZGluZ0JpdChpZFdpdGhMZWFkaW5nQml0KTtcbiAgcmV0dXJuIGlkLnRvU3RyaW5nKDMyKSArIG92ZXJmbG93O1xufVxuZnVuY3Rpb24gcHVzaFRyZWVGb3JrKHdvcmtJblByb2dyZXNzLCB0b3RhbENoaWxkcmVuKSB7XG4gIC8vIFRoaXMgaXMgY2FsbGVkIHJpZ2h0IGFmdGVyIHdlIHJlY29uY2lsZSBhbiBhcnJheSAob3IgaXRlcmF0b3IpIG9mIGNoaWxkXG4gIC8vIGZpYmVycywgYmVjYXVzZSB0aGF0J3MgdGhlIG9ubHkgcGxhY2Ugd2hlcmUgd2Uga25vdyBob3cgbWFueSBjaGlsZHJlbiBpblxuICAvLyB0aGUgd2hvbGUgc2V0IHdpdGhvdXQgZG9pbmcgZXh0cmEgd29yayBsYXRlciwgb3Igc3RvcmluZyBhZGR0aW9uYWxcbiAgLy8gaW5mb3JtYXRpb24gb24gdGhlIGZpYmVyLlxuICAvL1xuICAvLyBUaGF0J3Mgd2h5IHRoaXMgZnVuY3Rpb24gaXMgc2VwYXJhdGUgZnJvbSBwdXNoVHJlZUlkIOKAlCBpdCdzIGNhbGxlZCBkdXJpbmdcbiAgLy8gdGhlIHJlbmRlciBwaGFzZSBvZiB0aGUgZm9yayBwYXJlbnQsIG5vdCB0aGUgY2hpbGQsIHdoaWNoIGlzIHdoZXJlIHdlIHB1c2hcbiAgLy8gdGhlIG90aGVyIGNvbnRleHQgdmFsdWVzLlxuICAvL1xuICAvLyBJbiB0aGUgRml6eiBpbXBsZW1lbnRhdGlvbiB0aGlzIGlzIG11Y2ggc2ltcGxlciBiZWNhdXNlIHRoZSBjaGlsZCBpc1xuICAvLyByZW5kZXJlZCBpbiB0aGUgc2FtZSBjYWxsc3RhY2sgYXMgdGhlIHBhcmVudC5cbiAgLy9cbiAgLy8gSXQgbWlnaHQgYmUgYmV0dGVyIHRvIGp1c3QgYWRkIGEgYGZvcmtzYCBmaWVsZCB0byB0aGUgRmliZXIgdHlwZS4gSXQgd291bGRcbiAgLy8gbWFrZSB0aGlzIG1vZHVsZSBzaW1wbGVyLlxuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4KytdID0gdHJlZUZvcmtDb3VudDtcbiAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4KytdID0gdHJlZUZvcmtQcm92aWRlcjtcbiAgdHJlZUZvcmtQcm92aWRlciA9IHdvcmtJblByb2dyZXNzO1xuICB0cmVlRm9ya0NvdW50ID0gdG90YWxDaGlsZHJlbjtcbn1cbmZ1bmN0aW9uIHB1c2hUcmVlSWQod29ya0luUHJvZ3Jlc3MsIHRvdGFsQ2hpbGRyZW4sIGluZGV4KSB7XG4gIHdhcm5JZk5vdEh5ZHJhdGluZygpO1xuICBpZFN0YWNrW2lkU3RhY2tJbmRleCsrXSA9IHRyZWVDb250ZXh0SWQ7XG4gIGlkU3RhY2tbaWRTdGFja0luZGV4KytdID0gdHJlZUNvbnRleHRPdmVyZmxvdztcbiAgaWRTdGFja1tpZFN0YWNrSW5kZXgrK10gPSB0cmVlQ29udGV4dFByb3ZpZGVyO1xuICB0cmVlQ29udGV4dFByb3ZpZGVyID0gd29ya0luUHJvZ3Jlc3M7XG4gIHZhciBiYXNlSWRXaXRoTGVhZGluZ0JpdCA9IHRyZWVDb250ZXh0SWQ7XG4gIHZhciBiYXNlT3ZlcmZsb3cgPSB0cmVlQ29udGV4dE92ZXJmbG93OyAvLyBUaGUgbGVmdG1vc3QgMSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZSwgbm9uLWluY2x1c2l2ZS4gSXQncyBub3QgcGFydFxuICAvLyBvZiB0aGUgaWQ7IHdlIHVzZSBpdCB0byBhY2NvdW50IGZvciBsZWFkaW5nIDBzLlxuXG4gIHZhciBiYXNlTGVuZ3RoID0gZ2V0Qml0TGVuZ3RoKGJhc2VJZFdpdGhMZWFkaW5nQml0KSAtIDE7XG4gIHZhciBiYXNlSWQgPSBiYXNlSWRXaXRoTGVhZGluZ0JpdCAmIH4oMSA8PCBiYXNlTGVuZ3RoKTtcbiAgdmFyIHNsb3QgPSBpbmRleCArIDE7XG4gIHZhciBsZW5ndGggPSBnZXRCaXRMZW5ndGgodG90YWxDaGlsZHJlbikgKyBiYXNlTGVuZ3RoOyAvLyAzMCBpcyB0aGUgbWF4IGxlbmd0aCB3ZSBjYW4gc3RvcmUgd2l0aG91dCBvdmVyZmxvd2luZywgdGFraW5nIGludG9cbiAgLy8gY29uc2lkZXJhdGlvbiB0aGUgbGVhZGluZyAxIHdlIHVzZSB0byBtYXJrIHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLlxuXG4gIGlmIChsZW5ndGggPiAzMCkge1xuICAgIC8vIFdlIG92ZXJmbG93ZWQgdGhlIGJpdHdpc2Utc2FmZSByYW5nZS4gRmFsbCBiYWNrIHRvIHNsb3dlciBhbGdvcml0aG0uXG4gICAgLy8gVGhpcyBicmFuY2ggYXNzdW1lcyB0aGUgbGVuZ3RoIG9mIHRoZSBiYXNlIGlkIGlzIGdyZWF0ZXIgdGhhbiA1OyBpdCB3b24ndFxuICAgIC8vIHdvcmsgZm9yIHNtYWxsZXIgaWRzLCBiZWNhdXNlIHlvdSBuZWVkIDUgYml0cyBwZXIgY2hhcmFjdGVyLlxuICAgIC8vXG4gICAgLy8gV2UgZW5jb2RlIHRoZSBpZCBpbiBtdWx0aXBsZSBzdGVwczogZmlyc3QgdGhlIGJhc2UgaWQsIHRoZW4gdGhlXG4gICAgLy8gcmVtYWluaW5nIGRpZ2l0cy5cbiAgICAvL1xuICAgIC8vIEVhY2ggNSBiaXQgc2VxdWVuY2UgY29ycmVzcG9uZHMgdG8gYSBzaW5nbGUgYmFzZSAzMiBjaGFyYWN0ZXIuIFNvIGZvclxuICAgIC8vIGV4YW1wbGUsIGlmIHRoZSBjdXJyZW50IGlkIGlzIDIzIGJpdHMgbG9uZywgd2UgY2FuIGNvbnZlcnQgMjAgb2YgdGhvc2VcbiAgICAvLyBiaXRzIGludG8gYSBzdHJpbmcgb2YgNCBjaGFyYWN0ZXJzLCB3aXRoIDMgYml0cyBsZWZ0IG92ZXIuXG4gICAgLy9cbiAgICAvLyBGaXJzdCBjYWxjdWxhdGUgaG93IG1hbnkgYml0cyBpbiB0aGUgYmFzZSBpZCByZXByZXNlbnQgYSBjb21wbGV0ZVxuICAgIC8vIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMuXG4gICAgdmFyIG51bWJlck9mT3ZlcmZsb3dCaXRzID0gYmFzZUxlbmd0aCAtIGJhc2VMZW5ndGggJSA1OyAvLyBUaGVuIGNyZWF0ZSBhIGJpdG1hc2sgdGhhdCBzZWxlY3RzIG9ubHkgdGhvc2UgYml0cy5cblxuICAgIHZhciBuZXdPdmVyZmxvd0JpdHMgPSAoMSA8PCBudW1iZXJPZk92ZXJmbG93Qml0cykgLSAxOyAvLyBTZWxlY3QgdGhlIGJpdHMsIGFuZCBjb252ZXJ0IHRoZW0gdG8gYSBiYXNlIDMyIHN0cmluZy5cblxuICAgIHZhciBuZXdPdmVyZmxvdyA9IChiYXNlSWQgJiBuZXdPdmVyZmxvd0JpdHMpLnRvU3RyaW5nKDMyKTsgLy8gTm93IHdlIGNhbiByZW1vdmUgdGhvc2UgYml0cyBmcm9tIHRoZSBiYXNlIGlkLlxuXG4gICAgdmFyIHJlc3RPZkJhc2VJZCA9IGJhc2VJZCA+PiBudW1iZXJPZk92ZXJmbG93Qml0cztcbiAgICB2YXIgcmVzdE9mQmFzZUxlbmd0aCA9IGJhc2VMZW5ndGggLSBudW1iZXJPZk92ZXJmbG93Qml0czsgLy8gRmluYWxseSwgZW5jb2RlIHRoZSByZXN0IG9mIHRoZSBiaXRzIHVzaW5nIHRoZSBub3JtYWwgYWxnb3JpdGhtLiBCZWNhdXNlXG4gICAgLy8gd2UgbWFkZSBtb3JlIHJvb20sIHRoaXMgdGltZSBpdCB3b24ndCBvdmVyZmxvdy5cblxuICAgIHZhciByZXN0T2ZMZW5ndGggPSBnZXRCaXRMZW5ndGgodG90YWxDaGlsZHJlbikgKyByZXN0T2ZCYXNlTGVuZ3RoO1xuICAgIHZhciByZXN0T2ZOZXdCaXRzID0gc2xvdCA8PCByZXN0T2ZCYXNlTGVuZ3RoO1xuICAgIHZhciBpZCA9IHJlc3RPZk5ld0JpdHMgfCByZXN0T2ZCYXNlSWQ7XG4gICAgdmFyIG92ZXJmbG93ID0gbmV3T3ZlcmZsb3cgKyBiYXNlT3ZlcmZsb3c7XG4gICAgdHJlZUNvbnRleHRJZCA9IDEgPDwgcmVzdE9mTGVuZ3RoIHwgaWQ7XG4gICAgdHJlZUNvbnRleHRPdmVyZmxvdyA9IG92ZXJmbG93O1xuICB9IGVsc2Uge1xuICAgIC8vIE5vcm1hbCBwYXRoXG4gICAgdmFyIG5ld0JpdHMgPSBzbG90IDw8IGJhc2VMZW5ndGg7XG5cbiAgICB2YXIgX2lkID0gbmV3Qml0cyB8IGJhc2VJZDtcblxuICAgIHZhciBfb3ZlcmZsb3cgPSBiYXNlT3ZlcmZsb3c7XG4gICAgdHJlZUNvbnRleHRJZCA9IDEgPDwgbGVuZ3RoIHwgX2lkO1xuICAgIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBfb3ZlcmZsb3c7XG4gIH1cbn1cbmZ1bmN0aW9uIHB1c2hNYXRlcmlhbGl6ZWRUcmVlSWQod29ya0luUHJvZ3Jlc3MpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7IC8vIFRoaXMgY29tcG9uZW50IG1hdGVyaWFsaXplZCBhbiBpZC4gVGhpcyB3aWxsIGFmZmVjdCBhbnkgaWRzIHRoYXQgYXBwZWFyXG4gIC8vIGluIGl0cyBjaGlsZHJlbi5cblxuICB2YXIgcmV0dXJuRmliZXIgPSB3b3JrSW5Qcm9ncmVzcy5yZXR1cm47XG5cbiAgaWYgKHJldHVybkZpYmVyICE9PSBudWxsKSB7XG4gICAgdmFyIG51bWJlck9mRm9ya3MgPSAxO1xuICAgIHZhciBzbG90SW5kZXggPSAwO1xuICAgIHB1c2hUcmVlRm9yayh3b3JrSW5Qcm9ncmVzcywgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgcHVzaFRyZWVJZCh3b3JrSW5Qcm9ncmVzcywgbnVtYmVyT2ZGb3Jrcywgc2xvdEluZGV4KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRCaXRMZW5ndGgobnVtYmVyKSB7XG4gIHJldHVybiAzMiAtIGNsejMyKG51bWJlcik7XG59XG5cbmZ1bmN0aW9uIGdldExlYWRpbmdCaXQoaWQpIHtcbiAgcmV0dXJuIDEgPDwgZ2V0Qml0TGVuZ3RoKGlkKSAtIDE7XG59XG5cbmZ1bmN0aW9uIHBvcFRyZWVDb250ZXh0KHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIFJlc3RvcmUgdGhlIHByZXZpb3VzIHZhbHVlcy5cbiAgLy8gVGhpcyBpcyBhIGJpdCBtb3JlIGNvbXBsaWNhdGVkIHRoYW4gb3RoZXIgY29udGV4dC1saWtlIG1vZHVsZXMgaW4gRmliZXJcbiAgLy8gYmVjYXVzZSB0aGUgc2FtZSBGaWJlciBtYXkgYXBwZWFyIG9uIHRoZSBzdGFjayBtdWx0aXBsZSB0aW1lcyBhbmQgZm9yXG4gIC8vIGRpZmZlcmVudCByZWFzb25zLiBXZSBoYXZlIHRvIGtlZXAgcG9wcGluZyB1bnRpbCB0aGUgd29yay1pbi1wcm9ncmVzcyBpc1xuICAvLyBubyBsb25nZXIgYXQgdGhlIHRvcCBvZiB0aGUgc3RhY2suXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyA9PT0gdHJlZUZvcmtQcm92aWRlcikge1xuICAgIHRyZWVGb3JrUHJvdmlkZXIgPSBmb3JrU3RhY2tbLS1mb3JrU3RhY2tJbmRleF07XG4gICAgZm9ya1N0YWNrW2ZvcmtTdGFja0luZGV4XSA9IG51bGw7XG4gICAgdHJlZUZvcmtDb3VudCA9IGZvcmtTdGFja1stLWZvcmtTdGFja0luZGV4XTtcbiAgICBmb3JrU3RhY2tbZm9ya1N0YWNrSW5kZXhdID0gbnVsbDtcbiAgfVxuXG4gIHdoaWxlICh3b3JrSW5Qcm9ncmVzcyA9PT0gdHJlZUNvbnRleHRQcm92aWRlcikge1xuICAgIHRyZWVDb250ZXh0UHJvdmlkZXIgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICAgIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICAgIHRyZWVDb250ZXh0SWQgPSBpZFN0YWNrWy0taWRTdGFja0luZGV4XTtcbiAgICBpZFN0YWNrW2lkU3RhY2tJbmRleF0gPSBudWxsO1xuICB9XG59XG5mdW5jdGlvbiBnZXRTdXNwZW5kZWRUcmVlQ29udGV4dCgpIHtcbiAgd2FybklmTm90SHlkcmF0aW5nKCk7XG5cbiAgaWYgKHRyZWVDb250ZXh0UHJvdmlkZXIgIT09IG51bGwpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRyZWVDb250ZXh0SWQsXG4gICAgICBvdmVyZmxvdzogdHJlZUNvbnRleHRPdmVyZmxvd1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc3RvcmVTdXNwZW5kZWRUcmVlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuZGVkQ29udGV4dCkge1xuICB3YXJuSWZOb3RIeWRyYXRpbmcoKTtcbiAgaWRTdGFja1tpZFN0YWNrSW5kZXgrK10gPSB0cmVlQ29udGV4dElkO1xuICBpZFN0YWNrW2lkU3RhY2tJbmRleCsrXSA9IHRyZWVDb250ZXh0T3ZlcmZsb3c7XG4gIGlkU3RhY2tbaWRTdGFja0luZGV4KytdID0gdHJlZUNvbnRleHRQcm92aWRlcjtcbiAgdHJlZUNvbnRleHRJZCA9IHN1c3BlbmRlZENvbnRleHQuaWQ7XG4gIHRyZWVDb250ZXh0T3ZlcmZsb3cgPSBzdXNwZW5kZWRDb250ZXh0Lm92ZXJmbG93O1xuICB0cmVlQ29udGV4dFByb3ZpZGVyID0gd29ya0luUHJvZ3Jlc3M7XG59XG5cbmZ1bmN0aW9uIHdhcm5JZk5vdEh5ZHJhdGluZygpIHtcbiAge1xuICAgIGlmICghZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHRvIGJlIGh5ZHJhdGluZy4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgJyArICdhbiBpc3N1ZS4nKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBtYXkgaGF2ZSBiZWVuIGFuIGluc2VydGlvbiBvciBhIGh5ZHJhdGlvbi5cblxudmFyIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gbnVsbDtcbnZhciBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbnZhciBpc0h5ZHJhdGluZyA9IGZhbHNlOyAvLyBUaGlzIGZsYWcgYWxsb3dzIGZvciB3YXJuaW5nIHN1cHJlc3Npb24gd2hlbiB3ZSBleHBlY3QgdGhlcmUgdG8gYmUgbWlzbWF0Y2hlc1xuLy8gZHVlIHRvIGVhcmxpZXIgbWlzbWF0Y2hlcyBvciBhIHN1c3BlbmRlZCBmaWJlci5cblxudmFyIGRpZFN1c3BlbmRPckVycm9yREVWID0gZmFsc2U7IC8vIEh5ZHJhdGlvbiBlcnJvcnMgdGhhdCB3ZXJlIHRocm93biBpbnNpZGUgdGhpcyBib3VuZGFyeVxuXG52YXIgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcblxuZnVuY3Rpb24gd2FybklmSHlkcmF0aW5nKCkge1xuICB7XG4gICAgaWYgKGlzSHlkcmF0aW5nKSB7XG4gICAgICBlcnJvcignV2Ugc2hvdWxkIG5vdCBiZSBoeWRyYXRpbmcgaGVyZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYSBidWcuJyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtEaWRUaHJvd1doaWxlSHlkcmF0aW5nREVWKCkge1xuICB7XG4gICAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSB0cnVlO1xuICB9XG59XG5mdW5jdGlvbiBkaWRTdXNwZW5kT3JFcnJvcldoaWxlSHlkcmF0aW5nREVWKCkge1xuICB7XG4gICAgcmV0dXJuIGRpZFN1c3BlbmRPckVycm9yREVWO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVudGVySHlkcmF0aW9uU3RhdGUoZmliZXIpIHtcblxuICB2YXIgcGFyZW50SW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcbiAgbmV4dEh5ZHJhdGFibGVJbnN0YW5jZSA9IGdldEZpcnN0SHlkcmF0YWJsZUNoaWxkV2l0aGluQ29udGFpbmVyKHBhcmVudEluc3RhbmNlKTtcbiAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjtcbiAgaXNIeWRyYXRpbmcgPSB0cnVlO1xuICBoeWRyYXRpb25FcnJvcnMgPSBudWxsO1xuICBkaWRTdXNwZW5kT3JFcnJvckRFViA9IGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVlbnRlckh5ZHJhdGlvblN0YXRlRnJvbURlaHlkcmF0ZWRTdXNwZW5zZUluc3RhbmNlKGZpYmVyLCBzdXNwZW5zZUluc3RhbmNlLCB0cmVlQ29udGV4dCkge1xuXG4gIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZFdpdGhpblN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSk7XG4gIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7XG4gIGlzSHlkcmF0aW5nID0gdHJ1ZTtcbiAgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcbiAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSBmYWxzZTtcblxuICBpZiAodHJlZUNvbnRleHQgIT09IG51bGwpIHtcbiAgICByZXN0b3JlU3VzcGVuZGVkVHJlZUNvbnRleHQoZmliZXIsIHRyZWVDb250ZXh0KTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiB3YXJuVW5oeWRyYXRlZEluc3RhbmNlKHJldHVybkZpYmVyLCBpbnN0YW5jZSkge1xuICB7XG4gICAgc3dpdGNoIChyZXR1cm5GaWJlci50YWcpIHtcbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5Db250YWluZXIocmV0dXJuRmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8sIGluc3RhbmNlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgZGlkTm90SHlkcmF0ZUluc3RhbmNlKHJldHVybkZpYmVyLnR5cGUsIHJldHVybkZpYmVyLm1lbW9pemVkUHJvcHMsIHJldHVybkZpYmVyLnN0YXRlTm9kZSwgaW5zdGFuY2UsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgaXNDb25jdXJyZW50TW9kZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0gcmV0dXJuRmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICBpZiAoc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSBkaWROb3RIeWRyYXRlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZCwgaW5zdGFuY2UpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRlbGV0ZUh5ZHJhdGFibGVJbnN0YW5jZShyZXR1cm5GaWJlciwgaW5zdGFuY2UpIHtcbiAgd2FyblVuaHlkcmF0ZWRJbnN0YW5jZShyZXR1cm5GaWJlciwgaW5zdGFuY2UpO1xuICB2YXIgY2hpbGRUb0RlbGV0ZSA9IGNyZWF0ZUZpYmVyRnJvbUhvc3RJbnN0YW5jZUZvckRlbGV0aW9uKCk7XG4gIGNoaWxkVG9EZWxldGUuc3RhdGVOb2RlID0gaW5zdGFuY2U7XG4gIGNoaWxkVG9EZWxldGUucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gIHZhciBkZWxldGlvbnMgPSByZXR1cm5GaWJlci5kZWxldGlvbnM7XG5cbiAgaWYgKGRlbGV0aW9ucyA9PT0gbnVsbCkge1xuICAgIHJldHVybkZpYmVyLmRlbGV0aW9ucyA9IFtjaGlsZFRvRGVsZXRlXTtcbiAgICByZXR1cm5GaWJlci5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICB9IGVsc2Uge1xuICAgIGRlbGV0aW9ucy5wdXNoKGNoaWxkVG9EZWxldGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdhcm5Ob25oeWRyYXRlZEluc3RhbmNlKHJldHVybkZpYmVyLCBmaWJlcikge1xuICB7XG4gICAgaWYgKGRpZFN1c3BlbmRPckVycm9yREVWKSB7XG4gICAgICAvLyBJbnNpZGUgYSBib3VuZGFyeSB0aGF0IGFscmVhZHkgc3VzcGVuZGVkLiBXZSdyZSBjdXJyZW50bHkgcmVuZGVyaW5nIHRoZVxuICAgICAgLy8gc2libGluZ3Mgb2YgYSBzdXNwZW5kZWQgbm9kZS4gVGhlIG1pc21hdGNoIG1heSBiZSBkdWUgdG8gdGhlIG1pc3NpbmdcbiAgICAgIC8vIGRhdGEsIHNvIGl0J3MgcHJvYmFibHkgYSBmYWxzZSBwb3NpdGl2ZS5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHJldHVybkZpYmVyLnRhZykge1xuICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBwYXJlbnRDb250YWluZXIgPSByZXR1cm5GaWJlci5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztcblxuICAgICAgICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICAgICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgICAgICAgIHZhciB0eXBlID0gZmliZXIudHlwZTtcbiAgICAgICAgICAgICAgdmFyIHByb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgICAgICAgICAgICBkaWROb3RGaW5kSHlkcmF0YWJsZUluc3RhbmNlV2l0aGluQ29udGFpbmVyKHBhcmVudENvbnRhaW5lciwgdHlwZSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgICAgICAgICB2YXIgdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgICAgICAgZGlkTm90RmluZEh5ZHJhdGFibGVUZXh0SW5zdGFuY2VXaXRoaW5Db250YWluZXIocGFyZW50Q29udGFpbmVyLCB0ZXh0KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHBhcmVudFR5cGUgPSByZXR1cm5GaWJlci50eXBlO1xuICAgICAgICAgIHZhciBwYXJlbnRQcm9wcyA9IHJldHVybkZpYmVyLm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhciBfdHlwZSA9IGZpYmVyLnR5cGU7XG4gICAgICAgICAgICAgICAgdmFyIF9wcm9wcyA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgICAgICAgZGlkTm90RmluZEh5ZHJhdGFibGVJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIF90eXBlLCBfcHJvcHMsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgICAgICAgaXNDb25jdXJyZW50TW9kZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhciBfdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcblxuICAgICAgICAgICAgICAgIHZhciBfaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG5cbiAgICAgICAgICAgICAgICBkaWROb3RGaW5kSHlkcmF0YWJsZVRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIF90ZXh0LCAvLyBUT0RPOiBEZWxldGUgdGhpcyBhcmd1bWVudCB3aGVuIHdlIHJlbW92ZSB0aGUgbGVnYWN5IHJvb3QgQVBJLlxuICAgICAgICAgICAgICAgIF9pc0NvbmN1cnJlbnRNb2RlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgc3VzcGVuc2VTdGF0ZSA9IHJldHVybkZpYmVyLm1lbW9pemVkU3RhdGU7XG4gICAgICAgICAgdmFyIF9wYXJlbnRJbnN0YW5jZSA9IHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZDtcbiAgICAgICAgICBpZiAoX3BhcmVudEluc3RhbmNlICE9PSBudWxsKSBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgICAgICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgICAgICAgICB2YXIgX3R5cGUyID0gZmliZXIudHlwZTtcbiAgICAgICAgICAgICAgdmFyIF9wcm9wczIgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgICAgICAgICAgIGRpZE5vdEZpbmRIeWRyYXRhYmxlSW5zdGFuY2VXaXRoaW5TdXNwZW5zZUluc3RhbmNlKF9wYXJlbnRJbnN0YW5jZSwgX3R5cGUyKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICAgICAgICAgIHZhciBfdGV4dDIgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgICAgICAgICAgIGRpZE5vdEZpbmRIeWRyYXRhYmxlVGV4dEluc3RhbmNlV2l0aGluU3VzcGVuc2VJbnN0YW5jZShfcGFyZW50SW5zdGFuY2UsIF90ZXh0Mik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluc2VydE5vbkh5ZHJhdGVkSW5zdGFuY2UocmV0dXJuRmliZXIsIGZpYmVyKSB7XG4gIGZpYmVyLmZsYWdzID0gZmliZXIuZmxhZ3MgJiB+SHlkcmF0aW5nIHwgUGxhY2VtZW50O1xuICB3YXJuTm9uaHlkcmF0ZWRJbnN0YW5jZShyZXR1cm5GaWJlciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiB0cnlIeWRyYXRlKGZpYmVyLCBuZXh0SW5zdGFuY2UpIHtcbiAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciB0eXBlID0gZmliZXIudHlwZTtcbiAgICAgICAgdmFyIHByb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgICAgICB2YXIgaW5zdGFuY2UgPSBjYW5IeWRyYXRlSW5zdGFuY2UobmV4dEluc3RhbmNlLCB0eXBlKTtcblxuICAgICAgICBpZiAoaW5zdGFuY2UgIT09IG51bGwpIHtcbiAgICAgICAgICBmaWJlci5zdGF0ZU5vZGUgPSBpbnN0YW5jZTtcbiAgICAgICAgICBoeWRyYXRpb25QYXJlbnRGaWJlciA9IGZpYmVyO1xuICAgICAgICAgIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBnZXRGaXJzdEh5ZHJhdGFibGVDaGlsZChpbnN0YW5jZSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAge1xuICAgICAgICB2YXIgdGV4dCA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICAgICAgdmFyIHRleHRJbnN0YW5jZSA9IGNhbkh5ZHJhdGVUZXh0SW5zdGFuY2UobmV4dEluc3RhbmNlLCB0ZXh0KTtcblxuICAgICAgICBpZiAodGV4dEluc3RhbmNlICE9PSBudWxsKSB7XG4gICAgICAgICAgZmliZXIuc3RhdGVOb2RlID0gdGV4dEluc3RhbmNlO1xuICAgICAgICAgIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7IC8vIFRleHQgSW5zdGFuY2VzIGRvbid0IGhhdmUgY2hpbGRyZW4gc28gdGhlcmUncyBub3RoaW5nIHRvIGh5ZHJhdGUuXG5cbiAgICAgICAgICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBzdXNwZW5zZUluc3RhbmNlID0gY2FuSHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2UobmV4dEluc3RhbmNlKTtcblxuICAgICAgICBpZiAoc3VzcGVuc2VJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0ge1xuICAgICAgICAgICAgZGVoeWRyYXRlZDogc3VzcGVuc2VJbnN0YW5jZSxcbiAgICAgICAgICAgIHRyZWVDb250ZXh0OiBnZXRTdXNwZW5kZWRUcmVlQ29udGV4dCgpLFxuICAgICAgICAgICAgcmV0cnlMYW5lOiBPZmZzY3JlZW5MYW5lXG4gICAgICAgICAgfTtcbiAgICAgICAgICBmaWJlci5tZW1vaXplZFN0YXRlID0gc3VzcGVuc2VTdGF0ZTsgLy8gU3RvcmUgdGhlIGRlaHlkcmF0ZWQgZnJhZ21lbnQgYXMgYSBjaGlsZCBmaWJlci5cbiAgICAgICAgICAvLyBUaGlzIHNpbXBsaWZpZXMgdGhlIGNvZGUgZm9yIGdldEhvc3RTaWJsaW5nIGFuZCBkZWxldGluZyBub2RlcyxcbiAgICAgICAgICAvLyBzaW5jZSBpdCBkb2Vzbid0IGhhdmUgdG8gY29uc2lkZXIgYWxsIFN1c3BlbnNlIGJvdW5kYXJpZXMgYW5kXG4gICAgICAgICAgLy8gY2hlY2sgaWYgdGhleSdyZSBkZWh5ZHJhdGVkIG9uZXMgb3Igbm90LlxuXG4gICAgICAgICAgdmFyIGRlaHlkcmF0ZWRGcmFnbWVudCA9IGNyZWF0ZUZpYmVyRnJvbURlaHlkcmF0ZWRGcmFnbWVudChzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgICBkZWh5ZHJhdGVkRnJhZ21lbnQucmV0dXJuID0gZmliZXI7XG4gICAgICAgICAgZmliZXIuY2hpbGQgPSBkZWh5ZHJhdGVkRnJhZ21lbnQ7XG4gICAgICAgICAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjsgLy8gV2hpbGUgYSBTdXNwZW5zZSBJbnN0YW5jZSBkb2VzIGhhdmUgY2hpbGRyZW4sIHdlIHdvbid0IHN0ZXAgaW50b1xuICAgICAgICAgIC8vIGl0IGR1cmluZyB0aGUgZmlyc3QgcGFzcy4gSW5zdGVhZCwgd2UnbGwgcmVlbnRlciBpdCBsYXRlci5cblxuICAgICAgICAgIG5leHRIeWRyYXRhYmxlSW5zdGFuY2UgPSBudWxsO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRDbGllbnRSZW5kZXJPbk1pc21hdGNoKGZpYmVyKSB7XG4gIHJldHVybiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlICYmIChmaWJlci5mbGFncyAmIERpZENhcHR1cmUpID09PSBOb0ZsYWdzO1xufVxuXG5mdW5jdGlvbiB0aHJvd09uSHlkcmF0aW9uTWlzbWF0Y2goZmliZXIpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdIeWRyYXRpb24gZmFpbGVkIGJlY2F1c2UgdGhlIGluaXRpYWwgVUkgZG9lcyBub3QgbWF0Y2ggd2hhdCB3YXMgJyArICdyZW5kZXJlZCBvbiB0aGUgc2VydmVyLicpO1xufVxuXG5mdW5jdGlvbiB0cnlUb0NsYWltTmV4dEh5ZHJhdGFibGVJbnN0YW5jZShmaWJlcikge1xuICBpZiAoIWlzSHlkcmF0aW5nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5leHRJbnN0YW5jZSA9IG5leHRIeWRyYXRhYmxlSW5zdGFuY2U7XG5cbiAgaWYgKCFuZXh0SW5zdGFuY2UpIHtcbiAgICBpZiAoc2hvdWxkQ2xpZW50UmVuZGVyT25NaXNtYXRjaChmaWJlcikpIHtcbiAgICAgIHdhcm5Ob25oeWRyYXRlZEluc3RhbmNlKGh5ZHJhdGlvblBhcmVudEZpYmVyLCBmaWJlcik7XG4gICAgICB0aHJvd09uSHlkcmF0aW9uTWlzbWF0Y2goKTtcbiAgICB9IC8vIE5vdGhpbmcgdG8gaHlkcmF0ZS4gTWFrZSBpdCBhbiBpbnNlcnRpb24uXG5cblxuICAgIGluc2VydE5vbkh5ZHJhdGVkSW5zdGFuY2UoaHlkcmF0aW9uUGFyZW50RmliZXIsIGZpYmVyKTtcbiAgICBpc0h5ZHJhdGluZyA9IGZhbHNlO1xuICAgIGh5ZHJhdGlvblBhcmVudEZpYmVyID0gZmliZXI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGZpcnN0QXR0ZW1wdGVkSW5zdGFuY2UgPSBuZXh0SW5zdGFuY2U7XG5cbiAgaWYgKCF0cnlIeWRyYXRlKGZpYmVyLCBuZXh0SW5zdGFuY2UpKSB7XG4gICAgaWYgKHNob3VsZENsaWVudFJlbmRlck9uTWlzbWF0Y2goZmliZXIpKSB7XG4gICAgICB3YXJuTm9uaHlkcmF0ZWRJbnN0YW5jZShoeWRyYXRpb25QYXJlbnRGaWJlciwgZmliZXIpO1xuICAgICAgdGhyb3dPbkh5ZHJhdGlvbk1pc21hdGNoKCk7XG4gICAgfSAvLyBJZiB3ZSBjYW4ndCBoeWRyYXRlIHRoaXMgaW5zdGFuY2UgbGV0J3MgdHJ5IHRoZSBuZXh0IG9uZS5cbiAgICAvLyBXZSB1c2UgdGhpcyBhcyBhIGhldXJpc3RpYy4gSXQncyBiYXNlZCBvbiBpbnR1aXRpb24gYW5kIG5vdCBkYXRhIHNvIGl0XG4gICAgLy8gbWlnaHQgYmUgZmxhd2VkIG9yIHVubmVjZXNzYXJ5LlxuXG5cbiAgICBuZXh0SW5zdGFuY2UgPSBnZXROZXh0SHlkcmF0YWJsZVNpYmxpbmcoZmlyc3RBdHRlbXB0ZWRJbnN0YW5jZSk7XG4gICAgdmFyIHByZXZIeWRyYXRpb25QYXJlbnRGaWJlciA9IGh5ZHJhdGlvblBhcmVudEZpYmVyO1xuXG4gICAgaWYgKCFuZXh0SW5zdGFuY2UgfHwgIXRyeUh5ZHJhdGUoZmliZXIsIG5leHRJbnN0YW5jZSkpIHtcbiAgICAgIC8vIE5vdGhpbmcgdG8gaHlkcmF0ZS4gTWFrZSBpdCBhbiBpbnNlcnRpb24uXG4gICAgICBpbnNlcnROb25IeWRyYXRlZEluc3RhbmNlKGh5ZHJhdGlvblBhcmVudEZpYmVyLCBmaWJlcik7XG4gICAgICBpc0h5ZHJhdGluZyA9IGZhbHNlO1xuICAgICAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBmaWJlcjtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIFdlIG1hdGNoZWQgdGhlIG5leHQgb25lLCB3ZSdsbCBub3cgYXNzdW1lIHRoYXQgdGhlIGZpcnN0IG9uZSB3YXNcbiAgICAvLyBzdXBlcmZsdW91cyBhbmQgd2UnbGwgZGVsZXRlIGl0LiBTaW5jZSB3ZSBjYW4ndCBlYWdlcmx5IGRlbGV0ZSBpdFxuICAgIC8vIHdlJ2xsIGhhdmUgdG8gc2NoZWR1bGUgYSBkZWxldGlvbi4gVG8gZG8gdGhhdCwgdGhpcyBub2RlIG5lZWRzIGEgZHVtbXlcbiAgICAvLyBmaWJlciBhc3NvY2lhdGVkIHdpdGggaXQuXG5cblxuICAgIGRlbGV0ZUh5ZHJhdGFibGVJbnN0YW5jZShwcmV2SHlkcmF0aW9uUGFyZW50RmliZXIsIGZpcnN0QXR0ZW1wdGVkSW5zdGFuY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0SW5zdGFuY2UoZmliZXIsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQpIHtcblxuICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG4gIHZhciBzaG91bGRXYXJuSWZNaXNtYXRjaERldiA9ICFkaWRTdXNwZW5kT3JFcnJvckRFVjtcbiAgdmFyIHVwZGF0ZVBheWxvYWQgPSBoeWRyYXRlSW5zdGFuY2UoaW5zdGFuY2UsIGZpYmVyLnR5cGUsIGZpYmVyLm1lbW9pemVkUHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgaG9zdENvbnRleHQsIGZpYmVyLCBzaG91bGRXYXJuSWZNaXNtYXRjaERldik7IC8vIFRPRE86IFR5cGUgdGhpcyBzcGVjaWZpYyB0byB0aGlzIHR5cGUgb2YgY29tcG9uZW50LlxuXG4gIGZpYmVyLnVwZGF0ZVF1ZXVlID0gdXBkYXRlUGF5bG9hZDsgLy8gSWYgdGhlIHVwZGF0ZSBwYXlsb2FkIGluZGljYXRlcyB0aGF0IHRoZXJlIGlzIGEgY2hhbmdlIG9yIGlmIHRoZXJlXG4gIC8vIGlzIGEgbmV3IHJlZiB3ZSBtYXJrIHRoaXMgYXMgYW4gdXBkYXRlLlxuXG4gIGlmICh1cGRhdGVQYXlsb2FkICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0VGV4dEluc3RhbmNlKGZpYmVyKSB7XG5cbiAgdmFyIHRleHRJbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcbiAgdmFyIHRleHRDb250ZW50ID0gZmliZXIubWVtb2l6ZWRQcm9wcztcbiAgdmFyIHNob3VsZFVwZGF0ZSA9IGh5ZHJhdGVUZXh0SW5zdGFuY2UodGV4dEluc3RhbmNlLCB0ZXh0Q29udGVudCwgZmliZXIpO1xuXG4gIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAvLyBXZSBhc3N1bWUgdGhhdCBwcmVwYXJlVG9IeWRyYXRlSG9zdFRleHRJbnN0YW5jZSBpcyBjYWxsZWQgaW4gYSBjb250ZXh0IHdoZXJlIHRoZVxuICAgIC8vIGh5ZHJhdGlvbiBwYXJlbnQgaXMgdGhlIHBhcmVudCBob3N0IGNvbXBvbmVudCBvZiB0aGlzIGhvc3QgdGV4dC5cbiAgICB2YXIgcmV0dXJuRmliZXIgPSBoeWRyYXRpb25QYXJlbnRGaWJlcjtcblxuICAgIGlmIChyZXR1cm5GaWJlciAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChyZXR1cm5GaWJlci50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGFyZW50Q29udGFpbmVyID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG4gICAgICAgICAgICB2YXIgaXNDb25jdXJyZW50TW9kZSA9IChyZXR1cm5GaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG4gICAgICAgICAgICBkaWROb3RNYXRjaEh5ZHJhdGVkQ29udGFpbmVyVGV4dEluc3RhbmNlKHBhcmVudENvbnRhaW5lciwgdGV4dEluc3RhbmNlLCB0ZXh0Q29udGVudCwgLy8gVE9ETzogRGVsZXRlIHRoaXMgYXJndW1lbnQgd2hlbiB3ZSByZW1vdmUgdGhlIGxlZ2FjeSByb290IEFQSS5cbiAgICAgICAgICAgIGlzQ29uY3VycmVudE1vZGUpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcGFyZW50VHlwZSA9IHJldHVybkZpYmVyLnR5cGU7XG4gICAgICAgICAgICB2YXIgcGFyZW50UHJvcHMgPSByZXR1cm5GaWJlci5tZW1vaXplZFByb3BzO1xuICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlID0gcmV0dXJuRmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICB2YXIgX2lzQ29uY3VycmVudE1vZGUyID0gKHJldHVybkZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZTtcblxuICAgICAgICAgICAgZGlkTm90TWF0Y2hIeWRyYXRlZFRleHRJbnN0YW5jZShwYXJlbnRUeXBlLCBwYXJlbnRQcm9wcywgcGFyZW50SW5zdGFuY2UsIHRleHRJbnN0YW5jZSwgdGV4dENvbnRlbnQsIC8vIFRPRE86IERlbGV0ZSB0aGlzIGFyZ3VtZW50IHdoZW4gd2UgcmVtb3ZlIHRoZSBsZWdhY3kgcm9vdCBBUEkuXG4gICAgICAgICAgICBfaXNDb25jdXJyZW50TW9kZTIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaG91bGRVcGRhdGU7XG59XG5cbmZ1bmN0aW9uIHByZXBhcmVUb0h5ZHJhdGVIb3N0U3VzcGVuc2VJbnN0YW5jZShmaWJlcikge1xuXG4gIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBzdXNwZW5zZVN0YXRlICE9PSBudWxsID8gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkIDogbnVsbDtcblxuICBpZiAoIXN1c3BlbnNlSW5zdGFuY2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGhhdmUgYSBoeWRyYXRlZCBzdXNwZW5zZSBpbnN0YW5jZS4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgaHlkcmF0ZVN1c3BlbnNlSW5zdGFuY2Uoc3VzcGVuc2VJbnN0YW5jZSwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBza2lwUGFzdERlaHlkcmF0ZWRTdXNwZW5zZUluc3RhbmNlKGZpYmVyKSB7XG5cbiAgdmFyIHN1c3BlbnNlU3RhdGUgPSBmaWJlci5tZW1vaXplZFN0YXRlO1xuICB2YXIgc3VzcGVuc2VJbnN0YW5jZSA9IHN1c3BlbnNlU3RhdGUgIT09IG51bGwgPyBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQgOiBudWxsO1xuXG4gIGlmICghc3VzcGVuc2VJbnN0YW5jZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gaGF2ZSBhIGh5ZHJhdGVkIHN1c3BlbnNlIGluc3RhbmNlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cblxuICByZXR1cm4gZ2V0TmV4dEh5ZHJhdGFibGVJbnN0YW5jZUFmdGVyU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTtcbn1cblxuZnVuY3Rpb24gcG9wVG9OZXh0SG9zdFBhcmVudChmaWJlcikge1xuICB2YXIgcGFyZW50ID0gZmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwgJiYgcGFyZW50LnRhZyAhPT0gSG9zdENvbXBvbmVudCAmJiBwYXJlbnQudGFnICE9PSBIb3N0Um9vdCAmJiBwYXJlbnQudGFnICE9PSBTdXNwZW5zZUNvbXBvbmVudCkge1xuICAgIHBhcmVudCA9IHBhcmVudC5yZXR1cm47XG4gIH1cblxuICBoeWRyYXRpb25QYXJlbnRGaWJlciA9IHBhcmVudDtcbn1cblxuZnVuY3Rpb24gcG9wSHlkcmF0aW9uU3RhdGUoZmliZXIpIHtcblxuICBpZiAoZmliZXIgIT09IGh5ZHJhdGlvblBhcmVudEZpYmVyKSB7XG4gICAgLy8gV2UncmUgZGVlcGVyIHRoYW4gdGhlIGN1cnJlbnQgaHlkcmF0aW9uIGNvbnRleHQsIGluc2lkZSBhbiBpbnNlcnRlZFxuICAgIC8vIHRyZWUuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKCFpc0h5ZHJhdGluZykge1xuICAgIC8vIElmIHdlJ3JlIG5vdCBjdXJyZW50bHkgaHlkcmF0aW5nIGJ1dCB3ZSdyZSBpbiBhIGh5ZHJhdGlvbiBjb250ZXh0LCB0aGVuXG4gICAgLy8gd2Ugd2VyZSBhbiBpbnNlcnRpb24gYW5kIG5vdyBuZWVkIHRvIHBvcCB1cCByZWVudGVyIGh5ZHJhdGlvbiBvZiBvdXJcbiAgICAvLyBzaWJsaW5ncy5cbiAgICBwb3BUb05leHRIb3N0UGFyZW50KGZpYmVyKTtcbiAgICBpc0h5ZHJhdGluZyA9IHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIElmIHdlIGhhdmUgYW55IHJlbWFpbmluZyBoeWRyYXRhYmxlIG5vZGVzLCB3ZSBuZWVkIHRvIGRlbGV0ZSB0aGVtIG5vdy5cbiAgLy8gV2Ugb25seSBkbyB0aGlzIGRlZXBlciB0aGFuIGhlYWQgYW5kIGJvZHkgc2luY2UgdGhleSB0ZW5kIHRvIGhhdmUgcmFuZG9tXG4gIC8vIG90aGVyIG5vZGVzIGluIHRoZW0uIFdlIGFsc28gaWdub3JlIGNvbXBvbmVudHMgd2l0aCBwdXJlIHRleHQgY29udGVudCBpblxuICAvLyBzaWRlIG9mIHRoZW0uIFdlIGFsc28gZG9uJ3QgZGVsZXRlIGFueXRoaW5nIGluc2lkZSB0aGUgcm9vdCBjb250YWluZXIuXG5cblxuICBpZiAoZmliZXIudGFnICE9PSBIb3N0Um9vdCAmJiAoZmliZXIudGFnICE9PSBIb3N0Q29tcG9uZW50IHx8IHNob3VsZERlbGV0ZVVuaHlkcmF0ZWRUYWlsSW5zdGFuY2VzKGZpYmVyLnR5cGUpICYmICFzaG91bGRTZXRUZXh0Q29udGVudChmaWJlci50eXBlLCBmaWJlci5tZW1vaXplZFByb3BzKSkpIHtcbiAgICB2YXIgbmV4dEluc3RhbmNlID0gbmV4dEh5ZHJhdGFibGVJbnN0YW5jZTtcblxuICAgIGlmIChuZXh0SW5zdGFuY2UpIHtcbiAgICAgIGlmIChzaG91bGRDbGllbnRSZW5kZXJPbk1pc21hdGNoKGZpYmVyKSkge1xuICAgICAgICB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKGZpYmVyKTtcbiAgICAgICAgdGhyb3dPbkh5ZHJhdGlvbk1pc21hdGNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aGlsZSAobmV4dEluc3RhbmNlKSB7XG4gICAgICAgICAgZGVsZXRlSHlkcmF0YWJsZUluc3RhbmNlKGZpYmVyLCBuZXh0SW5zdGFuY2UpO1xuICAgICAgICAgIG5leHRJbnN0YW5jZSA9IGdldE5leHRIeWRyYXRhYmxlU2libGluZyhuZXh0SW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcG9wVG9OZXh0SG9zdFBhcmVudChmaWJlcik7XG5cbiAgaWYgKGZpYmVyLnRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gc2tpcFBhc3REZWh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShmaWJlcik7XG4gIH0gZWxzZSB7XG4gICAgbmV4dEh5ZHJhdGFibGVJbnN0YW5jZSA9IGh5ZHJhdGlvblBhcmVudEZpYmVyID8gZ2V0TmV4dEh5ZHJhdGFibGVTaWJsaW5nKGZpYmVyLnN0YXRlTm9kZSkgOiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGhhc1VuaHlkcmF0ZWRUYWlsTm9kZXMoKSB7XG4gIHJldHVybiBpc0h5ZHJhdGluZyAmJiBuZXh0SHlkcmF0YWJsZUluc3RhbmNlICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiB3YXJuSWZVbmh5ZHJhdGVkVGFpbE5vZGVzKGZpYmVyKSB7XG4gIHZhciBuZXh0SW5zdGFuY2UgPSBuZXh0SHlkcmF0YWJsZUluc3RhbmNlO1xuXG4gIHdoaWxlIChuZXh0SW5zdGFuY2UpIHtcbiAgICB3YXJuVW5oeWRyYXRlZEluc3RhbmNlKGZpYmVyLCBuZXh0SW5zdGFuY2UpO1xuICAgIG5leHRJbnN0YW5jZSA9IGdldE5leHRIeWRyYXRhYmxlU2libGluZyhuZXh0SW5zdGFuY2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0SHlkcmF0aW9uU3RhdGUoKSB7XG5cbiAgaHlkcmF0aW9uUGFyZW50RmliZXIgPSBudWxsO1xuICBuZXh0SHlkcmF0YWJsZUluc3RhbmNlID0gbnVsbDtcbiAgaXNIeWRyYXRpbmcgPSBmYWxzZTtcbiAgZGlkU3VzcGVuZE9yRXJyb3JERVYgPSBmYWxzZTtcbn1cblxuZnVuY3Rpb24gdXBncmFkZUh5ZHJhdGlvbkVycm9yc1RvUmVjb3ZlcmFibGUoKSB7XG4gIGlmIChoeWRyYXRpb25FcnJvcnMgIT09IG51bGwpIHtcbiAgICAvLyBTdWNjZXNzZnVsbHkgY29tcGxldGVkIGEgZm9yY2VkIGNsaWVudCByZW5kZXIuIFRoZSBlcnJvcnMgdGhhdCBvY2N1cnJlZFxuICAgIC8vIGR1cmluZyB0aGUgaHlkcmF0aW9uIGF0dGVtcHQgYXJlIG5vdyByZWNvdmVyZWQuIFdlIHdpbGwgbG9nIHRoZW0gaW5cbiAgICAvLyBjb21taXQgcGhhc2UsIG9uY2UgdGhlIGVudGlyZSB0cmVlIGhhcyBmaW5pc2hlZC5cbiAgICBxdWV1ZVJlY292ZXJhYmxlRXJyb3JzKGh5ZHJhdGlvbkVycm9ycyk7XG4gICAgaHlkcmF0aW9uRXJyb3JzID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRJc0h5ZHJhdGluZygpIHtcbiAgcmV0dXJuIGlzSHlkcmF0aW5nO1xufVxuXG5mdW5jdGlvbiBxdWV1ZUh5ZHJhdGlvbkVycm9yKGVycm9yKSB7XG4gIGlmIChoeWRyYXRpb25FcnJvcnMgPT09IG51bGwpIHtcbiAgICBoeWRyYXRpb25FcnJvcnMgPSBbZXJyb3JdO1xuICB9IGVsc2Uge1xuICAgIGh5ZHJhdGlvbkVycm9ycy5wdXNoKGVycm9yKTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnO1xudmFyIE5vVHJhbnNpdGlvbiA9IG51bGw7XG5mdW5jdGlvbiByZXF1ZXN0Q3VycmVudFRyYW5zaXRpb24oKSB7XG4gIHJldHVybiBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQxLnRyYW5zaXRpb247XG59XG5cbnZhciBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncyA9IHtcbiAgcmVjb3JkVW5zYWZlTGlmZWN5Y2xlV2FybmluZ3M6IGZ1bmN0aW9uIChmaWJlciwgaW5zdGFuY2UpIHt9LFxuICBmbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5nczogZnVuY3Rpb24gKCkge30sXG4gIHJlY29yZExlZ2FjeUNvbnRleHRXYXJuaW5nOiBmdW5jdGlvbiAoZmliZXIsIGluc3RhbmNlKSB7fSxcbiAgZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZzogZnVuY3Rpb24gKCkge30sXG4gIGRpc2NhcmRQZW5kaW5nV2FybmluZ3M6IGZ1bmN0aW9uICgpIHt9XG59O1xuXG57XG4gIHZhciBmaW5kU3RyaWN0Um9vdCA9IGZ1bmN0aW9uIChmaWJlcikge1xuICAgIHZhciBtYXliZVN0cmljdFJvb3QgPSBudWxsO1xuICAgIHZhciBub2RlID0gZmliZXI7XG5cbiAgICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgbWF5YmVTdHJpY3RSb290ID0gbm9kZTtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIHJldHVybiBtYXliZVN0cmljdFJvb3Q7XG4gIH07XG5cbiAgdmFyIHNldFRvU29ydGVkU3RyaW5nID0gZnVuY3Rpb24gKHNldCkge1xuICAgIHZhciBhcnJheSA9IFtdO1xuICAgIHNldC5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgYXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFycmF5LnNvcnQoKS5qb2luKCcsICcpO1xuICB9O1xuXG4gIHZhciBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MgPSBbXTtcbiAgdmFyIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1dhcm5pbmdzID0gW107XG4gIHZhciBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gIHZhciBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdOyAvLyBUcmFja3MgY29tcG9uZW50cyB3ZSBoYXZlIGFscmVhZHkgd2FybmVkIGFib3V0LlxuXG4gIHZhciBkaWRXYXJuQWJvdXRVbnNhZmVMaWZlY3ljbGVzID0gbmV3IFNldCgpO1xuXG4gIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZFVuc2FmZUxpZmVjeWNsZVdhcm5pbmdzID0gZnVuY3Rpb24gKGZpYmVyLCBpbnN0YW5jZSkge1xuICAgIC8vIERlZHVwZSBzdHJhdGVneTogV2FybiBvbmNlIHBlciBjb21wb25lbnQuXG4gICAgaWYgKGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuaGFzKGZpYmVyLnR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicgJiYgLy8gRG9uJ3Qgd2FybiBhYm91dCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMuXG4gICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50Ll9fc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmcgIT09IHRydWUpIHtcbiAgICAgIHBlbmRpbmdDb21wb25lbnRXaWxsTW91bnRXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgJiYgdHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MucHVzaChmaWJlcik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nICYmIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgJiYgdHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5wdXNoKGZpYmVyKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicgJiYgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZS5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLnB1c2goZmliZXIpO1xuICAgIH1cblxuICAgIGlmIChmaWJlci5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSAmJiB0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLnB1c2goZmliZXIpO1xuICAgIH1cbiAgfTtcblxuICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyBXZSBkbyBhbiBpbml0aWFsIHBhc3MgdG8gZ2F0aGVyIGNvbXBvbmVudCBuYW1lc1xuICAgIHZhciBjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxNb3VudFdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIGNvbXBvbmVudFdpbGxNb3VudFVuaXF1ZU5hbWVzLmFkZChnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICAgIGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuYWRkKGZpYmVyLnR5cGUpO1xuICAgICAgfSk7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudFVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ1VOU0FGRV9Db21wb25lbnRXaWxsTW91bnRXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50VW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MubGVuZ3RoID4gMCkge1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzVW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzV2FybmluZ3MgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNVbmlxdWVOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgIGlmIChwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncy5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzLmFkZChnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnQ29tcG9uZW50Jyk7XG4gICAgICAgIGRpZFdhcm5BYm91dFVuc2FmZUxpZmVjeWNsZXMuYWRkKGZpYmVyLnR5cGUpO1xuICAgICAgfSk7XG4gICAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBjb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMgPSBuZXcgU2V0KCk7XG5cbiAgICBpZiAocGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncy5sZW5ndGggPiAwKSB7XG4gICAgICBwZW5kaW5nQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIGNvbXBvbmVudFdpbGxVcGRhdGVVbmlxdWVOYW1lcy5hZGQoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgICBkaWRXYXJuQWJvdXRVbnNhZmVMaWZlY3ljbGVzLmFkZChmaWJlci50eXBlKTtcbiAgICAgIH0pO1xuICAgICAgcGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZVVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgaWYgKHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzLmZvckVhY2goZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgICAgIFVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMuYWRkKGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgICAgZGlkV2FybkFib3V0VW5zYWZlTGlmZWN5Y2xlcy5hZGQoZmliZXIudHlwZSk7XG4gICAgICB9KTtcbiAgICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gICAgfSAvLyBGaW5hbGx5LCB3ZSBmbHVzaCBhbGwgdGhlIHdhcm5pbmdzXG4gICAgLy8gVU5TQUZFXyBvbmVzIGJlZm9yZSB0aGUgZGVwcmVjYXRlZCBvbmVzLCBzaW5jZSB0aGV5J2xsIGJlICdsb3VkZXInXG5cblxuICAgIGlmIChVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50VW5pcXVlTmFtZXMuc2l6ZSA+IDApIHtcbiAgICAgIHZhciBzb3J0ZWROYW1lcyA9IHNldFRvU29ydGVkU3RyaW5nKFVOU0FGRV9jb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyk7XG5cbiAgICAgIGVycm9yKCdVc2luZyBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50IGluIHN0cmljdCBtb2RlIGlzIG5vdCByZWNvbW1lbmRlZCBhbmQgbWF5IGluZGljYXRlIGJ1Z3MgaW4geW91ciBjb2RlLiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvdW5zYWZlLWNvbXBvbmVudC1saWZlY3ljbGVzIGZvciBkZXRhaWxzLlxcblxcbicgKyAnKiBNb3ZlIGNvZGUgd2l0aCBzaWRlIGVmZmVjdHMgdG8gY29tcG9uZW50RGlkTW91bnQsIGFuZCBzZXQgaW5pdGlhbCBzdGF0ZSBpbiB0aGUgY29uc3RydWN0b3IuXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBzb3J0ZWROYW1lcyk7XG4gICAgfVxuXG4gICAgaWYgKFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzVW5pcXVlTmFtZXMuc2l6ZSA+IDApIHtcbiAgICAgIHZhciBfc29ydGVkTmFtZXMgPSBzZXRUb1NvcnRlZFN0cmluZyhVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzKTtcblxuICAgICAgZXJyb3IoJ1VzaW5nIFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzIGluIHN0cmljdCBtb2RlIGlzIG5vdCByZWNvbW1lbmRlZCAnICsgJ2FuZCBtYXkgaW5kaWNhdGUgYnVncyBpbiB5b3VyIGNvZGUuICcgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMgZm9yIGRldGFpbHMuXFxuXFxuJyArICcqIE1vdmUgZGF0YSBmZXRjaGluZyBjb2RlIG9yIHNpZGUgZWZmZWN0cyB0byBjb21wb25lbnREaWRVcGRhdGUuXFxuJyArIFwiKiBJZiB5b3UncmUgdXBkYXRpbmcgc3RhdGUgd2hlbmV2ZXIgcHJvcHMgY2hhbmdlLCBcIiArICdyZWZhY3RvciB5b3VyIGNvZGUgdG8gdXNlIG1lbW9pemF0aW9uIHRlY2huaXF1ZXMgb3IgbW92ZSBpdCB0byAnICsgJ3N0YXRpYyBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuIExlYXJuIG1vcmUgYXQ6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9kZXJpdmVkLXN0YXRlXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBfc29ydGVkTmFtZXMpO1xuICAgIH1cblxuICAgIGlmIChVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZVVuaXF1ZU5hbWVzLnNpemUgPiAwKSB7XG4gICAgICB2YXIgX3NvcnRlZE5hbWVzMiA9IHNldFRvU29ydGVkU3RyaW5nKFVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMpO1xuXG4gICAgICBlcnJvcignVXNpbmcgVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgaW4gc3RyaWN0IG1vZGUgaXMgbm90IHJlY29tbWVuZGVkICcgKyAnYW5kIG1heSBpbmRpY2F0ZSBidWdzIGluIHlvdXIgY29kZS4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcyBmb3IgZGV0YWlscy5cXG5cXG4nICsgJyogTW92ZSBkYXRhIGZldGNoaW5nIGNvZGUgb3Igc2lkZSBlZmZlY3RzIHRvIGNvbXBvbmVudERpZFVwZGF0ZS5cXG4nICsgJ1xcblBsZWFzZSB1cGRhdGUgdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAlcycsIF9zb3J0ZWROYW1lczIpO1xuICAgIH1cblxuICAgIGlmIChjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcy5zaXplID4gMCkge1xuICAgICAgdmFyIF9zb3J0ZWROYW1lczMgPSBzZXRUb1NvcnRlZFN0cmluZyhjb21wb25lbnRXaWxsTW91bnRVbmlxdWVOYW1lcyk7XG5cbiAgICAgIHdhcm4oJ2NvbXBvbmVudFdpbGxNb3VudCBoYXMgYmVlbiByZW5hbWVkLCBhbmQgaXMgbm90IHJlY29tbWVuZGVkIGZvciB1c2UuICcgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMgZm9yIGRldGFpbHMuXFxuXFxuJyArICcqIE1vdmUgY29kZSB3aXRoIHNpZGUgZWZmZWN0cyB0byBjb21wb25lbnREaWRNb3VudCwgYW5kIHNldCBpbml0aWFsIHN0YXRlIGluIHRoZSBjb25zdHJ1Y3Rvci5cXG4nICsgJyogUmVuYW1lIGNvbXBvbmVudFdpbGxNb3VudCB0byBVTlNBRkVfY29tcG9uZW50V2lsbE1vdW50IHRvIHN1cHByZXNzICcgKyAndGhpcyB3YXJuaW5nIGluIG5vbi1zdHJpY3QgbW9kZS4gSW4gUmVhY3QgMTgueCwgb25seSB0aGUgVU5TQUZFXyBuYW1lIHdpbGwgd29yay4gJyArICdUbyByZW5hbWUgYWxsIGRlcHJlY2F0ZWQgbGlmZWN5Y2xlcyB0byB0aGVpciBuZXcgbmFtZXMsIHlvdSBjYW4gcnVuICcgKyAnYG5weCByZWFjdC1jb2RlbW9kIHJlbmFtZS11bnNhZmUtbGlmZWN5Y2xlc2AgaW4geW91ciBwcm9qZWN0IHNvdXJjZSBmb2xkZXIuXFxuJyArICdcXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnLCBfc29ydGVkTmFtZXMzKTtcbiAgICB9XG5cbiAgICBpZiAoY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1VuaXF1ZU5hbWVzLnNpemUgPiAwKSB7XG4gICAgICB2YXIgX3NvcnRlZE5hbWVzNCA9IHNldFRvU29ydGVkU3RyaW5nKGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNVbmlxdWVOYW1lcyk7XG5cbiAgICAgIHdhcm4oJ2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgaGFzIGJlZW4gcmVuYW1lZCwgYW5kIGlzIG5vdCByZWNvbW1lbmRlZCBmb3IgdXNlLiAnICsgJ1NlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvdW5zYWZlLWNvbXBvbmVudC1saWZlY3ljbGVzIGZvciBkZXRhaWxzLlxcblxcbicgKyAnKiBNb3ZlIGRhdGEgZmV0Y2hpbmcgY29kZSBvciBzaWRlIGVmZmVjdHMgdG8gY29tcG9uZW50RGlkVXBkYXRlLlxcbicgKyBcIiogSWYgeW91J3JlIHVwZGF0aW5nIHN0YXRlIHdoZW5ldmVyIHByb3BzIGNoYW5nZSwgcmVmYWN0b3IgeW91ciBcIiArICdjb2RlIHRvIHVzZSBtZW1vaXphdGlvbiB0ZWNobmlxdWVzIG9yIG1vdmUgaXQgdG8gJyArICdzdGF0aWMgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLiBMZWFybiBtb3JlIGF0OiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvZGVyaXZlZC1zdGF0ZVxcbicgKyAnKiBSZW5hbWUgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyB0byBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyB0byBzdXBwcmVzcyAnICsgJ3RoaXMgd2FybmluZyBpbiBub24tc3RyaWN0IG1vZGUuIEluIFJlYWN0IDE4LngsIG9ubHkgdGhlIFVOU0FGRV8gbmFtZSB3aWxsIHdvcmsuICcgKyAnVG8gcmVuYW1lIGFsbCBkZXByZWNhdGVkIGxpZmVjeWNsZXMgdG8gdGhlaXIgbmV3IG5hbWVzLCB5b3UgY2FuIHJ1biAnICsgJ2BucHggcmVhY3QtY29kZW1vZCByZW5hbWUtdW5zYWZlLWxpZmVjeWNsZXNgIGluIHlvdXIgcHJvamVjdCBzb3VyY2UgZm9sZGVyLlxcbicgKyAnXFxuUGxlYXNlIHVwZGF0ZSB0aGUgZm9sbG93aW5nIGNvbXBvbmVudHM6ICVzJywgX3NvcnRlZE5hbWVzNCk7XG4gICAgfVxuXG4gICAgaWYgKGNvbXBvbmVudFdpbGxVcGRhdGVVbmlxdWVOYW1lcy5zaXplID4gMCkge1xuICAgICAgdmFyIF9zb3J0ZWROYW1lczUgPSBzZXRUb1NvcnRlZFN0cmluZyhjb21wb25lbnRXaWxsVXBkYXRlVW5pcXVlTmFtZXMpO1xuXG4gICAgICB3YXJuKCdjb21wb25lbnRXaWxsVXBkYXRlIGhhcyBiZWVuIHJlbmFtZWQsIGFuZCBpcyBub3QgcmVjb21tZW5kZWQgZm9yIHVzZS4gJyArICdTZWUgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3Vuc2FmZS1jb21wb25lbnQtbGlmZWN5Y2xlcyBmb3IgZGV0YWlscy5cXG5cXG4nICsgJyogTW92ZSBkYXRhIGZldGNoaW5nIGNvZGUgb3Igc2lkZSBlZmZlY3RzIHRvIGNvbXBvbmVudERpZFVwZGF0ZS5cXG4nICsgJyogUmVuYW1lIGNvbXBvbmVudFdpbGxVcGRhdGUgdG8gVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgdG8gc3VwcHJlc3MgJyArICd0aGlzIHdhcm5pbmcgaW4gbm9uLXN0cmljdCBtb2RlLiBJbiBSZWFjdCAxOC54LCBvbmx5IHRoZSBVTlNBRkVfIG5hbWUgd2lsbCB3b3JrLiAnICsgJ1RvIHJlbmFtZSBhbGwgZGVwcmVjYXRlZCBsaWZlY3ljbGVzIHRvIHRoZWlyIG5ldyBuYW1lcywgeW91IGNhbiBydW4gJyArICdgbnB4IHJlYWN0LWNvZGVtb2QgcmVuYW1lLXVuc2FmZS1saWZlY3ljbGVzYCBpbiB5b3VyIHByb2plY3Qgc291cmNlIGZvbGRlci5cXG4nICsgJ1xcblBsZWFzZSB1cGRhdGUgdGhlIGZvbGxvd2luZyBjb21wb25lbnRzOiAlcycsIF9zb3J0ZWROYW1lczUpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgcGVuZGluZ0xlZ2FjeUNvbnRleHRXYXJuaW5nID0gbmV3IE1hcCgpOyAvLyBUcmFja3MgY29tcG9uZW50cyB3ZSBoYXZlIGFscmVhZHkgd2FybmVkIGFib3V0LlxuXG4gIHZhciBkaWRXYXJuQWJvdXRMZWdhY3lDb250ZXh0ID0gbmV3IFNldCgpO1xuXG4gIFJlYWN0U3RyaWN0TW9kZVdhcm5pbmdzLnJlY29yZExlZ2FjeUNvbnRleHRXYXJuaW5nID0gZnVuY3Rpb24gKGZpYmVyLCBpbnN0YW5jZSkge1xuICAgIHZhciBzdHJpY3RSb290ID0gZmluZFN0cmljdFJvb3QoZmliZXIpO1xuXG4gICAgaWYgKHN0cmljdFJvb3QgPT09IG51bGwpIHtcbiAgICAgIGVycm9yKCdFeHBlY3RlZCB0byBmaW5kIGEgU3RyaWN0TW9kZSBjb21wb25lbnQgaW4gYSBzdHJpY3QgbW9kZSB0cmVlLiAnICsgJ1RoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9IC8vIERlZHVwIHN0cmF0ZWd5OiBXYXJuIG9uY2UgcGVyIGNvbXBvbmVudC5cblxuXG4gICAgaWYgKGRpZFdhcm5BYm91dExlZ2FjeUNvbnRleHQuaGFzKGZpYmVyLnR5cGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHdhcm5pbmdzRm9yUm9vdCA9IHBlbmRpbmdMZWdhY3lDb250ZXh0V2FybmluZy5nZXQoc3RyaWN0Um9vdCk7XG5cbiAgICBpZiAoZmliZXIudHlwZS5jb250ZXh0VHlwZXMgIT0gbnVsbCB8fCBmaWJlci50eXBlLmNoaWxkQ29udGV4dFR5cGVzICE9IG51bGwgfHwgaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlLmdldENoaWxkQ29udGV4dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHdhcm5pbmdzRm9yUm9vdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHdhcm5pbmdzRm9yUm9vdCA9IFtdO1xuICAgICAgICBwZW5kaW5nTGVnYWN5Q29udGV4dFdhcm5pbmcuc2V0KHN0cmljdFJvb3QsIHdhcm5pbmdzRm9yUm9vdCk7XG4gICAgICB9XG5cbiAgICAgIHdhcm5pbmdzRm9yUm9vdC5wdXNoKGZpYmVyKTtcbiAgICB9XG4gIH07XG5cbiAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZmx1c2hMZWdhY3lDb250ZXh0V2FybmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICBwZW5kaW5nTGVnYWN5Q29udGV4dFdhcm5pbmcuZm9yRWFjaChmdW5jdGlvbiAoZmliZXJBcnJheSwgc3RyaWN0Um9vdCkge1xuICAgICAgaWYgKGZpYmVyQXJyYXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGZpcnN0RmliZXIgPSBmaWJlckFycmF5WzBdO1xuICAgICAgdmFyIHVuaXF1ZU5hbWVzID0gbmV3IFNldCgpO1xuICAgICAgZmliZXJBcnJheS5mb3JFYWNoKGZ1bmN0aW9uIChmaWJlcikge1xuICAgICAgICB1bmlxdWVOYW1lcy5hZGQoZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCcpO1xuICAgICAgICBkaWRXYXJuQWJvdXRMZWdhY3lDb250ZXh0LmFkZChmaWJlci50eXBlKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIHNvcnRlZE5hbWVzID0gc2V0VG9Tb3J0ZWRTdHJpbmcodW5pcXVlTmFtZXMpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBzZXRDdXJyZW50RmliZXIoZmlyc3RGaWJlcik7XG5cbiAgICAgICAgZXJyb3IoJ0xlZ2FjeSBjb250ZXh0IEFQSSBoYXMgYmVlbiBkZXRlY3RlZCB3aXRoaW4gYSBzdHJpY3QtbW9kZSB0cmVlLicgKyAnXFxuXFxuVGhlIG9sZCBBUEkgd2lsbCBiZSBzdXBwb3J0ZWQgaW4gYWxsIDE2LnggcmVsZWFzZXMsIGJ1dCBhcHBsaWNhdGlvbnMgJyArICd1c2luZyBpdCBzaG91bGQgbWlncmF0ZSB0byB0aGUgbmV3IHZlcnNpb24uJyArICdcXG5cXG5QbGVhc2UgdXBkYXRlIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czogJXMnICsgJ1xcblxcbkxlYXJuIG1vcmUgYWJvdXQgdGhpcyB3YXJuaW5nIGhlcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9sZWdhY3ktY29udGV4dCcsIHNvcnRlZE5hbWVzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MuZGlzY2FyZFBlbmRpbmdXYXJuaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICBwZW5kaW5nQ29tcG9uZW50V2lsbE1vdW50V2FybmluZ3MgPSBbXTtcbiAgICBwZW5kaW5nVU5TQUZFX0NvbXBvbmVudFdpbGxNb3VudFdhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNXYXJuaW5ncyA9IFtdO1xuICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1dhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0NvbXBvbmVudFdpbGxVcGRhdGVXYXJuaW5ncyA9IFtdO1xuICAgIHBlbmRpbmdVTlNBRkVfQ29tcG9uZW50V2lsbFVwZGF0ZVdhcm5pbmdzID0gW107XG4gICAgcGVuZGluZ0xlZ2FjeUNvbnRleHRXYXJuaW5nID0gbmV3IE1hcCgpO1xuICB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudCwgYmFzZVByb3BzKSB7XG4gIGlmIChDb21wb25lbnQgJiYgQ29tcG9uZW50LmRlZmF1bHRQcm9wcykge1xuICAgIC8vIFJlc29sdmUgZGVmYXVsdCBwcm9wcy4gVGFrZW4gZnJvbSBSZWFjdEVsZW1lbnRcbiAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIGJhc2VQcm9wcyk7XG4gICAgdmFyIGRlZmF1bHRQcm9wcyA9IENvbXBvbmVudC5kZWZhdWx0UHJvcHM7XG5cbiAgICBmb3IgKHZhciBwcm9wTmFtZSBpbiBkZWZhdWx0UHJvcHMpIHtcbiAgICAgIGlmIChwcm9wc1twcm9wTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkZWZhdWx0UHJvcHNbcHJvcE5hbWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9wcztcbiAgfVxuXG4gIHJldHVybiBiYXNlUHJvcHM7XG59XG5cbnZhciB2YWx1ZUN1cnNvciA9IGNyZWF0ZUN1cnNvcihudWxsKTtcbnZhciByZW5kZXJlclNpZ2lsO1xuXG57XG4gIC8vIFVzZSB0aGlzIHRvIGRldGVjdCBtdWx0aXBsZSByZW5kZXJlcnMgdXNpbmcgdGhlIHNhbWUgY29udGV4dFxuICByZW5kZXJlclNpZ2lsID0ge307XG59XG5cbnZhciBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IG51bGw7XG52YXIgbGFzdENvbnRleHREZXBlbmRlbmN5ID0gbnVsbDtcbnZhciBsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPSBudWxsO1xudmFyIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSBmYWxzZTtcbmZ1bmN0aW9uIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpIHtcbiAgLy8gVGhpcyBpcyBjYWxsZWQgcmlnaHQgYmVmb3JlIFJlYWN0IHlpZWxkcyBleGVjdXRpb24sIHRvIGVuc3VyZSBgcmVhZENvbnRleHRgXG4gIC8vIGNhbm5vdCBiZSBjYWxsZWQgb3V0c2lkZSB0aGUgcmVuZGVyIHBoYXNlLlxuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IG51bGw7XG4gIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IG51bGw7XG4gIGxhc3RGdWxseU9ic2VydmVkQ29udGV4dCA9IG51bGw7XG5cbiAge1xuICAgIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gZW50ZXJEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpIHtcbiAge1xuICAgIGlzRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYgPSB0cnVlO1xuICB9XG59XG5mdW5jdGlvbiBleGl0RGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKSB7XG4gIHtcbiAgICBpc0Rpc2FsbG93ZWRDb250ZXh0UmVhZEluREVWID0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIHB1c2hQcm92aWRlcihwcm92aWRlckZpYmVyLCBjb250ZXh0LCBuZXh0VmFsdWUpIHtcbiAge1xuICAgIHB1c2godmFsdWVDdXJzb3IsIGNvbnRleHQuX2N1cnJlbnRWYWx1ZSwgcHJvdmlkZXJGaWJlcik7XG4gICAgY29udGV4dC5fY3VycmVudFZhbHVlID0gbmV4dFZhbHVlO1xuXG4gICAge1xuICAgICAgaWYgKGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciAhPT0gdW5kZWZpbmVkICYmIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciAhPT0gbnVsbCAmJiBjb250ZXh0Ll9jdXJyZW50UmVuZGVyZXIgIT09IHJlbmRlcmVyU2lnaWwpIHtcbiAgICAgICAgZXJyb3IoJ0RldGVjdGVkIG11bHRpcGxlIHJlbmRlcmVycyBjb25jdXJyZW50bHkgcmVuZGVyaW5nIHRoZSAnICsgJ3NhbWUgY29udGV4dCBwcm92aWRlci4gVGhpcyBpcyBjdXJyZW50bHkgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQuX2N1cnJlbnRSZW5kZXJlciA9IHJlbmRlcmVyU2lnaWw7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBwb3BQcm92aWRlcihjb250ZXh0LCBwcm92aWRlckZpYmVyKSB7XG4gIHZhciBjdXJyZW50VmFsdWUgPSB2YWx1ZUN1cnNvci5jdXJyZW50O1xuICBwb3AodmFsdWVDdXJzb3IsIHByb3ZpZGVyRmliZXIpO1xuXG4gIHtcbiAgICB7XG4gICAgICBjb250ZXh0Ll9jdXJyZW50VmFsdWUgPSBjdXJyZW50VmFsdWU7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBzY2hlZHVsZUNvbnRleHRXb3JrT25QYXJlbnRQYXRoKHBhcmVudCwgcmVuZGVyTGFuZXMsIHByb3BhZ2F0aW9uUm9vdCkge1xuICAvLyBVcGRhdGUgdGhlIGNoaWxkIGxhbmVzIG9mIGFsbCB0aGUgYW5jZXN0b3JzLCBpbmNsdWRpbmcgdGhlIGFsdGVybmF0ZXMuXG4gIHZhciBub2RlID0gcGFyZW50O1xuXG4gIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgdmFyIGFsdGVybmF0ZSA9IG5vZGUuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKCFpc1N1YnNldE9mTGFuZXMobm9kZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcykpIHtcbiAgICAgIG5vZGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobm9kZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgYWx0ZXJuYXRlLmNoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKGFsdGVybmF0ZS5jaGlsZExhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChhbHRlcm5hdGUgIT09IG51bGwgJiYgIWlzU3Vic2V0T2ZMYW5lcyhhbHRlcm5hdGUuY2hpbGRMYW5lcywgcmVuZGVyTGFuZXMpKSB7XG4gICAgICBhbHRlcm5hdGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmNoaWxkTGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICB9XG5cbiAgICBpZiAobm9kZSA9PT0gcHJvcGFnYXRpb25Sb290KSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gIH1cblxuICB7XG4gICAgaWYgKG5vZGUgIT09IHByb3BhZ2F0aW9uUm9vdCkge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgdGhlIHByb3BhZ2F0aW9uIHJvb3Qgd2hlbiBzY2hlZHVsaW5nIGNvbnRleHQgd29yay4gJyArICdUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gcHJvcGFnYXRlQ29udGV4dENoYW5nZSh3b3JrSW5Qcm9ncmVzcywgY29udGV4dCwgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIHByb3BhZ2F0ZUNvbnRleHRDaGFuZ2VfZWFnZXIod29ya0luUHJvZ3Jlc3MsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwcm9wYWdhdGVDb250ZXh0Q2hhbmdlX2VhZ2VyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCByZW5kZXJMYW5lcykge1xuXG4gIHZhciBmaWJlciA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gIGlmIChmaWJlciAhPT0gbnVsbCkge1xuICAgIC8vIFNldCB0aGUgcmV0dXJuIHBvaW50ZXIgb2YgdGhlIGNoaWxkIHRvIHRoZSB3b3JrLWluLXByb2dyZXNzIGZpYmVyLlxuICAgIGZpYmVyLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB9XG5cbiAgd2hpbGUgKGZpYmVyICE9PSBudWxsKSB7XG4gICAgdmFyIG5leHRGaWJlciA9IHZvaWQgMDsgLy8gVmlzaXQgdGhpcyBmaWJlci5cblxuICAgIHZhciBsaXN0ID0gZmliZXIuZGVwZW5kZW5jaWVzO1xuXG4gICAgaWYgKGxpc3QgIT09IG51bGwpIHtcbiAgICAgIG5leHRGaWJlciA9IGZpYmVyLmNoaWxkO1xuICAgICAgdmFyIGRlcGVuZGVuY3kgPSBsaXN0LmZpcnN0Q29udGV4dDtcblxuICAgICAgd2hpbGUgKGRlcGVuZGVuY3kgIT09IG51bGwpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNvbnRleHQgbWF0Y2hlcy5cbiAgICAgICAgaWYgKGRlcGVuZGVuY3kuY29udGV4dCA9PT0gY29udGV4dCkge1xuICAgICAgICAgIC8vIE1hdGNoISBTY2hlZHVsZSBhbiB1cGRhdGUgb24gdGhpcyBmaWJlci5cbiAgICAgICAgICBpZiAoZmliZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgICAgICAgLy8gU2NoZWR1bGUgYSBmb3JjZSB1cGRhdGUgb24gdGhlIHdvcmstaW4tcHJvZ3Jlc3MuXG4gICAgICAgICAgICB2YXIgbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJlbmRlckxhbmVzKTtcbiAgICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIGxhbmUpO1xuICAgICAgICAgICAgdXBkYXRlLnRhZyA9IEZvcmNlVXBkYXRlOyAvLyBUT0RPOiBCZWNhdXNlIHdlIGRvbid0IGhhdmUgYSB3b3JrLWluLXByb2dyZXNzLCB0aGlzIHdpbGwgYWRkIHRoZVxuICAgICAgICAgICAgLy8gdXBkYXRlIHRvIHRoZSBjdXJyZW50IGZpYmVyLCB0b28sIHdoaWNoIG1lYW5zIGl0IHdpbGwgcGVyc2lzdCBldmVuIGlmXG4gICAgICAgICAgICAvLyB0aGlzIHJlbmRlciBpcyB0aHJvd24gYXdheS4gU2luY2UgaXQncyBhIHJhY2UgY29uZGl0aW9uLCBub3Qgc3VyZSBpdCdzXG4gICAgICAgICAgICAvLyB3b3J0aCBmaXhpbmcuXG4gICAgICAgICAgICAvLyBJbmxpbmVkIGBlbnF1ZXVlVXBkYXRlYCB0byByZW1vdmUgaW50ZXJsZWF2ZWQgdXBkYXRlIGNoZWNrXG5cbiAgICAgICAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IGZpYmVyLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgICAgICBpZiAodXBkYXRlUXVldWUgPT09IG51bGwpIDsgZWxzZSB7XG4gICAgICAgICAgICAgIHZhciBzaGFyZWRRdWV1ZSA9IHVwZGF0ZVF1ZXVlLnNoYXJlZDtcbiAgICAgICAgICAgICAgdmFyIHBlbmRpbmcgPSBzaGFyZWRRdWV1ZS5wZW5kaW5nO1xuXG4gICAgICAgICAgICAgIGlmIChwZW5kaW5nID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgICAgICAgICAgICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZS5uZXh0ID0gcGVuZGluZy5uZXh0O1xuICAgICAgICAgICAgICAgIHBlbmRpbmcubmV4dCA9IHVwZGF0ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHNoYXJlZFF1ZXVlLnBlbmRpbmcgPSB1cGRhdGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKGZpYmVyLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICAgIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGFsdGVybmF0ZS5sYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2NoZWR1bGVDb250ZXh0V29ya09uUGFyZW50UGF0aChmaWJlci5yZXR1cm4sIHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcyk7IC8vIE1hcmsgdGhlIHVwZGF0ZWQgbGFuZXMgb24gdGhlIGxpc3QsIHRvby5cblxuICAgICAgICAgIGxpc3QubGFuZXMgPSBtZXJnZUxhbmVzKGxpc3QubGFuZXMsIHJlbmRlckxhbmVzKTsgLy8gU2luY2Ugd2UgYWxyZWFkeSBmb3VuZCBhIG1hdGNoLCB3ZSBjYW4gc3RvcCB0cmF2ZXJzaW5nIHRoZVxuICAgICAgICAgIC8vIGRlcGVuZGVuY3kgbGlzdC5cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVwZW5kZW5jeSA9IGRlcGVuZGVuY3kubmV4dDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZpYmVyLnRhZyA9PT0gQ29udGV4dFByb3ZpZGVyKSB7XG4gICAgICAvLyBEb24ndCBzY2FuIGRlZXBlciBpZiB0aGlzIGlzIGEgbWF0Y2hpbmcgcHJvdmlkZXJcbiAgICAgIG5leHRGaWJlciA9IGZpYmVyLnR5cGUgPT09IHdvcmtJblByb2dyZXNzLnR5cGUgPyBudWxsIDogZmliZXIuY2hpbGQ7XG4gICAgfSBlbHNlIGlmIChmaWJlci50YWcgPT09IERlaHlkcmF0ZWRGcmFnbWVudCkge1xuICAgICAgLy8gSWYgYSBkZWh5ZHJhdGVkIHN1c3BlbnNlIGJvdW5kYXJ5IGlzIGluIHRoaXMgc3VidHJlZSwgd2UgZG9uJ3Qga25vd1xuICAgICAgLy8gaWYgaXQgd2lsbCBoYXZlIGFueSBjb250ZXh0IGNvbnN1bWVycyBpbiBpdC4gVGhlIGJlc3Qgd2UgY2FuIGRvIGlzXG4gICAgICAvLyBtYXJrIGl0IGFzIGhhdmluZyB1cGRhdGVzLlxuICAgICAgdmFyIHBhcmVudFN1c3BlbnNlID0gZmliZXIucmV0dXJuO1xuXG4gICAgICBpZiAocGFyZW50U3VzcGVuc2UgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZSBqdXN0IGNhbWUgZnJvbSBhIHBhcmVudCBzbyB3ZSBtdXN0IGhhdmUgaGFkIGEgcGFyZW50LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LicpO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnRTdXNwZW5zZS5sYW5lcyA9IG1lcmdlTGFuZXMocGFyZW50U3VzcGVuc2UubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICAgIHZhciBfYWx0ZXJuYXRlID0gcGFyZW50U3VzcGVuc2UuYWx0ZXJuYXRlO1xuXG4gICAgICBpZiAoX2FsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgICBfYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhfYWx0ZXJuYXRlLmxhbmVzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9IC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBwYXNzaW5nIHRoaXMgZmliZXIgYXMgdGhlIHBhcmVudFxuICAgICAgLy8gYmVjYXVzZSB3ZSB3YW50IHRvIHNjaGVkdWxlIHRoaXMgZmliZXIgYXMgaGF2aW5nIHdvcmtcbiAgICAgIC8vIG9uIGl0cyBjaGlsZHJlbi4gV2UnbGwgdXNlIHRoZSBjaGlsZExhbmVzIG9uXG4gICAgICAvLyB0aGlzIGZpYmVyIHRvIGluZGljYXRlIHRoYXQgYSBjb250ZXh0IGhhcyBjaGFuZ2VkLlxuXG5cbiAgICAgIHNjaGVkdWxlQ29udGV4dFdvcmtPblBhcmVudFBhdGgocGFyZW50U3VzcGVuc2UsIHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBuZXh0RmliZXIgPSBmaWJlci5zaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUcmF2ZXJzZSBkb3duLlxuICAgICAgbmV4dEZpYmVyID0gZmliZXIuY2hpbGQ7XG4gICAgfVxuXG4gICAgaWYgKG5leHRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgLy8gU2V0IHRoZSByZXR1cm4gcG9pbnRlciBvZiB0aGUgY2hpbGQgdG8gdGhlIHdvcmstaW4tcHJvZ3Jlc3MgZmliZXIuXG4gICAgICBuZXh0RmliZXIucmV0dXJuID0gZmliZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGNoaWxkLiBUcmF2ZXJzZSB0byBuZXh0IHNpYmxpbmcuXG4gICAgICBuZXh0RmliZXIgPSBmaWJlcjtcblxuICAgICAgd2hpbGUgKG5leHRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgICBpZiAobmV4dEZpYmVyID09PSB3b3JrSW5Qcm9ncmVzcykge1xuICAgICAgICAgIC8vIFdlJ3JlIGJhY2sgdG8gdGhlIHJvb3Qgb2YgdGhpcyBzdWJ0cmVlLiBFeGl0LlxuICAgICAgICAgIG5leHRGaWJlciA9IG51bGw7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc2libGluZyA9IG5leHRGaWJlci5zaWJsaW5nO1xuXG4gICAgICAgIGlmIChzaWJsaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gU2V0IHRoZSByZXR1cm4gcG9pbnRlciBvZiB0aGUgc2libGluZyB0byB0aGUgd29yay1pbi1wcm9ncmVzcyBmaWJlci5cbiAgICAgICAgICBzaWJsaW5nLnJldHVybiA9IG5leHRGaWJlci5yZXR1cm47XG4gICAgICAgICAgbmV4dEZpYmVyID0gc2libGluZztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSAvLyBObyBtb3JlIHNpYmxpbmdzLiBUcmF2ZXJzZSB1cC5cblxuXG4gICAgICAgIG5leHRGaWJlciA9IG5leHRGaWJlci5yZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmliZXIgPSBuZXh0RmliZXI7XG4gIH1cbn1cbmZ1bmN0aW9uIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciA9IHdvcmtJblByb2dyZXNzO1xuICBsYXN0Q29udGV4dERlcGVuZGVuY3kgPSBudWxsO1xuICBsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPSBudWxsO1xuICB2YXIgZGVwZW5kZW5jaWVzID0gd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzO1xuXG4gIGlmIChkZXBlbmRlbmNpZXMgIT09IG51bGwpIHtcbiAgICB7XG4gICAgICB2YXIgZmlyc3RDb250ZXh0ID0gZGVwZW5kZW5jaWVzLmZpcnN0Q29udGV4dDtcblxuICAgICAgaWYgKGZpcnN0Q29udGV4dCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaW5jbHVkZXNTb21lTGFuZShkZXBlbmRlbmNpZXMubGFuZXMsIHJlbmRlckxhbmVzKSkge1xuICAgICAgICAgIC8vIENvbnRleHQgbGlzdCBoYXMgYSBwZW5kaW5nIHVwZGF0ZS4gTWFyayB0aGF0IHRoaXMgZmliZXIgcGVyZm9ybWVkIHdvcmsuXG4gICAgICAgICAgbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKTtcbiAgICAgICAgfSAvLyBSZXNldCB0aGUgd29yay1pbi1wcm9ncmVzcyBsaXN0XG5cblxuICAgICAgICBkZXBlbmRlbmNpZXMuZmlyc3RDb250ZXh0ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHJlYWRDb250ZXh0KGNvbnRleHQpIHtcbiAge1xuICAgIC8vIFRoaXMgd2FybmluZyB3b3VsZCBmaXJlIGlmIHlvdSByZWFkIGNvbnRleHQgaW5zaWRlIGEgSG9vayBsaWtlIHVzZU1lbW8uXG4gICAgLy8gVW5saWtlIHRoZSBjbGFzcyBjaGVjayBiZWxvdywgaXQncyBub3QgZW5mb3JjZWQgaW4gcHJvZHVjdGlvbiBmb3IgcGVyZi5cbiAgICBpZiAoaXNEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVikge1xuICAgICAgZXJyb3IoJ0NvbnRleHQgY2FuIG9ubHkgYmUgcmVhZCB3aGlsZSBSZWFjdCBpcyByZW5kZXJpbmcuICcgKyAnSW4gY2xhc3NlcywgeW91IGNhbiByZWFkIGl0IGluIHRoZSByZW5kZXIgbWV0aG9kIG9yIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcy4gJyArICdJbiBmdW5jdGlvbiBjb21wb25lbnRzLCB5b3UgY2FuIHJlYWQgaXQgZGlyZWN0bHkgaW4gdGhlIGZ1bmN0aW9uIGJvZHksIGJ1dCBub3QgJyArICdpbnNpZGUgSG9va3MgbGlrZSB1c2VSZWR1Y2VyKCkgb3IgdXNlTWVtbygpLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciB2YWx1ZSA9ICBjb250ZXh0Ll9jdXJyZW50VmFsdWUgO1xuXG4gIGlmIChsYXN0RnVsbHlPYnNlcnZlZENvbnRleHQgPT09IGNvbnRleHQpIDsgZWxzZSB7XG4gICAgdmFyIGNvbnRleHRJdGVtID0ge1xuICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgIG1lbW9pemVkVmFsdWU6IHZhbHVlLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG5cbiAgICBpZiAobGFzdENvbnRleHREZXBlbmRlbmN5ID09PSBudWxsKSB7XG4gICAgICBpZiAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250ZXh0IGNhbiBvbmx5IGJlIHJlYWQgd2hpbGUgUmVhY3QgaXMgcmVuZGVyaW5nLiAnICsgJ0luIGNsYXNzZXMsIHlvdSBjYW4gcmVhZCBpdCBpbiB0aGUgcmVuZGVyIG1ldGhvZCBvciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuICcgKyAnSW4gZnVuY3Rpb24gY29tcG9uZW50cywgeW91IGNhbiByZWFkIGl0IGRpcmVjdGx5IGluIHRoZSBmdW5jdGlvbiBib2R5LCBidXQgbm90ICcgKyAnaW5zaWRlIEhvb2tzIGxpa2UgdXNlUmVkdWNlcigpIG9yIHVzZU1lbW8oKS4nKTtcbiAgICAgIH0gLy8gVGhpcyBpcyB0aGUgZmlyc3QgZGVwZW5kZW5jeSBmb3IgdGhpcyBjb21wb25lbnQuIENyZWF0ZSBhIG5ldyBsaXN0LlxuXG5cbiAgICAgIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IGNvbnRleHRJdGVtO1xuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIuZGVwZW5kZW5jaWVzID0ge1xuICAgICAgICBsYW5lczogTm9MYW5lcyxcbiAgICAgICAgZmlyc3RDb250ZXh0OiBjb250ZXh0SXRlbVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXBwZW5kIGEgbmV3IGNvbnRleHQgaXRlbS5cbiAgICAgIGxhc3RDb250ZXh0RGVwZW5kZW5jeSA9IGxhc3RDb250ZXh0RGVwZW5kZW5jeS5uZXh0ID0gY29udGV4dEl0ZW07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vLyByZW5kZXIuIFdoZW4gdGhpcyByZW5kZXIgZXhpdHMsIGVpdGhlciBiZWNhdXNlIGl0IGZpbmlzaGVzIG9yIGJlY2F1c2UgaXQgaXNcbi8vIGludGVycnVwdGVkLCB0aGUgaW50ZXJsZWF2ZWQgdXBkYXRlcyB3aWxsIGJlIHRyYW5zZmVycmVkIG9udG8gdGhlIG1haW4gcGFydFxuLy8gb2YgdGhlIHF1ZXVlLlxuXG52YXIgY29uY3VycmVudFF1ZXVlcyA9IG51bGw7XG5mdW5jdGlvbiBwdXNoQ29uY3VycmVudFVwZGF0ZVF1ZXVlKHF1ZXVlKSB7XG4gIGlmIChjb25jdXJyZW50UXVldWVzID09PSBudWxsKSB7XG4gICAgY29uY3VycmVudFF1ZXVlcyA9IFtxdWV1ZV07XG4gIH0gZWxzZSB7XG4gICAgY29uY3VycmVudFF1ZXVlcy5wdXNoKHF1ZXVlKTtcbiAgfVxufVxuZnVuY3Rpb24gZmluaXNoUXVldWVpbmdDb25jdXJyZW50VXBkYXRlcygpIHtcbiAgLy8gVHJhbnNmZXIgdGhlIGludGVybGVhdmVkIHVwZGF0ZXMgb250byB0aGUgbWFpbiBxdWV1ZS4gRWFjaCBxdWV1ZSBoYXMgYVxuICAvLyBgcGVuZGluZ2AgZmllbGQgYW5kIGFuIGBpbnRlcmxlYXZlZGAgZmllbGQuIFdoZW4gdGhleSBhcmUgbm90IG51bGwsIHRoZXlcbiAgLy8gcG9pbnQgdG8gdGhlIGxhc3Qgbm9kZSBpbiBhIGNpcmN1bGFyIGxpbmtlZCBsaXN0LiBXZSBuZWVkIHRvIGFwcGVuZCB0aGVcbiAgLy8gaW50ZXJsZWF2ZWQgbGlzdCB0byB0aGUgZW5kIG9mIHRoZSBwZW5kaW5nIGxpc3QgYnkgam9pbmluZyB0aGVtIGludG8gYVxuICAvLyBzaW5nbGUsIGNpcmN1bGFyIGxpc3QuXG4gIGlmIChjb25jdXJyZW50UXVldWVzICE9PSBudWxsKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb25jdXJyZW50UXVldWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcXVldWUgPSBjb25jdXJyZW50UXVldWVzW2ldO1xuICAgICAgdmFyIGxhc3RJbnRlcmxlYXZlZFVwZGF0ZSA9IHF1ZXVlLmludGVybGVhdmVkO1xuXG4gICAgICBpZiAobGFzdEludGVybGVhdmVkVXBkYXRlICE9PSBudWxsKSB7XG4gICAgICAgIHF1ZXVlLmludGVybGVhdmVkID0gbnVsbDtcbiAgICAgICAgdmFyIGZpcnN0SW50ZXJsZWF2ZWRVcGRhdGUgPSBsYXN0SW50ZXJsZWF2ZWRVcGRhdGUubmV4dDtcbiAgICAgICAgdmFyIGxhc3RQZW5kaW5nVXBkYXRlID0gcXVldWUucGVuZGluZztcblxuICAgICAgICBpZiAobGFzdFBlbmRpbmdVcGRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgZmlyc3RQZW5kaW5nVXBkYXRlID0gbGFzdFBlbmRpbmdVcGRhdGUubmV4dDtcbiAgICAgICAgICBsYXN0UGVuZGluZ1VwZGF0ZS5uZXh0ID0gZmlyc3RJbnRlcmxlYXZlZFVwZGF0ZTtcbiAgICAgICAgICBsYXN0SW50ZXJsZWF2ZWRVcGRhdGUubmV4dCA9IGZpcnN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHF1ZXVlLnBlbmRpbmcgPSBsYXN0SW50ZXJsZWF2ZWRVcGRhdGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uY3VycmVudFF1ZXVlcyA9IG51bGw7XG4gIH1cbn1cbmZ1bmN0aW9uIGVucXVldWVDb25jdXJyZW50SG9va1VwZGF0ZShmaWJlciwgcXVldWUsIHVwZGF0ZSwgbGFuZSkge1xuICB2YXIgaW50ZXJsZWF2ZWQgPSBxdWV1ZS5pbnRlcmxlYXZlZDtcblxuICBpZiAoaW50ZXJsZWF2ZWQgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgdXBkYXRlLm5leHQgPSB1cGRhdGU7IC8vIEF0IHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgcmVuZGVyLCB0aGlzIHF1ZXVlJ3MgaW50ZXJsZWF2ZWQgdXBkYXRlcyB3aWxsXG4gICAgLy8gYmUgdHJhbnNmZXJyZWQgdG8gdGhlIHBlbmRpbmcgcXVldWUuXG5cbiAgICBwdXNoQ29uY3VycmVudFVwZGF0ZVF1ZXVlKHF1ZXVlKTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGUubmV4dCA9IGludGVybGVhdmVkLm5leHQ7XG4gICAgaW50ZXJsZWF2ZWQubmV4dCA9IHVwZGF0ZTtcbiAgfVxuXG4gIHF1ZXVlLmludGVybGVhdmVkID0gdXBkYXRlO1xuICByZXR1cm4gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3QoZmliZXIsIGxhbmUpO1xufVxuZnVuY3Rpb24gZW5xdWV1ZUNvbmN1cnJlbnRIb29rVXBkYXRlQW5kRWFnZXJseUJhaWxvdXQoZmliZXIsIHF1ZXVlLCB1cGRhdGUsIGxhbmUpIHtcbiAgdmFyIGludGVybGVhdmVkID0gcXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgaWYgKGludGVybGVhdmVkID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlOyAvLyBBdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHJlbmRlciwgdGhpcyBxdWV1ZSdzIGludGVybGVhdmVkIHVwZGF0ZXMgd2lsbFxuICAgIC8vIGJlIHRyYW5zZmVycmVkIHRvIHRoZSBwZW5kaW5nIHF1ZXVlLlxuXG4gICAgcHVzaENvbmN1cnJlbnRVcGRhdGVRdWV1ZShxdWV1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgIGludGVybGVhdmVkLm5leHQgPSB1cGRhdGU7XG4gIH1cblxuICBxdWV1ZS5pbnRlcmxlYXZlZCA9IHVwZGF0ZTtcbn1cbmZ1bmN0aW9uIGVucXVldWVDb25jdXJyZW50Q2xhc3NVcGRhdGUoZmliZXIsIHF1ZXVlLCB1cGRhdGUsIGxhbmUpIHtcbiAgdmFyIGludGVybGVhdmVkID0gcXVldWUuaW50ZXJsZWF2ZWQ7XG5cbiAgaWYgKGludGVybGVhdmVkID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgdXBkYXRlLiBDcmVhdGUgYSBjaXJjdWxhciBsaXN0LlxuICAgIHVwZGF0ZS5uZXh0ID0gdXBkYXRlOyAvLyBBdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHJlbmRlciwgdGhpcyBxdWV1ZSdzIGludGVybGVhdmVkIHVwZGF0ZXMgd2lsbFxuICAgIC8vIGJlIHRyYW5zZmVycmVkIHRvIHRoZSBwZW5kaW5nIHF1ZXVlLlxuXG4gICAgcHVzaENvbmN1cnJlbnRVcGRhdGVRdWV1ZShxdWV1ZSk7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgIGludGVybGVhdmVkLm5leHQgPSB1cGRhdGU7XG4gIH1cblxuICBxdWV1ZS5pbnRlcmxlYXZlZCA9IHVwZGF0ZTtcbiAgcmV0dXJuIG1hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KGZpYmVyLCBsYW5lKTtcbn1cbmZ1bmN0aW9uIGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShmaWJlciwgbGFuZSkge1xuICByZXR1cm4gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3QoZmliZXIsIGxhbmUpO1xufSAvLyBDYWxsaW5nIHRoaXMgZnVuY3Rpb24gb3V0c2lkZSB0aGlzIG1vZHVsZSBzaG91bGQgb25seSBiZSBkb25lIGZvciBiYWNrd2FyZHNcbi8vIGNvbXBhdGliaWxpdHkgYW5kIHNob3VsZCBhbHdheXMgYmUgYWNjb21wYW5pZWQgYnkgYSB3YXJuaW5nLlxuXG52YXIgdW5zYWZlX21hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290ID0gbWFya1VwZGF0ZUxhbmVGcm9tRmliZXJUb1Jvb3Q7XG5cbmZ1bmN0aW9uIG1hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KHNvdXJjZUZpYmVyLCBsYW5lKSB7XG4gIC8vIFVwZGF0ZSB0aGUgc291cmNlIGZpYmVyJ3MgbGFuZXNcbiAgc291cmNlRmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKHNvdXJjZUZpYmVyLmxhbmVzLCBsYW5lKTtcbiAgdmFyIGFsdGVybmF0ZSA9IHNvdXJjZUZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhhbHRlcm5hdGUubGFuZXMsIGxhbmUpO1xuICB9XG5cbiAge1xuICAgIGlmIChhbHRlcm5hdGUgPT09IG51bGwgJiYgKHNvdXJjZUZpYmVyLmZsYWdzICYgKFBsYWNlbWVudCB8IEh5ZHJhdGluZykpICE9PSBOb0ZsYWdzKSB7XG4gICAgICB3YXJuQWJvdXRVcGRhdGVPbk5vdFlldE1vdW50ZWRGaWJlckluREVWKHNvdXJjZUZpYmVyKTtcbiAgICB9XG4gIH0gLy8gV2FsayB0aGUgcGFyZW50IHBhdGggdG8gdGhlIHJvb3QgYW5kIHVwZGF0ZSB0aGUgY2hpbGQgbGFuZXMuXG5cblxuICB2YXIgbm9kZSA9IHNvdXJjZUZpYmVyO1xuICB2YXIgcGFyZW50ID0gc291cmNlRmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICBwYXJlbnQuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMocGFyZW50LmNoaWxkTGFuZXMsIGxhbmUpO1xuICAgIGFsdGVybmF0ZSA9IHBhcmVudC5hbHRlcm5hdGU7XG5cbiAgICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICBhbHRlcm5hdGUuY2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMoYWx0ZXJuYXRlLmNoaWxkTGFuZXMsIGxhbmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIGlmICgocGFyZW50LmZsYWdzICYgKFBsYWNlbWVudCB8IEh5ZHJhdGluZykpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgd2FybkFib3V0VXBkYXRlT25Ob3RZZXRNb3VudGVkRmliZXJJbkRFVihzb3VyY2VGaWJlcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBub2RlID0gcGFyZW50O1xuICAgIHBhcmVudCA9IHBhcmVudC5yZXR1cm47XG4gIH1cblxuICBpZiAobm9kZS50YWcgPT09IEhvc3RSb290KSB7XG4gICAgdmFyIHJvb3QgPSBub2RlLnN0YXRlTm9kZTtcbiAgICByZXR1cm4gcm9vdDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG52YXIgVXBkYXRlU3RhdGUgPSAwO1xudmFyIFJlcGxhY2VTdGF0ZSA9IDE7XG52YXIgRm9yY2VVcGRhdGUgPSAyO1xudmFyIENhcHR1cmVVcGRhdGUgPSAzOyAvLyBHbG9iYWwgc3RhdGUgdGhhdCBpcyByZXNldCBhdCB0aGUgYmVnaW5uaW5nIG9mIGNhbGxpbmcgYHByb2Nlc3NVcGRhdGVRdWV1ZWAuXG4vLyBJdCBzaG91bGQgb25seSBiZSByZWFkIHJpZ2h0IGFmdGVyIGNhbGxpbmcgYHByb2Nlc3NVcGRhdGVRdWV1ZWAsIHZpYVxuLy8gYGNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmdgLlxuXG52YXIgaGFzRm9yY2VVcGRhdGUgPSBmYWxzZTtcbnZhciBkaWRXYXJuVXBkYXRlSW5zaWRlVXBkYXRlO1xudmFyIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZTtcblxue1xuICBkaWRXYXJuVXBkYXRlSW5zaWRlVXBkYXRlID0gZmFsc2U7XG4gIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZSA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGluaXRpYWxpemVVcGRhdGVRdWV1ZShmaWJlcikge1xuICB2YXIgcXVldWUgPSB7XG4gICAgYmFzZVN0YXRlOiBmaWJlci5tZW1vaXplZFN0YXRlLFxuICAgIGZpcnN0QmFzZVVwZGF0ZTogbnVsbCxcbiAgICBsYXN0QmFzZVVwZGF0ZTogbnVsbCxcbiAgICBzaGFyZWQ6IHtcbiAgICAgIHBlbmRpbmc6IG51bGwsXG4gICAgICBpbnRlcmxlYXZlZDogbnVsbCxcbiAgICAgIGxhbmVzOiBOb0xhbmVzXG4gICAgfSxcbiAgICBlZmZlY3RzOiBudWxsXG4gIH07XG4gIGZpYmVyLnVwZGF0ZVF1ZXVlID0gcXVldWU7XG59XG5mdW5jdGlvbiBjbG9uZVVwZGF0ZVF1ZXVlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIENsb25lIHRoZSB1cGRhdGUgcXVldWUgZnJvbSBjdXJyZW50LiBVbmxlc3MgaXQncyBhbHJlYWR5IGEgY2xvbmUuXG4gIHZhciBxdWV1ZSA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuICB2YXIgY3VycmVudFF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTtcblxuICBpZiAocXVldWUgPT09IGN1cnJlbnRRdWV1ZSkge1xuICAgIHZhciBjbG9uZSA9IHtcbiAgICAgIGJhc2VTdGF0ZTogY3VycmVudFF1ZXVlLmJhc2VTdGF0ZSxcbiAgICAgIGZpcnN0QmFzZVVwZGF0ZTogY3VycmVudFF1ZXVlLmZpcnN0QmFzZVVwZGF0ZSxcbiAgICAgIGxhc3RCYXNlVXBkYXRlOiBjdXJyZW50UXVldWUubGFzdEJhc2VVcGRhdGUsXG4gICAgICBzaGFyZWQ6IGN1cnJlbnRRdWV1ZS5zaGFyZWQsXG4gICAgICBlZmZlY3RzOiBjdXJyZW50UXVldWUuZWZmZWN0c1xuICAgIH07XG4gICAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBjbG9uZTtcbiAgfVxufVxuZnVuY3Rpb24gY3JlYXRlVXBkYXRlKGV2ZW50VGltZSwgbGFuZSkge1xuICB2YXIgdXBkYXRlID0ge1xuICAgIGV2ZW50VGltZTogZXZlbnRUaW1lLFxuICAgIGxhbmU6IGxhbmUsXG4gICAgdGFnOiBVcGRhdGVTdGF0ZSxcbiAgICBwYXlsb2FkOiBudWxsLFxuICAgIGNhbGxiYWNrOiBudWxsLFxuICAgIG5leHQ6IG51bGxcbiAgfTtcbiAgcmV0dXJuIHVwZGF0ZTtcbn1cbmZ1bmN0aW9uIGVucXVldWVVcGRhdGUoZmliZXIsIHVwZGF0ZSwgbGFuZSkge1xuICB2YXIgdXBkYXRlUXVldWUgPSBmaWJlci51cGRhdGVRdWV1ZTtcblxuICBpZiAodXBkYXRlUXVldWUgPT09IG51bGwpIHtcbiAgICAvLyBPbmx5IG9jY3VycyBpZiB0aGUgZmliZXIgaGFzIGJlZW4gdW5tb3VudGVkLlxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIHNoYXJlZFF1ZXVlID0gdXBkYXRlUXVldWUuc2hhcmVkO1xuXG4gIHtcbiAgICBpZiAoY3VycmVudGx5UHJvY2Vzc2luZ1F1ZXVlID09PSBzaGFyZWRRdWV1ZSAmJiAhZGlkV2FyblVwZGF0ZUluc2lkZVVwZGF0ZSkge1xuICAgICAgZXJyb3IoJ0FuIHVwZGF0ZSAoc2V0U3RhdGUsIHJlcGxhY2VTdGF0ZSwgb3IgZm9yY2VVcGRhdGUpIHdhcyBzY2hlZHVsZWQgJyArICdmcm9tIGluc2lkZSBhbiB1cGRhdGUgZnVuY3Rpb24uIFVwZGF0ZSBmdW5jdGlvbnMgc2hvdWxkIGJlIHB1cmUsICcgKyAnd2l0aCB6ZXJvIHNpZGUtZWZmZWN0cy4gQ29uc2lkZXIgdXNpbmcgY29tcG9uZW50RGlkVXBkYXRlIG9yIGEgJyArICdjYWxsYmFjay4nKTtcblxuICAgICAgZGlkV2FyblVwZGF0ZUluc2lkZVVwZGF0ZSA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzVW5zYWZlQ2xhc3NSZW5kZXJQaGFzZVVwZGF0ZSgpKSB7XG4gICAgLy8gVGhpcyBpcyBhbiB1bnNhZmUgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gQWRkIGRpcmVjdGx5IHRvIHRoZSB1cGRhdGVcbiAgICAvLyBxdWV1ZSBzbyB3ZSBjYW4gcHJvY2VzcyBpdCBpbW1lZGlhdGVseSBkdXJpbmcgdGhlIGN1cnJlbnQgcmVuZGVyLlxuICAgIHZhciBwZW5kaW5nID0gc2hhcmVkUXVldWUucGVuZGluZztcblxuICAgIGlmIChwZW5kaW5nID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgICB1cGRhdGUubmV4dCA9IHVwZGF0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlLm5leHQgPSBwZW5kaW5nLm5leHQ7XG4gICAgICBwZW5kaW5nLm5leHQgPSB1cGRhdGU7XG4gICAgfVxuXG4gICAgc2hhcmVkUXVldWUucGVuZGluZyA9IHVwZGF0ZTsgLy8gVXBkYXRlIHRoZSBjaGlsZExhbmVzIGV2ZW4gdGhvdWdoIHdlJ3JlIG1vc3QgbGlrZWx5IGFscmVhZHkgcmVuZGVyaW5nXG4gICAgLy8gdGhpcyBmaWJlci4gVGhpcyBpcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgaW4gdGhlIGNhc2Ugd2hlcmUgeW91XG4gICAgLy8gdXBkYXRlIGEgZGlmZmVyZW50IGNvbXBvbmVudCBkdXJpbmcgcmVuZGVyIHBoYXNlIHRoYW4gdGhlIG9uZSB0aGF0IGlzXG4gICAgLy8gY3VycmVudGx5IHJlbmRlcmluZ3MgKGEgcGF0dGVybiB0aGF0IGlzIGFjY29tcGFuaWVkIGJ5IGEgd2FybmluZykuXG5cbiAgICByZXR1cm4gdW5zYWZlX21hcmtVcGRhdGVMYW5lRnJvbUZpYmVyVG9Sb290KGZpYmVyLCBsYW5lKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZW5xdWV1ZUNvbmN1cnJlbnRDbGFzc1VwZGF0ZShmaWJlciwgc2hhcmVkUXVldWUsIHVwZGF0ZSwgbGFuZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVudGFuZ2xlVHJhbnNpdGlvbnMocm9vdCwgZmliZXIsIGxhbmUpIHtcbiAgdmFyIHVwZGF0ZVF1ZXVlID0gZmliZXIudXBkYXRlUXVldWU7XG5cbiAgaWYgKHVwZGF0ZVF1ZXVlID09PSBudWxsKSB7XG4gICAgLy8gT25seSBvY2N1cnMgaWYgdGhlIGZpYmVyIGhhcyBiZWVuIHVubW91bnRlZC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2hhcmVkUXVldWUgPSB1cGRhdGVRdWV1ZS5zaGFyZWQ7XG5cbiAgaWYgKGlzVHJhbnNpdGlvbkxhbmUobGFuZSkpIHtcbiAgICB2YXIgcXVldWVMYW5lcyA9IHNoYXJlZFF1ZXVlLmxhbmVzOyAvLyBJZiBhbnkgZW50YW5nbGVkIGxhbmVzIGFyZSBubyBsb25nZXIgcGVuZGluZyBvbiB0aGUgcm9vdCwgdGhlbiB0aGV5IG11c3RcbiAgICAvLyBoYXZlIGZpbmlzaGVkLiBXZSBjYW4gcmVtb3ZlIHRoZW0gZnJvbSB0aGUgc2hhcmVkIHF1ZXVlLCB3aGljaCByZXByZXNlbnRzXG4gICAgLy8gYSBzdXBlcnNldCBvZiB0aGUgYWN0dWFsbHkgcGVuZGluZyBsYW5lcy4gSW4gc29tZSBjYXNlcyB3ZSBtYXkgZW50YW5nbGVcbiAgICAvLyBtb3JlIHRoYW4gd2UgbmVlZCB0bywgYnV0IHRoYXQncyBPSy4gSW4gZmFjdCBpdCdzIHdvcnNlIGlmIHdlICpkb24ndCpcbiAgICAvLyBlbnRhbmdsZSB3aGVuIHdlIHNob3VsZC5cblxuICAgIHF1ZXVlTGFuZXMgPSBpbnRlcnNlY3RMYW5lcyhxdWV1ZUxhbmVzLCByb290LnBlbmRpbmdMYW5lcyk7IC8vIEVudGFuZ2xlIHRoZSBuZXcgdHJhbnNpdGlvbiBsYW5lIHdpdGggdGhlIG90aGVyIHRyYW5zaXRpb24gbGFuZXMuXG5cbiAgICB2YXIgbmV3UXVldWVMYW5lcyA9IG1lcmdlTGFuZXMocXVldWVMYW5lcywgbGFuZSk7XG4gICAgc2hhcmVkUXVldWUubGFuZXMgPSBuZXdRdWV1ZUxhbmVzOyAvLyBFdmVuIGlmIHF1ZXVlLmxhbmVzIGFscmVhZHkgaW5jbHVkZSBsYW5lLCB3ZSBkb24ndCBrbm93IGZvciBjZXJ0YWluIGlmXG4gICAgLy8gdGhlIGxhbmUgZmluaXNoZWQgc2luY2UgdGhlIGxhc3QgdGltZSB3ZSBlbnRhbmdsZWQgaXQuIFNvIHdlIG5lZWQgdG9cbiAgICAvLyBlbnRhbmdsZSBpdCBhZ2FpbiwganVzdCB0byBiZSBzdXJlLlxuXG4gICAgbWFya1Jvb3RFbnRhbmdsZWQocm9vdCwgbmV3UXVldWVMYW5lcyk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVucXVldWVDYXB0dXJlZFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgY2FwdHVyZWRVcGRhdGUpIHtcbiAgLy8gQ2FwdHVyZWQgdXBkYXRlcyBhcmUgdXBkYXRlcyB0aGF0IGFyZSB0aHJvd24gYnkgYSBjaGlsZCBkdXJpbmcgdGhlIHJlbmRlclxuICAvLyBwaGFzZS4gVGhleSBzaG91bGQgYmUgZGlzY2FyZGVkIGlmIHRoZSByZW5kZXIgaXMgYWJvcnRlZC4gVGhlcmVmb3JlLFxuICAvLyB3ZSBzaG91bGQgb25seSBwdXQgdGhlbSBvbiB0aGUgd29yay1pbi1wcm9ncmVzcyBxdWV1ZSwgbm90IHRoZSBjdXJyZW50IG9uZS5cbiAgdmFyIHF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7IC8vIENoZWNrIGlmIHRoZSB3b3JrLWluLXByb2dyZXNzIHF1ZXVlIGlzIGEgY2xvbmUuXG5cbiAgdmFyIGN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGU7XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICB2YXIgY3VycmVudFF1ZXVlID0gY3VycmVudC51cGRhdGVRdWV1ZTtcblxuICAgIGlmIChxdWV1ZSA9PT0gY3VycmVudFF1ZXVlKSB7XG4gICAgICAvLyBUaGUgd29yay1pbi1wcm9ncmVzcyBxdWV1ZSBpcyB0aGUgc2FtZSBhcyBjdXJyZW50LiBUaGlzIGhhcHBlbnMgd2hlblxuICAgICAgLy8gd2UgYmFpbCBvdXQgb24gYSBwYXJlbnQgZmliZXIgdGhhdCB0aGVuIGNhcHR1cmVzIGFuIGVycm9yIHRocm93biBieVxuICAgICAgLy8gYSBjaGlsZC4gU2luY2Ugd2Ugd2FudCB0byBhcHBlbmQgdGhlIHVwZGF0ZSBvbmx5IHRvIHRoZSB3b3JrLWluXG4gICAgICAvLyAtcHJvZ3Jlc3MgcXVldWUsIHdlIG5lZWQgdG8gY2xvbmUgdGhlIHVwZGF0ZXMuIFdlIHVzdWFsbHkgY2xvbmUgZHVyaW5nXG4gICAgICAvLyBwcm9jZXNzVXBkYXRlUXVldWUsIGJ1dCB0aGF0IGRpZG4ndCBoYXBwZW4gaW4gdGhpcyBjYXNlIGJlY2F1c2Ugd2VcbiAgICAgIC8vIHNraXBwZWQgb3ZlciB0aGUgcGFyZW50IHdoZW4gd2UgYmFpbGVkIG91dC5cbiAgICAgIHZhciBuZXdGaXJzdCA9IG51bGw7XG4gICAgICB2YXIgbmV3TGFzdCA9IG51bGw7XG4gICAgICB2YXIgZmlyc3RCYXNlVXBkYXRlID0gcXVldWUuZmlyc3RCYXNlVXBkYXRlO1xuXG4gICAgICBpZiAoZmlyc3RCYXNlVXBkYXRlICE9PSBudWxsKSB7XG4gICAgICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgdXBkYXRlcyBhbmQgY2xvbmUgdGhlbS5cbiAgICAgICAgdmFyIHVwZGF0ZSA9IGZpcnN0QmFzZVVwZGF0ZTtcblxuICAgICAgICBkbyB7XG4gICAgICAgICAgdmFyIGNsb25lID0ge1xuICAgICAgICAgICAgZXZlbnRUaW1lOiB1cGRhdGUuZXZlbnRUaW1lLFxuICAgICAgICAgICAgbGFuZTogdXBkYXRlLmxhbmUsXG4gICAgICAgICAgICB0YWc6IHVwZGF0ZS50YWcsXG4gICAgICAgICAgICBwYXlsb2FkOiB1cGRhdGUucGF5bG9hZCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB1cGRhdGUuY2FsbGJhY2ssXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmIChuZXdMYXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgICBuZXdGaXJzdCA9IG5ld0xhc3QgPSBjbG9uZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3TGFzdC5uZXh0ID0gY2xvbmU7XG4gICAgICAgICAgICBuZXdMYXN0ID0gY2xvbmU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdXBkYXRlID0gdXBkYXRlLm5leHQ7XG4gICAgICAgIH0gd2hpbGUgKHVwZGF0ZSAhPT0gbnVsbCk7IC8vIEFwcGVuZCB0aGUgY2FwdHVyZWQgdXBkYXRlIHRoZSBlbmQgb2YgdGhlIGNsb25lZCBsaXN0LlxuXG5cbiAgICAgICAgaWYgKG5ld0xhc3QgPT09IG51bGwpIHtcbiAgICAgICAgICBuZXdGaXJzdCA9IG5ld0xhc3QgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdMYXN0Lm5leHQgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgICAgICAgICBuZXdMYXN0ID0gY2FwdHVyZWRVcGRhdGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoZXJlIGFyZSBubyBiYXNlIHVwZGF0ZXMuXG4gICAgICAgIG5ld0ZpcnN0ID0gbmV3TGFzdCA9IGNhcHR1cmVkVXBkYXRlO1xuICAgICAgfVxuXG4gICAgICBxdWV1ZSA9IHtcbiAgICAgICAgYmFzZVN0YXRlOiBjdXJyZW50UXVldWUuYmFzZVN0YXRlLFxuICAgICAgICBmaXJzdEJhc2VVcGRhdGU6IG5ld0ZpcnN0LFxuICAgICAgICBsYXN0QmFzZVVwZGF0ZTogbmV3TGFzdCxcbiAgICAgICAgc2hhcmVkOiBjdXJyZW50UXVldWUuc2hhcmVkLFxuICAgICAgICBlZmZlY3RzOiBjdXJyZW50UXVldWUuZWZmZWN0c1xuICAgICAgfTtcbiAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gcXVldWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9IC8vIEFwcGVuZCB0aGUgdXBkYXRlIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuXG5cblxuICB2YXIgbGFzdEJhc2VVcGRhdGUgPSBxdWV1ZS5sYXN0QmFzZVVwZGF0ZTtcblxuICBpZiAobGFzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICBxdWV1ZS5maXJzdEJhc2VVcGRhdGUgPSBjYXB0dXJlZFVwZGF0ZTtcbiAgfSBlbHNlIHtcbiAgICBsYXN0QmFzZVVwZGF0ZS5uZXh0ID0gY2FwdHVyZWRVcGRhdGU7XG4gIH1cblxuICBxdWV1ZS5sYXN0QmFzZVVwZGF0ZSA9IGNhcHR1cmVkVXBkYXRlO1xufVxuXG5mdW5jdGlvbiBnZXRTdGF0ZUZyb21VcGRhdGUod29ya0luUHJvZ3Jlc3MsIHF1ZXVlLCB1cGRhdGUsIHByZXZTdGF0ZSwgbmV4dFByb3BzLCBpbnN0YW5jZSkge1xuICBzd2l0Y2ggKHVwZGF0ZS50YWcpIHtcbiAgICBjYXNlIFJlcGxhY2VTdGF0ZTpcbiAgICAgIHtcbiAgICAgICAgdmFyIHBheWxvYWQgPSB1cGRhdGUucGF5bG9hZDtcblxuICAgICAgICBpZiAodHlwZW9mIHBheWxvYWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAvLyBVcGRhdGVyIGZ1bmN0aW9uXG4gICAgICAgICAge1xuICAgICAgICAgICAgZW50ZXJEaXNhbGxvd2VkQ29udGV4dFJlYWRJbkRFVigpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBuZXh0U3RhdGUgPSBwYXlsb2FkLmNhbGwoaW5zdGFuY2UsIHByZXZTdGF0ZSwgbmV4dFByb3BzKTtcblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHModHJ1ZSk7XG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmNhbGwoaW5zdGFuY2UsIHByZXZTdGF0ZSwgbmV4dFByb3BzKTtcbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyhmYWxzZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZXhpdERpc2FsbG93ZWRDb250ZXh0UmVhZEluREVWKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG5leHRTdGF0ZTtcbiAgICAgICAgfSAvLyBTdGF0ZSBvYmplY3RcblxuXG4gICAgICAgIHJldHVybiBwYXlsb2FkO1xuICAgICAgfVxuXG4gICAgY2FzZSBDYXB0dXJlVXBkYXRlOlxuICAgICAge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyA9IHdvcmtJblByb2dyZXNzLmZsYWdzICYgflNob3VsZENhcHR1cmUgfCBEaWRDYXB0dXJlO1xuICAgICAgfVxuICAgIC8vIEludGVudGlvbmFsIGZhbGx0aHJvdWdoXG5cbiAgICBjYXNlIFVwZGF0ZVN0YXRlOlxuICAgICAge1xuICAgICAgICB2YXIgX3BheWxvYWQgPSB1cGRhdGUucGF5bG9hZDtcbiAgICAgICAgdmFyIHBhcnRpYWxTdGF0ZTtcblxuICAgICAgICBpZiAodHlwZW9mIF9wYXlsb2FkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgLy8gVXBkYXRlciBmdW5jdGlvblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVudGVyRGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwYXJ0aWFsU3RhdGUgPSBfcGF5bG9hZC5jYWxsKGluc3RhbmNlLCBwcmV2U3RhdGUsIG5leHRQcm9wcyk7XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgX3BheWxvYWQuY2FsbChpbnN0YW5jZSwgcHJldlN0YXRlLCBuZXh0UHJvcHMpO1xuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBleGl0RGlzYWxsb3dlZENvbnRleHRSZWFkSW5ERVYoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUGFydGlhbCBzdGF0ZSBvYmplY3RcbiAgICAgICAgICBwYXJ0aWFsU3RhdGUgPSBfcGF5bG9hZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwYXJ0aWFsU3RhdGUgPT09IG51bGwgfHwgcGFydGlhbFN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBOdWxsIGFuZCB1bmRlZmluZWQgYXJlIHRyZWF0ZWQgYXMgbm8tb3BzLlxuICAgICAgICAgIHJldHVybiBwcmV2U3RhdGU7XG4gICAgICAgIH0gLy8gTWVyZ2UgdGhlIHBhcnRpYWwgc3RhdGUgYW5kIHRoZSBwcmV2aW91cyBzdGF0ZS5cblxuXG4gICAgICAgIHJldHVybiBhc3NpZ24oe30sIHByZXZTdGF0ZSwgcGFydGlhbFN0YXRlKTtcbiAgICAgIH1cblxuICAgIGNhc2UgRm9yY2VVcGRhdGU6XG4gICAgICB7XG4gICAgICAgIGhhc0ZvcmNlVXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHByZXZTdGF0ZTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBwcmV2U3RhdGU7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NVcGRhdGVRdWV1ZSh3b3JrSW5Qcm9ncmVzcywgcHJvcHMsIGluc3RhbmNlLCByZW5kZXJMYW5lcykge1xuICAvLyBUaGlzIGlzIGFsd2F5cyBub24tbnVsbCBvbiBhIENsYXNzQ29tcG9uZW50IG9yIEhvc3RSb290XG4gIHZhciBxdWV1ZSA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuICBoYXNGb3JjZVVwZGF0ZSA9IGZhbHNlO1xuXG4gIHtcbiAgICBjdXJyZW50bHlQcm9jZXNzaW5nUXVldWUgPSBxdWV1ZS5zaGFyZWQ7XG4gIH1cblxuICB2YXIgZmlyc3RCYXNlVXBkYXRlID0gcXVldWUuZmlyc3RCYXNlVXBkYXRlO1xuICB2YXIgbGFzdEJhc2VVcGRhdGUgPSBxdWV1ZS5sYXN0QmFzZVVwZGF0ZTsgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIHBlbmRpbmcgdXBkYXRlcy4gSWYgc28sIHRyYW5zZmVyIHRoZW0gdG8gdGhlIGJhc2UgcXVldWUuXG5cbiAgdmFyIHBlbmRpbmdRdWV1ZSA9IHF1ZXVlLnNoYXJlZC5wZW5kaW5nO1xuXG4gIGlmIChwZW5kaW5nUXVldWUgIT09IG51bGwpIHtcbiAgICBxdWV1ZS5zaGFyZWQucGVuZGluZyA9IG51bGw7IC8vIFRoZSBwZW5kaW5nIHF1ZXVlIGlzIGNpcmN1bGFyLiBEaXNjb25uZWN0IHRoZSBwb2ludGVyIGJldHdlZW4gZmlyc3RcbiAgICAvLyBhbmQgbGFzdCBzbyB0aGF0IGl0J3Mgbm9uLWNpcmN1bGFyLlxuXG4gICAgdmFyIGxhc3RQZW5kaW5nVXBkYXRlID0gcGVuZGluZ1F1ZXVlO1xuICAgIHZhciBmaXJzdFBlbmRpbmdVcGRhdGUgPSBsYXN0UGVuZGluZ1VwZGF0ZS5uZXh0O1xuICAgIGxhc3RQZW5kaW5nVXBkYXRlLm5leHQgPSBudWxsOyAvLyBBcHBlbmQgcGVuZGluZyB1cGRhdGVzIHRvIGJhc2UgcXVldWVcblxuICAgIGlmIChsYXN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgZmlyc3RCYXNlVXBkYXRlID0gZmlyc3RQZW5kaW5nVXBkYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0QmFzZVVwZGF0ZS5uZXh0ID0gZmlyc3RQZW5kaW5nVXBkYXRlO1xuICAgIH1cblxuICAgIGxhc3RCYXNlVXBkYXRlID0gbGFzdFBlbmRpbmdVcGRhdGU7IC8vIElmIHRoZXJlJ3MgYSBjdXJyZW50IHF1ZXVlLCBhbmQgaXQncyBkaWZmZXJlbnQgZnJvbSB0aGUgYmFzZSBxdWV1ZSwgdGhlblxuICAgIC8vIHdlIG5lZWQgdG8gdHJhbnNmZXIgdGhlIHVwZGF0ZXMgdG8gdGhhdCBxdWV1ZSwgdG9vLiBCZWNhdXNlIHRoZSBiYXNlXG4gICAgLy8gcXVldWUgaXMgYSBzaW5nbHktbGlua2VkIGxpc3Qgd2l0aCBubyBjeWNsZXMsIHdlIGNhbiBhcHBlbmQgdG8gYm90aFxuICAgIC8vIGxpc3RzIGFuZCB0YWtlIGFkdmFudGFnZSBvZiBzdHJ1Y3R1cmFsIHNoYXJpbmcuXG4gICAgLy8gVE9ETzogUGFzcyBgY3VycmVudGAgYXMgYXJndW1lbnRcblxuICAgIHZhciBjdXJyZW50ID0gd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaXMgYWx3YXlzIG5vbi1udWxsIG9uIGEgQ2xhc3NDb21wb25lbnQgb3IgSG9zdFJvb3RcbiAgICAgIHZhciBjdXJyZW50UXVldWUgPSBjdXJyZW50LnVwZGF0ZVF1ZXVlO1xuICAgICAgdmFyIGN1cnJlbnRMYXN0QmFzZVVwZGF0ZSA9IGN1cnJlbnRRdWV1ZS5sYXN0QmFzZVVwZGF0ZTtcblxuICAgICAgaWYgKGN1cnJlbnRMYXN0QmFzZVVwZGF0ZSAhPT0gbGFzdEJhc2VVcGRhdGUpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRMYXN0QmFzZVVwZGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIGN1cnJlbnRRdWV1ZS5maXJzdEJhc2VVcGRhdGUgPSBmaXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudExhc3RCYXNlVXBkYXRlLm5leHQgPSBmaXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50UXVldWUubGFzdEJhc2VVcGRhdGUgPSBsYXN0UGVuZGluZ1VwZGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gVGhlc2UgdmFsdWVzIG1heSBjaGFuZ2UgYXMgd2UgcHJvY2VzcyB0aGUgcXVldWUuXG5cblxuICBpZiAoZmlyc3RCYXNlVXBkYXRlICE9PSBudWxsKSB7XG4gICAgLy8gSXRlcmF0ZSB0aHJvdWdoIHRoZSBsaXN0IG9mIHVwZGF0ZXMgdG8gY29tcHV0ZSB0aGUgcmVzdWx0LlxuICAgIHZhciBuZXdTdGF0ZSA9IHF1ZXVlLmJhc2VTdGF0ZTsgLy8gVE9ETzogRG9uJ3QgbmVlZCB0byBhY2N1bXVsYXRlIHRoaXMuIEluc3RlYWQsIHdlIGNhbiByZW1vdmUgcmVuZGVyTGFuZXNcbiAgICAvLyBmcm9tIHRoZSBvcmlnaW5hbCBsYW5lcy5cblxuICAgIHZhciBuZXdMYW5lcyA9IE5vTGFuZXM7XG4gICAgdmFyIG5ld0Jhc2VTdGF0ZSA9IG51bGw7XG4gICAgdmFyIG5ld0ZpcnN0QmFzZVVwZGF0ZSA9IG51bGw7XG4gICAgdmFyIG5ld0xhc3RCYXNlVXBkYXRlID0gbnVsbDtcbiAgICB2YXIgdXBkYXRlID0gZmlyc3RCYXNlVXBkYXRlO1xuXG4gICAgZG8ge1xuICAgICAgdmFyIHVwZGF0ZUxhbmUgPSB1cGRhdGUubGFuZTtcbiAgICAgIHZhciB1cGRhdGVFdmVudFRpbWUgPSB1cGRhdGUuZXZlbnRUaW1lO1xuXG4gICAgICBpZiAoIWlzU3Vic2V0T2ZMYW5lcyhyZW5kZXJMYW5lcywgdXBkYXRlTGFuZSkpIHtcbiAgICAgICAgLy8gUHJpb3JpdHkgaXMgaW5zdWZmaWNpZW50LiBTa2lwIHRoaXMgdXBkYXRlLiBJZiB0aGlzIGlzIHRoZSBmaXJzdFxuICAgICAgICAvLyBza2lwcGVkIHVwZGF0ZSwgdGhlIHByZXZpb3VzIHVwZGF0ZS9zdGF0ZSBpcyB0aGUgbmV3IGJhc2VcbiAgICAgICAgLy8gdXBkYXRlL3N0YXRlLlxuICAgICAgICB2YXIgY2xvbmUgPSB7XG4gICAgICAgICAgZXZlbnRUaW1lOiB1cGRhdGVFdmVudFRpbWUsXG4gICAgICAgICAgbGFuZTogdXBkYXRlTGFuZSxcbiAgICAgICAgICB0YWc6IHVwZGF0ZS50YWcsXG4gICAgICAgICAgcGF5bG9hZDogdXBkYXRlLnBheWxvYWQsXG4gICAgICAgICAgY2FsbGJhY2s6IHVwZGF0ZS5jYWxsYmFjayxcbiAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG5ld0xhc3RCYXNlVXBkYXRlID09PSBudWxsKSB7XG4gICAgICAgICAgbmV3Rmlyc3RCYXNlVXBkYXRlID0gbmV3TGFzdEJhc2VVcGRhdGUgPSBjbG9uZTtcbiAgICAgICAgICBuZXdCYXNlU3RhdGUgPSBuZXdTdGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdMYXN0QmFzZVVwZGF0ZSA9IG5ld0xhc3RCYXNlVXBkYXRlLm5leHQgPSBjbG9uZTtcbiAgICAgICAgfSAvLyBVcGRhdGUgdGhlIHJlbWFpbmluZyBwcmlvcml0eSBpbiB0aGUgcXVldWUuXG5cblxuICAgICAgICBuZXdMYW5lcyA9IG1lcmdlTGFuZXMobmV3TGFuZXMsIHVwZGF0ZUxhbmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyB1cGRhdGUgZG9lcyBoYXZlIHN1ZmZpY2llbnQgcHJpb3JpdHkuXG4gICAgICAgIGlmIChuZXdMYXN0QmFzZVVwZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBfY2xvbmUgPSB7XG4gICAgICAgICAgICBldmVudFRpbWU6IHVwZGF0ZUV2ZW50VGltZSxcbiAgICAgICAgICAgIC8vIFRoaXMgdXBkYXRlIGlzIGdvaW5nIHRvIGJlIGNvbW1pdHRlZCBzbyB3ZSBuZXZlciB3YW50IHVuY29tbWl0XG4gICAgICAgICAgICAvLyBpdC4gVXNpbmcgTm9MYW5lIHdvcmtzIGJlY2F1c2UgMCBpcyBhIHN1YnNldCBvZiBhbGwgYml0bWFza3MsIHNvXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgbmV2ZXIgYmUgc2tpcHBlZCBieSB0aGUgY2hlY2sgYWJvdmUuXG4gICAgICAgICAgICBsYW5lOiBOb0xhbmUsXG4gICAgICAgICAgICB0YWc6IHVwZGF0ZS50YWcsXG4gICAgICAgICAgICBwYXlsb2FkOiB1cGRhdGUucGF5bG9hZCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB1cGRhdGUuY2FsbGJhY2ssXG4gICAgICAgICAgICBuZXh0OiBudWxsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBuZXdMYXN0QmFzZVVwZGF0ZSA9IG5ld0xhc3RCYXNlVXBkYXRlLm5leHQgPSBfY2xvbmU7XG4gICAgICAgIH0gLy8gUHJvY2VzcyB0aGlzIHVwZGF0ZS5cblxuXG4gICAgICAgIG5ld1N0YXRlID0gZ2V0U3RhdGVGcm9tVXBkYXRlKHdvcmtJblByb2dyZXNzLCBxdWV1ZSwgdXBkYXRlLCBuZXdTdGF0ZSwgcHJvcHMsIGluc3RhbmNlKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gdXBkYXRlLmNhbGxiYWNrO1xuXG4gICAgICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCAmJiAvLyBJZiB0aGUgdXBkYXRlIHdhcyBhbHJlYWR5IGNvbW1pdHRlZCwgd2Ugc2hvdWxkIG5vdCBxdWV1ZSBpdHNcbiAgICAgICAgLy8gY2FsbGJhY2sgYWdhaW4uXG4gICAgICAgIHVwZGF0ZS5sYW5lICE9PSBOb0xhbmUpIHtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBDYWxsYmFjaztcbiAgICAgICAgICB2YXIgZWZmZWN0cyA9IHF1ZXVlLmVmZmVjdHM7XG5cbiAgICAgICAgICBpZiAoZWZmZWN0cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcXVldWUuZWZmZWN0cyA9IFt1cGRhdGVdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlZmZlY3RzLnB1c2godXBkYXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdXBkYXRlID0gdXBkYXRlLm5leHQ7XG5cbiAgICAgIGlmICh1cGRhdGUgPT09IG51bGwpIHtcbiAgICAgICAgcGVuZGluZ1F1ZXVlID0gcXVldWUuc2hhcmVkLnBlbmRpbmc7XG5cbiAgICAgICAgaWYgKHBlbmRpbmdRdWV1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEFuIHVwZGF0ZSB3YXMgc2NoZWR1bGVkIGZyb20gaW5zaWRlIGEgcmVkdWNlci4gQWRkIHRoZSBuZXdcbiAgICAgICAgICAvLyBwZW5kaW5nIHVwZGF0ZXMgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBhbmQga2VlcCBwcm9jZXNzaW5nLlxuICAgICAgICAgIHZhciBfbGFzdFBlbmRpbmdVcGRhdGUgPSBwZW5kaW5nUXVldWU7IC8vIEludGVudGlvbmFsbHkgdW5zb3VuZC4gUGVuZGluZyB1cGRhdGVzIGZvcm0gYSBjaXJjdWxhciBsaXN0LCBidXQgd2VcbiAgICAgICAgICAvLyB1bnJhdmVsIHRoZW0gd2hlbiB0cmFuc2ZlcnJpbmcgdGhlbSB0byB0aGUgYmFzZSBxdWV1ZS5cblxuICAgICAgICAgIHZhciBfZmlyc3RQZW5kaW5nVXBkYXRlID0gX2xhc3RQZW5kaW5nVXBkYXRlLm5leHQ7XG4gICAgICAgICAgX2xhc3RQZW5kaW5nVXBkYXRlLm5leHQgPSBudWxsO1xuICAgICAgICAgIHVwZGF0ZSA9IF9maXJzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgICAgcXVldWUubGFzdEJhc2VVcGRhdGUgPSBfbGFzdFBlbmRpbmdVcGRhdGU7XG4gICAgICAgICAgcXVldWUuc2hhcmVkLnBlbmRpbmcgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAodHJ1ZSk7XG5cbiAgICBpZiAobmV3TGFzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICAgIG5ld0Jhc2VTdGF0ZSA9IG5ld1N0YXRlO1xuICAgIH1cblxuICAgIHF1ZXVlLmJhc2VTdGF0ZSA9IG5ld0Jhc2VTdGF0ZTtcbiAgICBxdWV1ZS5maXJzdEJhc2VVcGRhdGUgPSBuZXdGaXJzdEJhc2VVcGRhdGU7XG4gICAgcXVldWUubGFzdEJhc2VVcGRhdGUgPSBuZXdMYXN0QmFzZVVwZGF0ZTsgLy8gSW50ZXJsZWF2ZWQgdXBkYXRlcyBhcmUgc3RvcmVkIG9uIGEgc2VwYXJhdGUgcXVldWUuIFdlIGFyZW4ndCBnb2luZyB0b1xuICAgIC8vIHByb2Nlc3MgdGhlbSBkdXJpbmcgdGhpcyByZW5kZXIsIGJ1dCB3ZSBkbyBuZWVkIHRvIHRyYWNrIHdoaWNoIGxhbmVzXG4gICAgLy8gYXJlIHJlbWFpbmluZy5cblxuICAgIHZhciBsYXN0SW50ZXJsZWF2ZWQgPSBxdWV1ZS5zaGFyZWQuaW50ZXJsZWF2ZWQ7XG5cbiAgICBpZiAobGFzdEludGVybGVhdmVkICE9PSBudWxsKSB7XG4gICAgICB2YXIgaW50ZXJsZWF2ZWQgPSBsYXN0SW50ZXJsZWF2ZWQ7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgbmV3TGFuZXMgPSBtZXJnZUxhbmVzKG5ld0xhbmVzLCBpbnRlcmxlYXZlZC5sYW5lKTtcbiAgICAgICAgaW50ZXJsZWF2ZWQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgICAgfSB3aGlsZSAoaW50ZXJsZWF2ZWQgIT09IGxhc3RJbnRlcmxlYXZlZCk7XG4gICAgfSBlbHNlIGlmIChmaXJzdEJhc2VVcGRhdGUgPT09IG51bGwpIHtcbiAgICAgIC8vIGBxdWV1ZS5sYW5lc2AgaXMgdXNlZCBmb3IgZW50YW5nbGluZyB0cmFuc2l0aW9ucy4gV2UgY2FuIHNldCBpdCBiYWNrIHRvXG4gICAgICAvLyB6ZXJvIG9uY2UgdGhlIHF1ZXVlIGlzIGVtcHR5LlxuICAgICAgcXVldWUuc2hhcmVkLmxhbmVzID0gTm9MYW5lcztcbiAgICB9IC8vIFNldCB0aGUgcmVtYWluaW5nIGV4cGlyYXRpb24gdGltZSB0byBiZSB3aGF0ZXZlciBpcyByZW1haW5pbmcgaW4gdGhlIHF1ZXVlLlxuICAgIC8vIFRoaXMgc2hvdWxkIGJlIGZpbmUgYmVjYXVzZSB0aGUgb25seSB0d28gb3RoZXIgdGhpbmdzIHRoYXQgY29udHJpYnV0ZSB0b1xuICAgIC8vIGV4cGlyYXRpb24gdGltZSBhcmUgcHJvcHMgYW5kIGNvbnRleHQuIFdlJ3JlIGFscmVhZHkgaW4gdGhlIG1pZGRsZSBvZiB0aGVcbiAgICAvLyBiZWdpbiBwaGFzZSBieSB0aGUgdGltZSB3ZSBzdGFydCBwcm9jZXNzaW5nIHRoZSBxdWV1ZSwgc28gd2UndmUgYWxyZWFkeVxuICAgIC8vIGRlYWx0IHdpdGggdGhlIHByb3BzLiBDb250ZXh0IGluIGNvbXBvbmVudHMgdGhhdCBzcGVjaWZ5XG4gICAgLy8gc2hvdWxkQ29tcG9uZW50VXBkYXRlIGlzIHRyaWNreTsgYnV0IHdlJ2xsIGhhdmUgdG8gYWNjb3VudCBmb3JcbiAgICAvLyB0aGF0IHJlZ2FyZGxlc3MuXG5cblxuICAgIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMobmV3TGFuZXMpO1xuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbmV3TGFuZXM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9XG5cbiAge1xuICAgIGN1cnJlbnRseVByb2Nlc3NpbmdRdWV1ZSA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2FsbENhbGxiYWNrKGNhbGxiYWNrLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXJndW1lbnQgcGFzc2VkIGFzIGNhbGxiYWNrLiBFeHBlY3RlZCBhIGZ1bmN0aW9uLiBJbnN0ZWFkICcgKyAoXCJyZWNlaXZlZDogXCIgKyBjYWxsYmFjaykpO1xuICB9XG5cbiAgY2FsbGJhY2suY2FsbChjb250ZXh0KTtcbn1cblxuZnVuY3Rpb24gcmVzZXRIYXNGb3JjZVVwZGF0ZUJlZm9yZVByb2Nlc3NpbmcoKSB7XG4gIGhhc0ZvcmNlVXBkYXRlID0gZmFsc2U7XG59XG5mdW5jdGlvbiBjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkge1xuICByZXR1cm4gaGFzRm9yY2VVcGRhdGU7XG59XG5mdW5jdGlvbiBjb21taXRVcGRhdGVRdWV1ZShmaW5pc2hlZFdvcmssIGZpbmlzaGVkUXVldWUsIGluc3RhbmNlKSB7XG4gIC8vIENvbW1pdCB0aGUgZWZmZWN0c1xuICB2YXIgZWZmZWN0cyA9IGZpbmlzaGVkUXVldWUuZWZmZWN0cztcbiAgZmluaXNoZWRRdWV1ZS5lZmZlY3RzID0gbnVsbDtcblxuICBpZiAoZWZmZWN0cyAhPT0gbnVsbCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWZmZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGVmZmVjdCA9IGVmZmVjdHNbaV07XG4gICAgICB2YXIgY2FsbGJhY2sgPSBlZmZlY3QuY2FsbGJhY2s7XG5cbiAgICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCkge1xuICAgICAgICBlZmZlY3QuY2FsbGJhY2sgPSBudWxsO1xuICAgICAgICBjYWxsQ2FsbGJhY2soY2FsbGJhY2ssIGluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIGZha2VJbnRlcm5hbEluc3RhbmNlID0ge307IC8vIFJlYWN0LkNvbXBvbmVudCB1c2VzIGEgc2hhcmVkIGZyb3plbiBvYmplY3QgYnkgZGVmYXVsdC5cbi8vIFdlJ2xsIHVzZSBpdCB0byBkZXRlcm1pbmUgd2hldGhlciB3ZSBuZWVkIHRvIGluaXRpYWxpemUgbGVnYWN5IHJlZnMuXG5cbnZhciBlbXB0eVJlZnNPYmplY3QgPSBuZXcgUmVhY3QuQ29tcG9uZW50KCkucmVmcztcbnZhciBkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQ7XG52YXIgZGlkV2FybkFib3V0VW5pbml0aWFsaXplZFN0YXRlO1xudmFyIGRpZFdhcm5BYm91dEdldFNuYXBzaG90QmVmb3JlVXBkYXRlV2l0aG91dERpZFVwZGF0ZTtcbnZhciBkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlO1xudmFyIGRpZFdhcm5BYm91dFVuZGVmaW5lZERlcml2ZWRTdGF0ZTtcbnZhciB3YXJuT25VbmRlZmluZWREZXJpdmVkU3RhdGU7XG52YXIgd2Fybk9uSW52YWxpZENhbGxiYWNrO1xudmFyIGRpZFdhcm5BYm91dERpcmVjdGx5QXNzaWduaW5nUHJvcHNUb1N0YXRlO1xudmFyIGRpZFdhcm5BYm91dENvbnRleHRUeXBlQW5kQ29udGV4dFR5cGVzO1xudmFyIGRpZFdhcm5BYm91dEludmFsaWRhdGVDb250ZXh0VHlwZTtcblxue1xuICBkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQgPSBuZXcgU2V0KCk7XG4gIGRpZFdhcm5BYm91dFVuaW5pdGlhbGl6ZWRTdGF0ZSA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0R2V0U25hcHNob3RCZWZvcmVVcGRhdGVXaXRob3V0RGlkVXBkYXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXREaXJlY3RseUFzc2lnbmluZ1Byb3BzVG9TdGF0ZSA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0VW5kZWZpbmVkRGVyaXZlZFN0YXRlID0gbmV3IFNldCgpO1xuICBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZUFuZENvbnRleHRUeXBlcyA9IG5ldyBTZXQoKTtcbiAgZGlkV2FybkFib3V0SW52YWxpZGF0ZUNvbnRleHRUeXBlID0gbmV3IFNldCgpO1xuICB2YXIgZGlkV2Fybk9uSW52YWxpZENhbGxiYWNrID0gbmV3IFNldCgpO1xuXG4gIHdhcm5PbkludmFsaWRDYWxsYmFjayA9IGZ1bmN0aW9uIChjYWxsYmFjaywgY2FsbGVyTmFtZSkge1xuICAgIGlmIChjYWxsYmFjayA9PT0gbnVsbCB8fCB0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIga2V5ID0gY2FsbGVyTmFtZSArICdfJyArIGNhbGxiYWNrO1xuXG4gICAgaWYgKCFkaWRXYXJuT25JbnZhbGlkQ2FsbGJhY2suaGFzKGtleSkpIHtcbiAgICAgIGRpZFdhcm5PbkludmFsaWRDYWxsYmFjay5hZGQoa2V5KTtcblxuICAgICAgZXJyb3IoJyVzKC4uLik6IEV4cGVjdGVkIHRoZSBsYXN0IG9wdGlvbmFsIGBjYWxsYmFja2AgYXJndW1lbnQgdG8gYmUgYSAnICsgJ2Z1bmN0aW9uLiBJbnN0ZWFkIHJlY2VpdmVkOiAlcy4nLCBjYWxsZXJOYW1lLCBjYWxsYmFjayk7XG4gICAgfVxuICB9O1xuXG4gIHdhcm5PblVuZGVmaW5lZERlcml2ZWRTdGF0ZSA9IGZ1bmN0aW9uICh0eXBlLCBwYXJ0aWFsU3RhdGUpIHtcbiAgICBpZiAocGFydGlhbFN0YXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKHR5cGUpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFVuZGVmaW5lZERlcml2ZWRTdGF0ZS5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgZGlkV2FybkFib3V0VW5kZWZpbmVkRGVyaXZlZFN0YXRlLmFkZChjb21wb25lbnROYW1lKTtcblxuICAgICAgICBlcnJvcignJXMuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKCk6IEEgdmFsaWQgc3RhdGUgb2JqZWN0IChvciBudWxsKSBtdXN0IGJlIHJldHVybmVkLiAnICsgJ1lvdSBoYXZlIHJldHVybmVkIHVuZGVmaW5lZC4nLCBjb21wb25lbnROYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH07IC8vIFRoaXMgaXMgc28gZ3Jvc3MgYnV0IGl0J3MgYXQgbGVhc3Qgbm9uLWNyaXRpY2FsIGFuZCBjYW4gYmUgcmVtb3ZlZCBpZlxuICAvLyBpdCBjYXVzZXMgcHJvYmxlbXMuIFRoaXMgaXMgbWVhbnQgdG8gZ2l2ZSBhIG5pY2VyIGVycm9yIG1lc3NhZ2UgZm9yXG4gIC8vIFJlYWN0RE9NMTUudW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocmVhY3RET00xNkNvbXBvbmVudCxcbiAgLy8gLi4uKSkgd2hpY2ggb3RoZXJ3aXNlIHRocm93cyBhIFwiX3Byb2Nlc3NDaGlsZENvbnRleHQgaXMgbm90IGEgZnVuY3Rpb25cIlxuICAvLyBleGNlcHRpb24uXG5cblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZmFrZUludGVybmFsSW5zdGFuY2UsICdfcHJvY2Vzc0NoaWxkQ29udGV4dCcsIHtcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdfcHJvY2Vzc0NoaWxkQ29udGV4dCBpcyBub3QgYXZhaWxhYmxlIGluIFJlYWN0IDE2Ky4gVGhpcyBsaWtlbHkgJyArICdtZWFucyB5b3UgaGF2ZSBtdWx0aXBsZSBjb3BpZXMgb2YgUmVhY3QgYW5kIGFyZSBhdHRlbXB0aW5nIHRvIG5lc3QgJyArICdhIFJlYWN0IDE1IHRyZWUgaW5zaWRlIGEgUmVhY3QgMTYgdHJlZSB1c2luZyAnICsgXCJ1bnN0YWJsZV9yZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lciwgd2hpY2ggaXNuJ3Qgc3VwcG9ydGVkLiBUcnkgXCIgKyAndG8gbWFrZSBzdXJlIHlvdSBoYXZlIG9ubHkgb25lIGNvcHkgb2YgUmVhY3QgKGFuZCBpZGVhbGx5LCBzd2l0Y2ggJyArICd0byBSZWFjdERPTS5jcmVhdGVQb3J0YWwpLicpO1xuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5mcmVlemUoZmFrZUludGVybmFsSW5zdGFuY2UpO1xufVxuXG5mdW5jdGlvbiBhcHBseURlcml2ZWRTdGF0ZUZyb21Qcm9wcyh3b3JrSW5Qcm9ncmVzcywgY3RvciwgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLCBuZXh0UHJvcHMpIHtcbiAgdmFyIHByZXZTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIHZhciBwYXJ0aWFsU3RhdGUgPSBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMobmV4dFByb3BzLCBwcmV2U3RhdGUpO1xuXG4gIHtcbiAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICBzZXRJc1N0cmljdE1vZGVGb3JEZXZ0b29scyh0cnVlKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gSW52b2tlIHRoZSBmdW5jdGlvbiBhbiBleHRyYSB0aW1lIHRvIGhlbHAgZGV0ZWN0IHNpZGUtZWZmZWN0cy5cbiAgICAgICAgcGFydGlhbFN0YXRlID0gZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKG5leHRQcm9wcywgcHJldlN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3YXJuT25VbmRlZmluZWREZXJpdmVkU3RhdGUoY3RvciwgcGFydGlhbFN0YXRlKTtcbiAgfSAvLyBNZXJnZSB0aGUgcGFydGlhbCBzdGF0ZSBhbmQgdGhlIHByZXZpb3VzIHN0YXRlLlxuXG5cbiAgdmFyIG1lbW9pemVkU3RhdGUgPSBwYXJ0aWFsU3RhdGUgPT09IG51bGwgfHwgcGFydGlhbFN0YXRlID09PSB1bmRlZmluZWQgPyBwcmV2U3RhdGUgOiBhc3NpZ24oe30sIHByZXZTdGF0ZSwgcGFydGlhbFN0YXRlKTtcbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG1lbW9pemVkU3RhdGU7IC8vIE9uY2UgdGhlIHVwZGF0ZSBxdWV1ZSBpcyBlbXB0eSwgcGVyc2lzdCB0aGUgZGVyaXZlZCBzdGF0ZSBvbnRvIHRoZVxuICAvLyBiYXNlIHN0YXRlLlxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9PT0gTm9MYW5lcykge1xuICAgIC8vIFF1ZXVlIGlzIGFsd2F5cyBub24tbnVsbCBmb3IgY2xhc3Nlc1xuICAgIHZhciB1cGRhdGVRdWV1ZSA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuICAgIHVwZGF0ZVF1ZXVlLmJhc2VTdGF0ZSA9IG1lbW9pemVkU3RhdGU7XG4gIH1cbn1cblxudmFyIGNsYXNzQ29tcG9uZW50VXBkYXRlciA9IHtcbiAgaXNNb3VudGVkOiBpc01vdW50ZWQsXG4gIGVucXVldWVTZXRTdGF0ZTogZnVuY3Rpb24gKGluc3QsIHBheWxvYWQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpYmVyID0gZ2V0KGluc3QpO1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICAgIHVwZGF0ZS5wYXlsb2FkID0gcGF5bG9hZDtcblxuICAgIGlmIChjYWxsYmFjayAhPT0gdW5kZWZpbmVkICYmIGNhbGxiYWNrICE9PSBudWxsKSB7XG4gICAgICB7XG4gICAgICAgIHdhcm5PbkludmFsaWRDYWxsYmFjayhjYWxsYmFjaywgJ3NldFN0YXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIHZhciByb290ID0gZW5xdWV1ZVVwZGF0ZShmaWJlciwgdXBkYXRlLCBsYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGZpYmVyLCBsYW5lKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfSxcbiAgZW5xdWV1ZVJlcGxhY2VTdGF0ZTogZnVuY3Rpb24gKGluc3QsIHBheWxvYWQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpYmVyID0gZ2V0KGluc3QpO1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShmaWJlcik7XG4gICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICAgIHVwZGF0ZS50YWcgPSBSZXBsYWNlU3RhdGU7XG4gICAgdXBkYXRlLnBheWxvYWQgPSBwYXlsb2FkO1xuXG4gICAgaWYgKGNhbGxiYWNrICE9PSB1bmRlZmluZWQgJiYgY2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgd2Fybk9uSW52YWxpZENhbGxiYWNrKGNhbGxiYWNrLCAncmVwbGFjZVN0YXRlJyk7XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZS5jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIH1cblxuICAgIHZhciByb290ID0gZW5xdWV1ZVVwZGF0ZShmaWJlciwgdXBkYXRlLCBsYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGZpYmVyLCBsYW5lKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrU3RhdGVVcGRhdGVTY2hlZHVsZWQoZmliZXIsIGxhbmUpO1xuICAgIH1cbiAgfSxcbiAgZW5xdWV1ZUZvcmNlVXBkYXRlOiBmdW5jdGlvbiAoaW5zdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgZmliZXIgPSBnZXQoaW5zdCk7XG4gICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgICB2YXIgdXBkYXRlID0gY3JlYXRlVXBkYXRlKGV2ZW50VGltZSwgbGFuZSk7XG4gICAgdXBkYXRlLnRhZyA9IEZvcmNlVXBkYXRlO1xuXG4gICAgaWYgKGNhbGxiYWNrICE9PSB1bmRlZmluZWQgJiYgY2FsbGJhY2sgIT09IG51bGwpIHtcbiAgICAgIHtcbiAgICAgICAgd2Fybk9uSW52YWxpZENhbGxiYWNrKGNhbGxiYWNrLCAnZm9yY2VVcGRhdGUnKTtcbiAgICAgIH1cblxuICAgICAgdXBkYXRlLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlVXBkYXRlKGZpYmVyLCB1cGRhdGUsIGxhbmUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgICAgIGVudGFuZ2xlVHJhbnNpdGlvbnMocm9vdCwgZmliZXIsIGxhbmUpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIG1hcmtGb3JjZVVwZGF0ZVNjaGVkdWxlZChmaWJlciwgbGFuZSk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBjaGVja1Nob3VsZENvbXBvbmVudFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgY3Rvciwgb2xkUHJvcHMsIG5ld1Byb3BzLCBvbGRTdGF0ZSwgbmV3U3RhdGUsIG5leHRDb250ZXh0KSB7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcblxuICBpZiAodHlwZW9mIGluc3RhbmNlLnNob3VsZENvbXBvbmVudFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHZhciBzaG91bGRVcGRhdGUgPSBpbnN0YW5jZS5zaG91bGRDb21wb25lbnRVcGRhdGUobmV3UHJvcHMsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG5cbiAgICB7XG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gSW52b2tlIHRoZSBmdW5jdGlvbiBhbiBleHRyYSB0aW1lIHRvIGhlbHAgZGV0ZWN0IHNpZGUtZWZmZWN0cy5cbiAgICAgICAgICBzaG91bGRVcGRhdGUgPSBpbnN0YW5jZS5zaG91bGRDb21wb25lbnRVcGRhdGUobmV3UHJvcHMsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzaG91bGRVcGRhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlcnJvcignJXMuc2hvdWxkQ29tcG9uZW50VXBkYXRlKCk6IFJldHVybmVkIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIGEgJyArICdib29sZWFuIHZhbHVlLiBNYWtlIHN1cmUgdG8gcmV0dXJuIHRydWUgb3IgZmFsc2UuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2hvdWxkVXBkYXRlO1xuICB9XG5cbiAgaWYgKGN0b3IucHJvdG90eXBlICYmIGN0b3IucHJvdG90eXBlLmlzUHVyZVJlYWN0Q29tcG9uZW50KSB7XG4gICAgcmV0dXJuICFzaGFsbG93RXF1YWwob2xkUHJvcHMsIG5ld1Byb3BzKSB8fCAhc2hhbGxvd0VxdWFsKG9sZFN0YXRlLCBuZXdTdGF0ZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY2hlY2tDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBuZXdQcm9wcykge1xuICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAge1xuICAgIHZhciBuYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnO1xuICAgIHZhciByZW5kZXJQcmVzZW50ID0gaW5zdGFuY2UucmVuZGVyO1xuXG4gICAgaWYgKCFyZW5kZXJQcmVzZW50KSB7XG4gICAgICBpZiAoY3Rvci5wcm90b3R5cGUgJiYgdHlwZW9mIGN0b3IucHJvdG90eXBlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlcnJvcignJXMoLi4uKTogTm8gYHJlbmRlcmAgbWV0aG9kIGZvdW5kIG9uIHRoZSByZXR1cm5lZCBjb21wb25lbnQgJyArICdpbnN0YW5jZTogZGlkIHlvdSBhY2NpZGVudGFsbHkgcmV0dXJuIGFuIG9iamVjdCBmcm9tIHRoZSBjb25zdHJ1Y3Rvcj8nLCBuYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCclcyguLi4pOiBObyBgcmVuZGVyYCBtZXRob2QgZm91bmQgb24gdGhlIHJldHVybmVkIGNvbXBvbmVudCAnICsgJ2luc3RhbmNlOiB5b3UgbWF5IGhhdmUgZm9yZ290dGVuIHRvIGRlZmluZSBgcmVuZGVyYC4nLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW5zdGFuY2UuZ2V0SW5pdGlhbFN0YXRlICYmICFpbnN0YW5jZS5nZXRJbml0aWFsU3RhdGUuaXNSZWFjdENsYXNzQXBwcm92ZWQgJiYgIWluc3RhbmNlLnN0YXRlKSB7XG4gICAgICBlcnJvcignZ2V0SW5pdGlhbFN0YXRlIHdhcyBkZWZpbmVkIG9uICVzLCBhIHBsYWluIEphdmFTY3JpcHQgY2xhc3MuICcgKyAnVGhpcyBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgY2xhc3NlcyBjcmVhdGVkIHVzaW5nIFJlYWN0LmNyZWF0ZUNsYXNzLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBkZWZpbmUgYSBzdGF0ZSBwcm9wZXJ0eSBpbnN0ZWFkPycsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5nZXREZWZhdWx0UHJvcHMgJiYgIWluc3RhbmNlLmdldERlZmF1bHRQcm9wcy5pc1JlYWN0Q2xhc3NBcHByb3ZlZCkge1xuICAgICAgZXJyb3IoJ2dldERlZmF1bHRQcm9wcyB3YXMgZGVmaW5lZCBvbiAlcywgYSBwbGFpbiBKYXZhU2NyaXB0IGNsYXNzLiAnICsgJ1RoaXMgaXMgb25seSBzdXBwb3J0ZWQgZm9yIGNsYXNzZXMgY3JlYXRlZCB1c2luZyBSZWFjdC5jcmVhdGVDbGFzcy4gJyArICdVc2UgYSBzdGF0aWMgcHJvcGVydHkgdG8gZGVmaW5lIGRlZmF1bHRQcm9wcyBpbnN0ZWFkLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5wcm9wVHlwZXMpIHtcbiAgICAgIGVycm9yKCdwcm9wVHlwZXMgd2FzIGRlZmluZWQgYXMgYW4gaW5zdGFuY2UgcHJvcGVydHkgb24gJXMuIFVzZSBhIHN0YXRpYyAnICsgJ3Byb3BlcnR5IHRvIGRlZmluZSBwcm9wVHlwZXMgaW5zdGVhZC4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoaW5zdGFuY2UuY29udGV4dFR5cGUpIHtcbiAgICAgIGVycm9yKCdjb250ZXh0VHlwZSB3YXMgZGVmaW5lZCBhcyBhbiBpbnN0YW5jZSBwcm9wZXJ0eSBvbiAlcy4gVXNlIGEgc3RhdGljICcgKyAncHJvcGVydHkgdG8gZGVmaW5lIGNvbnRleHRUeXBlIGluc3RlYWQuJywgbmFtZSk7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKGluc3RhbmNlLmNvbnRleHRUeXBlcykge1xuICAgICAgICBlcnJvcignY29udGV4dFR5cGVzIHdhcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIHByb3BlcnR5IG9uICVzLiBVc2UgYSBzdGF0aWMgJyArICdwcm9wZXJ0eSB0byBkZWZpbmUgY29udGV4dFR5cGVzIGluc3RlYWQuJywgbmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdG9yLmNvbnRleHRUeXBlICYmIGN0b3IuY29udGV4dFR5cGVzICYmICFkaWRXYXJuQWJvdXRDb250ZXh0VHlwZUFuZENvbnRleHRUeXBlcy5oYXMoY3RvcikpIHtcbiAgICAgICAgZGlkV2FybkFib3V0Q29udGV4dFR5cGVBbmRDb250ZXh0VHlwZXMuYWRkKGN0b3IpO1xuXG4gICAgICAgIGVycm9yKCclcyBkZWNsYXJlcyBib3RoIGNvbnRleHRUeXBlcyBhbmQgY29udGV4dFR5cGUgc3RhdGljIHByb3BlcnRpZXMuICcgKyAnVGhlIGxlZ2FjeSBjb250ZXh0VHlwZXMgcHJvcGVydHkgd2lsbCBiZSBpZ25vcmVkLicsIG5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50U2hvdWxkVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudFNob3VsZFVwZGF0ZSgpLiBEaWQgeW91IG1lYW4gc2hvdWxkQ29tcG9uZW50VXBkYXRlKCk/ICcgKyAnVGhlIG5hbWUgaXMgcGhyYXNlZCBhcyBhIHF1ZXN0aW9uIGJlY2F1c2UgdGhlIGZ1bmN0aW9uIGlzICcgKyAnZXhwZWN0ZWQgdG8gcmV0dXJuIGEgdmFsdWUuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGN0b3IucHJvdG90eXBlICYmIGN0b3IucHJvdG90eXBlLmlzUHVyZVJlYWN0Q29tcG9uZW50ICYmIHR5cGVvZiBpbnN0YW5jZS5zaG91bGRDb21wb25lbnRVcGRhdGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCBzaG91bGRDb21wb25lbnRVcGRhdGUoKS4gJyArICdzaG91bGRDb21wb25lbnRVcGRhdGUgc2hvdWxkIG5vdCBiZSB1c2VkIHdoZW4gZXh0ZW5kaW5nIFJlYWN0LlB1cmVDb21wb25lbnQuICcgKyAnUGxlYXNlIGV4dGVuZCBSZWFjdC5Db21wb25lbnQgaWYgc2hvdWxkQ29tcG9uZW50VXBkYXRlIGlzIHVzZWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdBIHB1cmUgY29tcG9uZW50Jyk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignJXMgaGFzIGEgbWV0aG9kIGNhbGxlZCAnICsgJ2NvbXBvbmVudERpZFVubW91bnQoKS4gQnV0IHRoZXJlIGlzIG5vIHN1Y2ggbGlmZWN5Y2xlIG1ldGhvZC4gJyArICdEaWQgeW91IG1lYW4gY29tcG9uZW50V2lsbFVubW91bnQoKT8nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnREaWRSZWNlaXZlUHJvcHMoKS4gQnV0IHRoZXJlIGlzIG5vIHN1Y2ggbGlmZWN5Y2xlIG1ldGhvZC4gJyArICdJZiB5b3UgbWVhbnQgdG8gdXBkYXRlIHRoZSBzdGF0ZSBpbiByZXNwb25zZSB0byBjaGFuZ2luZyBwcm9wcywgJyArICd1c2UgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcygpLiBJZiB5b3UgbWVhbnQgdG8gZmV0Y2ggZGF0YSBvciAnICsgJ3J1biBzaWRlLWVmZmVjdHMgb3IgbXV0YXRpb25zIGFmdGVyIFJlYWN0IGhhcyB1cGRhdGVkIHRoZSBVSSwgdXNlIGNvbXBvbmVudERpZFVwZGF0ZSgpLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdjb21wb25lbnRXaWxsUmVjaWV2ZVByb3BzKCkuIERpZCB5b3UgbWVhbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCk/JywgbmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzIGhhcyBhIG1ldGhvZCBjYWxsZWQgJyArICdVTlNBRkVfY29tcG9uZW50V2lsbFJlY2lldmVQcm9wcygpLiBEaWQgeW91IG1lYW4gVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoKT8nLCBuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgaGFzTXV0YXRlZFByb3BzID0gaW5zdGFuY2UucHJvcHMgIT09IG5ld1Byb3BzO1xuXG4gICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSB1bmRlZmluZWQgJiYgaGFzTXV0YXRlZFByb3BzKSB7XG4gICAgICBlcnJvcignJXMoLi4uKTogV2hlbiBjYWxsaW5nIHN1cGVyKCkgaW4gYCVzYCwgbWFrZSBzdXJlIHRvIHBhc3MgJyArIFwidXAgdGhlIHNhbWUgcHJvcHMgdGhhdCB5b3VyIGNvbXBvbmVudCdzIGNvbnN0cnVjdG9yIHdhcyBwYXNzZWQuXCIsIG5hbWUsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5kZWZhdWx0UHJvcHMpIHtcbiAgICAgIGVycm9yKCdTZXR0aW5nIGRlZmF1bHRQcm9wcyBhcyBhbiBpbnN0YW5jZSBwcm9wZXJ0eSBvbiAlcyBpcyBub3Qgc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuJyArICcgSW5zdGVhZCwgZGVmaW5lIGRlZmF1bHRQcm9wcyBhcyBhIHN0YXRpYyBwcm9wZXJ0eSBvbiAlcy4nLCBuYW1lLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUgIT09ICdmdW5jdGlvbicgJiYgIWRpZFdhcm5BYm91dEdldFNuYXBzaG90QmVmb3JlVXBkYXRlV2l0aG91dERpZFVwZGF0ZS5oYXMoY3RvcikpIHtcbiAgICAgIGRpZFdhcm5BYm91dEdldFNuYXBzaG90QmVmb3JlVXBkYXRlV2l0aG91dERpZFVwZGF0ZS5hZGQoY3Rvcik7XG5cbiAgICAgIGVycm9yKCclczogZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKSBzaG91bGQgYmUgdXNlZCB3aXRoIGNvbXBvbmVudERpZFVwZGF0ZSgpLiAnICsgJ1RoaXMgY29tcG9uZW50IGRlZmluZXMgZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKSBvbmx5LicsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclczogZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKCkgaXMgZGVmaW5lZCBhcyBhbiBpbnN0YW5jZSBtZXRob2QgJyArICdhbmQgd2lsbCBiZSBpZ25vcmVkLiBJbnN0ZWFkLCBkZWNsYXJlIGl0IGFzIGEgc3RhdGljIG1ldGhvZC4nLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzOiBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoKSBpcyBkZWZpbmVkIGFzIGFuIGluc3RhbmNlIG1ldGhvZCAnICsgJ2FuZCB3aWxsIGJlIGlnbm9yZWQuIEluc3RlYWQsIGRlY2xhcmUgaXQgYXMgYSBzdGF0aWMgbWV0aG9kLicsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY3Rvci5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJyVzOiBnZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSgpIGlzIGRlZmluZWQgYXMgYSBzdGF0aWMgbWV0aG9kICcgKyAnYW5kIHdpbGwgYmUgaWdub3JlZC4gSW5zdGVhZCwgZGVjbGFyZSBpdCBhcyBhbiBpbnN0YW5jZSBtZXRob2QuJywgbmFtZSk7XG4gICAgfVxuXG4gICAgdmFyIF9zdGF0ZSA9IGluc3RhbmNlLnN0YXRlO1xuXG4gICAgaWYgKF9zdGF0ZSAmJiAodHlwZW9mIF9zdGF0ZSAhPT0gJ29iamVjdCcgfHwgaXNBcnJheShfc3RhdGUpKSkge1xuICAgICAgZXJyb3IoJyVzLnN0YXRlOiBtdXN0IGJlIHNldCB0byBhbiBvYmplY3Qgb3IgbnVsbCcsIG5hbWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0Q2hpbGRDb250ZXh0ID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBjdG9yLmNoaWxkQ29udGV4dFR5cGVzICE9PSAnb2JqZWN0Jykge1xuICAgICAgZXJyb3IoJyVzLmdldENoaWxkQ29udGV4dCgpOiBjaGlsZENvbnRleHRUeXBlcyBtdXN0IGJlIGRlZmluZWQgaW4gb3JkZXIgdG8gJyArICd1c2UgZ2V0Q2hpbGRDb250ZXh0KCkuJywgbmFtZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkb3B0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UudXBkYXRlciA9IGNsYXNzQ29tcG9uZW50VXBkYXRlcjtcbiAgd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID0gaW5zdGFuY2U7IC8vIFRoZSBpbnN0YW5jZSBuZWVkcyBhY2Nlc3MgdG8gdGhlIGZpYmVyIHNvIHRoYXQgaXQgY2FuIHNjaGVkdWxlIHVwZGF0ZXNcblxuICBzZXQoaW5zdGFuY2UsIHdvcmtJblByb2dyZXNzKTtcblxuICB7XG4gICAgaW5zdGFuY2UuX3JlYWN0SW50ZXJuYWxJbnN0YW5jZSA9IGZha2VJbnRlcm5hbEluc3RhbmNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHByb3BzKSB7XG4gIHZhciBpc0xlZ2FjeUNvbnRleHRDb25zdW1lciA9IGZhbHNlO1xuICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuICB2YXIgY29udGV4dCA9IGVtcHR5Q29udGV4dE9iamVjdDtcbiAgdmFyIGNvbnRleHRUeXBlID0gY3Rvci5jb250ZXh0VHlwZTtcblxuICB7XG4gICAgaWYgKCdjb250ZXh0VHlwZScgaW4gY3Rvcikge1xuICAgICAgdmFyIGlzVmFsaWQgPSAvLyBBbGxvdyBudWxsIGZvciBjb25kaXRpb25hbCBkZWNsYXJhdGlvblxuICAgICAgY29udGV4dFR5cGUgPT09IG51bGwgfHwgY29udGV4dFR5cGUgIT09IHVuZGVmaW5lZCAmJiBjb250ZXh0VHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfQ09OVEVYVF9UWVBFICYmIGNvbnRleHRUeXBlLl9jb250ZXh0ID09PSB1bmRlZmluZWQ7IC8vIE5vdCBhIDxDb250ZXh0LkNvbnN1bWVyPlxuXG4gICAgICBpZiAoIWlzVmFsaWQgJiYgIWRpZFdhcm5BYm91dEludmFsaWRhdGVDb250ZXh0VHlwZS5oYXMoY3RvcikpIHtcbiAgICAgICAgZGlkV2FybkFib3V0SW52YWxpZGF0ZUNvbnRleHRUeXBlLmFkZChjdG9yKTtcbiAgICAgICAgdmFyIGFkZGVuZHVtID0gJyc7XG5cbiAgICAgICAgaWYgKGNvbnRleHRUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhZGRlbmR1bSA9ICcgSG93ZXZlciwgaXQgaXMgc2V0IHRvIHVuZGVmaW5lZC4gJyArICdUaGlzIGNhbiBiZSBjYXVzZWQgYnkgYSB0eXBvIG9yIGJ5IG1peGluZyB1cCBuYW1lZCBhbmQgZGVmYXVsdCBpbXBvcnRzLiAnICsgJ1RoaXMgY2FuIGFsc28gaGFwcGVuIGR1ZSB0byBhIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHNvICcgKyAndHJ5IG1vdmluZyB0aGUgY3JlYXRlQ29udGV4dCgpIGNhbGwgdG8gYSBzZXBhcmF0ZSBmaWxlLic7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbnRleHRUeXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICAgIGFkZGVuZHVtID0gJyBIb3dldmVyLCBpdCBpcyBzZXQgdG8gYSAnICsgdHlwZW9mIGNvbnRleHRUeXBlICsgJy4nO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHRUeXBlLiQkdHlwZW9mID09PSBSRUFDVF9QUk9WSURFUl9UWVBFKSB7XG4gICAgICAgICAgYWRkZW5kdW0gPSAnIERpZCB5b3UgYWNjaWRlbnRhbGx5IHBhc3MgdGhlIENvbnRleHQuUHJvdmlkZXIgaW5zdGVhZD8nO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHRUeXBlLl9jb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyA8Q29udGV4dC5Db25zdW1lcj5cbiAgICAgICAgICBhZGRlbmR1bSA9ICcgRGlkIHlvdSBhY2NpZGVudGFsbHkgcGFzcyB0aGUgQ29udGV4dC5Db25zdW1lciBpbnN0ZWFkPyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYWRkZW5kdW0gPSAnIEhvd2V2ZXIsIGl0IGlzIHNldCB0byBhbiBvYmplY3Qgd2l0aCBrZXlzIHsnICsgT2JqZWN0LmtleXMoY29udGV4dFR5cGUpLmpvaW4oJywgJykgKyAnfS4nO1xuICAgICAgICB9XG5cbiAgICAgICAgZXJyb3IoJyVzIGRlZmluZXMgYW4gaW52YWxpZCBjb250ZXh0VHlwZS4gJyArICdjb250ZXh0VHlwZSBzaG91bGQgcG9pbnQgdG8gdGhlIENvbnRleHQgb2JqZWN0IHJldHVybmVkIGJ5IFJlYWN0LmNyZWF0ZUNvbnRleHQoKS4lcycsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSB8fCAnQ29tcG9uZW50JywgYWRkZW5kdW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIGNvbnRleHRUeXBlICE9PSBudWxsKSB7XG4gICAgY29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB1bm1hc2tlZENvbnRleHQgPSBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHRydWUpO1xuICAgIHZhciBjb250ZXh0VHlwZXMgPSBjdG9yLmNvbnRleHRUeXBlcztcbiAgICBpc0xlZ2FjeUNvbnRleHRDb25zdW1lciA9IGNvbnRleHRUeXBlcyAhPT0gbnVsbCAmJiBjb250ZXh0VHlwZXMgIT09IHVuZGVmaW5lZDtcbiAgICBjb250ZXh0ID0gaXNMZWdhY3lDb250ZXh0Q29uc3VtZXIgPyBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpIDogZW1wdHlDb250ZXh0T2JqZWN0O1xuICB9XG5cbiAgdmFyIGluc3RhbmNlID0gbmV3IGN0b3IocHJvcHMsIGNvbnRleHQpOyAvLyBJbnN0YW50aWF0ZSB0d2ljZSB0byBoZWxwIGRldGVjdCBzaWRlLWVmZmVjdHMuXG5cbiAge1xuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBpbnN0YW5jZSA9IG5ldyBjdG9yKHByb3BzLCBjb250ZXh0KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gaW5zdGFuY2Uuc3RhdGUgIT09IG51bGwgJiYgaW5zdGFuY2Uuc3RhdGUgIT09IHVuZGVmaW5lZCA/IGluc3RhbmNlLnN0YXRlIDogbnVsbDtcbiAgYWRvcHRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSk7XG5cbiAge1xuICAgIGlmICh0eXBlb2YgY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPT09ICdmdW5jdGlvbicgJiYgc3RhdGUgPT09IG51bGwpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKGN0b3IpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dFVuaW5pdGlhbGl6ZWRTdGF0ZS5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgZGlkV2FybkFib3V0VW5pbml0aWFsaXplZFN0YXRlLmFkZChjb21wb25lbnROYW1lKTtcblxuICAgICAgICBlcnJvcignYCVzYCB1c2VzIGBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHNgIGJ1dCBpdHMgaW5pdGlhbCBzdGF0ZSBpcyAnICsgJyVzLiBUaGlzIGlzIG5vdCByZWNvbW1lbmRlZC4gSW5zdGVhZCwgZGVmaW5lIHRoZSBpbml0aWFsIHN0YXRlIGJ5ICcgKyAnYXNzaWduaW5nIGFuIG9iamVjdCB0byBgdGhpcy5zdGF0ZWAgaW4gdGhlIGNvbnN0cnVjdG9yIG9mIGAlc2AuICcgKyAnVGhpcyBlbnN1cmVzIHRoYXQgYGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wc2AgYXJndW1lbnRzIGhhdmUgYSBjb25zaXN0ZW50IHNoYXBlLicsIGNvbXBvbmVudE5hbWUsIGluc3RhbmNlLnN0YXRlID09PSBudWxsID8gJ251bGwnIDogJ3VuZGVmaW5lZCcsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH0gLy8gSWYgbmV3IGNvbXBvbmVudCBBUElzIGFyZSBkZWZpbmVkLCBcInVuc2FmZVwiIGxpZmVjeWNsZXMgd29uJ3QgYmUgY2FsbGVkLlxuICAgIC8vIFdhcm4gYWJvdXQgdGhlc2UgbGlmZWN5Y2xlcyBpZiB0aGV5IGFyZSBwcmVzZW50LlxuICAgIC8vIERvbid0IHdhcm4gYWJvdXQgcmVhY3QtbGlmZWN5Y2xlcy1jb21wYXQgcG9seWZpbGxlZCBtZXRob2RzIHRob3VnaC5cblxuXG4gICAgaWYgKHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBmb3VuZFdpbGxNb3VudE5hbWUgPSBudWxsO1xuICAgICAgdmFyIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgPSBudWxsO1xuICAgICAgdmFyIGZvdW5kV2lsbFVwZGF0ZU5hbWUgPSBudWxsO1xuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJyAmJiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgICBmb3VuZFdpbGxNb3VudE5hbWUgPSAnY29tcG9uZW50V2lsbE1vdW50JztcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm91bmRXaWxsTW91bnROYW1lID0gJ1VOU0FGRV9jb21wb25lbnRXaWxsTW91bnQnO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicgJiYgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcy5fX3N1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5nICE9PSB0cnVlKSB7XG4gICAgICAgIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgPSAnY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyc7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmb3VuZFdpbGxSZWNlaXZlUHJvcHNOYW1lID0gJ1VOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJztcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nICYmIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVcGRhdGUuX19zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZyAhPT0gdHJ1ZSkge1xuICAgICAgICBmb3VuZFdpbGxVcGRhdGVOYW1lID0gJ2NvbXBvbmVudFdpbGxVcGRhdGUnO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZm91bmRXaWxsVXBkYXRlTmFtZSA9ICdVTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSc7XG4gICAgICB9XG5cbiAgICAgIGlmIChmb3VuZFdpbGxNb3VudE5hbWUgIT09IG51bGwgfHwgZm91bmRXaWxsUmVjZWl2ZVByb3BzTmFtZSAhPT0gbnVsbCB8fCBmb3VuZFdpbGxVcGRhdGVOYW1lICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBfY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSB8fCAnQ29tcG9uZW50JztcblxuICAgICAgICB2YXIgbmV3QXBpTmFtZSA9IHR5cGVvZiBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyA/ICdnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoKScgOiAnZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKSc7XG5cbiAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlLmhhcyhfY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgICBkaWRXYXJuQWJvdXRMZWdhY3lMaWZlY3ljbGVzQW5kRGVyaXZlZFN0YXRlLmFkZChfY29tcG9uZW50TmFtZSk7XG5cbiAgICAgICAgICBlcnJvcignVW5zYWZlIGxlZ2FjeSBsaWZlY3ljbGVzIHdpbGwgbm90IGJlIGNhbGxlZCBmb3IgY29tcG9uZW50cyB1c2luZyBuZXcgY29tcG9uZW50IEFQSXMuXFxuXFxuJyArICclcyB1c2VzICVzIGJ1dCBhbHNvIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgbGVnYWN5IGxpZmVjeWNsZXM6JXMlcyVzXFxuXFxuJyArICdUaGUgYWJvdmUgbGlmZWN5Y2xlcyBzaG91bGQgYmUgcmVtb3ZlZC4gTGVhcm4gbW9yZSBhYm91dCB0aGlzIHdhcm5pbmcgaGVyZTpcXG4nICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay91bnNhZmUtY29tcG9uZW50LWxpZmVjeWNsZXMnLCBfY29tcG9uZW50TmFtZSwgbmV3QXBpTmFtZSwgZm91bmRXaWxsTW91bnROYW1lICE9PSBudWxsID8gXCJcXG4gIFwiICsgZm91bmRXaWxsTW91bnROYW1lIDogJycsIGZvdW5kV2lsbFJlY2VpdmVQcm9wc05hbWUgIT09IG51bGwgPyBcIlxcbiAgXCIgKyBmb3VuZFdpbGxSZWNlaXZlUHJvcHNOYW1lIDogJycsIGZvdW5kV2lsbFVwZGF0ZU5hbWUgIT09IG51bGwgPyBcIlxcbiAgXCIgKyBmb3VuZFdpbGxVcGRhdGVOYW1lIDogJycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IC8vIENhY2hlIHVubWFza2VkIGNvbnRleHQgc28gd2UgY2FuIGF2b2lkIHJlY3JlYXRpbmcgbWFza2VkIGNvbnRleHQgdW5sZXNzIG5lY2Vzc2FyeS5cbiAgLy8gUmVhY3RGaWJlckNvbnRleHQgdXN1YWxseSB1cGRhdGVzIHRoaXMgY2FjaGUgYnV0IGNhbid0IGZvciBuZXdseS1jcmVhdGVkIGluc3RhbmNlcy5cblxuXG4gIGlmIChpc0xlZ2FjeUNvbnRleHRDb25zdW1lcikge1xuICAgIGNhY2hlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0LCBjb250ZXh0KTtcbiAgfVxuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuZnVuY3Rpb24gY2FsbENvbXBvbmVudFdpbGxNb3VudCh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpIHtcbiAgdmFyIG9sZFN0YXRlID0gaW5zdGFuY2Uuc3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpbnN0YW5jZS5jb21wb25lbnRXaWxsTW91bnQoKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQoKTtcbiAgfVxuXG4gIGlmIChvbGRTdGF0ZSAhPT0gaW5zdGFuY2Uuc3RhdGUpIHtcbiAgICB7XG4gICAgICBlcnJvcignJXMuY29tcG9uZW50V2lsbE1vdW50KCk6IEFzc2lnbmluZyBkaXJlY3RseSB0byB0aGlzLnN0YXRlIGlzICcgKyBcImRlcHJlY2F0ZWQgKGV4Y2VwdCBpbnNpZGUgYSBjb21wb25lbnQncyBcIiArICdjb25zdHJ1Y3RvcikuIFVzZSBzZXRTdGF0ZSBpbnN0ZWFkLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIod29ya0luUHJvZ3Jlc3MpIHx8ICdDb21wb25lbnQnKTtcbiAgICB9XG5cbiAgICBjbGFzc0NvbXBvbmVudFVwZGF0ZXIuZW5xdWV1ZVJlcGxhY2VTdGF0ZShpbnN0YW5jZSwgaW5zdGFuY2Uuc3RhdGUsIG51bGwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhbGxDb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKHdvcmtJblByb2dyZXNzLCBpbnN0YW5jZSwgbmV3UHJvcHMsIG5leHRDb250ZXh0KSB7XG4gIHZhciBvbGRTdGF0ZSA9IGluc3RhbmNlLnN0YXRlO1xuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV3UHJvcHMsIG5leHRDb250ZXh0KTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXdQcm9wcywgbmV4dENvbnRleHQpO1xuICB9XG5cbiAgaWYgKGluc3RhbmNlLnN0YXRlICE9PSBvbGRTdGF0ZSkge1xuICAgIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ0NvbXBvbmVudCc7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0U3RhdGVBc3NpZ25tZW50Rm9yQ29tcG9uZW50Lmhhcyhjb21wb25lbnROYW1lKSkge1xuICAgICAgICBkaWRXYXJuQWJvdXRTdGF0ZUFzc2lnbm1lbnRGb3JDb21wb25lbnQuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGVycm9yKCclcy5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKCk6IEFzc2lnbmluZyBkaXJlY3RseSB0byAnICsgXCJ0aGlzLnN0YXRlIGlzIGRlcHJlY2F0ZWQgKGV4Y2VwdCBpbnNpZGUgYSBjb21wb25lbnQncyBcIiArICdjb25zdHJ1Y3RvcikuIFVzZSBzZXRTdGF0ZSBpbnN0ZWFkLicsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNsYXNzQ29tcG9uZW50VXBkYXRlci5lbnF1ZXVlUmVwbGFjZVN0YXRlKGluc3RhbmNlLCBpbnN0YW5jZS5zdGF0ZSwgbnVsbCk7XG4gIH1cbn0gLy8gSW52b2tlcyB0aGUgbW91bnQgbGlmZS1jeWNsZXMgb24gYSBwcmV2aW91c2x5IG5ldmVyIHJlbmRlcmVkIGluc3RhbmNlLlxuXG5cbmZ1bmN0aW9uIG1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgY3RvciwgbmV3UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIHtcbiAgICBjaGVja0NsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIGN0b3IsIG5ld1Byb3BzKTtcbiAgfVxuXG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgaW5zdGFuY2UucHJvcHMgPSBuZXdQcm9wcztcbiAgaW5zdGFuY2Uuc3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuICBpbnN0YW5jZS5yZWZzID0gZW1wdHlSZWZzT2JqZWN0O1xuICBpbml0aWFsaXplVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgY29udGV4dFR5cGUgPSBjdG9yLmNvbnRleHRUeXBlO1xuXG4gIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIGNvbnRleHRUeXBlICE9PSBudWxsKSB7XG4gICAgaW5zdGFuY2UuY29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBjdG9yLCB0cnVlKTtcbiAgICBpbnN0YW5jZS5jb250ZXh0ID0gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHtcbiAgICBpZiAoaW5zdGFuY2Uuc3RhdGUgPT09IG5ld1Byb3BzKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShjdG9yKSB8fCAnQ29tcG9uZW50JztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXREaXJlY3RseUFzc2lnbmluZ1Byb3BzVG9TdGF0ZS5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgZGlkV2FybkFib3V0RGlyZWN0bHlBc3NpZ25pbmdQcm9wc1RvU3RhdGUuYWRkKGNvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGVycm9yKCclczogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGFzc2lnbiBwcm9wcyBkaXJlY3RseSB0byBzdGF0ZSAnICsgXCJiZWNhdXNlIHVwZGF0ZXMgdG8gcHJvcHMgd29uJ3QgYmUgcmVmbGVjdGVkIGluIHN0YXRlLiBcIiArICdJbiBtb3N0IGNhc2VzLCBpdCBpcyBiZXR0ZXIgdG8gdXNlIHByb3BzIGRpcmVjdGx5LicsIGNvbXBvbmVudE5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgUmVhY3RTdHJpY3RNb2RlV2FybmluZ3MucmVjb3JkTGVnYWN5Q29udGV4dFdhcm5pbmcod29ya0luUHJvZ3Jlc3MsIGluc3RhbmNlKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5yZWNvcmRVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UpO1xuICAgIH1cbiAgfVxuXG4gIGluc3RhbmNlLnN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9IGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzO1xuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgYXBwbHlEZXJpdmVkU3RhdGVGcm9tUHJvcHMod29ya0luUHJvZ3Jlc3MsIGN0b3IsIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcywgbmV3UHJvcHMpO1xuICAgIGluc3RhbmNlLnN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfSAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cblxuXG4gIGlmICh0eXBlb2YgY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlICE9PSAnZnVuY3Rpb24nICYmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nKSkge1xuICAgIGNhbGxDb21wb25lbnRXaWxsTW91bnQod29ya0luUHJvZ3Jlc3MsIGluc3RhbmNlKTsgLy8gSWYgd2UgaGFkIGFkZGl0aW9uYWwgc3RhdGUgdXBkYXRlcyBkdXJpbmcgdGhpcyBsaWZlLWN5Y2xlLCBsZXQnc1xuICAgIC8vIHByb2Nlc3MgdGhlbSBub3cuXG5cbiAgICBwcm9jZXNzVXBkYXRlUXVldWUod29ya0luUHJvZ3Jlc3MsIG5ld1Byb3BzLCBpbnN0YW5jZSwgcmVuZGVyTGFuZXMpO1xuICAgIGluc3RhbmNlLnN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB2YXIgZmliZXJGbGFncyA9IFVwZGF0ZTtcblxuICAgIHtcbiAgICAgIGZpYmVyRmxhZ3MgfD0gTGF5b3V0U3RhdGljO1xuICAgIH1cblxuICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBmaWJlckZsYWdzO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc3VtZU1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgY3RvciwgbmV3UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgdmFyIG9sZFByb3BzID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcztcbiAgaW5zdGFuY2UucHJvcHMgPSBvbGRQcm9wcztcbiAgdmFyIG9sZENvbnRleHQgPSBpbnN0YW5jZS5jb250ZXh0O1xuICB2YXIgY29udGV4dFR5cGUgPSBjdG9yLmNvbnRleHRUeXBlO1xuICB2YXIgbmV4dENvbnRleHQgPSBlbXB0eUNvbnRleHRPYmplY3Q7XG5cbiAgaWYgKHR5cGVvZiBjb250ZXh0VHlwZSA9PT0gJ29iamVjdCcgJiYgY29udGV4dFR5cGUgIT09IG51bGwpIHtcbiAgICBuZXh0Q29udGV4dCA9IHJlYWRDb250ZXh0KGNvbnRleHRUeXBlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbmV4dExlZ2FjeVVubWFza2VkQ29udGV4dCA9IGdldFVubWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgY3RvciwgdHJ1ZSk7XG4gICAgbmV4dENvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBuZXh0TGVnYWN5VW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHZhciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMgPSBjdG9yLmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcztcbiAgdmFyIGhhc05ld0xpZmVjeWNsZXMgPSB0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJzsgLy8gTm90ZTogRHVyaW5nIHRoZXNlIGxpZmUtY3ljbGVzLCBpbnN0YW5jZS5wcm9wcy9pbnN0YW5jZS5zdGF0ZSBhcmUgd2hhdFxuICAvLyBldmVyIHRoZSBwcmV2aW91c2x5IGF0dGVtcHRlZCB0byByZW5kZXIgLSBub3QgdGhlIFwiY3VycmVudFwiLiBIb3dldmVyLFxuICAvLyBkdXJpbmcgY29tcG9uZW50RGlkVXBkYXRlIHdlIHBhc3MgdGhlIFwiY3VycmVudFwiIHByb3BzLlxuICAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cblxuICBpZiAoIWhhc05ld0xpZmVjeWNsZXMgJiYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICBpZiAob2xkUHJvcHMgIT09IG5ld1Byb3BzIHx8IG9sZENvbnRleHQgIT09IG5leHRDb250ZXh0KSB7XG4gICAgICBjYWxsQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UsIG5ld1Byb3BzLCBuZXh0Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmVzZXRIYXNGb3JjZVVwZGF0ZUJlZm9yZVByb2Nlc3NpbmcoKTtcbiAgdmFyIG9sZFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIG5ld1N0YXRlID0gaW5zdGFuY2Uuc3RhdGUgPSBvbGRTdGF0ZTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXdQcm9wcywgaW5zdGFuY2UsIHJlbmRlckxhbmVzKTtcbiAgbmV3U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChvbGRQcm9wcyA9PT0gbmV3UHJvcHMgJiYgb2xkU3RhdGUgPT09IG5ld1N0YXRlICYmICFoYXNDb250ZXh0Q2hhbmdlZCgpICYmICFjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkpIHtcbiAgICAvLyBJZiBhbiB1cGRhdGUgd2FzIGFscmVhZHkgaW4gcHJvZ3Jlc3MsIHdlIHNob3VsZCBzY2hlZHVsZSBhbiBVcGRhdGVcbiAgICAvLyBlZmZlY3QgZXZlbiB0aG91Z2ggd2UncmUgYmFpbGluZyBvdXQsIHNvIHRoYXQgY1dVL2NEVSBhcmUgY2FsbGVkLlxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBmaWJlckZsYWdzID0gVXBkYXRlO1xuXG4gICAgICB7XG4gICAgICAgIGZpYmVyRmxhZ3MgfD0gTGF5b3V0U3RhdGljO1xuICAgICAgfVxuXG4gICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgICAgIH1cblxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gZmliZXJGbGFncztcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGFwcGx5RGVyaXZlZFN0YXRlRnJvbVByb3BzKHdvcmtJblByb2dyZXNzLCBjdG9yLCBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMsIG5ld1Byb3BzKTtcbiAgICBuZXdTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIH1cblxuICB2YXIgc2hvdWxkVXBkYXRlID0gY2hlY2tIYXNGb3JjZVVwZGF0ZUFmdGVyUHJvY2Vzc2luZygpIHx8IGNoZWNrU2hvdWxkQ29tcG9uZW50VXBkYXRlKHdvcmtJblByb2dyZXNzLCBjdG9yLCBvbGRQcm9wcywgbmV3UHJvcHMsIG9sZFN0YXRlLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpO1xuXG4gIGlmIChzaG91bGRVcGRhdGUpIHtcbiAgICAvLyBJbiBvcmRlciB0byBzdXBwb3J0IHJlYWN0LWxpZmVjeWNsZXMtY29tcGF0IHBvbHlmaWxsZWQgY29tcG9uZW50cyxcbiAgICAvLyBVbnNhZmUgbGlmZWN5Y2xlcyBzaG91bGQgbm90IGJlIGludm9rZWQgZm9yIGNvbXBvbmVudHMgdXNpbmcgdGhlIG5ldyBBUElzLlxuICAgIGlmICghaGFzTmV3TGlmZWN5Y2xlcyAmJiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbE1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxNb3VudCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBfZmliZXJGbGFncyA9IFVwZGF0ZTtcblxuICAgICAge1xuICAgICAgICBfZmliZXJGbGFncyB8PSBMYXlvdXRTdGF0aWM7XG4gICAgICB9XG5cbiAgICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RFZmZlY3RzTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICBfZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgICAgIH1cblxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gX2ZpYmVyRmxhZ3M7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElmIGFuIHVwZGF0ZSB3YXMgYWxyZWFkeSBpbiBwcm9ncmVzcywgd2Ugc2hvdWxkIHNjaGVkdWxlIGFuIFVwZGF0ZVxuICAgIC8vIGVmZmVjdCBldmVuIHRob3VnaCB3ZSdyZSBiYWlsaW5nIG91dCwgc28gdGhhdCBjV1UvY0RVIGFyZSBjYWxsZWQuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIF9maWJlckZsYWdzMiA9IFVwZGF0ZTtcblxuICAgICAge1xuICAgICAgICBfZmliZXJGbGFnczIgfD0gTGF5b3V0U3RhdGljO1xuICAgICAgfVxuXG4gICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgX2ZpYmVyRmxhZ3MyIHw9IE1vdW50TGF5b3V0RGV2O1xuICAgICAgfVxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBfZmliZXJGbGFnczI7XG4gICAgfSAvLyBJZiBzaG91bGRDb21wb25lbnRVcGRhdGUgcmV0dXJuZWQgZmFsc2UsIHdlIHNob3VsZCBzdGlsbCB1cGRhdGUgdGhlXG4gICAgLy8gbWVtb2l6ZWQgc3RhdGUgdG8gaW5kaWNhdGUgdGhhdCB0aGlzIHdvcmsgY2FuIGJlIHJldXNlZC5cblxuXG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcyA9IG5ld1Byb3BzO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBuZXdTdGF0ZTtcbiAgfSAvLyBVcGRhdGUgdGhlIGV4aXN0aW5nIGluc3RhbmNlJ3Mgc3RhdGUsIHByb3BzLCBhbmQgY29udGV4dCBwb2ludGVycyBldmVuXG4gIC8vIGlmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5zIGZhbHNlLlxuXG5cbiAgaW5zdGFuY2UucHJvcHMgPSBuZXdQcm9wcztcbiAgaW5zdGFuY2Uuc3RhdGUgPSBuZXdTdGF0ZTtcbiAgaW5zdGFuY2UuY29udGV4dCA9IG5leHRDb250ZXh0O1xuICByZXR1cm4gc2hvdWxkVXBkYXRlO1xufSAvLyBJbnZva2VzIHRoZSB1cGRhdGUgbGlmZS1jeWNsZXMgYW5kIHJldHVybnMgZmFsc2UgaWYgaXQgc2hvdWxkbid0IHJlcmVuZGVyLlxuXG5cbmZ1bmN0aW9uIHVwZGF0ZUNsYXNzSW5zdGFuY2UoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIGN0b3IsIG5ld1Byb3BzLCByZW5kZXJMYW5lcykge1xuICB2YXIgaW5zdGFuY2UgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gIGNsb25lVXBkYXRlUXVldWUoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgdW5yZXNvbHZlZE9sZFByb3BzID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcztcbiAgdmFyIG9sZFByb3BzID0gd29ya0luUHJvZ3Jlc3MudHlwZSA9PT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPyB1bnJlc29sdmVkT2xkUHJvcHMgOiByZXNvbHZlRGVmYXVsdFByb3BzKHdvcmtJblByb2dyZXNzLnR5cGUsIHVucmVzb2x2ZWRPbGRQcm9wcyk7XG4gIGluc3RhbmNlLnByb3BzID0gb2xkUHJvcHM7XG4gIHZhciB1bnJlc29sdmVkTmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBvbGRDb250ZXh0ID0gaW5zdGFuY2UuY29udGV4dDtcbiAgdmFyIGNvbnRleHRUeXBlID0gY3Rvci5jb250ZXh0VHlwZTtcbiAgdmFyIG5leHRDb250ZXh0ID0gZW1wdHlDb250ZXh0T2JqZWN0O1xuXG4gIGlmICh0eXBlb2YgY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIGNvbnRleHRUeXBlICE9PSBudWxsKSB7XG4gICAgbmV4dENvbnRleHQgPSByZWFkQ29udGV4dChjb250ZXh0VHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIG5leHRVbm1hc2tlZENvbnRleHQgPSBnZXRVbm1hc2tlZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIGN0b3IsIHRydWUpO1xuICAgIG5leHRDb250ZXh0ID0gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgbmV4dFVubWFza2VkQ29udGV4dCk7XG4gIH1cblxuICB2YXIgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID0gY3Rvci5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHM7XG4gIHZhciBoYXNOZXdMaWZlY3ljbGVzID0gdHlwZW9mIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbic7IC8vIE5vdGU6IER1cmluZyB0aGVzZSBsaWZlLWN5Y2xlcywgaW5zdGFuY2UucHJvcHMvaW5zdGFuY2Uuc3RhdGUgYXJlIHdoYXRcbiAgLy8gZXZlciB0aGUgcHJldmlvdXNseSBhdHRlbXB0ZWQgdG8gcmVuZGVyIC0gbm90IHRoZSBcImN1cnJlbnRcIi4gSG93ZXZlcixcbiAgLy8gZHVyaW5nIGNvbXBvbmVudERpZFVwZGF0ZSB3ZSBwYXNzIHRoZSBcImN1cnJlbnRcIiBwcm9wcy5cbiAgLy8gSW4gb3JkZXIgdG8gc3VwcG9ydCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMsXG4gIC8vIFVuc2FmZSBsaWZlY3ljbGVzIHNob3VsZCBub3QgYmUgaW52b2tlZCBmb3IgY29tcG9uZW50cyB1c2luZyB0aGUgbmV3IEFQSXMuXG5cbiAgaWYgKCFoYXNOZXdMaWZlY3ljbGVzICYmICh0eXBlb2YgaW5zdGFuY2UuVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPT09ICdmdW5jdGlvbicpKSB7XG4gICAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyAhPT0gdW5yZXNvbHZlZE5ld1Byb3BzIHx8IG9sZENvbnRleHQgIT09IG5leHRDb250ZXh0KSB7XG4gICAgICBjYWxsQ29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyh3b3JrSW5Qcm9ncmVzcywgaW5zdGFuY2UsIG5ld1Byb3BzLCBuZXh0Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmVzZXRIYXNGb3JjZVVwZGF0ZUJlZm9yZVByb2Nlc3NpbmcoKTtcbiAgdmFyIG9sZFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIG5ld1N0YXRlID0gaW5zdGFuY2Uuc3RhdGUgPSBvbGRTdGF0ZTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXdQcm9wcywgaW5zdGFuY2UsIHJlbmRlckxhbmVzKTtcbiAgbmV3U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgPT09IHVucmVzb2x2ZWROZXdQcm9wcyAmJiBvbGRTdGF0ZSA9PT0gbmV3U3RhdGUgJiYgIWhhc0NvbnRleHRDaGFuZ2VkKCkgJiYgIWNoZWNrSGFzRm9yY2VVcGRhdGVBZnRlclByb2Nlc3NpbmcoKSAmJiAhKGVuYWJsZUxhenlDb250ZXh0UHJvcGFnYXRpb24gICApKSB7XG4gICAgLy8gSWYgYW4gdXBkYXRlIHdhcyBhbHJlYWR5IGluIHByb2dyZXNzLCB3ZSBzaG91bGQgc2NoZWR1bGUgYW4gVXBkYXRlXG4gICAgLy8gZWZmZWN0IGV2ZW4gdGhvdWdoIHdlJ3JlIGJhaWxpbmcgb3V0LCBzbyB0aGF0IGNXVS9jRFUgYXJlIGNhbGxlZC5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgaWYgKHVucmVzb2x2ZWRPbGRQcm9wcyAhPT0gY3VycmVudC5tZW1vaXplZFByb3BzIHx8IG9sZFN0YXRlICE9PSBjdXJyZW50Lm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgIT09IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB8fCBvbGRTdGF0ZSAhPT0gY3VycmVudC5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFNuYXBzaG90O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgYXBwbHlEZXJpdmVkU3RhdGVGcm9tUHJvcHMod29ya0luUHJvZ3Jlc3MsIGN0b3IsIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcywgbmV3UHJvcHMpO1xuICAgIG5ld1N0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgfVxuXG4gIHZhciBzaG91bGRVcGRhdGUgPSBjaGVja0hhc0ZvcmNlVXBkYXRlQWZ0ZXJQcm9jZXNzaW5nKCkgfHwgY2hlY2tTaG91bGRDb21wb25lbnRVcGRhdGUod29ya0luUHJvZ3Jlc3MsIGN0b3IsIG9sZFByb3BzLCBuZXdQcm9wcywgb2xkU3RhdGUsIG5ld1N0YXRlLCBuZXh0Q29udGV4dCkgfHwgLy8gVE9ETzogSW4gc29tZSBjYXNlcywgd2UnbGwgZW5kIHVwIGNoZWNraW5nIGlmIGNvbnRleHQgaGFzIGNoYW5nZWQgdHdpY2UsXG4gIC8vIGJvdGggYmVmb3JlIGFuZCBhZnRlciBgc2hvdWxkQ29tcG9uZW50VXBkYXRlYCBoYXMgYmVlbiBjYWxsZWQuIE5vdCBpZGVhbCxcbiAgLy8gYnV0IEknbSBsb2F0aCB0byByZWZhY3RvciB0aGlzIGZ1bmN0aW9uLiBUaGlzIG9ubHkgaGFwcGVucyBmb3IgbWVtb2l6ZWRcbiAgLy8gY29tcG9uZW50cyBzbyBpdCdzIG5vdCB0aGF0IGNvbW1vbi5cbiAgZW5hYmxlTGF6eUNvbnRleHRQcm9wYWdhdGlvbiAgIDtcblxuICBpZiAoc2hvdWxkVXBkYXRlKSB7XG4gICAgLy8gSW4gb3JkZXIgdG8gc3VwcG9ydCByZWFjdC1saWZlY3ljbGVzLWNvbXBhdCBwb2x5ZmlsbGVkIGNvbXBvbmVudHMsXG4gICAgLy8gVW5zYWZlIGxpZmVjeWNsZXMgc2hvdWxkIG5vdCBiZSBpbnZva2VkIGZvciBjb21wb25lbnRzIHVzaW5nIHRoZSBuZXcgQVBJcy5cbiAgICBpZiAoIWhhc05ld0xpZmVjeWNsZXMgJiYgKHR5cGVvZiBpbnN0YW5jZS5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBpbnN0YW5jZS5jb21wb25lbnRXaWxsVXBkYXRlKG5ld1Byb3BzLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGluc3RhbmNlLlVOU0FGRV9jb21wb25lbnRXaWxsVXBkYXRlKG5ld1Byb3BzLCBuZXdTdGF0ZSwgbmV4dENvbnRleHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuY29tcG9uZW50RGlkVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU25hcHNob3Q7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIElmIGFuIHVwZGF0ZSB3YXMgYWxyZWFkeSBpbiBwcm9ncmVzcywgd2Ugc2hvdWxkIHNjaGVkdWxlIGFuIFVwZGF0ZVxuICAgIC8vIGVmZmVjdCBldmVuIHRob3VnaCB3ZSdyZSBiYWlsaW5nIG91dCwgc28gdGhhdCBjV1UvY0RVIGFyZSBjYWxsZWQuXG4gICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmICh1bnJlc29sdmVkT2xkUHJvcHMgIT09IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB8fCBvbGRTdGF0ZSAhPT0gY3VycmVudC5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluc3RhbmNlLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAodW5yZXNvbHZlZE9sZFByb3BzICE9PSBjdXJyZW50Lm1lbW9pemVkUHJvcHMgfHwgb2xkU3RhdGUgIT09IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSkge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBTbmFwc2hvdDtcbiAgICAgIH1cbiAgICB9IC8vIElmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5lZCBmYWxzZSwgd2Ugc2hvdWxkIHN0aWxsIHVwZGF0ZSB0aGVcbiAgICAvLyBtZW1vaXplZCBwcm9wcy9zdGF0ZSB0byBpbmRpY2F0ZSB0aGF0IHRoaXMgd29yayBjYW4gYmUgcmV1c2VkLlxuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzID0gbmV3UHJvcHM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9IC8vIFVwZGF0ZSB0aGUgZXhpc3RpbmcgaW5zdGFuY2UncyBzdGF0ZSwgcHJvcHMsIGFuZCBjb250ZXh0IHBvaW50ZXJzIGV2ZW5cbiAgLy8gaWYgc2hvdWxkQ29tcG9uZW50VXBkYXRlIHJldHVybnMgZmFsc2UuXG5cblxuICBpbnN0YW5jZS5wcm9wcyA9IG5ld1Byb3BzO1xuICBpbnN0YW5jZS5zdGF0ZSA9IG5ld1N0YXRlO1xuICBpbnN0YW5jZS5jb250ZXh0ID0gbmV4dENvbnRleHQ7XG4gIHJldHVybiBzaG91bGRVcGRhdGU7XG59XG5cbnZhciBkaWRXYXJuQWJvdXRNYXBzO1xudmFyIGRpZFdhcm5BYm91dEdlbmVyYXRvcnM7XG52YXIgZGlkV2FybkFib3V0U3RyaW5nUmVmcztcbnZhciBvd25lckhhc0tleVVzZVdhcm5pbmc7XG52YXIgb3duZXJIYXNGdW5jdGlvblR5cGVXYXJuaW5nO1xuXG52YXIgd2FybkZvck1pc3NpbmdLZXkgPSBmdW5jdGlvbiAoY2hpbGQsIHJldHVybkZpYmVyKSB7fTtcblxue1xuICBkaWRXYXJuQWJvdXRNYXBzID0gZmFsc2U7XG4gIGRpZFdhcm5BYm91dEdlbmVyYXRvcnMgPSBmYWxzZTtcbiAgZGlkV2FybkFib3V0U3RyaW5nUmVmcyA9IHt9O1xuICAvKipcbiAgICogV2FybiBpZiB0aGVyZSdzIG5vIGtleSBleHBsaWNpdGx5IHNldCBvbiBkeW5hbWljIGFycmF5cyBvZiBjaGlsZHJlbiBvclxuICAgKiBvYmplY3Qga2V5cyBhcmUgbm90IHZhbGlkLiBUaGlzIGFsbG93cyB1cyB0byBrZWVwIHRyYWNrIG9mIGNoaWxkcmVuIGJldHdlZW5cbiAgICogdXBkYXRlcy5cbiAgICovXG5cbiAgb3duZXJIYXNLZXlVc2VXYXJuaW5nID0ge307XG4gIG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZyA9IHt9O1xuXG4gIHdhcm5Gb3JNaXNzaW5nS2V5ID0gZnVuY3Rpb24gKGNoaWxkLCByZXR1cm5GaWJlcikge1xuICAgIGlmIChjaGlsZCA9PT0gbnVsbCB8fCB0eXBlb2YgY2hpbGQgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjaGlsZC5fc3RvcmUgfHwgY2hpbGQuX3N0b3JlLnZhbGlkYXRlZCB8fCBjaGlsZC5rZXkgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY2hpbGQuX3N0b3JlICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWFjdCBDb21wb25lbnQgaW4gd2FybkZvck1pc3NpbmdLZXkgc2hvdWxkIGhhdmUgYSBfc3RvcmUuICcgKyAnVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBjaGlsZC5fc3RvcmUudmFsaWRhdGVkID0gdHJ1ZTtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIocmV0dXJuRmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgaWYgKG93bmVySGFzS2V5VXNlV2FybmluZ1tjb21wb25lbnROYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG93bmVySGFzS2V5VXNlV2FybmluZ1tjb21wb25lbnROYW1lXSA9IHRydWU7XG5cbiAgICBlcnJvcignRWFjaCBjaGlsZCBpbiBhIGxpc3Qgc2hvdWxkIGhhdmUgYSB1bmlxdWUgJyArICdcImtleVwiIHByb3AuIFNlZSBodHRwczovL3JlYWN0anMub3JnL2xpbmsvd2FybmluZy1rZXlzIGZvciAnICsgJ21vcmUgaW5mb3JtYXRpb24uJyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvZXJjZVJlZihyZXR1cm5GaWJlciwgY3VycmVudCwgZWxlbWVudCkge1xuICB2YXIgbWl4ZWRSZWYgPSBlbGVtZW50LnJlZjtcblxuICBpZiAobWl4ZWRSZWYgIT09IG51bGwgJiYgdHlwZW9mIG1peGVkUmVmICE9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBtaXhlZFJlZiAhPT0gJ29iamVjdCcpIHtcbiAgICB7XG4gICAgICAvLyBUT0RPOiBDbGVhbiB0aGlzIHVwIG9uY2Ugd2UgdHVybiBvbiB0aGUgc3RyaW5nIHJlZiB3YXJuaW5nIGZvclxuICAgICAgLy8gZXZlcnlvbmUsIGJlY2F1c2UgdGhlIHN0cmljdCBtb2RlIGNhc2Ugd2lsbCBubyBsb25nZXIgYmUgcmVsZXZhbnRcbiAgICAgIGlmICgocmV0dXJuRmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUgfHwgd2FybkFib3V0U3RyaW5nUmVmcykgJiYgLy8gV2Ugd2FybiBpbiBSZWFjdEVsZW1lbnQuanMgaWYgb3duZXIgYW5kIHNlbGYgYXJlIGVxdWFsIGZvciBzdHJpbmcgcmVmc1xuICAgICAgLy8gYmVjYXVzZSB0aGVzZSBjYW5ub3QgYmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gYW4gYXJyb3cgZnVuY3Rpb25cbiAgICAgIC8vIHVzaW5nIGEgY29kZW1vZC4gVGhlcmVmb3JlLCB3ZSBkb24ndCBoYXZlIHRvIHdhcm4gYWJvdXQgc3RyaW5nIHJlZnMgYWdhaW4uXG4gICAgICAhKGVsZW1lbnQuX293bmVyICYmIGVsZW1lbnQuX3NlbGYgJiYgZWxlbWVudC5fb3duZXIuc3RhdGVOb2RlICE9PSBlbGVtZW50Ll9zZWxmKSkge1xuICAgICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIocmV0dXJuRmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgICAgIGlmICghZGlkV2FybkFib3V0U3RyaW5nUmVmc1tjb21wb25lbnROYW1lXSkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yKCdBIHN0cmluZyByZWYsIFwiJXNcIiwgaGFzIGJlZW4gZm91bmQgd2l0aGluIGEgc3RyaWN0IG1vZGUgdHJlZS4gJyArICdTdHJpbmcgcmVmcyBhcmUgYSBzb3VyY2Ugb2YgcG90ZW50aWFsIGJ1Z3MgYW5kIHNob3VsZCBiZSBhdm9pZGVkLiAnICsgJ1dlIHJlY29tbWVuZCB1c2luZyB1c2VSZWYoKSBvciBjcmVhdGVSZWYoKSBpbnN0ZWFkLiAnICsgJ0xlYXJuIG1vcmUgYWJvdXQgdXNpbmcgcmVmcyBzYWZlbHkgaGVyZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3RyaWN0LW1vZGUtc3RyaW5nLXJlZicsIG1peGVkUmVmKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkaWRXYXJuQWJvdXRTdHJpbmdSZWZzW2NvbXBvbmVudE5hbWVdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlbGVtZW50Ll9vd25lcikge1xuICAgICAgdmFyIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG4gICAgICB2YXIgaW5zdDtcblxuICAgICAgaWYgKG93bmVyKSB7XG4gICAgICAgIHZhciBvd25lckZpYmVyID0gb3duZXI7XG5cbiAgICAgICAgaWYgKG93bmVyRmliZXIudGFnICE9PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRnVuY3Rpb24gY29tcG9uZW50cyBjYW5ub3QgaGF2ZSBzdHJpbmcgcmVmcy4gJyArICdXZSByZWNvbW1lbmQgdXNpbmcgdXNlUmVmKCkgaW5zdGVhZC4gJyArICdMZWFybiBtb3JlIGFib3V0IHVzaW5nIHJlZnMgc2FmZWx5IGhlcmU6ICcgKyAnaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3N0cmljdC1tb2RlLXN0cmluZy1yZWYnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGluc3QgPSBvd25lckZpYmVyLnN0YXRlTm9kZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpbnN0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3Npbmcgb3duZXIgZm9yIHN0cmluZyByZWYgXCIgKyBtaXhlZFJlZiArIFwiLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBcIiArICdidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgfSAvLyBBc3NpZ25pbmcgdGhpcyB0byBhIGNvbnN0IHNvIEZsb3cga25vd3MgaXQgd29uJ3QgY2hhbmdlIGluIHRoZSBjbG9zdXJlXG5cblxuICAgICAgdmFyIHJlc29sdmVkSW5zdCA9IGluc3Q7XG5cbiAgICAgIHtcbiAgICAgICAgY2hlY2tQcm9wU3RyaW5nQ29lcmNpb24obWl4ZWRSZWYsICdyZWYnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHN0cmluZ1JlZiA9ICcnICsgbWl4ZWRSZWY7IC8vIENoZWNrIGlmIHByZXZpb3VzIHN0cmluZyByZWYgbWF0Y2hlcyBuZXcgc3RyaW5nIHJlZlxuXG4gICAgICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50LnJlZiAhPT0gbnVsbCAmJiB0eXBlb2YgY3VycmVudC5yZWYgPT09ICdmdW5jdGlvbicgJiYgY3VycmVudC5yZWYuX3N0cmluZ1JlZiA9PT0gc3RyaW5nUmVmKSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50LnJlZjtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlZiA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgcmVmcyA9IHJlc29sdmVkSW5zdC5yZWZzO1xuXG4gICAgICAgIGlmIChyZWZzID09PSBlbXB0eVJlZnNPYmplY3QpIHtcbiAgICAgICAgICAvLyBUaGlzIGlzIGEgbGF6eSBwb29sZWQgZnJvemVuIG9iamVjdCwgc28gd2UgbmVlZCB0byBpbml0aWFsaXplLlxuICAgICAgICAgIHJlZnMgPSByZXNvbHZlZEluc3QucmVmcyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgZGVsZXRlIHJlZnNbc3RyaW5nUmVmXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWZzW3N0cmluZ1JlZl0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgcmVmLl9zdHJpbmdSZWYgPSBzdHJpbmdSZWY7XG4gICAgICByZXR1cm4gcmVmO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZW9mIG1peGVkUmVmICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHJlZiB0byBiZSBhIGZ1bmN0aW9uLCBhIHN0cmluZywgYW4gb2JqZWN0IHJldHVybmVkIGJ5IFJlYWN0LmNyZWF0ZVJlZigpLCBvciBudWxsLicpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWVsZW1lbnQuX293bmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnQgcmVmIHdhcyBzcGVjaWZpZWQgYXMgYSBzdHJpbmcgKFwiICsgbWl4ZWRSZWYgKyBcIikgYnV0IG5vIG93bmVyIHdhcyBzZXQuIFRoaXMgY291bGQgaGFwcGVuIGZvciBvbmUgb2ZcIiArICcgdGhlIGZvbGxvd2luZyByZWFzb25zOlxcbicgKyAnMS4gWW91IG1heSBiZSBhZGRpbmcgYSByZWYgdG8gYSBmdW5jdGlvbiBjb21wb25lbnRcXG4nICsgXCIyLiBZb3UgbWF5IGJlIGFkZGluZyBhIHJlZiB0byBhIGNvbXBvbmVudCB0aGF0IHdhcyBub3QgY3JlYXRlZCBpbnNpZGUgYSBjb21wb25lbnQncyByZW5kZXIgbWV0aG9kXFxuXCIgKyAnMy4gWW91IGhhdmUgbXVsdGlwbGUgY29waWVzIG9mIFJlYWN0IGxvYWRlZFxcbicgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9yZWZzLW11c3QtaGF2ZS1vd25lciBmb3IgbW9yZSBpbmZvcm1hdGlvbi4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWl4ZWRSZWY7XG59XG5cbmZ1bmN0aW9uIHRocm93T25JbnZhbGlkT2JqZWN0VHlwZShyZXR1cm5GaWJlciwgbmV3Q2hpbGQpIHtcbiAgdmFyIGNoaWxkU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ld0NoaWxkKTtcbiAgdGhyb3cgbmV3IEVycm9yKFwiT2JqZWN0cyBhcmUgbm90IHZhbGlkIGFzIGEgUmVhY3QgY2hpbGQgKGZvdW5kOiBcIiArIChjaGlsZFN0cmluZyA9PT0gJ1tvYmplY3QgT2JqZWN0XScgPyAnb2JqZWN0IHdpdGgga2V5cyB7JyArIE9iamVjdC5rZXlzKG5ld0NoaWxkKS5qb2luKCcsICcpICsgJ30nIDogY2hpbGRTdHJpbmcpICsgXCIpLiBcIiArICdJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiwgdXNlIGFuIGFycmF5ICcgKyAnaW5zdGVhZC4nKTtcbn1cblxuZnVuY3Rpb24gd2Fybk9uRnVuY3Rpb25UeXBlKHJldHVybkZpYmVyKSB7XG4gIHtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIocmV0dXJuRmliZXIpIHx8ICdDb21wb25lbnQnO1xuXG4gICAgaWYgKG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZ1tjb21wb25lbnROYW1lXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG93bmVySGFzRnVuY3Rpb25UeXBlV2FybmluZ1tjb21wb25lbnROYW1lXSA9IHRydWU7XG5cbiAgICBlcnJvcignRnVuY3Rpb25zIGFyZSBub3QgdmFsaWQgYXMgYSBSZWFjdCBjaGlsZC4gVGhpcyBtYXkgaGFwcGVuIGlmICcgKyAneW91IHJldHVybiBhIENvbXBvbmVudCBpbnN0ZWFkIG9mIDxDb21wb25lbnQgLz4gZnJvbSByZW5kZXIuICcgKyAnT3IgbWF5YmUgeW91IG1lYW50IHRvIGNhbGwgdGhpcyBmdW5jdGlvbiByYXRoZXIgdGhhbiByZXR1cm4gaXQuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUxhenkobGF6eVR5cGUpIHtcbiAgdmFyIHBheWxvYWQgPSBsYXp5VHlwZS5fcGF5bG9hZDtcbiAgdmFyIGluaXQgPSBsYXp5VHlwZS5faW5pdDtcbiAgcmV0dXJuIGluaXQocGF5bG9hZCk7XG59IC8vIFRoaXMgd3JhcHBlciBmdW5jdGlvbiBleGlzdHMgYmVjYXVzZSBJIGV4cGVjdCB0byBjbG9uZSB0aGUgY29kZSBpbiBlYWNoIHBhdGhcbi8vIHRvIGJlIGFibGUgdG8gb3B0aW1pemUgZWFjaCBwYXRoIGluZGl2aWR1YWxseSBieSBicmFuY2hpbmcgZWFybHkuIFRoaXMgbmVlZHNcbi8vIGEgY29tcGlsZXIgb3Igd2UgY2FuIGRvIGl0IG1hbnVhbGx5LiBIZWxwZXJzIHRoYXQgZG9uJ3QgbmVlZCB0aGlzIGJyYW5jaGluZ1xuLy8gbGl2ZSBvdXRzaWRlIG9mIHRoaXMgZnVuY3Rpb24uXG5cblxuZnVuY3Rpb24gQ2hpbGRSZWNvbmNpbGVyKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgZnVuY3Rpb24gZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkVG9EZWxldGUpIHtcbiAgICBpZiAoIXNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIE5vb3AuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGRlbGV0aW9ucyA9IHJldHVybkZpYmVyLmRlbGV0aW9ucztcblxuICAgIGlmIChkZWxldGlvbnMgPT09IG51bGwpIHtcbiAgICAgIHJldHVybkZpYmVyLmRlbGV0aW9ucyA9IFtjaGlsZFRvRGVsZXRlXTtcbiAgICAgIHJldHVybkZpYmVyLmZsYWdzIHw9IENoaWxkRGVsZXRpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0aW9ucy5wdXNoKGNoaWxkVG9EZWxldGUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCkge1xuICAgIGlmICghc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgLy8gTm9vcC5cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gLy8gVE9ETzogRm9yIHRoZSBzaG91bGRDbG9uZSBjYXNlLCB0aGlzIGNvdWxkIGJlIG1pY3JvLW9wdGltaXplZCBhIGJpdCBieVxuICAgIC8vIGFzc3VtaW5nIHRoYXQgYWZ0ZXIgdGhlIGZpcnN0IGNoaWxkIHdlJ3ZlIGFscmVhZHkgYWRkZWQgZXZlcnl0aGluZy5cblxuXG4gICAgdmFyIGNoaWxkVG9EZWxldGUgPSBjdXJyZW50Rmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZFRvRGVsZXRlICE9PSBudWxsKSB7XG4gICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGRUb0RlbGV0ZSk7XG4gICAgICBjaGlsZFRvRGVsZXRlID0gY2hpbGRUb0RlbGV0ZS5zaWJsaW5nO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFwUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkKSB7XG4gICAgLy8gQWRkIHRoZSByZW1haW5pbmcgY2hpbGRyZW4gdG8gYSB0ZW1wb3JhcnkgbWFwIHNvIHRoYXQgd2UgY2FuIGZpbmQgdGhlbSBieVxuICAgIC8vIGtleXMgcXVpY2tseS4gSW1wbGljaXQgKG51bGwpIGtleXMgZ2V0IGFkZGVkIHRvIHRoaXMgc2V0IHdpdGggdGhlaXIgaW5kZXhcbiAgICAvLyBpbnN0ZWFkLlxuICAgIHZhciBleGlzdGluZ0NoaWxkcmVuID0gbmV3IE1hcCgpO1xuICAgIHZhciBleGlzdGluZ0NoaWxkID0gY3VycmVudEZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAoZXhpc3RpbmdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgaWYgKGV4aXN0aW5nQ2hpbGQua2V5ICE9PSBudWxsKSB7XG4gICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uc2V0KGV4aXN0aW5nQ2hpbGQua2V5LCBleGlzdGluZ0NoaWxkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uc2V0KGV4aXN0aW5nQ2hpbGQuaW5kZXgsIGV4aXN0aW5nQ2hpbGQpO1xuICAgICAgfVxuXG4gICAgICBleGlzdGluZ0NoaWxkID0gZXhpc3RpbmdDaGlsZC5zaWJsaW5nO1xuICAgIH1cblxuICAgIHJldHVybiBleGlzdGluZ0NoaWxkcmVuO1xuICB9XG5cbiAgZnVuY3Rpb24gdXNlRmliZXIoZmliZXIsIHBlbmRpbmdQcm9wcykge1xuICAgIC8vIFdlIGN1cnJlbnRseSBzZXQgc2libGluZyB0byBudWxsIGFuZCBpbmRleCB0byAwIGhlcmUgYmVjYXVzZSBpdCBpcyBlYXN5XG4gICAgLy8gdG8gZm9yZ2V0IHRvIGRvIGJlZm9yZSByZXR1cm5pbmcgaXQuIEUuZy4gZm9yIHRoZSBzaW5nbGUgY2hpbGQgY2FzZS5cbiAgICB2YXIgY2xvbmUgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhmaWJlciwgcGVuZGluZ1Byb3BzKTtcbiAgICBjbG9uZS5pbmRleCA9IDA7XG4gICAgY2xvbmUuc2libGluZyA9IG51bGw7XG4gICAgcmV0dXJuIGNsb25lO1xuICB9XG5cbiAgZnVuY3Rpb24gcGxhY2VDaGlsZChuZXdGaWJlciwgbGFzdFBsYWNlZEluZGV4LCBuZXdJbmRleCkge1xuICAgIG5ld0ZpYmVyLmluZGV4ID0gbmV3SW5kZXg7XG5cbiAgICBpZiAoIXNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIER1cmluZyBoeWRyYXRpb24sIHRoZSB1c2VJZCBhbGdvcml0aG0gbmVlZHMgdG8ga25vdyB3aGljaCBmaWJlcnMgYXJlXG4gICAgICAvLyBwYXJ0IG9mIGEgbGlzdCBvZiBjaGlsZHJlbiAoYXJyYXlzLCBpdGVyYXRvcnMpLlxuICAgICAgbmV3RmliZXIuZmxhZ3MgfD0gRm9ya2VkO1xuICAgICAgcmV0dXJuIGxhc3RQbGFjZWRJbmRleDtcbiAgICB9XG5cbiAgICB2YXIgY3VycmVudCA9IG5ld0ZpYmVyLmFsdGVybmF0ZTtcblxuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICB2YXIgb2xkSW5kZXggPSBjdXJyZW50LmluZGV4O1xuXG4gICAgICBpZiAob2xkSW5kZXggPCBsYXN0UGxhY2VkSW5kZXgpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIG1vdmUuXG4gICAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgICAgICAgcmV0dXJuIGxhc3RQbGFjZWRJbmRleDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgaXRlbSBjYW4gc3RheSBpbiBwbGFjZS5cbiAgICAgICAgcmV0dXJuIG9sZEluZGV4O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGlzIGFuIGluc2VydGlvbi5cbiAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgICAgIHJldHVybiBsYXN0UGxhY2VkSW5kZXg7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcGxhY2VTaW5nbGVDaGlsZChuZXdGaWJlcikge1xuICAgIC8vIFRoaXMgaXMgc2ltcGxlciBmb3IgdGhlIHNpbmdsZSBjaGlsZCBjYXNlLiBXZSBvbmx5IG5lZWQgdG8gZG8gYVxuICAgIC8vIHBsYWNlbWVudCBmb3IgaW5zZXJ0aW5nIG5ldyBjaGlsZHJlbi5cbiAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cyAmJiBuZXdGaWJlci5hbHRlcm5hdGUgPT09IG51bGwpIHtcbiAgICAgIG5ld0ZpYmVyLmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3RmliZXI7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVUZXh0Tm9kZShyZXR1cm5GaWJlciwgY3VycmVudCwgdGV4dENvbnRlbnQsIGxhbmVzKSB7XG4gICAgaWYgKGN1cnJlbnQgPT09IG51bGwgfHwgY3VycmVudC50YWcgIT09IEhvc3RUZXh0KSB7XG4gICAgICAvLyBJbnNlcnRcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tVGV4dCh0ZXh0Q29udGVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVcGRhdGVcbiAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGN1cnJlbnQsIHRleHRDb250ZW50KTtcbiAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnQocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQsIGxhbmVzKSB7XG4gICAgdmFyIGVsZW1lbnRUeXBlID0gZWxlbWVudC50eXBlO1xuXG4gICAgaWYgKGVsZW1lbnRUeXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFKSB7XG4gICAgICByZXR1cm4gdXBkYXRlRnJhZ21lbnQocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQucHJvcHMuY2hpbGRyZW4sIGxhbmVzLCBlbGVtZW50LmtleSk7XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIGlmIChjdXJyZW50LmVsZW1lbnRUeXBlID09PSBlbGVtZW50VHlwZSB8fCAoIC8vIEtlZXAgdGhpcyBjaGVjayBpbmxpbmUgc28gaXQgb25seSBydW5zIG9uIHRoZSBmYWxzZSBwYXRoOlxuICAgICAgIGlzQ29tcGF0aWJsZUZhbWlseUZvckhvdFJlbG9hZGluZyhjdXJyZW50LCBlbGVtZW50KSApIHx8IC8vIExhenkgdHlwZXMgc2hvdWxkIHJlY29uY2lsZSB0aGVpciByZXNvbHZlZCB0eXBlLlxuICAgICAgLy8gV2UgbmVlZCB0byBkbyB0aGlzIGFmdGVyIHRoZSBIb3QgUmVsb2FkaW5nIGNoZWNrIGFib3ZlLFxuICAgICAgLy8gYmVjYXVzZSBob3QgcmVsb2FkaW5nIGhhcyBkaWZmZXJlbnQgc2VtYW50aWNzIHRoYW4gcHJvZCBiZWNhdXNlXG4gICAgICAvLyBpdCBkb2Vzbid0IHJlc3VzcGVuZC4gU28gd2UgY2FuJ3QgbGV0IHRoZSBjYWxsIGJlbG93IHN1c3BlbmQuXG4gICAgICB0eXBlb2YgZWxlbWVudFR5cGUgPT09ICdvYmplY3QnICYmIGVsZW1lbnRUeXBlICE9PSBudWxsICYmIGVsZW1lbnRUeXBlLiQkdHlwZW9mID09PSBSRUFDVF9MQVpZX1RZUEUgJiYgcmVzb2x2ZUxhenkoZWxlbWVudFR5cGUpID09PSBjdXJyZW50LnR5cGUpIHtcbiAgICAgICAgLy8gTW92ZSBiYXNlZCBvbiBpbmRleFxuICAgICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjdXJyZW50LCBlbGVtZW50LnByb3BzKTtcbiAgICAgICAgZXhpc3RpbmcucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjdXJyZW50LCBlbGVtZW50KTtcbiAgICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG5cbiAgICAgICAge1xuICAgICAgICAgIGV4aXN0aW5nLl9kZWJ1Z1NvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcbiAgICAgICAgICBleGlzdGluZy5fZGVidWdPd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgICAgfVxuICAgIH0gLy8gSW5zZXJ0XG5cblxuICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tRWxlbWVudChlbGVtZW50LCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG4gICAgY3JlYXRlZC5yZWYgPSBjb2VyY2VSZWYocmV0dXJuRmliZXIsIGN1cnJlbnQsIGVsZW1lbnQpO1xuICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgcmV0dXJuIGNyZWF0ZWQ7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVQb3J0YWwocmV0dXJuRmliZXIsIGN1cnJlbnQsIHBvcnRhbCwgbGFuZXMpIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LnRhZyAhPT0gSG9zdFBvcnRhbCB8fCBjdXJyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvICE9PSBwb3J0YWwuY29udGFpbmVySW5mbyB8fCBjdXJyZW50LnN0YXRlTm9kZS5pbXBsZW1lbnRhdGlvbiAhPT0gcG9ydGFsLmltcGxlbWVudGF0aW9uKSB7XG4gICAgICAvLyBJbnNlcnRcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tUG9ydGFsKHBvcnRhbCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBVcGRhdGVcbiAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGN1cnJlbnQsIHBvcnRhbC5jaGlsZHJlbiB8fCBbXSk7XG4gICAgICBleGlzdGluZy5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBleGlzdGluZztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGcmFnbWVudChyZXR1cm5GaWJlciwgY3VycmVudCwgZnJhZ21lbnQsIGxhbmVzLCBrZXkpIHtcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LnRhZyAhPT0gRnJhZ21lbnQpIHtcbiAgICAgIC8vIEluc2VydFxuICAgICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmcmFnbWVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMsIGtleSk7XG4gICAgICBjcmVhdGVkLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgcmV0dXJuIGNyZWF0ZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVwZGF0ZVxuICAgICAgdmFyIGV4aXN0aW5nID0gdXNlRmliZXIoY3VycmVudCwgZnJhZ21lbnQpO1xuICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2hpbGQocmV0dXJuRmliZXIsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnICYmIG5ld0NoaWxkICE9PSAnJyB8fCB0eXBlb2YgbmV3Q2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBUZXh0IG5vZGVzIGRvbid0IGhhdmUga2V5cy4gSWYgdGhlIHByZXZpb3VzIG5vZGUgaXMgaW1wbGljaXRseSBrZXllZFxuICAgICAgLy8gd2UgY2FuIGNvbnRpbnVlIHRvIHJlcGxhY2UgaXQgd2l0aG91dCBhYm9ydGluZyBldmVuIGlmIGl0IGlzIG5vdCBhIHRleHRcbiAgICAgIC8vIG5vZGUuXG4gICAgICB2YXIgY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbVRleHQoJycgKyBuZXdDaGlsZCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuICAgICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdvYmplY3QnICYmIG5ld0NoaWxkICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKG5ld0NoaWxkLiQkdHlwZW9mKSB7XG4gICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBfY3JlYXRlZCA9IGNyZWF0ZUZpYmVyRnJvbUVsZW1lbnQobmV3Q2hpbGQsIHJldHVybkZpYmVyLm1vZGUsIGxhbmVzKTtcblxuICAgICAgICAgICAgX2NyZWF0ZWQucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBudWxsLCBuZXdDaGlsZCk7XG4gICAgICAgICAgICBfY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgICAgICAgIHJldHVybiBfY3JlYXRlZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgX2NyZWF0ZWQyID0gY3JlYXRlRmliZXJGcm9tUG9ydGFsKG5ld0NoaWxkLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG5cbiAgICAgICAgICAgIF9jcmVhdGVkMi5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICAgICAgICAgIHJldHVybiBfY3JlYXRlZDI7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBwYXlsb2FkID0gbmV3Q2hpbGQuX3BheWxvYWQ7XG4gICAgICAgICAgICB2YXIgaW5pdCA9IG5ld0NoaWxkLl9pbml0O1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNoaWxkKHJldHVybkZpYmVyLCBpbml0KHBheWxvYWQpLCBsYW5lcyk7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheShuZXdDaGlsZCkgfHwgZ2V0SXRlcmF0b3JGbihuZXdDaGlsZCkpIHtcbiAgICAgICAgdmFyIF9jcmVhdGVkMyA9IGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KG5ld0NoaWxkLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcywgbnVsbCk7XG5cbiAgICAgICAgX2NyZWF0ZWQzLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgICByZXR1cm4gX2NyZWF0ZWQzO1xuICAgICAgfVxuXG4gICAgICB0aHJvd09uSW52YWxpZE9iamVjdFR5cGUocmV0dXJuRmliZXIsIG5ld0NoaWxkKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTbG90KHJldHVybkZpYmVyLCBvbGRGaWJlciwgbmV3Q2hpbGQsIGxhbmVzKSB7XG4gICAgLy8gVXBkYXRlIHRoZSBmaWJlciBpZiB0aGUga2V5cyBtYXRjaCwgb3RoZXJ3aXNlIHJldHVybiBudWxsLlxuICAgIHZhciBrZXkgPSBvbGRGaWJlciAhPT0gbnVsbCA/IG9sZEZpYmVyLmtleSA6IG51bGw7XG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnc3RyaW5nJyAmJiBuZXdDaGlsZCAhPT0gJycgfHwgdHlwZW9mIG5ld0NoaWxkID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gVGV4dCBub2RlcyBkb24ndCBoYXZlIGtleXMuIElmIHRoZSBwcmV2aW91cyBub2RlIGlzIGltcGxpY2l0bHkga2V5ZWRcbiAgICAgIC8vIHdlIGNhbiBjb250aW51ZSB0byByZXBsYWNlIGl0IHdpdGhvdXQgYWJvcnRpbmcgZXZlbiBpZiBpdCBpcyBub3QgYSB0ZXh0XG4gICAgICAvLyBub2RlLlxuICAgICAgaWYgKGtleSAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVwZGF0ZVRleHROb2RlKHJldHVybkZpYmVyLCBvbGRGaWJlciwgJycgKyBuZXdDaGlsZCwgbGFuZXMpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdvYmplY3QnICYmIG5ld0NoaWxkICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKG5ld0NoaWxkLiQkdHlwZW9mKSB7XG4gICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmIChuZXdDaGlsZC5rZXkgPT09IGtleSkge1xuICAgICAgICAgICAgICByZXR1cm4gdXBkYXRlRWxlbWVudChyZXR1cm5GaWJlciwgb2xkRmliZXIsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAobmV3Q2hpbGQua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVBvcnRhbChyZXR1cm5GaWJlciwgb2xkRmliZXIsIG5ld0NoaWxkLCBsYW5lcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIHBheWxvYWQgPSBuZXdDaGlsZC5fcGF5bG9hZDtcbiAgICAgICAgICAgIHZhciBpbml0ID0gbmV3Q2hpbGQuX2luaXQ7XG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlU2xvdChyZXR1cm5GaWJlciwgb2xkRmliZXIsIGluaXQocGF5bG9hZCksIGxhbmVzKTtcbiAgICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0FycmF5KG5ld0NoaWxkKSB8fCBnZXRJdGVyYXRvckZuKG5ld0NoaWxkKSkge1xuICAgICAgICBpZiAoa2V5ICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdXBkYXRlRnJhZ21lbnQocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBuZXdDaGlsZCwgbGFuZXMsIG51bGwpO1xuICAgICAgfVxuXG4gICAgICB0aHJvd09uSW52YWxpZE9iamVjdFR5cGUocmV0dXJuRmliZXIsIG5ld0NoaWxkKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGcm9tTWFwKGV4aXN0aW5nQ2hpbGRyZW4sIHJldHVybkZpYmVyLCBuZXdJZHgsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdzdHJpbmcnICYmIG5ld0NoaWxkICE9PSAnJyB8fCB0eXBlb2YgbmV3Q2hpbGQgPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBUZXh0IG5vZGVzIGRvbid0IGhhdmUga2V5cywgc28gd2UgbmVpdGhlciBoYXZlIHRvIGNoZWNrIHRoZSBvbGQgbm9yXG4gICAgICAvLyBuZXcgbm9kZSBmb3IgdGhlIGtleS4gSWYgYm90aCBhcmUgdGV4dCBub2RlcywgdGhleSBtYXRjaC5cbiAgICAgIHZhciBtYXRjaGVkRmliZXIgPSBleGlzdGluZ0NoaWxkcmVuLmdldChuZXdJZHgpIHx8IG51bGw7XG4gICAgICByZXR1cm4gdXBkYXRlVGV4dE5vZGUocmV0dXJuRmliZXIsIG1hdGNoZWRGaWJlciwgJycgKyBuZXdDaGlsZCwgbGFuZXMpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdvYmplY3QnICYmIG5ld0NoaWxkICE9PSBudWxsKSB7XG4gICAgICBzd2l0Y2ggKG5ld0NoaWxkLiQkdHlwZW9mKSB7XG4gICAgICAgIGNhc2UgUkVBQ1RfRUxFTUVOVF9UWVBFOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBfbWF0Y2hlZEZpYmVyID0gZXhpc3RpbmdDaGlsZHJlbi5nZXQobmV3Q2hpbGQua2V5ID09PSBudWxsID8gbmV3SWR4IDogbmV3Q2hpbGQua2V5KSB8fCBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlRWxlbWVudChyZXR1cm5GaWJlciwgX21hdGNoZWRGaWJlciwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgX21hdGNoZWRGaWJlcjIgPSBleGlzdGluZ0NoaWxkcmVuLmdldChuZXdDaGlsZC5rZXkgPT09IG51bGwgPyBuZXdJZHggOiBuZXdDaGlsZC5rZXkpIHx8IG51bGw7XG5cbiAgICAgICAgICAgIHJldHVybiB1cGRhdGVQb3J0YWwocmV0dXJuRmliZXIsIF9tYXRjaGVkRmliZXIyLCBuZXdDaGlsZCwgbGFuZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAgICB2YXIgcGF5bG9hZCA9IG5ld0NoaWxkLl9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbmV3Q2hpbGQuX2luaXQ7XG4gICAgICAgICAgcmV0dXJuIHVwZGF0ZUZyb21NYXAoZXhpc3RpbmdDaGlsZHJlbiwgcmV0dXJuRmliZXIsIG5ld0lkeCwgaW5pdChwYXlsb2FkKSwgbGFuZXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheShuZXdDaGlsZCkgfHwgZ2V0SXRlcmF0b3JGbihuZXdDaGlsZCkpIHtcbiAgICAgICAgdmFyIF9tYXRjaGVkRmliZXIzID0gZXhpc3RpbmdDaGlsZHJlbi5nZXQobmV3SWR4KSB8fCBudWxsO1xuXG4gICAgICAgIHJldHVybiB1cGRhdGVGcmFnbWVudChyZXR1cm5GaWJlciwgX21hdGNoZWRGaWJlcjMsIG5ld0NoaWxkLCBsYW5lcywgbnVsbCk7XG4gICAgICB9XG5cbiAgICAgIHRocm93T25JbnZhbGlkT2JqZWN0VHlwZShyZXR1cm5GaWJlciwgbmV3Q2hpbGQpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgd2Fybk9uRnVuY3Rpb25UeXBlKHJldHVybkZpYmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvKipcbiAgICogV2FybnMgaWYgdGhlcmUgaXMgYSBkdXBsaWNhdGUgb3IgbWlzc2luZyBrZXlcbiAgICovXG5cblxuICBmdW5jdGlvbiB3YXJuT25JbnZhbGlkS2V5KGNoaWxkLCBrbm93bktleXMsIHJldHVybkZpYmVyKSB7XG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBjaGlsZCAhPT0gJ29iamVjdCcgfHwgY2hpbGQgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGtub3duS2V5cztcbiAgICAgIH1cblxuICAgICAgc3dpdGNoIChjaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICB3YXJuRm9yTWlzc2luZ0tleShjaGlsZCwgcmV0dXJuRmliZXIpO1xuICAgICAgICAgIHZhciBrZXkgPSBjaGlsZC5rZXk7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChrbm93bktleXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGtub3duS2V5cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIGtub3duS2V5cy5hZGQoa2V5KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICgha25vd25LZXlzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICBrbm93bktleXMuYWRkKGtleSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlcnJvcignRW5jb3VudGVyZWQgdHdvIGNoaWxkcmVuIHdpdGggdGhlIHNhbWUga2V5LCBgJXNgLiAnICsgJ0tleXMgc2hvdWxkIGJlIHVuaXF1ZSBzbyB0aGF0IGNvbXBvbmVudHMgbWFpbnRhaW4gdGhlaXIgaWRlbnRpdHkgJyArICdhY3Jvc3MgdXBkYXRlcy4gTm9uLXVuaXF1ZSBrZXlzIG1heSBjYXVzZSBjaGlsZHJlbiB0byBiZSAnICsgJ2R1cGxpY2F0ZWQgYW5kL29yIG9taXR0ZWQg4oCUIHRoZSBiZWhhdmlvciBpcyB1bnN1cHBvcnRlZCBhbmQgJyArICdjb3VsZCBjaGFuZ2UgaW4gYSBmdXR1cmUgdmVyc2lvbi4nLCBrZXkpO1xuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBSRUFDVF9MQVpZX1RZUEU6XG4gICAgICAgICAgdmFyIHBheWxvYWQgPSBjaGlsZC5fcGF5bG9hZDtcbiAgICAgICAgICB2YXIgaW5pdCA9IGNoaWxkLl9pbml0O1xuICAgICAgICAgIHdhcm5PbkludmFsaWRLZXkoaW5pdChwYXlsb2FkKSwga25vd25LZXlzLCByZXR1cm5GaWJlcik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGtub3duS2V5cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZUNoaWxkcmVuQXJyYXkocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZHJlbiwgbGFuZXMpIHtcbiAgICAvLyBUaGlzIGFsZ29yaXRobSBjYW4ndCBvcHRpbWl6ZSBieSBzZWFyY2hpbmcgZnJvbSBib3RoIGVuZHMgc2luY2Ugd2VcbiAgICAvLyBkb24ndCBoYXZlIGJhY2twb2ludGVycyBvbiBmaWJlcnMuIEknbSB0cnlpbmcgdG8gc2VlIGhvdyBmYXIgd2UgY2FuIGdldFxuICAgIC8vIHdpdGggdGhhdCBtb2RlbC4gSWYgaXQgZW5kcyB1cCBub3QgYmVpbmcgd29ydGggdGhlIHRyYWRlb2Zmcywgd2UgY2FuXG4gICAgLy8gYWRkIGl0IGxhdGVyLlxuICAgIC8vIEV2ZW4gd2l0aCBhIHR3byBlbmRlZCBvcHRpbWl6YXRpb24sIHdlJ2Qgd2FudCB0byBvcHRpbWl6ZSBmb3IgdGhlIGNhc2VcbiAgICAvLyB3aGVyZSB0aGVyZSBhcmUgZmV3IGNoYW5nZXMgYW5kIGJydXRlIGZvcmNlIHRoZSBjb21wYXJpc29uIGluc3RlYWQgb2ZcbiAgICAvLyBnb2luZyBmb3IgdGhlIE1hcC4gSXQnZCBsaWtlIHRvIGV4cGxvcmUgaGl0dGluZyB0aGF0IHBhdGggZmlyc3QgaW5cbiAgICAvLyBmb3J3YXJkLW9ubHkgbW9kZSBhbmQgb25seSBnbyBmb3IgdGhlIE1hcCBvbmNlIHdlIG5vdGljZSB0aGF0IHdlIG5lZWRcbiAgICAvLyBsb3RzIG9mIGxvb2sgYWhlYWQuIFRoaXMgZG9lc24ndCBoYW5kbGUgcmV2ZXJzYWwgYXMgd2VsbCBhcyB0d28gZW5kZWRcbiAgICAvLyBzZWFyY2ggYnV0IHRoYXQncyB1bnVzdWFsLiBCZXNpZGVzLCBmb3IgdGhlIHR3byBlbmRlZCBvcHRpbWl6YXRpb24gdG9cbiAgICAvLyB3b3JrIG9uIEl0ZXJhYmxlcywgd2UnZCBuZWVkIHRvIGNvcHkgdGhlIHdob2xlIHNldC5cbiAgICAvLyBJbiB0aGlzIGZpcnN0IGl0ZXJhdGlvbiwgd2UnbGwganVzdCBsaXZlIHdpdGggaGl0dGluZyB0aGUgYmFkIGNhc2VcbiAgICAvLyAoYWRkaW5nIGV2ZXJ5dGhpbmcgdG8gYSBNYXApIGluIGZvciBldmVyeSBpbnNlcnQvbW92ZS5cbiAgICAvLyBJZiB5b3UgY2hhbmdlIHRoaXMgY29kZSwgYWxzbyB1cGRhdGUgcmVjb25jaWxlQ2hpbGRyZW5JdGVyYXRvcigpIHdoaWNoXG4gICAgLy8gdXNlcyB0aGUgc2FtZSBhbGdvcml0aG0uXG4gICAge1xuICAgICAgLy8gRmlyc3QsIHZhbGlkYXRlIGtleXMuXG4gICAgICB2YXIga25vd25LZXlzID0gbnVsbDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXdDaGlsZHJlbltpXTtcbiAgICAgICAga25vd25LZXlzID0gd2Fybk9uSW52YWxpZEtleShjaGlsZCwga25vd25LZXlzLCByZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdGluZ0ZpcnN0Q2hpbGQgPSBudWxsO1xuICAgIHZhciBwcmV2aW91c05ld0ZpYmVyID0gbnVsbDtcbiAgICB2YXIgb2xkRmliZXIgPSBjdXJyZW50Rmlyc3RDaGlsZDtcbiAgICB2YXIgbGFzdFBsYWNlZEluZGV4ID0gMDtcbiAgICB2YXIgbmV3SWR4ID0gMDtcbiAgICB2YXIgbmV4dE9sZEZpYmVyID0gbnVsbDtcblxuICAgIGZvciAoOyBvbGRGaWJlciAhPT0gbnVsbCAmJiBuZXdJZHggPCBuZXdDaGlsZHJlbi5sZW5ndGg7IG5ld0lkeCsrKSB7XG4gICAgICBpZiAob2xkRmliZXIuaW5kZXggPiBuZXdJZHgpIHtcbiAgICAgICAgbmV4dE9sZEZpYmVyID0gb2xkRmliZXI7XG4gICAgICAgIG9sZEZpYmVyID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRPbGRGaWJlciA9IG9sZEZpYmVyLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXdGaWJlciA9IHVwZGF0ZVNsb3QocmV0dXJuRmliZXIsIG9sZEZpYmVyLCBuZXdDaGlsZHJlbltuZXdJZHhdLCBsYW5lcyk7XG5cbiAgICAgIGlmIChuZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGJyZWFrcyBvbiBlbXB0eSBzbG90cyBsaWtlIG51bGwgY2hpbGRyZW4uIFRoYXQnc1xuICAgICAgICAvLyB1bmZvcnR1bmF0ZSBiZWNhdXNlIGl0IHRyaWdnZXJzIHRoZSBzbG93IHBhdGggYWxsIHRoZSB0aW1lLiBXZSBuZWVkXG4gICAgICAgIC8vIGEgYmV0dGVyIHdheSB0byBjb21tdW5pY2F0ZSB3aGV0aGVyIHRoaXMgd2FzIGEgbWlzcyBvciBudWxsLFxuICAgICAgICAvLyBib29sZWFuLCB1bmRlZmluZWQsIGV0Yy5cbiAgICAgICAgaWYgKG9sZEZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgb2xkRmliZXIgPSBuZXh0T2xkRmliZXI7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgICAgaWYgKG9sZEZpYmVyICYmIG5ld0ZpYmVyLmFsdGVybmF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlIG1hdGNoZWQgdGhlIHNsb3QsIGJ1dCB3ZSBkaWRuJ3QgcmV1c2UgdGhlIGV4aXN0aW5nIGZpYmVyLCBzbyB3ZVxuICAgICAgICAgIC8vIG5lZWQgdG8gZGVsZXRlIHRoZSBleGlzdGluZyBjaGlsZC5cbiAgICAgICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgb2xkRmliZXIpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQobmV3RmliZXIsIGxhc3RQbGFjZWRJbmRleCwgbmV3SWR4KTtcblxuICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgLy8gVE9ETzogTW92ZSBvdXQgb2YgdGhlIGxvb3AuIFRoaXMgb25seSBoYXBwZW5zIGZvciB0aGUgZmlyc3QgcnVuLlxuICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gbmV3RmliZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUT0RPOiBEZWZlciBzaWJsaW5ncyBpZiB3ZSdyZSBub3QgYXQgdGhlIHJpZ2h0IGluZGV4IGZvciB0aGlzIHNsb3QuXG4gICAgICAgIC8vIEkuZS4gaWYgd2UgaGFkIG51bGwgdmFsdWVzIGJlZm9yZSwgdGhlbiB3ZSB3YW50IHRvIGRlZmVyIHRoaXNcbiAgICAgICAgLy8gZm9yIGVhY2ggbnVsbCB2YWx1ZS4gSG93ZXZlciwgd2UgYWxzbyBkb24ndCB3YW50IHRvIGNhbGwgdXBkYXRlU2xvdFxuICAgICAgICAvLyB3aXRoIHRoZSBwcmV2aW91cyBvbmUuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IG5ld0ZpYmVyO1xuICAgICAgfVxuXG4gICAgICBwcmV2aW91c05ld0ZpYmVyID0gbmV3RmliZXI7XG4gICAgICBvbGRGaWJlciA9IG5leHRPbGRGaWJlcjtcbiAgICB9XG5cbiAgICBpZiAobmV3SWR4ID09PSBuZXdDaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIC8vIFdlJ3ZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgbmV3IGNoaWxkcmVuLiBXZSBjYW4gZGVsZXRlIHRoZSByZXN0LlxuICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTtcblxuICAgICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgICAgdmFyIG51bWJlck9mRm9ya3MgPSBuZXdJZHg7XG4gICAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH1cblxuICAgIGlmIChvbGRGaWJlciA9PT0gbnVsbCkge1xuICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbnkgbW9yZSBleGlzdGluZyBjaGlsZHJlbiB3ZSBjYW4gY2hvb3NlIGEgZmFzdCBwYXRoXG4gICAgICAvLyBzaW5jZSB0aGUgcmVzdCB3aWxsIGFsbCBiZSBpbnNlcnRpb25zLlxuICAgICAgZm9yICg7IG5ld0lkeCA8IG5ld0NoaWxkcmVuLmxlbmd0aDsgbmV3SWR4KyspIHtcbiAgICAgICAgdmFyIF9uZXdGaWJlciA9IGNyZWF0ZUNoaWxkKHJldHVybkZpYmVyLCBuZXdDaGlsZHJlbltuZXdJZHhdLCBsYW5lcyk7XG5cbiAgICAgICAgaWYgKF9uZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChfbmV3RmliZXIsIGxhc3RQbGFjZWRJbmRleCwgbmV3SWR4KTtcblxuICAgICAgICBpZiAocHJldmlvdXNOZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFRPRE86IE1vdmUgb3V0IG9mIHRoZSBsb29wLiBUaGlzIG9ubHkgaGFwcGVucyBmb3IgdGhlIGZpcnN0IHJ1bi5cbiAgICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gX25ld0ZpYmVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZpb3VzTmV3RmliZXIuc2libGluZyA9IF9uZXdGaWJlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXI7XG4gICAgICB9XG5cbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpKSB7XG4gICAgICAgIHZhciBfbnVtYmVyT2ZGb3JrcyA9IG5ld0lkeDtcbiAgICAgICAgcHVzaFRyZWVGb3JrKHJldHVybkZpYmVyLCBfbnVtYmVyT2ZGb3Jrcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH0gLy8gQWRkIGFsbCBjaGlsZHJlbiB0byBhIGtleSBtYXAgZm9yIHF1aWNrIGxvb2t1cHMuXG5cblxuICAgIHZhciBleGlzdGluZ0NoaWxkcmVuID0gbWFwUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTsgLy8gS2VlcCBzY2FubmluZyBhbmQgdXNlIHRoZSBtYXAgdG8gcmVzdG9yZSBkZWxldGVkIGl0ZW1zIGFzIG1vdmVzLlxuXG4gICAgZm9yICg7IG5ld0lkeCA8IG5ld0NoaWxkcmVuLmxlbmd0aDsgbmV3SWR4KyspIHtcbiAgICAgIHZhciBfbmV3RmliZXIyID0gdXBkYXRlRnJvbU1hcChleGlzdGluZ0NoaWxkcmVuLCByZXR1cm5GaWJlciwgbmV3SWR4LCBuZXdDaGlsZHJlbltuZXdJZHhdLCBsYW5lcyk7XG5cbiAgICAgIGlmIChfbmV3RmliZXIyICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAgICAgaWYgKF9uZXdGaWJlcjIuYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBUaGUgbmV3IGZpYmVyIGlzIGEgd29yayBpbiBwcm9ncmVzcywgYnV0IGlmIHRoZXJlIGV4aXN0cyBhXG4gICAgICAgICAgICAvLyBjdXJyZW50LCB0aGF0IG1lYW5zIHRoYXQgd2UgcmV1c2VkIHRoZSBmaWJlci4gV2UgbmVlZCB0byBkZWxldGVcbiAgICAgICAgICAgIC8vIGl0IGZyb20gdGhlIGNoaWxkIGxpc3Qgc28gdGhhdCB3ZSBkb24ndCBhZGQgaXQgdG8gdGhlIGRlbGV0aW9uXG4gICAgICAgICAgICAvLyBsaXN0LlxuICAgICAgICAgICAgZXhpc3RpbmdDaGlsZHJlbi5kZWxldGUoX25ld0ZpYmVyMi5rZXkgPT09IG51bGwgPyBuZXdJZHggOiBfbmV3RmliZXIyLmtleSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChfbmV3RmliZXIyLCBsYXN0UGxhY2VkSW5kZXgsIG5ld0lkeCk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICByZXN1bHRpbmdGaXJzdENoaWxkID0gX25ld0ZpYmVyMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2aW91c05ld0ZpYmVyLnNpYmxpbmcgPSBfbmV3RmliZXIyO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJldmlvdXNOZXdGaWJlciA9IF9uZXdGaWJlcjI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFRyYWNrU2lkZUVmZmVjdHMpIHtcbiAgICAgIC8vIEFueSBleGlzdGluZyBjaGlsZHJlbiB0aGF0IHdlcmVuJ3QgY29uc3VtZWQgYWJvdmUgd2VyZSBkZWxldGVkLiBXZSBuZWVkXG4gICAgICAvLyB0byBhZGQgdGhlbSB0byB0aGUgZGVsZXRpb24gbGlzdC5cbiAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIGRlbGV0ZUNoaWxkKHJldHVybkZpYmVyLCBjaGlsZCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgdmFyIF9udW1iZXJPZkZvcmtzMiA9IG5ld0lkeDtcbiAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgX251bWJlck9mRm9ya3MyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0aW5nRmlyc3RDaGlsZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZUNoaWxkcmVuSXRlcmF0b3IocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZHJlbkl0ZXJhYmxlLCBsYW5lcykge1xuICAgIC8vIFRoaXMgaXMgdGhlIHNhbWUgaW1wbGVtZW50YXRpb24gYXMgcmVjb25jaWxlQ2hpbGRyZW5BcnJheSgpLFxuICAgIC8vIGJ1dCB1c2luZyB0aGUgaXRlcmF0b3IgaW5zdGVhZC5cbiAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4obmV3Q2hpbGRyZW5JdGVyYWJsZSk7XG5cbiAgICBpZiAodHlwZW9mIGl0ZXJhdG9yRm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gb2JqZWN0IGlzIG5vdCBhbiBpdGVyYWJsZS4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnIGluICcgKyAnUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgcmVuZGVyaW5nIEdlbmVyYXRvcnMgYmVjYXVzZSBpdCdzIGEgbXV0YXRpb24uXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMjk5NVxuICAgICAgaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgLy8gJEZsb3dGaXhNZSBGbG93IGRvZXNuJ3Qga25vdyBhYm91dCB0b1N0cmluZ1RhZ1xuICAgICAgbmV3Q2hpbGRyZW5JdGVyYWJsZVtTeW1ib2wudG9TdHJpbmdUYWddID09PSAnR2VuZXJhdG9yJykge1xuICAgICAgICBpZiAoIWRpZFdhcm5BYm91dEdlbmVyYXRvcnMpIHtcbiAgICAgICAgICBlcnJvcignVXNpbmcgR2VuZXJhdG9ycyBhcyBjaGlsZHJlbiBpcyB1bnN1cHBvcnRlZCBhbmQgd2lsbCBsaWtlbHkgeWllbGQgJyArICd1bmV4cGVjdGVkIHJlc3VsdHMgYmVjYXVzZSBlbnVtZXJhdGluZyBhIGdlbmVyYXRvciBtdXRhdGVzIGl0LiAnICsgJ1lvdSBtYXkgY29udmVydCBpdCB0byBhbiBhcnJheSB3aXRoIGBBcnJheS5mcm9tKClgIG9yIHRoZSAnICsgJ2BbLi4uc3ByZWFkXWAgb3BlcmF0b3IgYmVmb3JlIHJlbmRlcmluZy4gS2VlcCBpbiBtaW5kICcgKyAneW91IG1pZ2h0IG5lZWQgdG8gcG9seWZpbGwgdGhlc2UgZmVhdHVyZXMgZm9yIG9sZGVyIGJyb3dzZXJzLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGlkV2FybkFib3V0R2VuZXJhdG9ycyA9IHRydWU7XG4gICAgICB9IC8vIFdhcm4gYWJvdXQgdXNpbmcgTWFwcyBhcyBjaGlsZHJlblxuXG5cbiAgICAgIGlmIChuZXdDaGlsZHJlbkl0ZXJhYmxlLmVudHJpZXMgPT09IGl0ZXJhdG9yRm4pIHtcbiAgICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNYXBzKSB7XG4gICAgICAgICAgZXJyb3IoJ1VzaW5nIE1hcHMgYXMgY2hpbGRyZW4gaXMgbm90IHN1cHBvcnRlZC4gJyArICdVc2UgYW4gYXJyYXkgb2Yga2V5ZWQgUmVhY3RFbGVtZW50cyBpbnN0ZWFkLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgZGlkV2FybkFib3V0TWFwcyA9IHRydWU7XG4gICAgICB9IC8vIEZpcnN0LCB2YWxpZGF0ZSBrZXlzLlxuICAgICAgLy8gV2UnbGwgZ2V0IGEgZGlmZmVyZW50IGl0ZXJhdG9yIGxhdGVyIGZvciB0aGUgbWFpbiBwYXNzLlxuXG5cbiAgICAgIHZhciBfbmV3Q2hpbGRyZW4gPSBpdGVyYXRvckZuLmNhbGwobmV3Q2hpbGRyZW5JdGVyYWJsZSk7XG5cbiAgICAgIGlmIChfbmV3Q2hpbGRyZW4pIHtcbiAgICAgICAgdmFyIGtub3duS2V5cyA9IG51bGw7XG5cbiAgICAgICAgdmFyIF9zdGVwID0gX25ld0NoaWxkcmVuLm5leHQoKTtcblxuICAgICAgICBmb3IgKDsgIV9zdGVwLmRvbmU7IF9zdGVwID0gX25ld0NoaWxkcmVuLm5leHQoKSkge1xuICAgICAgICAgIHZhciBjaGlsZCA9IF9zdGVwLnZhbHVlO1xuICAgICAgICAgIGtub3duS2V5cyA9IHdhcm5PbkludmFsaWRLZXkoY2hpbGQsIGtub3duS2V5cywgcmV0dXJuRmliZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG5ld0NoaWxkcmVuID0gaXRlcmF0b3JGbi5jYWxsKG5ld0NoaWxkcmVuSXRlcmFibGUpO1xuXG4gICAgaWYgKG5ld0NoaWxkcmVuID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gaXRlcmFibGUgb2JqZWN0IHByb3ZpZGVkIG5vIGl0ZXJhdG9yLicpO1xuICAgIH1cblxuICAgIHZhciByZXN1bHRpbmdGaXJzdENoaWxkID0gbnVsbDtcbiAgICB2YXIgcHJldmlvdXNOZXdGaWJlciA9IG51bGw7XG4gICAgdmFyIG9sZEZpYmVyID0gY3VycmVudEZpcnN0Q2hpbGQ7XG4gICAgdmFyIGxhc3RQbGFjZWRJbmRleCA9IDA7XG4gICAgdmFyIG5ld0lkeCA9IDA7XG4gICAgdmFyIG5leHRPbGRGaWJlciA9IG51bGw7XG4gICAgdmFyIHN0ZXAgPSBuZXdDaGlsZHJlbi5uZXh0KCk7XG5cbiAgICBmb3IgKDsgb2xkRmliZXIgIT09IG51bGwgJiYgIXN0ZXAuZG9uZTsgbmV3SWR4KyssIHN0ZXAgPSBuZXdDaGlsZHJlbi5uZXh0KCkpIHtcbiAgICAgIGlmIChvbGRGaWJlci5pbmRleCA+IG5ld0lkeCkge1xuICAgICAgICBuZXh0T2xkRmliZXIgPSBvbGRGaWJlcjtcbiAgICAgICAgb2xkRmliZXIgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dE9sZEZpYmVyID0gb2xkRmliZXIuc2libGluZztcbiAgICAgIH1cblxuICAgICAgdmFyIG5ld0ZpYmVyID0gdXBkYXRlU2xvdChyZXR1cm5GaWJlciwgb2xkRmliZXIsIHN0ZXAudmFsdWUsIGxhbmVzKTtcblxuICAgICAgaWYgKG5ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgIC8vIFRPRE86IFRoaXMgYnJlYWtzIG9uIGVtcHR5IHNsb3RzIGxpa2UgbnVsbCBjaGlsZHJlbi4gVGhhdCdzXG4gICAgICAgIC8vIHVuZm9ydHVuYXRlIGJlY2F1c2UgaXQgdHJpZ2dlcnMgdGhlIHNsb3cgcGF0aCBhbGwgdGhlIHRpbWUuIFdlIG5lZWRcbiAgICAgICAgLy8gYSBiZXR0ZXIgd2F5IHRvIGNvbW11bmljYXRlIHdoZXRoZXIgdGhpcyB3YXMgYSBtaXNzIG9yIG51bGwsXG4gICAgICAgIC8vIGJvb2xlYW4sIHVuZGVmaW5lZCwgZXRjLlxuICAgICAgICBpZiAob2xkRmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICBvbGRGaWJlciA9IG5leHRPbGRGaWJlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgICBpZiAob2xkRmliZXIgJiYgbmV3RmliZXIuYWx0ZXJuYXRlID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UgbWF0Y2hlZCB0aGUgc2xvdCwgYnV0IHdlIGRpZG4ndCByZXVzZSB0aGUgZXhpc3RpbmcgZmliZXIsIHNvIHdlXG4gICAgICAgICAgLy8gbmVlZCB0byBkZWxldGUgdGhlIGV4aXN0aW5nIGNoaWxkLlxuICAgICAgICAgIGRlbGV0ZUNoaWxkKHJldHVybkZpYmVyLCBvbGRGaWJlcik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChuZXdGaWJlciwgbGFzdFBsYWNlZEluZGV4LCBuZXdJZHgpO1xuXG4gICAgICBpZiAocHJldmlvdXNOZXdGaWJlciA9PT0gbnVsbCkge1xuICAgICAgICAvLyBUT0RPOiBNb3ZlIG91dCBvZiB0aGUgbG9vcC4gVGhpcyBvbmx5IGhhcHBlbnMgZm9yIHRoZSBmaXJzdCBydW4uXG4gICAgICAgIHJlc3VsdGluZ0ZpcnN0Q2hpbGQgPSBuZXdGaWJlcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE86IERlZmVyIHNpYmxpbmdzIGlmIHdlJ3JlIG5vdCBhdCB0aGUgcmlnaHQgaW5kZXggZm9yIHRoaXMgc2xvdC5cbiAgICAgICAgLy8gSS5lLiBpZiB3ZSBoYWQgbnVsbCB2YWx1ZXMgYmVmb3JlLCB0aGVuIHdlIHdhbnQgdG8gZGVmZXIgdGhpc1xuICAgICAgICAvLyBmb3IgZWFjaCBudWxsIHZhbHVlLiBIb3dldmVyLCB3ZSBhbHNvIGRvbid0IHdhbnQgdG8gY2FsbCB1cGRhdGVTbG90XG4gICAgICAgIC8vIHdpdGggdGhlIHByZXZpb3VzIG9uZS5cbiAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gbmV3RmliZXI7XG4gICAgICB9XG5cbiAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBuZXdGaWJlcjtcbiAgICAgIG9sZEZpYmVyID0gbmV4dE9sZEZpYmVyO1xuICAgIH1cblxuICAgIGlmIChzdGVwLmRvbmUpIHtcbiAgICAgIC8vIFdlJ3ZlIHJlYWNoZWQgdGhlIGVuZCBvZiB0aGUgbmV3IGNoaWxkcmVuLiBXZSBjYW4gZGVsZXRlIHRoZSByZXN0LlxuICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTtcblxuICAgICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgICAgdmFyIG51bWJlck9mRm9ya3MgPSBuZXdJZHg7XG4gICAgICAgIHB1c2hUcmVlRm9yayhyZXR1cm5GaWJlciwgbnVtYmVyT2ZGb3Jrcyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH1cblxuICAgIGlmIChvbGRGaWJlciA9PT0gbnVsbCkge1xuICAgICAgLy8gSWYgd2UgZG9uJ3QgaGF2ZSBhbnkgbW9yZSBleGlzdGluZyBjaGlsZHJlbiB3ZSBjYW4gY2hvb3NlIGEgZmFzdCBwYXRoXG4gICAgICAvLyBzaW5jZSB0aGUgcmVzdCB3aWxsIGFsbCBiZSBpbnNlcnRpb25zLlxuICAgICAgZm9yICg7ICFzdGVwLmRvbmU7IG5ld0lkeCsrLCBzdGVwID0gbmV3Q2hpbGRyZW4ubmV4dCgpKSB7XG4gICAgICAgIHZhciBfbmV3RmliZXIzID0gY3JlYXRlQ2hpbGQocmV0dXJuRmliZXIsIHN0ZXAudmFsdWUsIGxhbmVzKTtcblxuICAgICAgICBpZiAoX25ld0ZpYmVyMyA9PT0gbnVsbCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgbGFzdFBsYWNlZEluZGV4ID0gcGxhY2VDaGlsZChfbmV3RmliZXIzLCBsYXN0UGxhY2VkSW5kZXgsIG5ld0lkeCk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzTmV3RmliZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBUT0RPOiBNb3ZlIG91dCBvZiB0aGUgbG9vcC4gVGhpcyBvbmx5IGhhcHBlbnMgZm9yIHRoZSBmaXJzdCBydW4uXG4gICAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IF9uZXdGaWJlcjM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gX25ld0ZpYmVyMztcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXIzO1xuICAgICAgfVxuXG4gICAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSkge1xuICAgICAgICB2YXIgX251bWJlck9mRm9ya3MzID0gbmV3SWR4O1xuICAgICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIF9udW1iZXJPZkZvcmtzMyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRpbmdGaXJzdENoaWxkO1xuICAgIH0gLy8gQWRkIGFsbCBjaGlsZHJlbiB0byBhIGtleSBtYXAgZm9yIHF1aWNrIGxvb2t1cHMuXG5cblxuICAgIHZhciBleGlzdGluZ0NoaWxkcmVuID0gbWFwUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIG9sZEZpYmVyKTsgLy8gS2VlcCBzY2FubmluZyBhbmQgdXNlIHRoZSBtYXAgdG8gcmVzdG9yZSBkZWxldGVkIGl0ZW1zIGFzIG1vdmVzLlxuXG4gICAgZm9yICg7ICFzdGVwLmRvbmU7IG5ld0lkeCsrLCBzdGVwID0gbmV3Q2hpbGRyZW4ubmV4dCgpKSB7XG4gICAgICB2YXIgX25ld0ZpYmVyNCA9IHVwZGF0ZUZyb21NYXAoZXhpc3RpbmdDaGlsZHJlbiwgcmV0dXJuRmliZXIsIG5ld0lkeCwgc3RlcC52YWx1ZSwgbGFuZXMpO1xuXG4gICAgICBpZiAoX25ld0ZpYmVyNCAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoc2hvdWxkVHJhY2tTaWRlRWZmZWN0cykge1xuICAgICAgICAgIGlmIChfbmV3RmliZXI0LmFsdGVybmF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gVGhlIG5ldyBmaWJlciBpcyBhIHdvcmsgaW4gcHJvZ3Jlc3MsIGJ1dCBpZiB0aGVyZSBleGlzdHMgYVxuICAgICAgICAgICAgLy8gY3VycmVudCwgdGhhdCBtZWFucyB0aGF0IHdlIHJldXNlZCB0aGUgZmliZXIuIFdlIG5lZWQgdG8gZGVsZXRlXG4gICAgICAgICAgICAvLyBpdCBmcm9tIHRoZSBjaGlsZCBsaXN0IHNvIHRoYXQgd2UgZG9uJ3QgYWRkIGl0IHRvIHRoZSBkZWxldGlvblxuICAgICAgICAgICAgLy8gbGlzdC5cbiAgICAgICAgICAgIGV4aXN0aW5nQ2hpbGRyZW4uZGVsZXRlKF9uZXdGaWJlcjQua2V5ID09PSBudWxsID8gbmV3SWR4IDogX25ld0ZpYmVyNC5rZXkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxhc3RQbGFjZWRJbmRleCA9IHBsYWNlQ2hpbGQoX25ld0ZpYmVyNCwgbGFzdFBsYWNlZEluZGV4LCBuZXdJZHgpO1xuXG4gICAgICAgIGlmIChwcmV2aW91c05ld0ZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgcmVzdWx0aW5nRmlyc3RDaGlsZCA9IF9uZXdGaWJlcjQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNOZXdGaWJlci5zaWJsaW5nID0gX25ld0ZpYmVyNDtcbiAgICAgICAgfVxuXG4gICAgICAgIHByZXZpb3VzTmV3RmliZXIgPSBfbmV3RmliZXI0O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzaG91bGRUcmFja1NpZGVFZmZlY3RzKSB7XG4gICAgICAvLyBBbnkgZXhpc3RpbmcgY2hpbGRyZW4gdGhhdCB3ZXJlbid0IGNvbnN1bWVkIGFib3ZlIHdlcmUgZGVsZXRlZC4gV2UgbmVlZFxuICAgICAgLy8gdG8gYWRkIHRoZW0gdG8gdGhlIGRlbGV0aW9uIGxpc3QuXG4gICAgICBleGlzdGluZ0NoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIHJldHVybiBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAgIHZhciBfbnVtYmVyT2ZGb3JrczQgPSBuZXdJZHg7XG4gICAgICBwdXNoVHJlZUZvcmsocmV0dXJuRmliZXIsIF9udW1iZXJPZkZvcmtzNCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdGluZ0ZpcnN0Q2hpbGQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWNvbmNpbGVTaW5nbGVUZXh0Tm9kZShyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIHRleHRDb250ZW50LCBsYW5lcykge1xuICAgIC8vIFRoZXJlJ3Mgbm8gbmVlZCB0byBjaGVjayBmb3Iga2V5cyBvbiB0ZXh0IG5vZGVzIHNpbmNlIHdlIGRvbid0IGhhdmUgYVxuICAgIC8vIHdheSB0byBkZWZpbmUgdGhlbS5cbiAgICBpZiAoY3VycmVudEZpcnN0Q2hpbGQgIT09IG51bGwgJiYgY3VycmVudEZpcnN0Q2hpbGQudGFnID09PSBIb3N0VGV4dCkge1xuICAgICAgLy8gV2UgYWxyZWFkeSBoYXZlIGFuIGV4aXN0aW5nIG5vZGUgc28gbGV0J3MganVzdCB1cGRhdGUgaXQgYW5kIGRlbGV0ZVxuICAgICAgLy8gdGhlIHJlc3QuXG4gICAgICBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQuc2libGluZyk7XG4gICAgICB2YXIgZXhpc3RpbmcgPSB1c2VGaWJlcihjdXJyZW50Rmlyc3RDaGlsZCwgdGV4dENvbnRlbnQpO1xuICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgfSAvLyBUaGUgZXhpc3RpbmcgZmlyc3QgY2hpbGQgaXMgbm90IGEgdGV4dCBub2RlIHNvIHdlIG5lZWQgdG8gY3JlYXRlIG9uZVxuICAgIC8vIGFuZCBkZWxldGUgdGhlIGV4aXN0aW5nIG9uZXMuXG5cblxuICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCk7XG4gICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21UZXh0KHRleHRDb250ZW50LCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG4gICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICByZXR1cm4gY3JlYXRlZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZVNpbmdsZUVsZW1lbnQocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBlbGVtZW50LCBsYW5lcykge1xuICAgIHZhciBrZXkgPSBlbGVtZW50LmtleTtcbiAgICB2YXIgY2hpbGQgPSBjdXJyZW50Rmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSWYga2V5ID09PSBudWxsIGFuZCBjaGlsZC5rZXkgPT09IG51bGwsIHRoZW4gdGhpcyBvbmx5IGFwcGxpZXMgdG9cbiAgICAgIC8vIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBsaXN0LlxuICAgICAgaWYgKGNoaWxkLmtleSA9PT0ga2V5KSB7XG4gICAgICAgIHZhciBlbGVtZW50VHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgICAgICBpZiAoZWxlbWVudFR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUpIHtcbiAgICAgICAgICBpZiAoY2hpbGQudGFnID09PSBGcmFnbWVudCkge1xuICAgICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkLnNpYmxpbmcpO1xuICAgICAgICAgICAgdmFyIGV4aXN0aW5nID0gdXNlRmliZXIoY2hpbGQsIGVsZW1lbnQucHJvcHMuY2hpbGRyZW4pO1xuICAgICAgICAgICAgZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXhpc3RpbmcuX2RlYnVnU291cmNlID0gZWxlbWVudC5fc291cmNlO1xuICAgICAgICAgICAgICBleGlzdGluZy5fZGVidWdPd25lciA9IGVsZW1lbnQuX293bmVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZXhpc3Rpbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjaGlsZC5lbGVtZW50VHlwZSA9PT0gZWxlbWVudFR5cGUgfHwgKCAvLyBLZWVwIHRoaXMgY2hlY2sgaW5saW5lIHNvIGl0IG9ubHkgcnVucyBvbiB0aGUgZmFsc2UgcGF0aDpcbiAgICAgICAgICAgaXNDb21wYXRpYmxlRmFtaWx5Rm9ySG90UmVsb2FkaW5nKGNoaWxkLCBlbGVtZW50KSApIHx8IC8vIExhenkgdHlwZXMgc2hvdWxkIHJlY29uY2lsZSB0aGVpciByZXNvbHZlZCB0eXBlLlxuICAgICAgICAgIC8vIFdlIG5lZWQgdG8gZG8gdGhpcyBhZnRlciB0aGUgSG90IFJlbG9hZGluZyBjaGVjayBhYm92ZSxcbiAgICAgICAgICAvLyBiZWNhdXNlIGhvdCByZWxvYWRpbmcgaGFzIGRpZmZlcmVudCBzZW1hbnRpY3MgdGhhbiBwcm9kIGJlY2F1c2VcbiAgICAgICAgICAvLyBpdCBkb2Vzbid0IHJlc3VzcGVuZC4gU28gd2UgY2FuJ3QgbGV0IHRoZSBjYWxsIGJlbG93IHN1c3BlbmQuXG4gICAgICAgICAgdHlwZW9mIGVsZW1lbnRUeXBlID09PSAnb2JqZWN0JyAmJiBlbGVtZW50VHlwZSAhPT0gbnVsbCAmJiBlbGVtZW50VHlwZS4kJHR5cGVvZiA9PT0gUkVBQ1RfTEFaWV9UWVBFICYmIHJlc29sdmVMYXp5KGVsZW1lbnRUeXBlKSA9PT0gY2hpbGQudHlwZSkge1xuICAgICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkLnNpYmxpbmcpO1xuXG4gICAgICAgICAgICB2YXIgX2V4aXN0aW5nID0gdXNlRmliZXIoY2hpbGQsIGVsZW1lbnQucHJvcHMpO1xuXG4gICAgICAgICAgICBfZXhpc3RpbmcucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjaGlsZCwgZWxlbWVudCk7XG4gICAgICAgICAgICBfZXhpc3RpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgX2V4aXN0aW5nLl9kZWJ1Z1NvdXJjZSA9IGVsZW1lbnQuX3NvdXJjZTtcbiAgICAgICAgICAgICAgX2V4aXN0aW5nLl9kZWJ1Z093bmVyID0gZWxlbWVudC5fb3duZXI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBfZXhpc3Rpbmc7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIERpZG4ndCBtYXRjaC5cblxuXG4gICAgICAgIGRlbGV0ZVJlbWFpbmluZ0NoaWxkcmVuKHJldHVybkZpYmVyLCBjaGlsZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlQ2hpbGQocmV0dXJuRmliZXIsIGNoaWxkKTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50LnR5cGUgPT09IFJFQUNUX0ZSQUdNRU5UX1RZUEUpIHtcbiAgICAgIHZhciBjcmVhdGVkID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZWxlbWVudC5wcm9wcy5jaGlsZHJlbiwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMsIGVsZW1lbnQua2V5KTtcbiAgICAgIGNyZWF0ZWQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gY3JlYXRlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9jcmVhdGVkNCA9IGNyZWF0ZUZpYmVyRnJvbUVsZW1lbnQoZWxlbWVudCwgcmV0dXJuRmliZXIubW9kZSwgbGFuZXMpO1xuXG4gICAgICBfY3JlYXRlZDQucmVmID0gY29lcmNlUmVmKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgZWxlbWVudCk7XG4gICAgICBfY3JlYXRlZDQucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICByZXR1cm4gX2NyZWF0ZWQ0O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlY29uY2lsZVNpbmdsZVBvcnRhbChyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIHBvcnRhbCwgbGFuZXMpIHtcbiAgICB2YXIga2V5ID0gcG9ydGFsLmtleTtcbiAgICB2YXIgY2hpbGQgPSBjdXJyZW50Rmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSWYga2V5ID09PSBudWxsIGFuZCBjaGlsZC5rZXkgPT09IG51bGwsIHRoZW4gdGhpcyBvbmx5IGFwcGxpZXMgdG9cbiAgICAgIC8vIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBsaXN0LlxuICAgICAgaWYgKGNoaWxkLmtleSA9PT0ga2V5KSB7XG4gICAgICAgIGlmIChjaGlsZC50YWcgPT09IEhvc3RQb3J0YWwgJiYgY2hpbGQuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8gPT09IHBvcnRhbC5jb250YWluZXJJbmZvICYmIGNoaWxkLnN0YXRlTm9kZS5pbXBsZW1lbnRhdGlvbiA9PT0gcG9ydGFsLmltcGxlbWVudGF0aW9uKSB7XG4gICAgICAgICAgZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGNoaWxkLnNpYmxpbmcpO1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IHVzZUZpYmVyKGNoaWxkLCBwb3J0YWwuY2hpbGRyZW4gfHwgW10pO1xuICAgICAgICAgIGV4aXN0aW5nLnJldHVybiA9IHJldHVybkZpYmVyO1xuICAgICAgICAgIHJldHVybiBleGlzdGluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZWxldGVSZW1haW5pbmdDaGlsZHJlbihyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGVDaGlsZChyZXR1cm5GaWJlciwgY2hpbGQpO1xuICAgICAgfVxuXG4gICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgfVxuXG4gICAgdmFyIGNyZWF0ZWQgPSBjcmVhdGVGaWJlckZyb21Qb3J0YWwocG9ydGFsLCByZXR1cm5GaWJlci5tb2RlLCBsYW5lcyk7XG4gICAgY3JlYXRlZC5yZXR1cm4gPSByZXR1cm5GaWJlcjtcbiAgICByZXR1cm4gY3JlYXRlZDtcbiAgfSAvLyBUaGlzIEFQSSB3aWxsIHRhZyB0aGUgY2hpbGRyZW4gd2l0aCB0aGUgc2lkZS1lZmZlY3Qgb2YgdGhlIHJlY29uY2lsaWF0aW9uXG4gIC8vIGl0c2VsZi4gVGhleSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBzaWRlLWVmZmVjdCBsaXN0IGFzIHdlIHBhc3MgdGhyb3VnaCB0aGVcbiAgLy8gY2hpbGRyZW4gYW5kIHRoZSBwYXJlbnQuXG5cblxuICBmdW5jdGlvbiByZWNvbmNpbGVDaGlsZEZpYmVycyhyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIG5ld0NoaWxkLCBsYW5lcykge1xuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IHJlY3Vyc2l2ZS5cbiAgICAvLyBJZiB0aGUgdG9wIGxldmVsIGl0ZW0gaXMgYW4gYXJyYXksIHdlIHRyZWF0IGl0IGFzIGEgc2V0IG9mIGNoaWxkcmVuLFxuICAgIC8vIG5vdCBhcyBhIGZyYWdtZW50LiBOZXN0ZWQgYXJyYXlzIG9uIHRoZSBvdGhlciBoYW5kIHdpbGwgYmUgdHJlYXRlZCBhc1xuICAgIC8vIGZyYWdtZW50IG5vZGVzLiBSZWN1cnNpb24gaGFwcGVucyBhdCB0aGUgbm9ybWFsIGZsb3cuXG4gICAgLy8gSGFuZGxlIHRvcCBsZXZlbCB1bmtleWVkIGZyYWdtZW50cyBhcyBpZiB0aGV5IHdlcmUgYXJyYXlzLlxuICAgIC8vIFRoaXMgbGVhZHMgdG8gYW4gYW1iaWd1aXR5IGJldHdlZW4gPD57Wy4uLl19PC8+IGFuZCA8Pi4uLjwvPi5cbiAgICAvLyBXZSB0cmVhdCB0aGUgYW1iaWd1b3VzIGNhc2VzIGFib3ZlIHRoZSBzYW1lLlxuICAgIHZhciBpc1Vua2V5ZWRUb3BMZXZlbEZyYWdtZW50ID0gdHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCAmJiBuZXdDaGlsZC50eXBlID09PSBSRUFDVF9GUkFHTUVOVF9UWVBFICYmIG5ld0NoaWxkLmtleSA9PT0gbnVsbDtcblxuICAgIGlmIChpc1Vua2V5ZWRUb3BMZXZlbEZyYWdtZW50KSB7XG4gICAgICBuZXdDaGlsZCA9IG5ld0NoaWxkLnByb3BzLmNoaWxkcmVuO1xuICAgIH0gLy8gSGFuZGxlIG9iamVjdCB0eXBlc1xuXG5cbiAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnb2JqZWN0JyAmJiBuZXdDaGlsZCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChuZXdDaGlsZC4kJHR5cGVvZikge1xuICAgICAgICBjYXNlIFJFQUNUX0VMRU1FTlRfVFlQRTpcbiAgICAgICAgICByZXR1cm4gcGxhY2VTaW5nbGVDaGlsZChyZWNvbmNpbGVTaW5nbGVFbGVtZW50KHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKSk7XG5cbiAgICAgICAgY2FzZSBSRUFDVF9QT1JUQUxfVFlQRTpcbiAgICAgICAgICByZXR1cm4gcGxhY2VTaW5nbGVDaGlsZChyZWNvbmNpbGVTaW5nbGVQb3J0YWwocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkLCBuZXdDaGlsZCwgbGFuZXMpKTtcblxuICAgICAgICBjYXNlIFJFQUNUX0xBWllfVFlQRTpcbiAgICAgICAgICB2YXIgcGF5bG9hZCA9IG5ld0NoaWxkLl9wYXlsb2FkO1xuICAgICAgICAgIHZhciBpbml0ID0gbmV3Q2hpbGQuX2luaXQ7IC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gaXMgc3VwcG9zZWQgdG8gYmUgbm9uLXJlY3Vyc2l2ZS5cblxuICAgICAgICAgIHJldHVybiByZWNvbmNpbGVDaGlsZEZpYmVycyhyZXR1cm5GaWJlciwgY3VycmVudEZpcnN0Q2hpbGQsIGluaXQocGF5bG9hZCksIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkobmV3Q2hpbGQpKSB7XG4gICAgICAgIHJldHVybiByZWNvbmNpbGVDaGlsZHJlbkFycmF5KHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdldEl0ZXJhdG9yRm4obmV3Q2hpbGQpKSB7XG4gICAgICAgIHJldHVybiByZWNvbmNpbGVDaGlsZHJlbkl0ZXJhdG9yKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgbmV3Q2hpbGQsIGxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3dPbkludmFsaWRPYmplY3RUeXBlKHJldHVybkZpYmVyLCBuZXdDaGlsZCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBuZXdDaGlsZCA9PT0gJ3N0cmluZycgJiYgbmV3Q2hpbGQgIT09ICcnIHx8IHR5cGVvZiBuZXdDaGlsZCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBwbGFjZVNpbmdsZUNoaWxkKHJlY29uY2lsZVNpbmdsZVRleHROb2RlKHJldHVybkZpYmVyLCBjdXJyZW50Rmlyc3RDaGlsZCwgJycgKyBuZXdDaGlsZCwgbGFuZXMpKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHdhcm5PbkZ1bmN0aW9uVHlwZShyZXR1cm5GaWJlcik7XG4gICAgICB9XG4gICAgfSAvLyBSZW1haW5pbmcgY2FzZXMgYXJlIGFsbCB0cmVhdGVkIGFzIGVtcHR5LlxuXG5cbiAgICByZXR1cm4gZGVsZXRlUmVtYWluaW5nQ2hpbGRyZW4ocmV0dXJuRmliZXIsIGN1cnJlbnRGaXJzdENoaWxkKTtcbiAgfVxuXG4gIHJldHVybiByZWNvbmNpbGVDaGlsZEZpYmVycztcbn1cblxudmFyIHJlY29uY2lsZUNoaWxkRmliZXJzID0gQ2hpbGRSZWNvbmNpbGVyKHRydWUpO1xudmFyIG1vdW50Q2hpbGRGaWJlcnMgPSBDaGlsZFJlY29uY2lsZXIoZmFsc2UpO1xuZnVuY3Rpb24gY2xvbmVDaGlsZEZpYmVycyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcykge1xuICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiB3b3JrSW5Qcm9ncmVzcy5jaGlsZCAhPT0gY3VycmVudC5jaGlsZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVzdW1pbmcgd29yayBub3QgeWV0IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzLmNoaWxkID09PSBudWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGN1cnJlbnRDaGlsZCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICB2YXIgbmV3Q2hpbGQgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50Q2hpbGQsIGN1cnJlbnRDaGlsZC5wZW5kaW5nUHJvcHMpO1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IG5ld0NoaWxkO1xuICBuZXdDaGlsZC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcblxuICB3aGlsZSAoY3VycmVudENoaWxkLnNpYmxpbmcgIT09IG51bGwpIHtcbiAgICBjdXJyZW50Q2hpbGQgPSBjdXJyZW50Q2hpbGQuc2libGluZztcbiAgICBuZXdDaGlsZCA9IG5ld0NoaWxkLnNpYmxpbmcgPSBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50Q2hpbGQsIGN1cnJlbnRDaGlsZC5wZW5kaW5nUHJvcHMpO1xuICAgIG5ld0NoaWxkLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB9XG5cbiAgbmV3Q2hpbGQuc2libGluZyA9IG51bGw7XG59IC8vIFJlc2V0IGEgd29ya0luUHJvZ3Jlc3MgY2hpbGQgc2V0IHRvIHByZXBhcmUgaXQgZm9yIGEgc2Vjb25kIHBhc3MuXG5cbmZ1bmN0aW9uIHJlc2V0Q2hpbGRGaWJlcnMod29ya0luUHJvZ3Jlc3MsIGxhbmVzKSB7XG4gIHZhciBjaGlsZCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgIHJlc2V0V29ya0luUHJvZ3Jlc3MoY2hpbGQsIGxhbmVzKTtcbiAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gIH1cbn1cblxudmFyIE5PX0NPTlRFWFQgPSB7fTtcbnZhciBjb250ZXh0U3RhY2tDdXJzb3IkMSA9IGNyZWF0ZUN1cnNvcihOT19DT05URVhUKTtcbnZhciBjb250ZXh0RmliZXJTdGFja0N1cnNvciA9IGNyZWF0ZUN1cnNvcihOT19DT05URVhUKTtcbnZhciByb290SW5zdGFuY2VTdGFja0N1cnNvciA9IGNyZWF0ZUN1cnNvcihOT19DT05URVhUKTtcblxuZnVuY3Rpb24gcmVxdWlyZWRDb250ZXh0KGMpIHtcbiAgaWYgKGMgPT09IE5PX0NPTlRFWFQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGhvc3QgY29udGV4dCB0byBleGlzdC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5IGEgYnVnICcgKyAnaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgcmV0dXJuIGM7XG59XG5cbmZ1bmN0aW9uIGdldFJvb3RIb3N0Q29udGFpbmVyKCkge1xuICB2YXIgcm9vdEluc3RhbmNlID0gcmVxdWlyZWRDb250ZXh0KHJvb3RJbnN0YW5jZVN0YWNrQ3Vyc29yLmN1cnJlbnQpO1xuICByZXR1cm4gcm9vdEluc3RhbmNlO1xufVxuXG5mdW5jdGlvbiBwdXNoSG9zdENvbnRhaW5lcihmaWJlciwgbmV4dFJvb3RJbnN0YW5jZSkge1xuICAvLyBQdXNoIGN1cnJlbnQgcm9vdCBpbnN0YW5jZSBvbnRvIHRoZSBzdGFjaztcbiAgLy8gVGhpcyBhbGxvd3MgdXMgdG8gcmVzZXQgcm9vdCB3aGVuIHBvcnRhbHMgYXJlIHBvcHBlZC5cbiAgcHVzaChyb290SW5zdGFuY2VTdGFja0N1cnNvciwgbmV4dFJvb3RJbnN0YW5jZSwgZmliZXIpOyAvLyBUcmFjayB0aGUgY29udGV4dCBhbmQgdGhlIEZpYmVyIHRoYXQgcHJvdmlkZWQgaXQuXG4gIC8vIFRoaXMgZW5hYmxlcyB1cyB0byBwb3Agb25seSBGaWJlcnMgdGhhdCBwcm92aWRlIHVuaXF1ZSBjb250ZXh0cy5cblxuICBwdXNoKGNvbnRleHRGaWJlclN0YWNrQ3Vyc29yLCBmaWJlciwgZmliZXIpOyAvLyBGaW5hbGx5LCB3ZSBuZWVkIHRvIHB1c2ggdGhlIGhvc3QgY29udGV4dCB0byB0aGUgc3RhY2suXG4gIC8vIEhvd2V2ZXIsIHdlIGNhbid0IGp1c3QgY2FsbCBnZXRSb290SG9zdENvbnRleHQoKSBhbmQgcHVzaCBpdCBiZWNhdXNlXG4gIC8vIHdlJ2QgaGF2ZSBhIGRpZmZlcmVudCBudW1iZXIgb2YgZW50cmllcyBvbiB0aGUgc3RhY2sgZGVwZW5kaW5nIG9uXG4gIC8vIHdoZXRoZXIgZ2V0Um9vdEhvc3RDb250ZXh0KCkgdGhyb3dzIHNvbWV3aGVyZSBpbiByZW5kZXJlciBjb2RlIG9yIG5vdC5cbiAgLy8gU28gd2UgcHVzaCBhbiBlbXB0eSB2YWx1ZSBmaXJzdC4gVGhpcyBsZXRzIHVzIHNhZmVseSB1bndpbmQgb24gZXJyb3JzLlxuXG4gIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yJDEsIE5PX0NPTlRFWFQsIGZpYmVyKTtcbiAgdmFyIG5leHRSb290Q29udGV4dCA9IGdldFJvb3RIb3N0Q29udGV4dChuZXh0Um9vdEluc3RhbmNlKTsgLy8gTm93IHRoYXQgd2Uga25vdyB0aGlzIGZ1bmN0aW9uIGRvZXNuJ3QgdGhyb3csIHJlcGxhY2UgaXQuXG5cbiAgcG9wKGNvbnRleHRTdGFja0N1cnNvciQxLCBmaWJlcik7XG4gIHB1c2goY29udGV4dFN0YWNrQ3Vyc29yJDEsIG5leHRSb290Q29udGV4dCwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBwb3BIb3N0Q29udGFpbmVyKGZpYmVyKSB7XG4gIHBvcChjb250ZXh0U3RhY2tDdXJzb3IkMSwgZmliZXIpO1xuICBwb3AoY29udGV4dEZpYmVyU3RhY2tDdXJzb3IsIGZpYmVyKTtcbiAgcG9wKHJvb3RJbnN0YW5jZVN0YWNrQ3Vyc29yLCBmaWJlcik7XG59XG5cbmZ1bmN0aW9uIGdldEhvc3RDb250ZXh0KCkge1xuICB2YXIgY29udGV4dCA9IHJlcXVpcmVkQ29udGV4dChjb250ZXh0U3RhY2tDdXJzb3IkMS5jdXJyZW50KTtcbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbmZ1bmN0aW9uIHB1c2hIb3N0Q29udGV4dChmaWJlcikge1xuICB2YXIgcm9vdEluc3RhbmNlID0gcmVxdWlyZWRDb250ZXh0KHJvb3RJbnN0YW5jZVN0YWNrQ3Vyc29yLmN1cnJlbnQpO1xuICB2YXIgY29udGV4dCA9IHJlcXVpcmVkQ29udGV4dChjb250ZXh0U3RhY2tDdXJzb3IkMS5jdXJyZW50KTtcbiAgdmFyIG5leHRDb250ZXh0ID0gZ2V0Q2hpbGRIb3N0Q29udGV4dChjb250ZXh0LCBmaWJlci50eXBlKTsgLy8gRG9uJ3QgcHVzaCB0aGlzIEZpYmVyJ3MgY29udGV4dCB1bmxlc3MgaXQncyB1bmlxdWUuXG5cbiAgaWYgKGNvbnRleHQgPT09IG5leHRDb250ZXh0KSB7XG4gICAgcmV0dXJuO1xuICB9IC8vIFRyYWNrIHRoZSBjb250ZXh0IGFuZCB0aGUgRmliZXIgdGhhdCBwcm92aWRlZCBpdC5cbiAgLy8gVGhpcyBlbmFibGVzIHVzIHRvIHBvcCBvbmx5IEZpYmVycyB0aGF0IHByb3ZpZGUgdW5pcXVlIGNvbnRleHRzLlxuXG5cbiAgcHVzaChjb250ZXh0RmliZXJTdGFja0N1cnNvciwgZmliZXIsIGZpYmVyKTtcbiAgcHVzaChjb250ZXh0U3RhY2tDdXJzb3IkMSwgbmV4dENvbnRleHQsIGZpYmVyKTtcbn1cblxuZnVuY3Rpb24gcG9wSG9zdENvbnRleHQoZmliZXIpIHtcbiAgLy8gRG8gbm90IHBvcCB1bmxlc3MgdGhpcyBGaWJlciBwcm92aWRlZCB0aGUgY3VycmVudCBjb250ZXh0LlxuICAvLyBwdXNoSG9zdENvbnRleHQoKSBvbmx5IHB1c2hlcyBGaWJlcnMgdGhhdCBwcm92aWRlIHVuaXF1ZSBjb250ZXh0cy5cbiAgaWYgKGNvbnRleHRGaWJlclN0YWNrQ3Vyc29yLmN1cnJlbnQgIT09IGZpYmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcG9wKGNvbnRleHRTdGFja0N1cnNvciQxLCBmaWJlcik7XG4gIHBvcChjb250ZXh0RmliZXJTdGFja0N1cnNvciwgZmliZXIpO1xufVxuXG52YXIgRGVmYXVsdFN1c3BlbnNlQ29udGV4dCA9IDA7IC8vIFRoZSBTdXNwZW5zZSBDb250ZXh0IGlzIHNwbGl0IGludG8gdHdvIHBhcnRzLiBUaGUgbG93ZXIgYml0cyBpc1xuLy8gaW5oZXJpdGVkIGRlZXBseSBkb3duIHRoZSBzdWJ0cmVlLiBUaGUgdXBwZXIgYml0cyBvbmx5IGFmZmVjdFxuLy8gdGhpcyBpbW1lZGlhdGUgc3VzcGVuc2UgYm91bmRhcnkgYW5kIGdldHMgcmVzZXQgZWFjaCBuZXdcbi8vIGJvdW5kYXJ5IG9yIHN1c3BlbnNlIGxpc3QuXG5cbnZhciBTdWJ0cmVlU3VzcGVuc2VDb250ZXh0TWFzayA9IDE7IC8vIFN1YnRyZWUgRmxhZ3M6XG4vLyBJbnZpc2libGVQYXJlbnRTdXNwZW5zZUNvbnRleHQgaW5kaWNhdGVzIHRoYXQgb25lIG9mIG91ciBwYXJlbnQgU3VzcGVuc2Vcbi8vIGJvdW5kYXJpZXMgaXMgbm90IGN1cnJlbnRseSBzaG93aW5nIHZpc2libGUgbWFpbiBjb250ZW50LlxuLy8gRWl0aGVyIGJlY2F1c2UgaXQgaXMgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2sgb3IgaXMgbm90IG1vdW50ZWQgYXQgYWxsLlxuLy8gV2UgY2FuIHVzZSB0aGlzIHRvIGRldGVybWluZSBpZiBpdCBpcyBkZXNpcmFibGUgdG8gdHJpZ2dlciBhIGZhbGxiYWNrIGF0XG4vLyB0aGUgcGFyZW50LiBJZiBub3QsIHRoZW4gd2UgbWlnaHQgbmVlZCB0byB0cmlnZ2VyIHVuZGVzaXJhYmxlIGJvdW5kYXJpZXNcbi8vIGFuZC9vciBzdXNwZW5kIHRoZSBjb21taXQgdG8gYXZvaWQgaGlkaW5nIHRoZSBwYXJlbnQgY29udGVudC5cblxudmFyIEludmlzaWJsZVBhcmVudFN1c3BlbnNlQ29udGV4dCA9IDE7IC8vIFNoYWxsb3cgRmxhZ3M6XG4vLyBGb3JjZVN1c3BlbnNlRmFsbGJhY2sgY2FuIGJlIHVzZWQgYnkgU3VzcGVuc2VMaXN0IHRvIGZvcmNlIG5ld2x5IGFkZGVkXG4vLyBpdGVtcyBpbnRvIHRoZWlyIGZhbGxiYWNrIHN0YXRlIGR1cmluZyBvbmUgb2YgdGhlIHJlbmRlciBwYXNzZXMuXG5cbnZhciBGb3JjZVN1c3BlbnNlRmFsbGJhY2sgPSAyO1xudmFyIHN1c3BlbnNlU3RhY2tDdXJzb3IgPSBjcmVhdGVDdXJzb3IoRGVmYXVsdFN1c3BlbnNlQ29udGV4dCk7XG5mdW5jdGlvbiBoYXNTdXNwZW5zZUNvbnRleHQocGFyZW50Q29udGV4dCwgZmxhZykge1xuICByZXR1cm4gKHBhcmVudENvbnRleHQgJiBmbGFnKSAhPT0gMDtcbn1cbmZ1bmN0aW9uIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHBhcmVudENvbnRleHQpIHtcbiAgcmV0dXJuIHBhcmVudENvbnRleHQgJiBTdWJ0cmVlU3VzcGVuc2VDb250ZXh0TWFzaztcbn1cbmZ1bmN0aW9uIHNldFNoYWxsb3dTdXNwZW5zZUNvbnRleHQocGFyZW50Q29udGV4dCwgc2hhbGxvd0NvbnRleHQpIHtcbiAgcmV0dXJuIHBhcmVudENvbnRleHQgJiBTdWJ0cmVlU3VzcGVuc2VDb250ZXh0TWFzayB8IHNoYWxsb3dDb250ZXh0O1xufVxuZnVuY3Rpb24gYWRkU3VidHJlZVN1c3BlbnNlQ29udGV4dChwYXJlbnRDb250ZXh0LCBzdWJ0cmVlQ29udGV4dCkge1xuICByZXR1cm4gcGFyZW50Q29udGV4dCB8IHN1YnRyZWVDb250ZXh0O1xufVxuZnVuY3Rpb24gcHVzaFN1c3BlbnNlQ29udGV4dChmaWJlciwgbmV3Q29udGV4dCkge1xuICBwdXNoKHN1c3BlbnNlU3RhY2tDdXJzb3IsIG5ld0NvbnRleHQsIGZpYmVyKTtcbn1cbmZ1bmN0aW9uIHBvcFN1c3BlbnNlQ29udGV4dChmaWJlcikge1xuICBwb3Aoc3VzcGVuc2VTdGFja0N1cnNvciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRDYXB0dXJlU3VzcGVuc2Uod29ya0luUHJvZ3Jlc3MsIGhhc0ludmlzaWJsZVBhcmVudCkge1xuICAvLyBJZiBpdCB3YXMgdGhlIHByaW1hcnkgY2hpbGRyZW4gdGhhdCBqdXN0IHN1c3BlbmRlZCwgY2FwdHVyZSBhbmQgcmVuZGVyIHRoZVxuICAvLyBmYWxsYmFjay4gT3RoZXJ3aXNlLCBkb24ndCBjYXB0dXJlIGFuZCBidWJibGUgdG8gdGhlIG5leHQgYm91bmRhcnkuXG4gIHZhciBuZXh0U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChuZXh0U3RhdGUgIT09IG51bGwpIHtcbiAgICBpZiAobmV4dFN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICAgIC8vIEEgZGVoeWRyYXRlZCBib3VuZGFyeSBhbHdheXMgY2FwdHVyZXMuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgcHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzOyAvLyBSZWd1bGFyIGJvdW5kYXJpZXMgYWx3YXlzIGNhcHR1cmUuXG5cbiAge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIElmIGl0J3MgYSBib3VuZGFyeSB3ZSBzaG91bGQgYXZvaWQsIHRoZW4gd2UgcHJlZmVyIHRvIGJ1YmJsZSB1cCB0byB0aGVcbn1cbmZ1bmN0aW9uIGZpbmRGaXJzdFN1c3BlbmRlZChyb3cpIHtcbiAgdmFyIG5vZGUgPSByb3c7XG5cbiAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50KSB7XG4gICAgICB2YXIgc3RhdGUgPSBub2RlLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgIGlmIChzdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgZGVoeWRyYXRlZCA9IHN0YXRlLmRlaHlkcmF0ZWQ7XG5cbiAgICAgICAgaWYgKGRlaHlkcmF0ZWQgPT09IG51bGwgfHwgaXNTdXNwZW5zZUluc3RhbmNlUGVuZGluZyhkZWh5ZHJhdGVkKSB8fCBpc1N1c3BlbnNlSW5zdGFuY2VGYWxsYmFjayhkZWh5ZHJhdGVkKSkge1xuICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChub2RlLnRhZyA9PT0gU3VzcGVuc2VMaXN0Q29tcG9uZW50ICYmIC8vIHJldmVhbE9yZGVyIHVuZGVmaW5lZCBjYW4ndCBiZSB0cnVzdGVkIGJlY2F1c2UgaXQgZG9uJ3RcbiAgICAvLyBrZWVwIHRyYWNrIG9mIHdoZXRoZXIgaXQgc3VzcGVuZGVkIG9yIG5vdC5cbiAgICBub2RlLm1lbW9pemVkUHJvcHMucmV2ZWFsT3JkZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIGRpZFN1c3BlbmQgPSAobm9kZS5mbGFncyAmIERpZENhcHR1cmUpICE9PSBOb0ZsYWdzO1xuXG4gICAgICBpZiAoZGlkU3VzcGVuZCkge1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgPT09IHJvdykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSByb3cpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG52YXIgTm9GbGFncyQxID1cbi8qICAgKi9cbjA7IC8vIFJlcHJlc2VudHMgd2hldGhlciBlZmZlY3Qgc2hvdWxkIGZpcmUuXG5cbnZhciBIYXNFZmZlY3QgPVxuLyogKi9cbjE7IC8vIFJlcHJlc2VudHMgdGhlIHBoYXNlIGluIHdoaWNoIHRoZSBlZmZlY3QgKG5vdCB0aGUgY2xlYW4tdXApIGZpcmVzLlxuXG52YXIgSW5zZXJ0aW9uID1cbi8qICAqL1xuMjtcbnZhciBMYXlvdXQgPVxuLyogICAgKi9cbjQ7XG52YXIgUGFzc2l2ZSQxID1cbi8qICAgKi9cbjg7XG5cbi8vIGFuZCBzaG91bGQgYmUgcmVzZXQgYmVmb3JlIHN0YXJ0aW5nIGEgbmV3IHJlbmRlci5cbi8vIFRoaXMgdHJhY2tzIHdoaWNoIG11dGFibGUgc291cmNlcyBuZWVkIHRvIGJlIHJlc2V0IGFmdGVyIGEgcmVuZGVyLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NTb3VyY2VzID0gW107XG5mdW5jdGlvbiByZXNldFdvcmtJblByb2dyZXNzVmVyc2lvbnMoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgd29ya0luUHJvZ3Jlc3NTb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG11dGFibGVTb3VyY2UgPSB3b3JrSW5Qcm9ncmVzc1NvdXJjZXNbaV07XG5cbiAgICB7XG4gICAgICBtdXRhYmxlU291cmNlLl93b3JrSW5Qcm9ncmVzc1ZlcnNpb25QcmltYXJ5ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzc1NvdXJjZXMubGVuZ3RoID0gMDtcbn1cbi8vIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSB2ZXJzaW9uIHVzZWQgZm9yIHNlcnZlciByZW5kZXJpbmcgbWF0Y2hlcyB0aGUgb25lXG4vLyB0aGF0IGlzIGV2ZW50dWFsbHkgcmVhZCBkdXJpbmcgaHlkcmF0aW9uLlxuLy8gSWYgdGhleSBkb24ndCBtYXRjaCB0aGVyZSdzIGEgcG90ZW50aWFsIHRlYXIgYW5kIGEgZnVsbCBkZW9wdCByZW5kZXIgaXMgcmVxdWlyZWQuXG5cbmZ1bmN0aW9uIHJlZ2lzdGVyTXV0YWJsZVNvdXJjZUZvckh5ZHJhdGlvbihyb290LCBtdXRhYmxlU291cmNlKSB7XG4gIHZhciBnZXRWZXJzaW9uID0gbXV0YWJsZVNvdXJjZS5fZ2V0VmVyc2lvbjtcbiAgdmFyIHZlcnNpb24gPSBnZXRWZXJzaW9uKG11dGFibGVTb3VyY2UuX3NvdXJjZSk7IC8vIFRPRE8gQ2xlYXIgdGhpcyBkYXRhIG9uY2UgYWxsIHBlbmRpbmcgaHlkcmF0aW9uIHdvcmsgaXMgZmluaXNoZWQuXG4gIC8vIFJldGFpbmluZyBpdCBmb3JldmVyIG1heSBpbnRlcmZlcmUgd2l0aCBHQy5cblxuICBpZiAocm9vdC5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhID09IG51bGwpIHtcbiAgICByb290Lm11dGFibGVTb3VyY2VFYWdlckh5ZHJhdGlvbkRhdGEgPSBbbXV0YWJsZVNvdXJjZSwgdmVyc2lvbl07XG4gIH0gZWxzZSB7XG4gICAgcm9vdC5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhLnB1c2gobXV0YWJsZVNvdXJjZSwgdmVyc2lvbik7XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMSA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudERpc3BhdGNoZXIsXG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMiA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnO1xudmFyIGRpZFdhcm5BYm91dE1pc21hdGNoZWRIb29rc0ZvckNvbXBvbmVudDtcbnZhciBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdDtcblxue1xuICBkaWRXYXJuQWJvdXRNaXNtYXRjaGVkSG9va3NGb3JDb21wb25lbnQgPSBuZXcgU2V0KCk7XG59XG5cbi8vIFRoZXNlIGFyZSBzZXQgcmlnaHQgYmVmb3JlIGNhbGxpbmcgdGhlIGNvbXBvbmVudC5cbnZhciByZW5kZXJMYW5lcyA9IE5vTGFuZXM7IC8vIFRoZSB3b3JrLWluLXByb2dyZXNzIGZpYmVyLiBJJ3ZlIG5hbWVkIGl0IGRpZmZlcmVudGx5IHRvIGRpc3Rpbmd1aXNoIGl0IGZyb21cbi8vIHRoZSB3b3JrLWluLXByb2dyZXNzIGhvb2suXG5cbnZhciBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxID0gbnVsbDsgLy8gSG9va3MgYXJlIHN0b3JlZCBhcyBhIGxpbmtlZCBsaXN0IG9uIHRoZSBmaWJlcidzIG1lbW9pemVkU3RhdGUgZmllbGQuIFRoZVxuLy8gY3VycmVudCBob29rIGxpc3QgaXMgdGhlIGxpc3QgdGhhdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IGZpYmVyLiBUaGVcbi8vIHdvcmstaW4tcHJvZ3Jlc3MgaG9vayBsaXN0IGlzIGEgbmV3IGxpc3QgdGhhdCB3aWxsIGJlIGFkZGVkIHRvIHRoZVxuLy8gd29yay1pbi1wcm9ncmVzcyBmaWJlci5cblxudmFyIGN1cnJlbnRIb29rID0gbnVsbDtcbnZhciB3b3JrSW5Qcm9ncmVzc0hvb2sgPSBudWxsOyAvLyBXaGV0aGVyIGFuIHVwZGF0ZSB3YXMgc2NoZWR1bGVkIGF0IGFueSBwb2ludCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS4gVGhpc1xuLy8gZG9lcyBub3QgZ2V0IHJlc2V0IGlmIHdlIGRvIGFub3RoZXIgcmVuZGVyIHBhc3M7IG9ubHkgd2hlbiB3ZSdyZSBjb21wbGV0ZWx5XG4vLyBmaW5pc2hlZCBldmFsdWF0aW5nIHRoaXMgY29tcG9uZW50LiBUaGlzIGlzIGFuIG9wdGltaXphdGlvbiBzbyB3ZSBrbm93XG4vLyB3aGV0aGVyIHdlIG5lZWQgdG8gY2xlYXIgcmVuZGVyIHBoYXNlIHVwZGF0ZXMgYWZ0ZXIgYSB0aHJvdy5cblxudmFyIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSBmYWxzZTsgLy8gV2hlcmUgYW4gdXBkYXRlIHdhcyBzY2hlZHVsZWQgb25seSBkdXJpbmcgdGhlIGN1cnJlbnQgcmVuZGVyIHBhc3MuIFRoaXNcbi8vIGdldHMgcmVzZXQgYWZ0ZXIgZWFjaCBhdHRlbXB0LlxuLy8gVE9ETzogTWF5YmUgdGhlcmUncyBzb21lIHdheSB0byBjb25zb2xpZGF0ZSB0aGlzIHdpdGhcbi8vIGBkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlYC4gT3Igd2l0aCBgbnVtYmVyT2ZSZVJlbmRlcnNgLlxuXG52YXIgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZUR1cmluZ1RoaXNQYXNzID0gZmFsc2U7IC8vIENvdW50cyB0aGUgbnVtYmVyIG9mIHVzZUlkIGhvb2tzIGluIHRoaXMgY29tcG9uZW50LlxuXG52YXIgbG9jYWxJZENvdW50ZXIgPSAwOyAvLyBVc2VkIGZvciBpZHMgdGhhdCBhcmUgZ2VuZXJhdGVkIGNvbXBsZXRlbHkgY2xpZW50LXNpZGUgKGkuZS4gbm90IGR1cmluZ1xuLy8gaHlkcmF0aW9uKS4gVGhpcyBjb3VudGVyIGlzIGdsb2JhbCwgc28gY2xpZW50IGlkcyBhcmUgbm90IHN0YWJsZSBhY3Jvc3Ncbi8vIHJlbmRlciBhdHRlbXB0cy5cblxudmFyIGdsb2JhbENsaWVudElkQ291bnRlciA9IDA7XG52YXIgUkVfUkVOREVSX0xJTUlUID0gMjU7IC8vIEluIERFViwgdGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgY3VycmVudGx5IGV4ZWN1dGluZyBwcmltaXRpdmUgaG9va1xuXG52YXIgY3VycmVudEhvb2tOYW1lSW5EZXYgPSBudWxsOyAvLyBJbiBERVYsIHRoaXMgbGlzdCBlbnN1cmVzIHRoYXQgaG9va3MgYXJlIGNhbGxlZCBpbiB0aGUgc2FtZSBvcmRlciBiZXR3ZWVuIHJlbmRlcnMuXG4vLyBUaGUgbGlzdCBzdG9yZXMgdGhlIG9yZGVyIG9mIGhvb2tzIHVzZWQgZHVyaW5nIHRoZSBpbml0aWFsIHJlbmRlciAobW91bnQpLlxuLy8gU3Vic2VxdWVudCByZW5kZXJzICh1cGRhdGVzKSByZWZlcmVuY2UgdGhpcyBsaXN0LlxuXG52YXIgaG9va1R5cGVzRGV2ID0gbnVsbDtcbnZhciBob29rVHlwZXNVcGRhdGVJbmRleERldiA9IC0xOyAvLyBJbiBERVYsIHRoaXMgdHJhY2tzIHdoZXRoZXIgY3VycmVudGx5IHJlbmRlcmluZyBjb21wb25lbnQgbmVlZHMgdG8gaWdub3JlXG4vLyB0aGUgZGVwZW5kZW5jaWVzIGZvciBIb29rcyB0aGF0IG5lZWQgdGhlbSAoZS5nLiB1c2VFZmZlY3Qgb3IgdXNlTWVtbykuXG4vLyBXaGVuIHRydWUsIHN1Y2ggSG9va3Mgd2lsbCBhbHdheXMgYmUgXCJyZW1vdW50ZWRcIi4gT25seSB1c2VkIGR1cmluZyBob3QgcmVsb2FkLlxuXG52YXIgaWdub3JlUHJldmlvdXNEZXBlbmRlbmNpZXMgPSBmYWxzZTtcblxuZnVuY3Rpb24gbW91bnRIb29rVHlwZXNEZXYoKSB7XG4gIHtcbiAgICB2YXIgaG9va05hbWUgPSBjdXJyZW50SG9va05hbWVJbkRldjtcblxuICAgIGlmIChob29rVHlwZXNEZXYgPT09IG51bGwpIHtcbiAgICAgIGhvb2tUeXBlc0RldiA9IFtob29rTmFtZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGhvb2tUeXBlc0Rldi5wdXNoKGhvb2tOYW1lKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlSG9va1R5cGVzRGV2KCkge1xuICB7XG4gICAgdmFyIGhvb2tOYW1lID0gY3VycmVudEhvb2tOYW1lSW5EZXY7XG5cbiAgICBpZiAoaG9va1R5cGVzRGV2ICE9PSBudWxsKSB7XG4gICAgICBob29rVHlwZXNVcGRhdGVJbmRleERldisrO1xuXG4gICAgICBpZiAoaG9va1R5cGVzRGV2W2hvb2tUeXBlc1VwZGF0ZUluZGV4RGV2XSAhPT0gaG9va05hbWUpIHtcbiAgICAgICAgd2Fybk9uSG9va01pc21hdGNoSW5EZXYoaG9va05hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0RlcHNBcmVBcnJheURldihkZXBzKSB7XG4gIHtcbiAgICBpZiAoZGVwcyAhPT0gdW5kZWZpbmVkICYmIGRlcHMgIT09IG51bGwgJiYgIWlzQXJyYXkoZGVwcykpIHtcbiAgICAgIC8vIFZlcmlmeSBkZXBzLCBidXQgb25seSBvbiBtb3VudCB0byBhdm9pZCBleHRyYSBjaGVja3MuXG4gICAgICAvLyBJdCdzIHVubGlrZWx5IHRoZWlyIHR5cGUgd291bGQgY2hhbmdlIGFzIHVzdWFsbHkgeW91IGRlZmluZSB0aGVtIGlubGluZS5cbiAgICAgIGVycm9yKCclcyByZWNlaXZlZCBhIGZpbmFsIGFyZ3VtZW50IHRoYXQgaXMgbm90IGFuIGFycmF5IChpbnN0ZWFkLCByZWNlaXZlZCBgJXNgKS4gV2hlbiAnICsgJ3NwZWNpZmllZCwgdGhlIGZpbmFsIGFyZ3VtZW50IG11c3QgYmUgYW4gYXJyYXkuJywgY3VycmVudEhvb2tOYW1lSW5EZXYsIHR5cGVvZiBkZXBzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybk9uSG9va01pc21hdGNoSW5EZXYoY3VycmVudEhvb2tOYW1lKSB7XG4gIHtcbiAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSk7XG5cbiAgICBpZiAoIWRpZFdhcm5BYm91dE1pc21hdGNoZWRIb29rc0ZvckNvbXBvbmVudC5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgIGRpZFdhcm5BYm91dE1pc21hdGNoZWRIb29rc0ZvckNvbXBvbmVudC5hZGQoY29tcG9uZW50TmFtZSk7XG5cbiAgICAgIGlmIChob29rVHlwZXNEZXYgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHRhYmxlID0gJyc7XG4gICAgICAgIHZhciBzZWNvbmRDb2x1bW5TdGFydCA9IDMwO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2OyBpKyspIHtcbiAgICAgICAgICB2YXIgb2xkSG9va05hbWUgPSBob29rVHlwZXNEZXZbaV07XG4gICAgICAgICAgdmFyIG5ld0hvb2tOYW1lID0gaSA9PT0gaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPyBjdXJyZW50SG9va05hbWUgOiBvbGRIb29rTmFtZTtcbiAgICAgICAgICB2YXIgcm93ID0gaSArIDEgKyBcIi4gXCIgKyBvbGRIb29rTmFtZTsgLy8gRXh0cmEgc3BhY2Ugc28gc2Vjb25kIGNvbHVtbiBsaW5lcyB1cFxuICAgICAgICAgIC8vIGxvbCBAIElFIG5vdCBzdXBwb3J0aW5nIFN0cmluZyNyZXBlYXRcblxuICAgICAgICAgIHdoaWxlIChyb3cubGVuZ3RoIDwgc2Vjb25kQ29sdW1uU3RhcnQpIHtcbiAgICAgICAgICAgIHJvdyArPSAnICc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcm93ICs9IG5ld0hvb2tOYW1lICsgJ1xcbic7XG4gICAgICAgICAgdGFibGUgKz0gcm93O1xuICAgICAgICB9XG5cbiAgICAgICAgZXJyb3IoJ1JlYWN0IGhhcyBkZXRlY3RlZCBhIGNoYW5nZSBpbiB0aGUgb3JkZXIgb2YgSG9va3MgY2FsbGVkIGJ5ICVzLiAnICsgJ1RoaXMgd2lsbCBsZWFkIHRvIGJ1Z3MgYW5kIGVycm9ycyBpZiBub3QgZml4ZWQuICcgKyAnRm9yIG1vcmUgaW5mb3JtYXRpb24sIHJlYWQgdGhlIFJ1bGVzIG9mIEhvb2tzOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvcnVsZXMtb2YtaG9va3NcXG5cXG4nICsgJyAgIFByZXZpb3VzIHJlbmRlciAgICAgICAgICAgIE5leHQgcmVuZGVyXFxuJyArICcgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG4nICsgJyVzJyArICcgICBeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5cXG4nLCBjb21wb25lbnROYW1lLCB0YWJsZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHRocm93SW52YWxpZEhvb2tFcnJvcigpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhvb2sgY2FsbC4gSG9va3MgY2FuIG9ubHkgYmUgY2FsbGVkIGluc2lkZSBvZiB0aGUgYm9keSBvZiBhIGZ1bmN0aW9uIGNvbXBvbmVudC4gVGhpcyBjb3VsZCBoYXBwZW4gZm9yJyArICcgb25lIG9mIHRoZSBmb2xsb3dpbmcgcmVhc29uczpcXG4nICsgJzEuIFlvdSBtaWdodCBoYXZlIG1pc21hdGNoaW5nIHZlcnNpb25zIG9mIFJlYWN0IGFuZCB0aGUgcmVuZGVyZXIgKHN1Y2ggYXMgUmVhY3QgRE9NKVxcbicgKyAnMi4gWW91IG1pZ2h0IGJlIGJyZWFraW5nIHRoZSBSdWxlcyBvZiBIb29rc1xcbicgKyAnMy4gWW91IG1pZ2h0IGhhdmUgbW9yZSB0aGFuIG9uZSBjb3B5IG9mIFJlYWN0IGluIHRoZSBzYW1lIGFwcFxcbicgKyAnU2VlIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9pbnZhbGlkLWhvb2stY2FsbCBmb3IgdGlwcyBhYm91dCBob3cgdG8gZGVidWcgYW5kIGZpeCB0aGlzIHByb2JsZW0uJyk7XG59XG5cbmZ1bmN0aW9uIGFyZUhvb2tJbnB1dHNFcXVhbChuZXh0RGVwcywgcHJldkRlcHMpIHtcbiAge1xuICAgIGlmIChpZ25vcmVQcmV2aW91c0RlcGVuZGVuY2llcykge1xuICAgICAgLy8gT25seSB0cnVlIHdoZW4gdGhpcyBjb21wb25lbnQgaXMgYmVpbmcgaG90IHJlbG9hZGVkLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChwcmV2RGVwcyA9PT0gbnVsbCkge1xuICAgIHtcbiAgICAgIGVycm9yKCclcyByZWNlaXZlZCBhIGZpbmFsIGFyZ3VtZW50IGR1cmluZyB0aGlzIHJlbmRlciwgYnV0IG5vdCBkdXJpbmcgJyArICd0aGUgcHJldmlvdXMgcmVuZGVyLiBFdmVuIHRob3VnaCB0aGUgZmluYWwgYXJndW1lbnQgaXMgb3B0aW9uYWwsICcgKyAnaXRzIHR5cGUgY2Fubm90IGNoYW5nZSBiZXR3ZWVuIHJlbmRlcnMuJywgY3VycmVudEhvb2tOYW1lSW5EZXYpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHtcbiAgICAvLyBEb24ndCBib3RoZXIgY29tcGFyaW5nIGxlbmd0aHMgaW4gcHJvZCBiZWNhdXNlIHRoZXNlIGFycmF5cyBzaG91bGQgYmVcbiAgICAvLyBwYXNzZWQgaW5saW5lLlxuICAgIGlmIChuZXh0RGVwcy5sZW5ndGggIT09IHByZXZEZXBzLmxlbmd0aCkge1xuICAgICAgZXJyb3IoJ1RoZSBmaW5hbCBhcmd1bWVudCBwYXNzZWQgdG8gJXMgY2hhbmdlZCBzaXplIGJldHdlZW4gcmVuZGVycy4gVGhlICcgKyAnb3JkZXIgYW5kIHNpemUgb2YgdGhpcyBhcnJheSBtdXN0IHJlbWFpbiBjb25zdGFudC5cXG5cXG4nICsgJ1ByZXZpb3VzOiAlc1xcbicgKyAnSW5jb21pbmc6ICVzJywgY3VycmVudEhvb2tOYW1lSW5EZXYsIFwiW1wiICsgcHJldkRlcHMuam9pbignLCAnKSArIFwiXVwiLCBcIltcIiArIG5leHREZXBzLmpvaW4oJywgJykgKyBcIl1cIik7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcmV2RGVwcy5sZW5ndGggJiYgaSA8IG5leHREZXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG9iamVjdElzKG5leHREZXBzW2ldLCBwcmV2RGVwc1tpXSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcHJvcHMsIHNlY29uZEFyZywgbmV4dFJlbmRlckxhbmVzKSB7XG4gIHJlbmRlckxhbmVzID0gbmV4dFJlbmRlckxhbmVzO1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxID0gd29ya0luUHJvZ3Jlc3M7XG5cbiAge1xuICAgIGhvb2tUeXBlc0RldiA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Ll9kZWJ1Z0hvb2tUeXBlcyA6IG51bGw7XG4gICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTsgLy8gVXNlZCBmb3IgaG90IHJlbG9hZGluZzpcblxuICAgIGlnbm9yZVByZXZpb3VzRGVwZW5kZW5jaWVzID0gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50LnR5cGUgIT09IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IE5vTGFuZXM7IC8vIFRoZSBmb2xsb3dpbmcgc2hvdWxkIGhhdmUgYWxyZWFkeSBiZWVuIHJlc2V0XG4gIC8vIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgLy8gd29ya0luUHJvZ3Jlc3NIb29rID0gbnVsbDtcbiAgLy8gZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZSA9IGZhbHNlO1xuICAvLyBsb2NhbElkQ291bnRlciA9IDA7XG4gIC8vIFRPRE8gV2FybiBpZiBubyBob29rcyBhcmUgdXNlZCBhdCBhbGwgZHVyaW5nIG1vdW50LCB0aGVuIHNvbWUgYXJlIHVzZWQgZHVyaW5nIHVwZGF0ZS5cbiAgLy8gQ3VycmVudGx5IHdlIHdpbGwgaWRlbnRpZnkgdGhlIHVwZGF0ZSByZW5kZXIgYXMgYSBtb3VudCBiZWNhdXNlIG1lbW9pemVkU3RhdGUgPT09IG51bGwuXG4gIC8vIFRoaXMgaXMgdHJpY2t5IGJlY2F1c2UgaXQncyB2YWxpZCBmb3IgY2VydGFpbiB0eXBlcyBvZiBjb21wb25lbnRzIChlLmcuIFJlYWN0LmxhenkpXG4gIC8vIFVzaW5nIG1lbW9pemVkU3RhdGUgdG8gZGlmZmVyZW50aWF0ZSBiZXR3ZWVuIG1vdW50L3VwZGF0ZSBvbmx5IHdvcmtzIGlmIGF0IGxlYXN0IG9uZSBzdGF0ZWZ1bCBob29rIGlzIHVzZWQuXG4gIC8vIE5vbi1zdGF0ZWZ1bCBob29rcyAoZS5nLiBjb250ZXh0KSBkb24ndCBnZXQgYWRkZWQgdG8gbWVtb2l6ZWRTdGF0ZSxcbiAgLy8gc28gbWVtb2l6ZWRTdGF0ZSB3b3VsZCBiZSBudWxsIGR1cmluZyB1cGRhdGVzIGFuZCBtb3VudHMuXG5cbiAge1xuICAgIGlmIChjdXJyZW50ICE9PSBudWxsICYmIGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuICAgIH0gZWxzZSBpZiAoaG9va1R5cGVzRGV2ICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGRpc3BhdGNoZXIgaGFuZGxlcyBhbiBlZGdlIGNhc2Ugd2hlcmUgYSBjb21wb25lbnQgaXMgdXBkYXRpbmcsXG4gICAgICAvLyBidXQgbm8gc3RhdGVmdWwgaG9va3MgaGF2ZSBiZWVuIHVzZWQuXG4gICAgICAvLyBXZSB3YW50IHRvIG1hdGNoIHRoZSBwcm9kdWN0aW9uIGNvZGUgYmVoYXZpb3IgKHdoaWNoIHdpbGwgdXNlIEhvb2tzRGlzcGF0Y2hlck9uTW91bnQpLFxuICAgICAgLy8gYnV0IHdpdGggdGhlIGV4dHJhIERFViB2YWxpZGF0aW9uIHRvIGVuc3VyZSBob29rcyBvcmRlcmluZyBoYXNuJ3QgY2hhbmdlZC5cbiAgICAgIC8vIFRoaXMgZGlzcGF0Y2hlciBkb2VzIHRoYXQuXG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEhvb2tzRGlzcGF0Y2hlck9uTW91bnRXaXRoSG9va1R5cGVzSW5ERVY7XG4gICAgfSBlbHNlIHtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjaGlsZHJlbiA9IENvbXBvbmVudChwcm9wcywgc2Vjb25kQXJnKTsgLy8gQ2hlY2sgaWYgdGhlcmUgd2FzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZVxuXG4gIGlmIChkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlRHVyaW5nVGhpc1Bhc3MpIHtcbiAgICAvLyBLZWVwIHJlbmRlcmluZyBpbiBhIGxvb3AgZm9yIGFzIGxvbmcgYXMgcmVuZGVyIHBoYXNlIHVwZGF0ZXMgY29udGludWUgdG9cbiAgICAvLyBiZSBzY2hlZHVsZWQuIFVzZSBhIGNvdW50ZXIgdG8gcHJldmVudCBpbmZpbml0ZSBsb29wcy5cbiAgICB2YXIgbnVtYmVyT2ZSZVJlbmRlcnMgPSAwO1xuXG4gICAgZG8ge1xuICAgICAgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZUR1cmluZ1RoaXNQYXNzID0gZmFsc2U7XG4gICAgICBsb2NhbElkQ291bnRlciA9IDA7XG5cbiAgICAgIGlmIChudW1iZXJPZlJlUmVuZGVycyA+PSBSRV9SRU5ERVJfTElNSVQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUb28gbWFueSByZS1yZW5kZXJzLiBSZWFjdCBsaW1pdHMgdGhlIG51bWJlciBvZiByZW5kZXJzIHRvIHByZXZlbnQgJyArICdhbiBpbmZpbml0ZSBsb29wLicpO1xuICAgICAgfVxuXG4gICAgICBudW1iZXJPZlJlUmVuZGVycyArPSAxO1xuXG4gICAgICB7XG4gICAgICAgIC8vIEV2ZW4gd2hlbiBob3QgcmVsb2FkaW5nLCBhbGxvdyBkZXBlbmRlbmNpZXMgdG8gc3RhYmlsaXplXG4gICAgICAgIC8vIGFmdGVyIGZpcnN0IHJlbmRlciB0byBwcmV2ZW50IGluZmluaXRlIHJlbmRlciBwaGFzZSB1cGRhdGVzLlxuICAgICAgICBpZ25vcmVQcmV2aW91c0RlcGVuZGVuY2llcyA9IGZhbHNlO1xuICAgICAgfSAvLyBTdGFydCBvdmVyIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdFxuXG5cbiAgICAgIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgICAgIHdvcmtJblByb2dyZXNzSG9vayA9IG51bGw7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IG51bGw7XG5cbiAgICAgIHtcbiAgICAgICAgLy8gQWxzbyB2YWxpZGF0ZSBob29rIG9yZGVyIGZvciBjYXNjYWRpbmcgdXBkYXRlcy5cbiAgICAgICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTtcbiAgICAgIH1cblxuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSAgSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWIDtcbiAgICAgIGNoaWxkcmVuID0gQ29tcG9uZW50KHByb3BzLCBzZWNvbmRBcmcpO1xuICAgIH0gd2hpbGUgKGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyk7XG4gIH0gLy8gV2UgY2FuIGFzc3VtZSB0aGUgcHJldmlvdXMgZGlzcGF0Y2hlciBpcyBhbHdheXMgdGhpcyBvbmUsIHNpbmNlIHdlIHNldCBpdFxuICAvLyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZW5kZXIgcGhhc2UgYW5kIHRoZXJlJ3Mgbm8gcmUtZW50cmFuY2UuXG5cblxuICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IENvbnRleHRPbmx5RGlzcGF0Y2hlcjtcblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3MuX2RlYnVnSG9va1R5cGVzID0gaG9va1R5cGVzRGV2O1xuICB9IC8vIFRoaXMgY2hlY2sgdXNlcyBjdXJyZW50SG9vayBzbyB0aGF0IGl0IHdvcmtzIHRoZSBzYW1lIGluIERFViBhbmQgcHJvZCBidW5kbGVzLlxuICAvLyBob29rVHlwZXNEZXYgY291bGQgY2F0Y2ggbW9yZSBjYXNlcyAoZS5nLiBjb250ZXh0KSBidXQgb25seSBpbiBERVYgYnVuZGxlcy5cblxuXG4gIHZhciBkaWRSZW5kZXJUb29GZXdIb29rcyA9IGN1cnJlbnRIb29rICE9PSBudWxsICYmIGN1cnJlbnRIb29rLm5leHQgIT09IG51bGw7XG4gIHJlbmRlckxhbmVzID0gTm9MYW5lcztcbiAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMSA9IG51bGw7XG4gIGN1cnJlbnRIb29rID0gbnVsbDtcbiAgd29ya0luUHJvZ3Jlc3NIb29rID0gbnVsbDtcblxuICB7XG4gICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSBudWxsO1xuICAgIGhvb2tUeXBlc0RldiA9IG51bGw7XG4gICAgaG9va1R5cGVzVXBkYXRlSW5kZXhEZXYgPSAtMTsgLy8gQ29uZmlybSB0aGF0IGEgc3RhdGljIGZsYWcgd2FzIG5vdCBhZGRlZCBvciByZW1vdmVkIHNpbmNlIHRoZSBsYXN0XG4gICAgLy8gcmVuZGVyLiBJZiB0aGlzIGZpcmVzLCBpdCBzdWdnZXN0cyB0aGF0IHdlIGluY29ycmVjdGx5IHJlc2V0IHRoZSBzdGF0aWNcbiAgICAvLyBmbGFncyBpbiBzb21lIG90aGVyIHBhcnQgb2YgdGhlIGNvZGViYXNlLiBUaGlzIGhhcyBoYXBwZW5lZCBiZWZvcmUsIGZvclxuICAgIC8vIGV4YW1wbGUsIGluIHRoZSBTdXNwZW5zZUxpc3QgaW1wbGVtZW50YXRpb24uXG5cbiAgICBpZiAoY3VycmVudCAhPT0gbnVsbCAmJiAoY3VycmVudC5mbGFncyAmIFN0YXRpY01hc2spICE9PSAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBTdGF0aWNNYXNrKSAmJiAvLyBEaXNhYmxlIHRoaXMgd2FybmluZyBpbiBsZWdhY3kgbW9kZSwgYmVjYXVzZSBsZWdhY3kgU3VzcGVuc2UgaXMgd2VpcmRcbiAgICAvLyBhbmQgY3JlYXRlcyBmYWxzZSBwb3NpdGl2ZXMuIFRvIG1ha2UgdGhpcyB3b3JrIGluIGxlZ2FjeSBtb2RlLCB3ZSdkXG4gICAgLy8gbmVlZCB0byBtYXJrIGZpYmVycyB0aGF0IGNvbW1pdCBpbiBhbiBpbmNvbXBsZXRlIHN0YXRlLCBzb21laG93LiBGb3JcbiAgICAvLyBub3cgSSdsbCBkaXNhYmxlIHRoZSB3YXJuaW5nIHRoYXQgbW9zdCBvZiB0aGUgYnVncyB0aGF0IHdvdWxkIHRyaWdnZXJcbiAgICAvLyBpdCBhcmUgZWl0aGVyIGV4Y2x1c2l2ZSB0byBjb25jdXJyZW50IG1vZGUgb3IgZXhpc3QgaW4gYm90aC5cbiAgICAoY3VycmVudC5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgIGVycm9yKCdJbnRlcm5hbCBSZWFjdCBlcnJvcjogRXhwZWN0ZWQgc3RhdGljIGZsYWcgd2FzIG1pc3NpbmcuIFBsZWFzZSAnICsgJ25vdGlmeSB0aGUgUmVhY3QgdGVhbS4nKTtcbiAgICB9XG4gIH1cblxuICBkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlID0gZmFsc2U7IC8vIFRoaXMgaXMgcmVzZXQgYnkgY2hlY2tEaWRSZW5kZXJJZEhvb2tcbiAgLy8gbG9jYWxJZENvdW50ZXIgPSAwO1xuXG4gIGlmIChkaWRSZW5kZXJUb29GZXdIb29rcykge1xuICAgIHRocm93IG5ldyBFcnJvcignUmVuZGVyZWQgZmV3ZXIgaG9va3MgdGhhbiBleHBlY3RlZC4gVGhpcyBtYXkgYmUgY2F1c2VkIGJ5IGFuIGFjY2lkZW50YWwgJyArICdlYXJseSByZXR1cm4gc3RhdGVtZW50LicpO1xuICB9XG5cbiAgcmV0dXJuIGNoaWxkcmVuO1xufVxuZnVuY3Rpb24gY2hlY2tEaWRSZW5kZXJJZEhvb2soKSB7XG4gIC8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBhZnRlciBldmVyeSByZW5kZXJXaXRoSG9va3MgY2FsbC5cbiAgLy8gQ29uY2VwdHVhbGx5LCBpdCdzIHBhcnQgb2YgdGhlIHJldHVybiB2YWx1ZSBvZiByZW5kZXJXaXRoSG9va3M7IGl0J3Mgb25seSBhXG4gIC8vIHNlcGFyYXRlIGZ1bmN0aW9uIHRvIGF2b2lkIHVzaW5nIGFuIGFycmF5IHR1cGxlLlxuICB2YXIgZGlkUmVuZGVySWRIb29rID0gbG9jYWxJZENvdW50ZXIgIT09IDA7XG4gIGxvY2FsSWRDb3VudGVyID0gMDtcbiAgcmV0dXJuIGRpZFJlbmRlcklkSG9vaztcbn1cbmZ1bmN0aW9uIGJhaWxvdXRIb29rcyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbGFuZXMpIHtcbiAgd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWUgPSBjdXJyZW50LnVwZGF0ZVF1ZXVlOyAvLyBUT0RPOiBEb24ndCBuZWVkIHRvIHJlc2V0IHRoZSBmbGFncyBoZXJlLCBiZWNhdXNlIHRoZXkncmUgcmVzZXQgaW4gdGhlXG4gIC8vIGNvbXBsZXRlIHBoYXNlIChidWJibGVQcm9wZXJ0aWVzKS5cblxuICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyAmPSB+KE1vdW50UGFzc2l2ZURldiB8IE1vdW50TGF5b3V0RGV2IHwgUGFzc2l2ZSB8IFVwZGF0ZSk7XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJj0gfihQYXNzaXZlIHwgVXBkYXRlKTtcbiAgfVxuXG4gIGN1cnJlbnQubGFuZXMgPSByZW1vdmVMYW5lcyhjdXJyZW50LmxhbmVzLCBsYW5lcyk7XG59XG5mdW5jdGlvbiByZXNldEhvb2tzQWZ0ZXJUaHJvdygpIHtcbiAgLy8gV2UgY2FuIGFzc3VtZSB0aGUgcHJldmlvdXMgZGlzcGF0Y2hlciBpcyBhbHdheXMgdGhpcyBvbmUsIHNpbmNlIHdlIHNldCBpdFxuICAvLyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSByZW5kZXIgcGhhc2UgYW5kIHRoZXJlJ3Mgbm8gcmUtZW50cmFuY2UuXG4gIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gQ29udGV4dE9ubHlEaXNwYXRjaGVyO1xuXG4gIGlmIChkaWRTY2hlZHVsZVJlbmRlclBoYXNlVXBkYXRlKSB7XG4gICAgLy8gVGhlcmUgd2VyZSByZW5kZXIgcGhhc2UgdXBkYXRlcy4gVGhlc2UgYXJlIG9ubHkgdmFsaWQgZm9yIHRoaXMgcmVuZGVyXG4gICAgLy8gcGhhc2UsIHdoaWNoIHdlIGFyZSBub3cgYWJvcnRpbmcuIFJlbW92ZSB0aGUgdXBkYXRlcyBmcm9tIHRoZSBxdWV1ZXMgc29cbiAgICAvLyB0aGV5IGRvIG5vdCBwZXJzaXN0IHRvIHRoZSBuZXh0IHJlbmRlci4gRG8gbm90IHJlbW92ZSB1cGRhdGVzIGZyb20gaG9va3NcbiAgICAvLyB0aGF0IHdlcmVuJ3QgcHJvY2Vzc2VkLlxuICAgIC8vXG4gICAgLy8gT25seSByZXNldCB0aGUgdXBkYXRlcyBmcm9tIHRoZSBxdWV1ZSBpZiBpdCBoYXMgYSBjbG9uZS4gSWYgaXQgZG9lc1xuICAgIC8vIG5vdCBoYXZlIGEgY2xvbmUsIHRoYXQgbWVhbnMgaXQgd2Fzbid0IHByb2Nlc3NlZCwgYW5kIHRoZSB1cGRhdGVzIHdlcmVcbiAgICAvLyBzY2hlZHVsZWQgYmVmb3JlIHdlIGVudGVyZWQgdGhlIHJlbmRlciBwaGFzZS5cbiAgICB2YXIgaG9vayA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubWVtb2l6ZWRTdGF0ZTtcblxuICAgIHdoaWxlIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgcXVldWUgPSBob29rLnF1ZXVlO1xuXG4gICAgICBpZiAocXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgcXVldWUucGVuZGluZyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGhvb2sgPSBob29rLm5leHQ7XG4gICAgfVxuXG4gICAgZGlkU2NoZWR1bGVSZW5kZXJQaGFzZVVwZGF0ZSA9IGZhbHNlO1xuICB9XG5cbiAgcmVuZGVyTGFuZXMgPSBOb0xhbmVzO1xuICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxID0gbnVsbDtcbiAgY3VycmVudEhvb2sgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSBudWxsO1xuXG4gIHtcbiAgICBob29rVHlwZXNEZXYgPSBudWxsO1xuICAgIGhvb2tUeXBlc1VwZGF0ZUluZGV4RGV2ID0gLTE7XG4gICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSBudWxsO1xuICAgIGlzVXBkYXRpbmdPcGFxdWVWYWx1ZUluUmVuZGVyUGhhc2UgPSBmYWxzZTtcbiAgfVxuXG4gIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGZhbHNlO1xuICBsb2NhbElkQ291bnRlciA9IDA7XG59XG5cbmZ1bmN0aW9uIG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCkge1xuICB2YXIgaG9vayA9IHtcbiAgICBtZW1vaXplZFN0YXRlOiBudWxsLFxuICAgIGJhc2VTdGF0ZTogbnVsbCxcbiAgICBiYXNlUXVldWU6IG51bGwsXG4gICAgcXVldWU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc0hvb2sgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCBob29rIGluIHRoZSBsaXN0XG4gICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tZW1vaXplZFN0YXRlID0gd29ya0luUHJvZ3Jlc3NIb29rID0gaG9vaztcbiAgfSBlbHNlIHtcbiAgICAvLyBBcHBlbmQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdFxuICAgIHdvcmtJblByb2dyZXNzSG9vayA9IHdvcmtJblByb2dyZXNzSG9vay5uZXh0ID0gaG9vaztcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc0hvb2s7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpIHtcbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJvdGggZm9yIHVwZGF0ZXMgYW5kIGZvciByZS1yZW5kZXJzIHRyaWdnZXJlZCBieSBhXG4gIC8vIHJlbmRlciBwaGFzZSB1cGRhdGUuIEl0IGFzc3VtZXMgdGhlcmUgaXMgZWl0aGVyIGEgY3VycmVudCBob29rIHdlIGNhblxuICAvLyBjbG9uZSwgb3IgYSB3b3JrLWluLXByb2dyZXNzIGhvb2sgZnJvbSBhIHByZXZpb3VzIHJlbmRlciBwYXNzIHRoYXQgd2UgY2FuXG4gIC8vIHVzZSBhcyBhIGJhc2UuIFdoZW4gd2UgcmVhY2ggdGhlIGVuZCBvZiB0aGUgYmFzZSBsaXN0LCB3ZSBtdXN0IHN3aXRjaCB0b1xuICAvLyB0aGUgZGlzcGF0Y2hlciB1c2VkIGZvciBtb3VudHMuXG4gIHZhciBuZXh0Q3VycmVudEhvb2s7XG5cbiAgaWYgKGN1cnJlbnRIb29rID09PSBudWxsKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmFsdGVybmF0ZTtcblxuICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICBuZXh0Q3VycmVudEhvb2sgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5leHRDdXJyZW50SG9vayA9IG51bGw7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIG5leHRDdXJyZW50SG9vayA9IGN1cnJlbnRIb29rLm5leHQ7XG4gIH1cblxuICB2YXIgbmV4dFdvcmtJblByb2dyZXNzSG9vaztcblxuICBpZiAod29ya0luUHJvZ3Jlc3NIb29rID09PSBudWxsKSB7XG4gICAgbmV4dFdvcmtJblByb2dyZXNzSG9vayA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubWVtb2l6ZWRTdGF0ZTtcbiAgfSBlbHNlIHtcbiAgICBuZXh0V29ya0luUHJvZ3Jlc3NIb29rID0gd29ya0luUHJvZ3Jlc3NIb29rLm5leHQ7XG4gIH1cblxuICBpZiAobmV4dFdvcmtJblByb2dyZXNzSG9vayAhPT0gbnVsbCkge1xuICAgIC8vIFRoZXJlJ3MgYWxyZWFkeSBhIHdvcmstaW4tcHJvZ3Jlc3MuIFJldXNlIGl0LlxuICAgIHdvcmtJblByb2dyZXNzSG9vayA9IG5leHRXb3JrSW5Qcm9ncmVzc0hvb2s7XG4gICAgbmV4dFdvcmtJblByb2dyZXNzSG9vayA9IHdvcmtJblByb2dyZXNzSG9vay5uZXh0O1xuICAgIGN1cnJlbnRIb29rID0gbmV4dEN1cnJlbnRIb29rO1xuICB9IGVsc2Uge1xuICAgIC8vIENsb25lIGZyb20gdGhlIGN1cnJlbnQgaG9vay5cbiAgICBpZiAobmV4dEN1cnJlbnRIb29rID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbmRlcmVkIG1vcmUgaG9va3MgdGhhbiBkdXJpbmcgdGhlIHByZXZpb3VzIHJlbmRlci4nKTtcbiAgICB9XG5cbiAgICBjdXJyZW50SG9vayA9IG5leHRDdXJyZW50SG9vaztcbiAgICB2YXIgbmV3SG9vayA9IHtcbiAgICAgIG1lbW9pemVkU3RhdGU6IGN1cnJlbnRIb29rLm1lbW9pemVkU3RhdGUsXG4gICAgICBiYXNlU3RhdGU6IGN1cnJlbnRIb29rLmJhc2VTdGF0ZSxcbiAgICAgIGJhc2VRdWV1ZTogY3VycmVudEhvb2suYmFzZVF1ZXVlLFxuICAgICAgcXVldWU6IGN1cnJlbnRIb29rLnF1ZXVlLFxuICAgICAgbmV4dDogbnVsbFxuICAgIH07XG5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3NIb29rID09PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCBob29rIGluIHRoZSBsaXN0LlxuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tZW1vaXplZFN0YXRlID0gd29ya0luUHJvZ3Jlc3NIb29rID0gbmV3SG9vaztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXBwZW5kIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuXG4gICAgICB3b3JrSW5Qcm9ncmVzc0hvb2sgPSB3b3JrSW5Qcm9ncmVzc0hvb2submV4dCA9IG5ld0hvb2s7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzSG9vaztcbn1cblxuZnVuY3Rpb24gY3JlYXRlRnVuY3Rpb25Db21wb25lbnRVcGRhdGVRdWV1ZSgpIHtcbiAgcmV0dXJuIHtcbiAgICBsYXN0RWZmZWN0OiBudWxsLFxuICAgIHN0b3JlczogbnVsbFxuICB9O1xufVxuXG5mdW5jdGlvbiBiYXNpY1N0YXRlUmVkdWNlcihzdGF0ZSwgYWN0aW9uKSB7XG4gIC8vICRGbG93Rml4TWU6IEZsb3cgZG9lc24ndCBsaWtlIG1peGVkIHR5cGVzXG4gIHJldHVybiB0eXBlb2YgYWN0aW9uID09PSAnZnVuY3Rpb24nID8gYWN0aW9uKHN0YXRlKSA6IGFjdGlvbjtcbn1cblxuZnVuY3Rpb24gbW91bnRSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgaW5pdGlhbFN0YXRlO1xuXG4gIGlmIChpbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpbml0aWFsU3RhdGUgPSBpbml0KGluaXRpYWxBcmcpO1xuICB9IGVsc2Uge1xuICAgIGluaXRpYWxTdGF0ZSA9IGluaXRpYWxBcmc7XG4gIH1cblxuICBob29rLm1lbW9pemVkU3RhdGUgPSBob29rLmJhc2VTdGF0ZSA9IGluaXRpYWxTdGF0ZTtcbiAgdmFyIHF1ZXVlID0ge1xuICAgIHBlbmRpbmc6IG51bGwsXG4gICAgaW50ZXJsZWF2ZWQ6IG51bGwsXG4gICAgbGFuZXM6IE5vTGFuZXMsXG4gICAgZGlzcGF0Y2g6IG51bGwsXG4gICAgbGFzdFJlbmRlcmVkUmVkdWNlcjogcmVkdWNlcixcbiAgICBsYXN0UmVuZGVyZWRTdGF0ZTogaW5pdGlhbFN0YXRlXG4gIH07XG4gIGhvb2sucXVldWUgPSBxdWV1ZTtcbiAgdmFyIGRpc3BhdGNoID0gcXVldWUuZGlzcGF0Y2ggPSBkaXNwYXRjaFJlZHVjZXJBY3Rpb24uYmluZChudWxsLCBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLCBxdWV1ZSk7XG4gIHJldHVybiBbaG9vay5tZW1vaXplZFN0YXRlLCBkaXNwYXRjaF07XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgcXVldWUgPSBob29rLnF1ZXVlO1xuXG4gIGlmIChxdWV1ZSA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hvdWxkIGhhdmUgYSBxdWV1ZS4gVGhpcyBpcyBsaWtlbHkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9XG5cbiAgcXVldWUubGFzdFJlbmRlcmVkUmVkdWNlciA9IHJlZHVjZXI7XG4gIHZhciBjdXJyZW50ID0gY3VycmVudEhvb2s7IC8vIFRoZSBsYXN0IHJlYmFzZSB1cGRhdGUgdGhhdCBpcyBOT1QgcGFydCBvZiB0aGUgYmFzZSBzdGF0ZS5cblxuICB2YXIgYmFzZVF1ZXVlID0gY3VycmVudC5iYXNlUXVldWU7IC8vIFRoZSBsYXN0IHBlbmRpbmcgdXBkYXRlIHRoYXQgaGFzbid0IGJlZW4gcHJvY2Vzc2VkIHlldC5cblxuICB2YXIgcGVuZGluZ1F1ZXVlID0gcXVldWUucGVuZGluZztcblxuICBpZiAocGVuZGluZ1F1ZXVlICE9PSBudWxsKSB7XG4gICAgLy8gV2UgaGF2ZSBuZXcgdXBkYXRlcyB0aGF0IGhhdmVuJ3QgYmVlbiBwcm9jZXNzZWQgeWV0LlxuICAgIC8vIFdlJ2xsIGFkZCB0aGVtIHRvIHRoZSBiYXNlIHF1ZXVlLlxuICAgIGlmIChiYXNlUXVldWUgIT09IG51bGwpIHtcbiAgICAgIC8vIE1lcmdlIHRoZSBwZW5kaW5nIHF1ZXVlIGFuZCB0aGUgYmFzZSBxdWV1ZS5cbiAgICAgIHZhciBiYXNlRmlyc3QgPSBiYXNlUXVldWUubmV4dDtcbiAgICAgIHZhciBwZW5kaW5nRmlyc3QgPSBwZW5kaW5nUXVldWUubmV4dDtcbiAgICAgIGJhc2VRdWV1ZS5uZXh0ID0gcGVuZGluZ0ZpcnN0O1xuICAgICAgcGVuZGluZ1F1ZXVlLm5leHQgPSBiYXNlRmlyc3Q7XG4gICAgfVxuXG4gICAge1xuICAgICAgaWYgKGN1cnJlbnQuYmFzZVF1ZXVlICE9PSBiYXNlUXVldWUpIHtcbiAgICAgICAgLy8gSW50ZXJuYWwgaW52YXJpYW50IHRoYXQgc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0IGZlYXNpYmx5IGNvdWxkIGluXG4gICAgICAgIC8vIHRoZSBmdXR1cmUgaWYgd2UgaW1wbGVtZW50IHJlc3VtaW5nLCBvciBzb21lIGZvcm0gb2YgdGhhdC5cbiAgICAgICAgZXJyb3IoJ0ludGVybmFsIGVycm9yOiBFeHBlY3RlZCB3b3JrLWluLXByb2dyZXNzIHF1ZXVlIHRvIGJlIGEgY2xvbmUuICcgKyAnVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjdXJyZW50LmJhc2VRdWV1ZSA9IGJhc2VRdWV1ZSA9IHBlbmRpbmdRdWV1ZTtcbiAgICBxdWV1ZS5wZW5kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChiYXNlUXVldWUgIT09IG51bGwpIHtcbiAgICAvLyBXZSBoYXZlIGEgcXVldWUgdG8gcHJvY2Vzcy5cbiAgICB2YXIgZmlyc3QgPSBiYXNlUXVldWUubmV4dDtcbiAgICB2YXIgbmV3U3RhdGUgPSBjdXJyZW50LmJhc2VTdGF0ZTtcbiAgICB2YXIgbmV3QmFzZVN0YXRlID0gbnVsbDtcbiAgICB2YXIgbmV3QmFzZVF1ZXVlRmlyc3QgPSBudWxsO1xuICAgIHZhciBuZXdCYXNlUXVldWVMYXN0ID0gbnVsbDtcbiAgICB2YXIgdXBkYXRlID0gZmlyc3Q7XG5cbiAgICBkbyB7XG4gICAgICB2YXIgdXBkYXRlTGFuZSA9IHVwZGF0ZS5sYW5lO1xuXG4gICAgICBpZiAoIWlzU3Vic2V0T2ZMYW5lcyhyZW5kZXJMYW5lcywgdXBkYXRlTGFuZSkpIHtcbiAgICAgICAgLy8gUHJpb3JpdHkgaXMgaW5zdWZmaWNpZW50LiBTa2lwIHRoaXMgdXBkYXRlLiBJZiB0aGlzIGlzIHRoZSBmaXJzdFxuICAgICAgICAvLyBza2lwcGVkIHVwZGF0ZSwgdGhlIHByZXZpb3VzIHVwZGF0ZS9zdGF0ZSBpcyB0aGUgbmV3IGJhc2VcbiAgICAgICAgLy8gdXBkYXRlL3N0YXRlLlxuICAgICAgICB2YXIgY2xvbmUgPSB7XG4gICAgICAgICAgbGFuZTogdXBkYXRlTGFuZSxcbiAgICAgICAgICBhY3Rpb246IHVwZGF0ZS5hY3Rpb24sXG4gICAgICAgICAgaGFzRWFnZXJTdGF0ZTogdXBkYXRlLmhhc0VhZ2VyU3RhdGUsXG4gICAgICAgICAgZWFnZXJTdGF0ZTogdXBkYXRlLmVhZ2VyU3RhdGUsXG4gICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChuZXdCYXNlUXVldWVMYXN0ID09PSBudWxsKSB7XG4gICAgICAgICAgbmV3QmFzZVF1ZXVlRmlyc3QgPSBuZXdCYXNlUXVldWVMYXN0ID0gY2xvbmU7XG4gICAgICAgICAgbmV3QmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3QmFzZVF1ZXVlTGFzdCA9IG5ld0Jhc2VRdWV1ZUxhc3QubmV4dCA9IGNsb25lO1xuICAgICAgICB9IC8vIFVwZGF0ZSB0aGUgcmVtYWluaW5nIHByaW9yaXR5IGluIHRoZSBxdWV1ZS5cbiAgICAgICAgLy8gVE9ETzogRG9uJ3QgbmVlZCB0byBhY2N1bXVsYXRlIHRoaXMuIEluc3RlYWQsIHdlIGNhbiByZW1vdmVcbiAgICAgICAgLy8gcmVuZGVyTGFuZXMgZnJvbSB0aGUgb3JpZ2luYWwgbGFuZXMuXG5cblxuICAgICAgICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzID0gbWVyZ2VMYW5lcyhjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzLCB1cGRhdGVMYW5lKTtcbiAgICAgICAgbWFya1NraXBwZWRVcGRhdGVMYW5lcyh1cGRhdGVMYW5lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgdXBkYXRlIGRvZXMgaGF2ZSBzdWZmaWNpZW50IHByaW9yaXR5LlxuICAgICAgICBpZiAobmV3QmFzZVF1ZXVlTGFzdCAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBfY2xvbmUgPSB7XG4gICAgICAgICAgICAvLyBUaGlzIHVwZGF0ZSBpcyBnb2luZyB0byBiZSBjb21taXR0ZWQgc28gd2UgbmV2ZXIgd2FudCB1bmNvbW1pdFxuICAgICAgICAgICAgLy8gaXQuIFVzaW5nIE5vTGFuZSB3b3JrcyBiZWNhdXNlIDAgaXMgYSBzdWJzZXQgb2YgYWxsIGJpdG1hc2tzLCBzb1xuICAgICAgICAgICAgLy8gdGhpcyB3aWxsIG5ldmVyIGJlIHNraXBwZWQgYnkgdGhlIGNoZWNrIGFib3ZlLlxuICAgICAgICAgICAgbGFuZTogTm9MYW5lLFxuICAgICAgICAgICAgYWN0aW9uOiB1cGRhdGUuYWN0aW9uLFxuICAgICAgICAgICAgaGFzRWFnZXJTdGF0ZTogdXBkYXRlLmhhc0VhZ2VyU3RhdGUsXG4gICAgICAgICAgICBlYWdlclN0YXRlOiB1cGRhdGUuZWFnZXJTdGF0ZSxcbiAgICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgICB9O1xuICAgICAgICAgIG5ld0Jhc2VRdWV1ZUxhc3QgPSBuZXdCYXNlUXVldWVMYXN0Lm5leHQgPSBfY2xvbmU7XG4gICAgICAgIH0gLy8gUHJvY2VzcyB0aGlzIHVwZGF0ZS5cblxuXG4gICAgICAgIGlmICh1cGRhdGUuaGFzRWFnZXJTdGF0ZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgdXBkYXRlIGlzIGEgc3RhdGUgdXBkYXRlIChub3QgYSByZWR1Y2VyKSBhbmQgd2FzIHByb2Nlc3NlZCBlYWdlcmx5LFxuICAgICAgICAgIC8vIHdlIGNhbiB1c2UgdGhlIGVhZ2VybHkgY29tcHV0ZWQgc3RhdGVcbiAgICAgICAgICBuZXdTdGF0ZSA9IHVwZGF0ZS5lYWdlclN0YXRlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBhY3Rpb24gPSB1cGRhdGUuYWN0aW9uO1xuICAgICAgICAgIG5ld1N0YXRlID0gcmVkdWNlcihuZXdTdGF0ZSwgYWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB1cGRhdGUgPSB1cGRhdGUubmV4dDtcbiAgICB9IHdoaWxlICh1cGRhdGUgIT09IG51bGwgJiYgdXBkYXRlICE9PSBmaXJzdCk7XG5cbiAgICBpZiAobmV3QmFzZVF1ZXVlTGFzdCA9PT0gbnVsbCkge1xuICAgICAgbmV3QmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0Jhc2VRdWV1ZUxhc3QubmV4dCA9IG5ld0Jhc2VRdWV1ZUZpcnN0O1xuICAgIH0gLy8gTWFyayB0aGF0IHRoZSBmaWJlciBwZXJmb3JtZWQgd29yaywgYnV0IG9ubHkgaWYgdGhlIG5ldyBzdGF0ZSBpc1xuICAgIC8vIGRpZmZlcmVudCBmcm9tIHRoZSBjdXJyZW50IHN0YXRlLlxuXG5cbiAgICBpZiAoIW9iamVjdElzKG5ld1N0YXRlLCBob29rLm1lbW9pemVkU3RhdGUpKSB7XG4gICAgICBtYXJrV29ya0luUHJvZ3Jlc3NSZWNlaXZlZFVwZGF0ZSgpO1xuICAgIH1cblxuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICAgIGhvb2suYmFzZVN0YXRlID0gbmV3QmFzZVN0YXRlO1xuICAgIGhvb2suYmFzZVF1ZXVlID0gbmV3QmFzZVF1ZXVlTGFzdDtcbiAgICBxdWV1ZS5sYXN0UmVuZGVyZWRTdGF0ZSA9IG5ld1N0YXRlO1xuICB9IC8vIEludGVybGVhdmVkIHVwZGF0ZXMgYXJlIHN0b3JlZCBvbiBhIHNlcGFyYXRlIHF1ZXVlLiBXZSBhcmVuJ3QgZ29pbmcgdG9cbiAgLy8gcHJvY2VzcyB0aGVtIGR1cmluZyB0aGlzIHJlbmRlciwgYnV0IHdlIGRvIG5lZWQgdG8gdHJhY2sgd2hpY2ggbGFuZXNcbiAgLy8gYXJlIHJlbWFpbmluZy5cblxuXG4gIHZhciBsYXN0SW50ZXJsZWF2ZWQgPSBxdWV1ZS5pbnRlcmxlYXZlZDtcblxuICBpZiAobGFzdEludGVybGVhdmVkICE9PSBudWxsKSB7XG4gICAgdmFyIGludGVybGVhdmVkID0gbGFzdEludGVybGVhdmVkO1xuXG4gICAgZG8ge1xuICAgICAgdmFyIGludGVybGVhdmVkTGFuZSA9IGludGVybGVhdmVkLmxhbmU7XG4gICAgICBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzID0gbWVyZ2VMYW5lcyhjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLmxhbmVzLCBpbnRlcmxlYXZlZExhbmUpO1xuICAgICAgbWFya1NraXBwZWRVcGRhdGVMYW5lcyhpbnRlcmxlYXZlZExhbmUpO1xuICAgICAgaW50ZXJsZWF2ZWQgPSBpbnRlcmxlYXZlZC5uZXh0O1xuICAgIH0gd2hpbGUgKGludGVybGVhdmVkICE9PSBsYXN0SW50ZXJsZWF2ZWQpO1xuICB9IGVsc2UgaWYgKGJhc2VRdWV1ZSA9PT0gbnVsbCkge1xuICAgIC8vIGBxdWV1ZS5sYW5lc2AgaXMgdXNlZCBmb3IgZW50YW5nbGluZyB0cmFuc2l0aW9ucy4gV2UgY2FuIHNldCBpdCBiYWNrIHRvXG4gICAgLy8gemVybyBvbmNlIHRoZSBxdWV1ZSBpcyBlbXB0eS5cbiAgICBxdWV1ZS5sYW5lcyA9IE5vTGFuZXM7XG4gIH1cblxuICB2YXIgZGlzcGF0Y2ggPSBxdWV1ZS5kaXNwYXRjaDtcbiAgcmV0dXJuIFtob29rLm1lbW9pemVkU3RhdGUsIGRpc3BhdGNoXTtcbn1cblxuZnVuY3Rpb24gcmVyZW5kZXJSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHF1ZXVlID0gaG9vay5xdWV1ZTtcblxuICBpZiAocXVldWUgPT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Nob3VsZCBoYXZlIGEgcXVldWUuIFRoaXMgaXMgbGlrZWx5IGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHF1ZXVlLmxhc3RSZW5kZXJlZFJlZHVjZXIgPSByZWR1Y2VyOyAvLyBUaGlzIGlzIGEgcmUtcmVuZGVyLiBBcHBseSB0aGUgbmV3IHJlbmRlciBwaGFzZSB1cGRhdGVzIHRvIHRoZSBwcmV2aW91c1xuICAvLyB3b3JrLWluLXByb2dyZXNzIGhvb2suXG5cbiAgdmFyIGRpc3BhdGNoID0gcXVldWUuZGlzcGF0Y2g7XG4gIHZhciBsYXN0UmVuZGVyUGhhc2VVcGRhdGUgPSBxdWV1ZS5wZW5kaW5nO1xuICB2YXIgbmV3U3RhdGUgPSBob29rLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKGxhc3RSZW5kZXJQaGFzZVVwZGF0ZSAhPT0gbnVsbCkge1xuICAgIC8vIFRoZSBxdWV1ZSBkb2Vzbid0IHBlcnNpc3QgcGFzdCB0aGlzIHJlbmRlciBwYXNzLlxuICAgIHF1ZXVlLnBlbmRpbmcgPSBudWxsO1xuICAgIHZhciBmaXJzdFJlbmRlclBoYXNlVXBkYXRlID0gbGFzdFJlbmRlclBoYXNlVXBkYXRlLm5leHQ7XG4gICAgdmFyIHVwZGF0ZSA9IGZpcnN0UmVuZGVyUGhhc2VVcGRhdGU7XG5cbiAgICBkbyB7XG4gICAgICAvLyBQcm9jZXNzIHRoaXMgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gV2UgZG9uJ3QgaGF2ZSB0byBjaGVjayB0aGVcbiAgICAgIC8vIHByaW9yaXR5IGJlY2F1c2UgaXQgd2lsbCBhbHdheXMgYmUgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnRcbiAgICAgIC8vIHJlbmRlcidzLlxuICAgICAgdmFyIGFjdGlvbiA9IHVwZGF0ZS5hY3Rpb247XG4gICAgICBuZXdTdGF0ZSA9IHJlZHVjZXIobmV3U3RhdGUsIGFjdGlvbik7XG4gICAgICB1cGRhdGUgPSB1cGRhdGUubmV4dDtcbiAgICB9IHdoaWxlICh1cGRhdGUgIT09IGZpcnN0UmVuZGVyUGhhc2VVcGRhdGUpOyAvLyBNYXJrIHRoYXQgdGhlIGZpYmVyIHBlcmZvcm1lZCB3b3JrLCBidXQgb25seSBpZiB0aGUgbmV3IHN0YXRlIGlzXG4gICAgLy8gZGlmZmVyZW50IGZyb20gdGhlIGN1cnJlbnQgc3RhdGUuXG5cblxuICAgIGlmICghb2JqZWN0SXMobmV3U3RhdGUsIGhvb2subWVtb2l6ZWRTdGF0ZSkpIHtcbiAgICAgIG1hcmtXb3JrSW5Qcm9ncmVzc1JlY2VpdmVkVXBkYXRlKCk7XG4gICAgfVxuXG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7IC8vIERvbid0IHBlcnNpc3QgdGhlIHN0YXRlIGFjY3VtdWxhdGVkIGZyb20gdGhlIHJlbmRlciBwaGFzZSB1cGRhdGVzIHRvXG4gICAgLy8gdGhlIGJhc2Ugc3RhdGUgdW5sZXNzIHRoZSBxdWV1ZSBpcyBlbXB0eS5cbiAgICAvLyBUT0RPOiBOb3Qgc3VyZSBpZiB0aGlzIGlzIHRoZSBkZXNpcmVkIHNlbWFudGljcywgYnV0IGl0J3Mgd2hhdCB3ZVxuICAgIC8vIGRvIGZvciBnRFNGUC4gSSBjYW4ndCByZW1lbWJlciB3aHkuXG5cbiAgICBpZiAoaG9vay5iYXNlUXVldWUgPT09IG51bGwpIHtcbiAgICAgIGhvb2suYmFzZVN0YXRlID0gbmV3U3RhdGU7XG4gICAgfVxuXG4gICAgcXVldWUubGFzdFJlbmRlcmVkU3RhdGUgPSBuZXdTdGF0ZTtcbiAgfVxuXG4gIHJldHVybiBbbmV3U3RhdGUsIGRpc3BhdGNoXTtcbn1cblxuZnVuY3Rpb24gbW91bnRNdXRhYmxlU291cmNlKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVNdXRhYmxlU291cmNlKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb3VudFN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gIHZhciBmaWJlciA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDE7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHRTbmFwc2hvdDtcbiAgdmFyIGlzSHlkcmF0aW5nID0gZ2V0SXNIeWRyYXRpbmcoKTtcblxuICBpZiAoaXNIeWRyYXRpbmcpIHtcbiAgICBpZiAoZ2V0U2VydmVyU25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGdldFNlcnZlclNuYXBzaG90LCB3aGljaCBpcyByZXF1aXJlZCBmb3IgJyArICdzZXJ2ZXItcmVuZGVyZWQgY29udGVudC4gV2lsbCByZXZlcnQgdG8gY2xpZW50IHJlbmRlcmluZy4nKTtcbiAgICB9XG5cbiAgICBuZXh0U25hcHNob3QgPSBnZXRTZXJ2ZXJTbmFwc2hvdCgpO1xuXG4gICAge1xuICAgICAgaWYgKCFkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCkge1xuICAgICAgICBpZiAobmV4dFNuYXBzaG90ICE9PSBnZXRTZXJ2ZXJTbmFwc2hvdCgpKSB7XG4gICAgICAgICAgZXJyb3IoJ1RoZSByZXN1bHQgb2YgZ2V0U2VydmVyU25hcHNob3Qgc2hvdWxkIGJlIGNhY2hlZCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wJyk7XG5cbiAgICAgICAgICBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbmV4dFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICAgIHtcbiAgICAgIGlmICghZGlkV2FyblVuY2FjaGVkR2V0U25hcHNob3QpIHtcbiAgICAgICAgdmFyIGNhY2hlZFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICAgICAgICBpZiAoIW9iamVjdElzKG5leHRTbmFwc2hvdCwgY2FjaGVkU25hcHNob3QpKSB7XG4gICAgICAgICAgZXJyb3IoJ1RoZSByZXN1bHQgb2YgZ2V0U25hcHNob3Qgc2hvdWxkIGJlIGNhY2hlZCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wJyk7XG5cbiAgICAgICAgICBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IC8vIFVubGVzcyB3ZSdyZSByZW5kZXJpbmcgYSBibG9ja2luZyBsYW5lLCBzY2hlZHVsZSBhIGNvbnNpc3RlbmN5IGNoZWNrLlxuICAgIC8vIFJpZ2h0IGJlZm9yZSBjb21taXR0aW5nLCB3ZSB3aWxsIHdhbGsgdGhlIHRyZWUgYW5kIGNoZWNrIGlmIGFueSBvZiB0aGVcbiAgICAvLyBzdG9yZXMgd2VyZSBtdXRhdGVkLlxuICAgIC8vXG4gICAgLy8gV2Ugd29uJ3QgZG8gdGhpcyBpZiB3ZSdyZSBoeWRyYXRpbmcgc2VydmVyLXJlbmRlcmVkIGNvbnRlbnQsIGJlY2F1c2UgaWZcbiAgICAvLyB0aGUgY29udGVudCBpcyBzdGFsZSwgaXQncyBhbHJlYWR5IHZpc2libGUgYW55d2F5LiBJbnN0ZWFkIHdlJ2xsIHBhdGNoXG4gICAgLy8gaXQgdXAgaW4gYSBwYXNzaXZlIGVmZmVjdC5cblxuXG4gICAgdmFyIHJvb3QgPSBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKTtcblxuICAgIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGEgd29yay1pbi1wcm9ncmVzcyByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIHJlbmRlckxhbmVzKSkge1xuICAgICAgcHVzaFN0b3JlQ29uc2lzdGVuY3lDaGVjayhmaWJlciwgZ2V0U25hcHNob3QsIG5leHRTbmFwc2hvdCk7XG4gICAgfVxuICB9IC8vIFJlYWQgdGhlIGN1cnJlbnQgc25hcHNob3QgZnJvbSB0aGUgc3RvcmUgb24gZXZlcnkgcmVuZGVyLiBUaGlzIGJyZWFrcyB0aGVcbiAgLy8gbm9ybWFsIHJ1bGVzIG9mIFJlYWN0LCBhbmQgb25seSB3b3JrcyBiZWNhdXNlIHN0b3JlIHVwZGF0ZXMgYXJlXG4gIC8vIGFsd2F5cyBzeW5jaHJvbm91cy5cblxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5leHRTbmFwc2hvdDtcbiAgdmFyIGluc3QgPSB7XG4gICAgdmFsdWU6IG5leHRTbmFwc2hvdCxcbiAgICBnZXRTbmFwc2hvdDogZ2V0U25hcHNob3RcbiAgfTtcbiAgaG9vay5xdWV1ZSA9IGluc3Q7IC8vIFNjaGVkdWxlIGFuIGVmZmVjdCB0byBzdWJzY3JpYmUgdG8gdGhlIHN0b3JlLlxuXG4gIG1vdW50RWZmZWN0KHN1YnNjcmliZVRvU3RvcmUuYmluZChudWxsLCBmaWJlciwgaW5zdCwgc3Vic2NyaWJlKSwgW3N1YnNjcmliZV0pOyAvLyBTY2hlZHVsZSBhbiBlZmZlY3QgdG8gdXBkYXRlIHRoZSBtdXRhYmxlIGluc3RhbmNlIGZpZWxkcy4gV2Ugd2lsbCB1cGRhdGVcbiAgLy8gdGhpcyB3aGVuZXZlciBzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBvciB2YWx1ZSBjaGFuZ2VzLiBCZWNhdXNlIHRoZXJlJ3Mgbm9cbiAgLy8gY2xlYW4tdXAgZnVuY3Rpb24sIGFuZCB3ZSB0cmFjayB0aGUgZGVwcyBjb3JyZWN0bHksIHdlIGNhbiBjYWxsIHB1c2hFZmZlY3RcbiAgLy8gZGlyZWN0bHksIHdpdGhvdXQgc3RvcmluZyBhbnkgYWRkaXRpb25hbCBzdGF0ZS4gRm9yIHRoZSBzYW1lIHJlYXNvbiwgd2VcbiAgLy8gZG9uJ3QgbmVlZCB0byBzZXQgYSBzdGF0aWMgZmxhZywgZWl0aGVyLlxuICAvLyBUT0RPOiBXZSBjYW4gbW92ZSB0aGlzIHRvIHRoZSBwYXNzaXZlIHBoYXNlIG9uY2Ugd2UgYWRkIGEgcHJlLWNvbW1pdFxuICAvLyBjb25zaXN0ZW5jeSBjaGVjay4gU2VlIHRoZSBuZXh0IGNvbW1lbnQuXG5cbiAgZmliZXIuZmxhZ3MgfD0gUGFzc2l2ZTtcbiAgcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBQYXNzaXZlJDEsIHVwZGF0ZVN0b3JlSW5zdGFuY2UuYmluZChudWxsLCBmaWJlciwgaW5zdCwgbmV4dFNuYXBzaG90LCBnZXRTbmFwc2hvdCksIHVuZGVmaW5lZCwgbnVsbCk7XG4gIHJldHVybiBuZXh0U25hcHNob3Q7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gIHZhciBmaWJlciA9IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDE7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7IC8vIFJlYWQgdGhlIGN1cnJlbnQgc25hcHNob3QgZnJvbSB0aGUgc3RvcmUgb24gZXZlcnkgcmVuZGVyLiBUaGlzIGJyZWFrcyB0aGVcbiAgLy8gbm9ybWFsIHJ1bGVzIG9mIFJlYWN0LCBhbmQgb25seSB3b3JrcyBiZWNhdXNlIHN0b3JlIHVwZGF0ZXMgYXJlXG4gIC8vIGFsd2F5cyBzeW5jaHJvbm91cy5cblxuICB2YXIgbmV4dFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICB7XG4gICAgaWYgKCFkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCkge1xuICAgICAgdmFyIGNhY2hlZFNuYXBzaG90ID0gZ2V0U25hcHNob3QoKTtcblxuICAgICAgaWYgKCFvYmplY3RJcyhuZXh0U25hcHNob3QsIGNhY2hlZFNuYXBzaG90KSkge1xuICAgICAgICBlcnJvcignVGhlIHJlc3VsdCBvZiBnZXRTbmFwc2hvdCBzaG91bGQgYmUgY2FjaGVkIHRvIGF2b2lkIGFuIGluZmluaXRlIGxvb3AnKTtcblxuICAgICAgICBkaWRXYXJuVW5jYWNoZWRHZXRTbmFwc2hvdCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHByZXZTbmFwc2hvdCA9IGhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHNuYXBzaG90Q2hhbmdlZCA9ICFvYmplY3RJcyhwcmV2U25hcHNob3QsIG5leHRTbmFwc2hvdCk7XG5cbiAgaWYgKHNuYXBzaG90Q2hhbmdlZCkge1xuICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IG5leHRTbmFwc2hvdDtcbiAgICBtYXJrV29ya0luUHJvZ3Jlc3NSZWNlaXZlZFVwZGF0ZSgpO1xuICB9XG5cbiAgdmFyIGluc3QgPSBob29rLnF1ZXVlO1xuICB1cGRhdGVFZmZlY3Qoc3Vic2NyaWJlVG9TdG9yZS5iaW5kKG51bGwsIGZpYmVyLCBpbnN0LCBzdWJzY3JpYmUpLCBbc3Vic2NyaWJlXSk7IC8vIFdoZW5ldmVyIGdldFNuYXBzaG90IG9yIHN1YnNjcmliZSBjaGFuZ2VzLCB3ZSBuZWVkIHRvIGNoZWNrIGluIHRoZVxuICAvLyBjb21taXQgcGhhc2UgaWYgdGhlcmUgd2FzIGFuIGludGVybGVhdmVkIG11dGF0aW9uLiBJbiBjb25jdXJyZW50IG1vZGVcbiAgLy8gdGhpcyBjYW4gaGFwcGVuIGFsbCB0aGUgdGltZSwgYnV0IGV2ZW4gaW4gc3luY2hyb25vdXMgbW9kZSwgYW4gZWFybGllclxuICAvLyBlZmZlY3QgbWF5IGhhdmUgbXV0YXRlZCB0aGUgc3RvcmUuXG5cbiAgaWYgKGluc3QuZ2V0U25hcHNob3QgIT09IGdldFNuYXBzaG90IHx8IHNuYXBzaG90Q2hhbmdlZCB8fCAvLyBDaGVjayBpZiB0aGUgc3VzYmNyaWJlIGZ1bmN0aW9uIGNoYW5nZWQuIFdlIGNhbiBzYXZlIHNvbWUgbWVtb3J5IGJ5XG4gIC8vIGNoZWNraW5nIHdoZXRoZXIgd2Ugc2NoZWR1bGVkIGEgc3Vic2NyaXB0aW9uIGVmZmVjdCBhYm92ZS5cbiAgd29ya0luUHJvZ3Jlc3NIb29rICE9PSBudWxsICYmIHdvcmtJblByb2dyZXNzSG9vay5tZW1vaXplZFN0YXRlLnRhZyAmIEhhc0VmZmVjdCkge1xuICAgIGZpYmVyLmZsYWdzIHw9IFBhc3NpdmU7XG4gICAgcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBQYXNzaXZlJDEsIHVwZGF0ZVN0b3JlSW5zdGFuY2UuYmluZChudWxsLCBmaWJlciwgaW5zdCwgbmV4dFNuYXBzaG90LCBnZXRTbmFwc2hvdCksIHVuZGVmaW5lZCwgbnVsbCk7IC8vIFVubGVzcyB3ZSdyZSByZW5kZXJpbmcgYSBibG9ja2luZyBsYW5lLCBzY2hlZHVsZSBhIGNvbnNpc3RlbmN5IGNoZWNrLlxuICAgIC8vIFJpZ2h0IGJlZm9yZSBjb21taXR0aW5nLCB3ZSB3aWxsIHdhbGsgdGhlIHRyZWUgYW5kIGNoZWNrIGlmIGFueSBvZiB0aGVcbiAgICAvLyBzdG9yZXMgd2VyZSBtdXRhdGVkLlxuXG4gICAgdmFyIHJvb3QgPSBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKTtcblxuICAgIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGEgd29yay1pbi1wcm9ncmVzcyByb290LiBUaGlzIGlzIGEgYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgICB9XG5cbiAgICBpZiAoIWluY2x1ZGVzQmxvY2tpbmdMYW5lKHJvb3QsIHJlbmRlckxhbmVzKSkge1xuICAgICAgcHVzaFN0b3JlQ29uc2lzdGVuY3lDaGVjayhmaWJlciwgZ2V0U25hcHNob3QsIG5leHRTbmFwc2hvdCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRTbmFwc2hvdDtcbn1cblxuZnVuY3Rpb24gcHVzaFN0b3JlQ29uc2lzdGVuY3lDaGVjayhmaWJlciwgZ2V0U25hcHNob3QsIHJlbmRlcmVkU25hcHNob3QpIHtcbiAgZmliZXIuZmxhZ3MgfD0gU3RvcmVDb25zaXN0ZW5jeTtcbiAgdmFyIGNoZWNrID0ge1xuICAgIGdldFNuYXBzaG90OiBnZXRTbmFwc2hvdCxcbiAgICB2YWx1ZTogcmVuZGVyZWRTbmFwc2hvdFxuICB9O1xuICB2YXIgY29tcG9uZW50VXBkYXRlUXVldWUgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLnVwZGF0ZVF1ZXVlO1xuXG4gIGlmIChjb21wb25lbnRVcGRhdGVRdWV1ZSA9PT0gbnVsbCkge1xuICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlID0gY3JlYXRlRnVuY3Rpb25Db21wb25lbnRVcGRhdGVRdWV1ZSgpO1xuICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEudXBkYXRlUXVldWUgPSBjb21wb25lbnRVcGRhdGVRdWV1ZTtcbiAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5zdG9yZXMgPSBbY2hlY2tdO1xuICB9IGVsc2Uge1xuICAgIHZhciBzdG9yZXMgPSBjb21wb25lbnRVcGRhdGVRdWV1ZS5zdG9yZXM7XG5cbiAgICBpZiAoc3RvcmVzID09PSBudWxsKSB7XG4gICAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5zdG9yZXMgPSBbY2hlY2tdO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdG9yZXMucHVzaChjaGVjayk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN0b3JlSW5zdGFuY2UoZmliZXIsIGluc3QsIG5leHRTbmFwc2hvdCwgZ2V0U25hcHNob3QpIHtcbiAgLy8gVGhlc2UgYXJlIHVwZGF0ZWQgaW4gdGhlIHBhc3NpdmUgcGhhc2VcbiAgaW5zdC52YWx1ZSA9IG5leHRTbmFwc2hvdDtcbiAgaW5zdC5nZXRTbmFwc2hvdCA9IGdldFNuYXBzaG90OyAvLyBTb21ldGhpbmcgbWF5IGhhdmUgYmVlbiBtdXRhdGVkIGluIGJldHdlZW4gcmVuZGVyIGFuZCBjb21taXQuIFRoaXMgY291bGRcbiAgLy8gaGF2ZSBiZWVuIGluIGFuIGV2ZW50IHRoYXQgZmlyZWQgYmVmb3JlIHRoZSBwYXNzaXZlIGVmZmVjdHMsIG9yIGl0IGNvdWxkXG4gIC8vIGhhdmUgYmVlbiBpbiBhIGxheW91dCBlZmZlY3QuIEluIHRoYXQgY2FzZSwgd2Ugd291bGQgaGF2ZSB1c2VkIHRoZSBvbGRcbiAgLy8gc25hcHNobyBhbmQgZ2V0U25hcHNob3QgdmFsdWVzIHRvIGJhaWwgb3V0LiBXZSBuZWVkIHRvIGNoZWNrIG9uZSBtb3JlIHRpbWUuXG5cbiAgaWYgKGNoZWNrSWZTbmFwc2hvdENoYW5nZWQoaW5zdCkpIHtcbiAgICAvLyBGb3JjZSBhIHJlLXJlbmRlci5cbiAgICBmb3JjZVN0b3JlUmVyZW5kZXIoZmliZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN1YnNjcmliZVRvU3RvcmUoZmliZXIsIGluc3QsIHN1YnNjcmliZSkge1xuICB2YXIgaGFuZGxlU3RvcmVDaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gVGhlIHN0b3JlIGNoYW5nZWQuIENoZWNrIGlmIHRoZSBzbmFwc2hvdCBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2VcbiAgICAvLyByZWFkIGZyb20gdGhlIHN0b3JlLlxuICAgIGlmIChjaGVja0lmU25hcHNob3RDaGFuZ2VkKGluc3QpKSB7XG4gICAgICAvLyBGb3JjZSBhIHJlLXJlbmRlci5cbiAgICAgIGZvcmNlU3RvcmVSZXJlbmRlcihmaWJlcik7XG4gICAgfVxuICB9OyAvLyBTdWJzY3JpYmUgdG8gdGhlIHN0b3JlIGFuZCByZXR1cm4gYSBjbGVhbi11cCBmdW5jdGlvbi5cblxuXG4gIHJldHVybiBzdWJzY3JpYmUoaGFuZGxlU3RvcmVDaGFuZ2UpO1xufVxuXG5mdW5jdGlvbiBjaGVja0lmU25hcHNob3RDaGFuZ2VkKGluc3QpIHtcbiAgdmFyIGxhdGVzdEdldFNuYXBzaG90ID0gaW5zdC5nZXRTbmFwc2hvdDtcbiAgdmFyIHByZXZWYWx1ZSA9IGluc3QudmFsdWU7XG5cbiAgdHJ5IHtcbiAgICB2YXIgbmV4dFZhbHVlID0gbGF0ZXN0R2V0U25hcHNob3QoKTtcbiAgICByZXR1cm4gIW9iamVjdElzKHByZXZWYWx1ZSwgbmV4dFZhbHVlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JjZVN0b3JlUmVyZW5kZXIoZmliZXIpIHtcbiAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIFN5bmNMYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtb3VudFN0YXRlKGluaXRpYWxTdGF0ZSkge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG5cbiAgaWYgKHR5cGVvZiBpbml0aWFsU3RhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyAkRmxvd0ZpeE1lOiBGbG93IGRvZXNuJ3QgbGlrZSBtaXhlZCB0eXBlc1xuICAgIGluaXRpYWxTdGF0ZSA9IGluaXRpYWxTdGF0ZSgpO1xuICB9XG5cbiAgaG9vay5tZW1vaXplZFN0YXRlID0gaG9vay5iYXNlU3RhdGUgPSBpbml0aWFsU3RhdGU7XG4gIHZhciBxdWV1ZSA9IHtcbiAgICBwZW5kaW5nOiBudWxsLFxuICAgIGludGVybGVhdmVkOiBudWxsLFxuICAgIGxhbmVzOiBOb0xhbmVzLFxuICAgIGRpc3BhdGNoOiBudWxsLFxuICAgIGxhc3RSZW5kZXJlZFJlZHVjZXI6IGJhc2ljU3RhdGVSZWR1Y2VyLFxuICAgIGxhc3RSZW5kZXJlZFN0YXRlOiBpbml0aWFsU3RhdGVcbiAgfTtcbiAgaG9vay5xdWV1ZSA9IHF1ZXVlO1xuICB2YXIgZGlzcGF0Y2ggPSBxdWV1ZS5kaXNwYXRjaCA9IGRpc3BhdGNoU2V0U3RhdGUuYmluZChudWxsLCBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLCBxdWV1ZSk7XG4gIHJldHVybiBbaG9vay5tZW1vaXplZFN0YXRlLCBkaXNwYXRjaF07XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN0YXRlKGluaXRpYWxTdGF0ZSkge1xuICByZXR1cm4gdXBkYXRlUmVkdWNlcihiYXNpY1N0YXRlUmVkdWNlcik7XG59XG5cbmZ1bmN0aW9uIHJlcmVuZGVyU3RhdGUoaW5pdGlhbFN0YXRlKSB7XG4gIHJldHVybiByZXJlbmRlclJlZHVjZXIoYmFzaWNTdGF0ZVJlZHVjZXIpO1xufVxuXG5mdW5jdGlvbiBwdXNoRWZmZWN0KHRhZywgY3JlYXRlLCBkZXN0cm95LCBkZXBzKSB7XG4gIHZhciBlZmZlY3QgPSB7XG4gICAgdGFnOiB0YWcsXG4gICAgY3JlYXRlOiBjcmVhdGUsXG4gICAgZGVzdHJveTogZGVzdHJveSxcbiAgICBkZXBzOiBkZXBzLFxuICAgIC8vIENpcmN1bGFyXG4gICAgbmV4dDogbnVsbFxuICB9O1xuICB2YXIgY29tcG9uZW50VXBkYXRlUXVldWUgPSBjdXJyZW50bHlSZW5kZXJpbmdGaWJlciQxLnVwZGF0ZVF1ZXVlO1xuXG4gIGlmIChjb21wb25lbnRVcGRhdGVRdWV1ZSA9PT0gbnVsbCkge1xuICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlID0gY3JlYXRlRnVuY3Rpb25Db21wb25lbnRVcGRhdGVRdWV1ZSgpO1xuICAgIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEudXBkYXRlUXVldWUgPSBjb21wb25lbnRVcGRhdGVRdWV1ZTtcbiAgICBjb21wb25lbnRVcGRhdGVRdWV1ZS5sYXN0RWZmZWN0ID0gZWZmZWN0Lm5leHQgPSBlZmZlY3Q7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxhc3RFZmZlY3QgPSBjb21wb25lbnRVcGRhdGVRdWV1ZS5sYXN0RWZmZWN0O1xuXG4gICAgaWYgKGxhc3RFZmZlY3QgPT09IG51bGwpIHtcbiAgICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlLmxhc3RFZmZlY3QgPSBlZmZlY3QubmV4dCA9IGVmZmVjdDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpcnN0RWZmZWN0ID0gbGFzdEVmZmVjdC5uZXh0O1xuICAgICAgbGFzdEVmZmVjdC5uZXh0ID0gZWZmZWN0O1xuICAgICAgZWZmZWN0Lm5leHQgPSBmaXJzdEVmZmVjdDtcbiAgICAgIGNvbXBvbmVudFVwZGF0ZVF1ZXVlLmxhc3RFZmZlY3QgPSBlZmZlY3Q7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVmZmVjdDtcbn1cblxuZnVuY3Rpb24gbW91bnRSZWYoaW5pdGlhbFZhbHVlKSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcblxuICB7XG4gICAgdmFyIF9yZWYyID0ge1xuICAgICAgY3VycmVudDogaW5pdGlhbFZhbHVlXG4gICAgfTtcbiAgICBob29rLm1lbW9pemVkU3RhdGUgPSBfcmVmMjtcbiAgICByZXR1cm4gX3JlZjI7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlUmVmKGluaXRpYWxWYWx1ZSkge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICByZXR1cm4gaG9vay5tZW1vaXplZFN0YXRlO1xufVxuXG5mdW5jdGlvbiBtb3VudEVmZmVjdEltcGwoZmliZXJGbGFncywgaG9va0ZsYWdzLCBjcmVhdGUsIGRlcHMpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5mbGFncyB8PSBmaWJlckZsYWdzO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBwdXNoRWZmZWN0KEhhc0VmZmVjdCB8IGhvb2tGbGFncywgY3JlYXRlLCB1bmRlZmluZWQsIG5leHREZXBzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRWZmZWN0SW1wbChmaWJlckZsYWdzLCBob29rRmxhZ3MsIGNyZWF0ZSwgZGVwcykge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgdmFyIGRlc3Ryb3kgPSB1bmRlZmluZWQ7XG5cbiAgaWYgKGN1cnJlbnRIb29rICE9PSBudWxsKSB7XG4gICAgdmFyIHByZXZFZmZlY3QgPSBjdXJyZW50SG9vay5tZW1vaXplZFN0YXRlO1xuICAgIGRlc3Ryb3kgPSBwcmV2RWZmZWN0LmRlc3Ryb3k7XG5cbiAgICBpZiAobmV4dERlcHMgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2RGVwcyA9IHByZXZFZmZlY3QuZGVwcztcblxuICAgICAgaWYgKGFyZUhvb2tJbnB1dHNFcXVhbChuZXh0RGVwcywgcHJldkRlcHMpKSB7XG4gICAgICAgIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHB1c2hFZmZlY3QoaG9va0ZsYWdzLCBjcmVhdGUsIGRlc3Ryb3ksIG5leHREZXBzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEuZmxhZ3MgfD0gZmliZXJGbGFncztcbiAgaG9vay5tZW1vaXplZFN0YXRlID0gcHVzaEVmZmVjdChIYXNFZmZlY3QgfCBob29rRmxhZ3MsIGNyZWF0ZSwgZGVzdHJveSwgbmV4dERlcHMpO1xufVxuXG5mdW5jdGlvbiBtb3VudEVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgaWYgKCAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICByZXR1cm4gbW91bnRFZmZlY3RJbXBsKE1vdW50UGFzc2l2ZURldiB8IFBhc3NpdmUgfCBQYXNzaXZlU3RhdGljLCBQYXNzaXZlJDEsIGNyZWF0ZSwgZGVwcyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChQYXNzaXZlIHwgUGFzc2l2ZVN0YXRpYywgUGFzc2l2ZSQxLCBjcmVhdGUsIGRlcHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgcmV0dXJuIHVwZGF0ZUVmZmVjdEltcGwoUGFzc2l2ZSwgUGFzc2l2ZSQxLCBjcmVhdGUsIGRlcHMpO1xufVxuXG5mdW5jdGlvbiBtb3VudEluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpIHtcbiAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChVcGRhdGUsIEluc2VydGlvbiwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcykge1xuICByZXR1cm4gdXBkYXRlRWZmZWN0SW1wbChVcGRhdGUsIEluc2VydGlvbiwgY3JlYXRlLCBkZXBzKTtcbn1cblxuZnVuY3Rpb24gbW91bnRMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHZhciBmaWJlckZsYWdzID0gVXBkYXRlO1xuXG4gIHtcbiAgICBmaWJlckZsYWdzIHw9IExheW91dFN0YXRpYztcbiAgfVxuXG4gIGlmICggKGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEubW9kZSAmIFN0cmljdEVmZmVjdHNNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgZmliZXJGbGFncyB8PSBNb3VudExheW91dERldjtcbiAgfVxuXG4gIHJldHVybiBtb3VudEVmZmVjdEltcGwoZmliZXJGbGFncywgTGF5b3V0LCBjcmVhdGUsIGRlcHMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKSB7XG4gIHJldHVybiB1cGRhdGVFZmZlY3RJbXBsKFVwZGF0ZSwgTGF5b3V0LCBjcmVhdGUsIGRlcHMpO1xufVxuXG5mdW5jdGlvbiBpbXBlcmF0aXZlSGFuZGxlRWZmZWN0KGNyZWF0ZSwgcmVmKSB7XG4gIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIHJlZkNhbGxiYWNrID0gcmVmO1xuXG4gICAgdmFyIF9pbnN0ID0gY3JlYXRlKCk7XG5cbiAgICByZWZDYWxsYmFjayhfaW5zdCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlZkNhbGxiYWNrKG51bGwpO1xuICAgIH07XG4gIH0gZWxzZSBpZiAocmVmICE9PSBudWxsICYmIHJlZiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHJlZk9iamVjdCA9IHJlZjtcblxuICAgIHtcbiAgICAgIGlmICghcmVmT2JqZWN0Lmhhc093blByb3BlcnR5KCdjdXJyZW50JykpIHtcbiAgICAgICAgZXJyb3IoJ0V4cGVjdGVkIHVzZUltcGVyYXRpdmVIYW5kbGUoKSBmaXJzdCBhcmd1bWVudCB0byBlaXRoZXIgYmUgYSAnICsgJ3JlZiBjYWxsYmFjayBvciBSZWFjdC5jcmVhdGVSZWYoKSBvYmplY3QuIEluc3RlYWQgcmVjZWl2ZWQ6ICVzLicsICdhbiBvYmplY3Qgd2l0aCBrZXlzIHsnICsgT2JqZWN0LmtleXMocmVmT2JqZWN0KS5qb2luKCcsICcpICsgJ30nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgX2luc3QyID0gY3JlYXRlKCk7XG5cbiAgICByZWZPYmplY3QuY3VycmVudCA9IF9pbnN0MjtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgcmVmT2JqZWN0LmN1cnJlbnQgPSBudWxsO1xuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHVzZUltcGVyYXRpdmVIYW5kbGUoKSBzZWNvbmQgYXJndW1lbnQgdG8gYmUgYSBmdW5jdGlvbiAnICsgJ3RoYXQgY3JlYXRlcyBhIGhhbmRsZS4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY3JlYXRlICE9PSBudWxsID8gdHlwZW9mIGNyZWF0ZSA6ICdudWxsJyk7XG4gICAgfVxuICB9IC8vIFRPRE86IElmIGRlcHMgYXJlIHByb3ZpZGVkLCBzaG91bGQgd2Ugc2tpcCBjb21wYXJpbmcgdGhlIHJlZiBpdHNlbGY/XG5cblxuICB2YXIgZWZmZWN0RGVwcyA9IGRlcHMgIT09IG51bGwgJiYgZGVwcyAhPT0gdW5kZWZpbmVkID8gZGVwcy5jb25jYXQoW3JlZl0pIDogbnVsbDtcbiAgdmFyIGZpYmVyRmxhZ3MgPSBVcGRhdGU7XG5cbiAge1xuICAgIGZpYmVyRmxhZ3MgfD0gTGF5b3V0U3RhdGljO1xuICB9XG5cbiAgaWYgKCAoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5tb2RlICYgU3RyaWN0RWZmZWN0c01vZGUpICE9PSBOb01vZGUpIHtcbiAgICBmaWJlckZsYWdzIHw9IE1vdW50TGF5b3V0RGV2O1xuICB9XG5cbiAgcmV0dXJuIG1vdW50RWZmZWN0SW1wbChmaWJlckZsYWdzLCBMYXlvdXQsIGltcGVyYXRpdmVIYW5kbGVFZmZlY3QuYmluZChudWxsLCBjcmVhdGUsIHJlZiksIGVmZmVjdERlcHMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGNyZWF0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ0V4cGVjdGVkIHVzZUltcGVyYXRpdmVIYW5kbGUoKSBzZWNvbmQgYXJndW1lbnQgdG8gYmUgYSBmdW5jdGlvbiAnICsgJ3RoYXQgY3JlYXRlcyBhIGhhbmRsZS4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY3JlYXRlICE9PSBudWxsID8gdHlwZW9mIGNyZWF0ZSA6ICdudWxsJyk7XG4gICAgfVxuICB9IC8vIFRPRE86IElmIGRlcHMgYXJlIHByb3ZpZGVkLCBzaG91bGQgd2Ugc2tpcCBjb21wYXJpbmcgdGhlIHJlZiBpdHNlbGY/XG5cblxuICB2YXIgZWZmZWN0RGVwcyA9IGRlcHMgIT09IG51bGwgJiYgZGVwcyAhPT0gdW5kZWZpbmVkID8gZGVwcy5jb25jYXQoW3JlZl0pIDogbnVsbDtcbiAgcmV0dXJuIHVwZGF0ZUVmZmVjdEltcGwoVXBkYXRlLCBMYXlvdXQsIGltcGVyYXRpdmVIYW5kbGVFZmZlY3QuYmluZChudWxsLCBjcmVhdGUsIHJlZiksIGVmZmVjdERlcHMpO1xufVxuXG5mdW5jdGlvbiBtb3VudERlYnVnVmFsdWUodmFsdWUsIGZvcm1hdHRlckZuKSB7Ly8gVGhpcyBob29rIGlzIG5vcm1hbGx5IGEgbm8tb3AuXG4gIC8vIFRoZSByZWFjdC1kZWJ1Zy1ob29rcyBwYWNrYWdlIGluamVjdHMgaXRzIG93biBpbXBsZW1lbnRhdGlvblxuICAvLyBzbyB0aGF0IGUuZy4gRGV2VG9vbHMgY2FuIGRpc3BsYXkgY3VzdG9tIGhvb2sgdmFsdWVzLlxufVxuXG52YXIgdXBkYXRlRGVidWdWYWx1ZSA9IG1vdW50RGVidWdWYWx1ZTtcblxuZnVuY3Rpb24gbW91bnRDYWxsYmFjayhjYWxsYmFjaywgZGVwcykge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBuZXh0RGVwcyA9IGRlcHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZXBzO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBbY2FsbGJhY2ssIG5leHREZXBzXTtcbiAgcmV0dXJuIGNhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcykge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgbmV4dERlcHMgPSBkZXBzID09PSB1bmRlZmluZWQgPyBudWxsIDogZGVwcztcbiAgdmFyIHByZXZTdGF0ZSA9IGhvb2subWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAocHJldlN0YXRlICE9PSBudWxsKSB7XG4gICAgaWYgKG5leHREZXBzICE9PSBudWxsKSB7XG4gICAgICB2YXIgcHJldkRlcHMgPSBwcmV2U3RhdGVbMV07XG5cbiAgICAgIGlmIChhcmVIb29rSW5wdXRzRXF1YWwobmV4dERlcHMsIHByZXZEZXBzKSkge1xuICAgICAgICByZXR1cm4gcHJldlN0YXRlWzBdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IFtjYWxsYmFjaywgbmV4dERlcHNdO1xuICByZXR1cm4gY2FsbGJhY2s7XG59XG5cbmZ1bmN0aW9uIG1vdW50TWVtbyhuZXh0Q3JlYXRlLCBkZXBzKSB7XG4gIHZhciBob29rID0gbW91bnRXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIG5leHREZXBzID0gZGVwcyA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGRlcHM7XG4gIHZhciBuZXh0VmFsdWUgPSBuZXh0Q3JlYXRlKCk7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IFtuZXh0VmFsdWUsIG5leHREZXBzXTtcbiAgcmV0dXJuIG5leHRWYWx1ZTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTWVtbyhuZXh0Q3JlYXRlLCBkZXBzKSB7XG4gIHZhciBob29rID0gdXBkYXRlV29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIHZhciBuZXh0RGVwcyA9IGRlcHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZXBzO1xuICB2YXIgcHJldlN0YXRlID0gaG9vay5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAvLyBBc3N1bWUgdGhlc2UgYXJlIGRlZmluZWQuIElmIHRoZXkncmUgbm90LCBhcmVIb29rSW5wdXRzRXF1YWwgd2lsbCB3YXJuLlxuICAgIGlmIChuZXh0RGVwcyAhPT0gbnVsbCkge1xuICAgICAgdmFyIHByZXZEZXBzID0gcHJldlN0YXRlWzFdO1xuXG4gICAgICBpZiAoYXJlSG9va0lucHV0c0VxdWFsKG5leHREZXBzLCBwcmV2RGVwcykpIHtcbiAgICAgICAgcmV0dXJuIHByZXZTdGF0ZVswXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbmV4dFZhbHVlID0gbmV4dENyZWF0ZSgpO1xuICBob29rLm1lbW9pemVkU3RhdGUgPSBbbmV4dFZhbHVlLCBuZXh0RGVwc107XG4gIHJldHVybiBuZXh0VmFsdWU7XG59XG5cbmZ1bmN0aW9uIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSkge1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHZhbHVlO1xuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZURlZmVycmVkVmFsdWUodmFsdWUpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHJlc29sdmVkQ3VycmVudEhvb2sgPSBjdXJyZW50SG9vaztcbiAgdmFyIHByZXZWYWx1ZSA9IHJlc29sdmVkQ3VycmVudEhvb2subWVtb2l6ZWRTdGF0ZTtcbiAgcmV0dXJuIHVwZGF0ZURlZmVycmVkVmFsdWVJbXBsKGhvb2ssIHByZXZWYWx1ZSwgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiByZXJlbmRlckRlZmVycmVkVmFsdWUodmFsdWUpIHtcbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcblxuICBpZiAoY3VycmVudEhvb2sgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIGEgcmVyZW5kZXIgZHVyaW5nIGEgbW91bnQuXG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSByZXJlbmRlciBkdXJpbmcgYW4gdXBkYXRlLlxuICAgIHZhciBwcmV2VmFsdWUgPSBjdXJyZW50SG9vay5tZW1vaXplZFN0YXRlO1xuICAgIHJldHVybiB1cGRhdGVEZWZlcnJlZFZhbHVlSW1wbChob29rLCBwcmV2VmFsdWUsIHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1cGRhdGVEZWZlcnJlZFZhbHVlSW1wbChob29rLCBwcmV2VmFsdWUsIHZhbHVlKSB7XG4gIHZhciBzaG91bGREZWZlclZhbHVlID0gIWluY2x1ZGVzT25seU5vblVyZ2VudExhbmVzKHJlbmRlckxhbmVzKTtcblxuICBpZiAoc2hvdWxkRGVmZXJWYWx1ZSkge1xuICAgIC8vIFRoaXMgaXMgYW4gdXJnZW50IHVwZGF0ZS4gSWYgdGhlIHZhbHVlIGhhcyBjaGFuZ2VkLCBrZWVwIHVzaW5nIHRoZVxuICAgIC8vIHByZXZpb3VzIHZhbHVlIGFuZCBzcGF3biBhIGRlZmVycmVkIHJlbmRlciB0byB1cGRhdGUgaXQgbGF0ZXIuXG4gICAgaWYgKCFvYmplY3RJcyh2YWx1ZSwgcHJldlZhbHVlKSkge1xuICAgICAgLy8gU2NoZWR1bGUgYSBkZWZlcnJlZCByZW5kZXJcbiAgICAgIHZhciBkZWZlcnJlZExhbmUgPSBjbGFpbU5leHRUcmFuc2l0aW9uTGFuZSgpO1xuICAgICAgY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcyA9IG1lcmdlTGFuZXMoY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMS5sYW5lcywgZGVmZXJyZWRMYW5lKTtcbiAgICAgIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMoZGVmZXJyZWRMYW5lKTsgLy8gU2V0IHRoaXMgdG8gdHJ1ZSB0byBpbmRpY2F0ZSB0aGF0IHRoZSByZW5kZXJlZCB2YWx1ZSBpcyBpbmNvbnNpc3RlbnRcbiAgICAgIC8vIGZyb20gdGhlIGxhdGVzdCB2YWx1ZS4gVGhlIG5hbWUgXCJiYXNlU3RhdGVcIiBkb2Vzbid0IHJlYWxseSBtYXRjaCBob3cgd2VcbiAgICAgIC8vIHVzZSBpdCBiZWNhdXNlIHdlJ3JlIHJldXNpbmcgYSBzdGF0ZSBob29rIGZpZWxkIGluc3RlYWQgb2YgY3JlYXRpbmcgYVxuICAgICAgLy8gbmV3IG9uZS5cblxuICAgICAgaG9vay5iYXNlU3RhdGUgPSB0cnVlO1xuICAgIH0gLy8gUmV1c2UgdGhlIHByZXZpb3VzIHZhbHVlXG5cblxuICAgIHJldHVybiBwcmV2VmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBub3QgYW4gdXJnZW50IHVwZGF0ZSwgc28gd2UgY2FuIHVzZSB0aGUgbGF0ZXN0IHZhbHVlIHJlZ2FyZGxlc3NcbiAgICAvLyBvZiB3aGF0IGl0IGlzLiBObyBuZWVkIHRvIGRlZmVyIGl0LlxuICAgIC8vIEhvd2V2ZXIsIGlmIHdlJ3JlIGN1cnJlbnRseSBpbnNpZGUgYSBzcGF3bmVkIHJlbmRlciwgdGhlbiB3ZSBuZWVkIHRvIG1hcmtcbiAgICAvLyB0aGlzIGFzIGFuIHVwZGF0ZSB0byBwcmV2ZW50IHRoZSBmaWJlciBmcm9tIGJhaWxpbmcgb3V0LlxuICAgIC8vXG4gICAgLy8gYGJhc2VTdGF0ZWAgaXMgdHJ1ZSB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGlzIGRpZmZlcmVudCBmcm9tIHRoZSByZW5kZXJlZFxuICAgIC8vIHZhbHVlLiBUaGUgbmFtZSBkb2Vzbid0IHJlYWxseSBtYXRjaCBob3cgd2UgdXNlIGl0IGJlY2F1c2Ugd2UncmUgcmV1c2luZ1xuICAgIC8vIGEgc3RhdGUgaG9vayBmaWVsZCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IG9uZS5cbiAgICBpZiAoaG9vay5iYXNlU3RhdGUpIHtcbiAgICAgIC8vIEZsaXAgdGhpcyBiYWNrIHRvIGZhbHNlLlxuICAgICAgaG9vay5iYXNlU3RhdGUgPSBmYWxzZTtcbiAgICAgIG1hcmtXb3JrSW5Qcm9ncmVzc1JlY2VpdmVkVXBkYXRlKCk7XG4gICAgfVxuXG4gICAgaG9vay5tZW1vaXplZFN0YXRlID0gdmFsdWU7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0YXJ0VHJhbnNpdGlvbihzZXRQZW5kaW5nLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICB2YXIgcHJldmlvdXNQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoaGlnaGVyRXZlbnRQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5LCBDb250aW51b3VzRXZlbnRQcmlvcml0eSkpO1xuICBzZXRQZW5kaW5nKHRydWUpO1xuICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQyLnRyYW5zaXRpb247XG4gIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDIudHJhbnNpdGlvbiA9IHt9O1xuICB2YXIgY3VycmVudFRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQyLnRyYW5zaXRpb247XG5cbiAge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDIudHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycyA9IG5ldyBTZXQoKTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgc2V0UGVuZGluZyhmYWxzZSk7XG4gICAgY2FsbGJhY2soKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSk7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMi50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG5cbiAgICB7XG4gICAgICBpZiAocHJldlRyYW5zaXRpb24gPT09IG51bGwgJiYgY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMpIHtcbiAgICAgICAgdmFyIHVwZGF0ZWRGaWJlcnNDb3VudCA9IGN1cnJlbnRUcmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLnNpemU7XG5cbiAgICAgICAgaWYgKHVwZGF0ZWRGaWJlcnNDb3VudCA+IDEwKSB7XG4gICAgICAgICAgd2FybignRGV0ZWN0ZWQgYSBsYXJnZSBudW1iZXIgb2YgdXBkYXRlcyBpbnNpZGUgc3RhcnRUcmFuc2l0aW9uLiAnICsgJ0lmIHRoaXMgaXMgZHVlIHRvIGEgc3Vic2NyaXB0aW9uIHBsZWFzZSByZS13cml0ZSBpdCB0byB1c2UgUmVhY3QgcHJvdmlkZWQgaG9va3MuICcgKyAnT3RoZXJ3aXNlIGNvbmN1cnJlbnQgbW9kZSBndWFyYW50ZWVzIGFyZSBvZmYgdGhlIHRhYmxlLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudFRyYW5zaXRpb24uX3VwZGF0ZWRGaWJlcnMuY2xlYXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRUcmFuc2l0aW9uKCkge1xuICB2YXIgX21vdW50U3RhdGUgPSBtb3VudFN0YXRlKGZhbHNlKSxcbiAgICAgIGlzUGVuZGluZyA9IF9tb3VudFN0YXRlWzBdLFxuICAgICAgc2V0UGVuZGluZyA9IF9tb3VudFN0YXRlWzFdOyAvLyBUaGUgYHN0YXJ0YCBtZXRob2QgbmV2ZXIgY2hhbmdlcy5cblxuXG4gIHZhciBzdGFydCA9IHN0YXJ0VHJhbnNpdGlvbi5iaW5kKG51bGwsIHNldFBlbmRpbmcpO1xuICB2YXIgaG9vayA9IG1vdW50V29ya0luUHJvZ3Jlc3NIb29rKCk7XG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IHN0YXJ0O1xuICByZXR1cm4gW2lzUGVuZGluZywgc3RhcnRdO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVUcmFuc2l0aW9uKCkge1xuICB2YXIgX3VwZGF0ZVN0YXRlID0gdXBkYXRlU3RhdGUoKSxcbiAgICAgIGlzUGVuZGluZyA9IF91cGRhdGVTdGF0ZVswXTtcblxuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgc3RhcnQgPSBob29rLm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiBbaXNQZW5kaW5nLCBzdGFydF07XG59XG5cbmZ1bmN0aW9uIHJlcmVuZGVyVHJhbnNpdGlvbigpIHtcbiAgdmFyIF9yZXJlbmRlclN0YXRlID0gcmVyZW5kZXJTdGF0ZSgpLFxuICAgICAgaXNQZW5kaW5nID0gX3JlcmVuZGVyU3RhdGVbMF07XG5cbiAgdmFyIGhvb2sgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc0hvb2soKTtcbiAgdmFyIHN0YXJ0ID0gaG9vay5tZW1vaXplZFN0YXRlO1xuICByZXR1cm4gW2lzUGVuZGluZywgc3RhcnRdO1xufVxuXG52YXIgaXNVcGRhdGluZ09wYXF1ZVZhbHVlSW5SZW5kZXJQaGFzZSA9IGZhbHNlO1xuZnVuY3Rpb24gZ2V0SXNVcGRhdGluZ09wYXF1ZVZhbHVlSW5SZW5kZXJQaGFzZUluREVWKCkge1xuICB7XG4gICAgcmV0dXJuIGlzVXBkYXRpbmdPcGFxdWVWYWx1ZUluUmVuZGVyUGhhc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gbW91bnRJZCgpIHtcbiAgdmFyIGhvb2sgPSBtb3VudFdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgcm9vdCA9IGdldFdvcmtJblByb2dyZXNzUm9vdCgpOyAvLyBUT0RPOiBJbiBGaXp6LCBpZCBnZW5lcmF0aW9uIGlzIHNwZWNpZmljIHRvIGVhY2ggc2VydmVyIGNvbmZpZy4gTWF5YmUgd2VcbiAgLy8gc2hvdWxkIGRvIHRoaXMgaW4gRmliZXIsIHRvbz8gRGVmZXJyaW5nIHRoaXMgZGVjaXNpb24gZm9yIG5vdyBiZWNhdXNlXG4gIC8vIHRoZXJlJ3Mgbm8gb3RoZXIgcGxhY2UgdG8gc3RvcmUgdGhlIHByZWZpeCBleGNlcHQgZm9yIGFuIGludGVybmFsIGZpZWxkIG9uXG4gIC8vIHRoZSBwdWJsaWMgY3JlYXRlUm9vdCBvYmplY3QsIHdoaWNoIHRoZSBmaWJlciB0cmVlIGRvZXMgbm90IGN1cnJlbnRseSBoYXZlXG4gIC8vIGEgcmVmZXJlbmNlIHRvLlxuXG4gIHZhciBpZGVudGlmaWVyUHJlZml4ID0gcm9vdC5pZGVudGlmaWVyUHJlZml4O1xuICB2YXIgaWQ7XG5cbiAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICB2YXIgdHJlZUlkID0gZ2V0VHJlZUlkKCk7IC8vIFVzZSBhIGNhcHRpYWwgUiBwcmVmaXggZm9yIHNlcnZlci1nZW5lcmF0ZWQgaWRzLlxuXG4gICAgaWQgPSAnOicgKyBpZGVudGlmaWVyUHJlZml4ICsgJ1InICsgdHJlZUlkOyAvLyBVbmxlc3MgdGhpcyBpcyB0aGUgZmlyc3QgaWQgYXQgdGhpcyBsZXZlbCwgYXBwZW5kIGEgbnVtYmVyIGF0IHRoZSBlbmRcbiAgICAvLyB0aGF0IHJlcHJlc2VudHMgdGhlIHBvc2l0aW9uIG9mIHRoaXMgdXNlSWQgaG9vayBhbW9uZyBhbGwgdGhlIHVzZUlkXG4gICAgLy8gaG9va3MgZm9yIHRoaXMgZmliZXIuXG5cbiAgICB2YXIgbG9jYWxJZCA9IGxvY2FsSWRDb3VudGVyKys7XG5cbiAgICBpZiAobG9jYWxJZCA+IDApIHtcbiAgICAgIGlkICs9ICdIJyArIGxvY2FsSWQudG9TdHJpbmcoMzIpO1xuICAgIH1cblxuICAgIGlkICs9ICc6JztcbiAgfSBlbHNlIHtcbiAgICAvLyBVc2UgYSBsb3dlcmNhc2UgciBwcmVmaXggZm9yIGNsaWVudC1nZW5lcmF0ZWQgaWRzLlxuICAgIHZhciBnbG9iYWxDbGllbnRJZCA9IGdsb2JhbENsaWVudElkQ291bnRlcisrO1xuICAgIGlkID0gJzonICsgaWRlbnRpZmllclByZWZpeCArICdyJyArIGdsb2JhbENsaWVudElkLnRvU3RyaW5nKDMyKSArICc6JztcbiAgfVxuXG4gIGhvb2subWVtb2l6ZWRTdGF0ZSA9IGlkO1xuICByZXR1cm4gaWQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUlkKCkge1xuICB2YXIgaG9vayA9IHVwZGF0ZVdvcmtJblByb2dyZXNzSG9vaygpO1xuICB2YXIgaWQgPSBob29rLm1lbW9pemVkU3RhdGU7XG4gIHJldHVybiBpZDtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hSZWR1Y2VyQWN0aW9uKGZpYmVyLCBxdWV1ZSwgYWN0aW9uKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1szXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoXCJTdGF0ZSB1cGRhdGVzIGZyb20gdGhlIHVzZVN0YXRlKCkgYW5kIHVzZVJlZHVjZXIoKSBIb29rcyBkb24ndCBzdXBwb3J0IHRoZSBcIiArICdzZWNvbmQgY2FsbGJhY2sgYXJndW1lbnQuIFRvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciAnICsgJ3JlbmRlcmluZywgZGVjbGFyZSBpdCBpbiB0aGUgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHVwZGF0ZSA9IHtcbiAgICBsYW5lOiBsYW5lLFxuICAgIGFjdGlvbjogYWN0aW9uLFxuICAgIGhhc0VhZ2VyU3RhdGU6IGZhbHNlLFxuICAgIGVhZ2VyU3RhdGU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmIChpc1JlbmRlclBoYXNlVXBkYXRlKGZpYmVyKSkge1xuICAgIGVucXVldWVSZW5kZXJQaGFzZVVwZGF0ZShxdWV1ZSwgdXBkYXRlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcm9vdCA9IGVucXVldWVDb25jdXJyZW50SG9va1VwZGF0ZShmaWJlciwgcXVldWUsIHVwZGF0ZSwgbGFuZSk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgICAgIGVudGFuZ2xlVHJhbnNpdGlvblVwZGF0ZShyb290LCBxdWV1ZSwgbGFuZSk7XG4gICAgfVxuICB9XG5cbiAgbWFya1VwZGF0ZUluRGV2VG9vbHMoZmliZXIsIGxhbmUpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaFNldFN0YXRlKGZpYmVyLCBxdWV1ZSwgYWN0aW9uKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1szXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoXCJTdGF0ZSB1cGRhdGVzIGZyb20gdGhlIHVzZVN0YXRlKCkgYW5kIHVzZVJlZHVjZXIoKSBIb29rcyBkb24ndCBzdXBwb3J0IHRoZSBcIiArICdzZWNvbmQgY2FsbGJhY2sgYXJndW1lbnQuIFRvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciAnICsgJ3JlbmRlcmluZywgZGVjbGFyZSBpdCBpbiB0aGUgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHVwZGF0ZSA9IHtcbiAgICBsYW5lOiBsYW5lLFxuICAgIGFjdGlvbjogYWN0aW9uLFxuICAgIGhhc0VhZ2VyU3RhdGU6IGZhbHNlLFxuICAgIGVhZ2VyU3RhdGU6IG51bGwsXG4gICAgbmV4dDogbnVsbFxuICB9O1xuXG4gIGlmIChpc1JlbmRlclBoYXNlVXBkYXRlKGZpYmVyKSkge1xuICAgIGVucXVldWVSZW5kZXJQaGFzZVVwZGF0ZShxdWV1ZSwgdXBkYXRlKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGZpYmVyLmxhbmVzID09PSBOb0xhbmVzICYmIChhbHRlcm5hdGUgPT09IG51bGwgfHwgYWx0ZXJuYXRlLmxhbmVzID09PSBOb0xhbmVzKSkge1xuICAgICAgLy8gVGhlIHF1ZXVlIGlzIGN1cnJlbnRseSBlbXB0eSwgd2hpY2ggbWVhbnMgd2UgY2FuIGVhZ2VybHkgY29tcHV0ZSB0aGVcbiAgICAgIC8vIG5leHQgc3RhdGUgYmVmb3JlIGVudGVyaW5nIHRoZSByZW5kZXIgcGhhc2UuIElmIHRoZSBuZXcgc3RhdGUgaXMgdGhlXG4gICAgICAvLyBzYW1lIGFzIHRoZSBjdXJyZW50IHN0YXRlLCB3ZSBtYXkgYmUgYWJsZSB0byBiYWlsIG91dCBlbnRpcmVseS5cbiAgICAgIHZhciBsYXN0UmVuZGVyZWRSZWR1Y2VyID0gcXVldWUubGFzdFJlbmRlcmVkUmVkdWNlcjtcblxuICAgICAgaWYgKGxhc3RSZW5kZXJlZFJlZHVjZXIgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHByZXZEaXNwYXRjaGVyO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHZhciBjdXJyZW50U3RhdGUgPSBxdWV1ZS5sYXN0UmVuZGVyZWRTdGF0ZTtcbiAgICAgICAgICB2YXIgZWFnZXJTdGF0ZSA9IGxhc3RSZW5kZXJlZFJlZHVjZXIoY3VycmVudFN0YXRlLCBhY3Rpb24pOyAvLyBTdGFzaCB0aGUgZWFnZXJseSBjb21wdXRlZCBzdGF0ZSwgYW5kIHRoZSByZWR1Y2VyIHVzZWQgdG8gY29tcHV0ZVxuICAgICAgICAgIC8vIGl0LCBvbiB0aGUgdXBkYXRlIG9iamVjdC4gSWYgdGhlIHJlZHVjZXIgaGFzbid0IGNoYW5nZWQgYnkgdGhlXG4gICAgICAgICAgLy8gdGltZSB3ZSBlbnRlciB0aGUgcmVuZGVyIHBoYXNlLCB0aGVuIHRoZSBlYWdlciBzdGF0ZSBjYW4gYmUgdXNlZFxuICAgICAgICAgIC8vIHdpdGhvdXQgY2FsbGluZyB0aGUgcmVkdWNlciBhZ2Fpbi5cblxuICAgICAgICAgIHVwZGF0ZS5oYXNFYWdlclN0YXRlID0gdHJ1ZTtcbiAgICAgICAgICB1cGRhdGUuZWFnZXJTdGF0ZSA9IGVhZ2VyU3RhdGU7XG5cbiAgICAgICAgICBpZiAob2JqZWN0SXMoZWFnZXJTdGF0ZSwgY3VycmVudFN0YXRlKSkge1xuICAgICAgICAgICAgLy8gRmFzdCBwYXRoLiBXZSBjYW4gYmFpbCBvdXQgd2l0aG91dCBzY2hlZHVsaW5nIFJlYWN0IHRvIHJlLXJlbmRlci5cbiAgICAgICAgICAgIC8vIEl0J3Mgc3RpbGwgcG9zc2libGUgdGhhdCB3ZSdsbCBuZWVkIHRvIHJlYmFzZSB0aGlzIHVwZGF0ZSBsYXRlcixcbiAgICAgICAgICAgIC8vIGlmIHRoZSBjb21wb25lbnQgcmUtcmVuZGVycyBmb3IgYSBkaWZmZXJlbnQgcmVhc29uIGFuZCBieSB0aGF0XG4gICAgICAgICAgICAvLyB0aW1lIHRoZSByZWR1Y2VyIGhhcyBjaGFuZ2VkLlxuICAgICAgICAgICAgLy8gVE9ETzogRG8gd2Ugc3RpbGwgbmVlZCB0byBlbnRhbmdsZSB0cmFuc2l0aW9ucyBpbiB0aGlzIGNhc2U/XG4gICAgICAgICAgICBlbnF1ZXVlQ29uY3VycmVudEhvb2tVcGRhdGVBbmRFYWdlcmx5QmFpbG91dChmaWJlciwgcXVldWUsIHVwZGF0ZSwgbGFuZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikgey8vIFN1cHByZXNzIHRoZSBlcnJvci4gSXQgd2lsbCB0aHJvdyBhZ2FpbiBpbiB0aGUgcmVuZGVyIHBoYXNlLlxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudEhvb2tVcGRhdGUoZmliZXIsIHF1ZXVlLCB1cGRhdGUsIGxhbmUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gICAgICBlbnRhbmdsZVRyYW5zaXRpb25VcGRhdGUocm9vdCwgcXVldWUsIGxhbmUpO1xuICAgIH1cbiAgfVxuXG4gIG1hcmtVcGRhdGVJbkRldlRvb2xzKGZpYmVyLCBsYW5lKTtcbn1cblxuZnVuY3Rpb24gaXNSZW5kZXJQaGFzZVVwZGF0ZShmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuICByZXR1cm4gZmliZXIgPT09IGN1cnJlbnRseVJlbmRlcmluZ0ZpYmVyJDEgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGFsdGVybmF0ZSA9PT0gY3VycmVudGx5UmVuZGVyaW5nRmliZXIkMTtcbn1cblxuZnVuY3Rpb24gZW5xdWV1ZVJlbmRlclBoYXNlVXBkYXRlKHF1ZXVlLCB1cGRhdGUpIHtcbiAgLy8gVGhpcyBpcyBhIHJlbmRlciBwaGFzZSB1cGRhdGUuIFN0YXNoIGl0IGluIGEgbGF6aWx5LWNyZWF0ZWQgbWFwIG9mXG4gIC8vIHF1ZXVlIC0+IGxpbmtlZCBsaXN0IG9mIHVwZGF0ZXMuIEFmdGVyIHRoaXMgcmVuZGVyIHBhc3MsIHdlJ2xsIHJlc3RhcnRcbiAgLy8gYW5kIGFwcGx5IHRoZSBzdGFzaGVkIHVwZGF0ZXMgb24gdG9wIG9mIHRoZSB3b3JrLWluLXByb2dyZXNzIGhvb2suXG4gIGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGVEdXJpbmdUaGlzUGFzcyA9IGRpZFNjaGVkdWxlUmVuZGVyUGhhc2VVcGRhdGUgPSB0cnVlO1xuICB2YXIgcGVuZGluZyA9IHF1ZXVlLnBlbmRpbmc7XG5cbiAgaWYgKHBlbmRpbmcgPT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUuIENyZWF0ZSBhIGNpcmN1bGFyIGxpc3QuXG4gICAgdXBkYXRlLm5leHQgPSB1cGRhdGU7XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLm5leHQgPSBwZW5kaW5nLm5leHQ7XG4gICAgcGVuZGluZy5uZXh0ID0gdXBkYXRlO1xuICB9XG5cbiAgcXVldWUucGVuZGluZyA9IHVwZGF0ZTtcbn0gLy8gVE9ETzogTW92ZSB0byBSZWFjdEZpYmVyQ29uY3VycmVudFVwZGF0ZXM/XG5cblxuZnVuY3Rpb24gZW50YW5nbGVUcmFuc2l0aW9uVXBkYXRlKHJvb3QsIHF1ZXVlLCBsYW5lKSB7XG4gIGlmIChpc1RyYW5zaXRpb25MYW5lKGxhbmUpKSB7XG4gICAgdmFyIHF1ZXVlTGFuZXMgPSBxdWV1ZS5sYW5lczsgLy8gSWYgYW55IGVudGFuZ2xlZCBsYW5lcyBhcmUgbm8gbG9uZ2VyIHBlbmRpbmcgb24gdGhlIHJvb3QsIHRoZW4gdGhleVxuICAgIC8vIG11c3QgaGF2ZSBmaW5pc2hlZC4gV2UgY2FuIHJlbW92ZSB0aGVtIGZyb20gdGhlIHNoYXJlZCBxdWV1ZSwgd2hpY2hcbiAgICAvLyByZXByZXNlbnRzIGEgc3VwZXJzZXQgb2YgdGhlIGFjdHVhbGx5IHBlbmRpbmcgbGFuZXMuIEluIHNvbWUgY2FzZXMgd2VcbiAgICAvLyBtYXkgZW50YW5nbGUgbW9yZSB0aGFuIHdlIG5lZWQgdG8sIGJ1dCB0aGF0J3MgT0suIEluIGZhY3QgaXQncyB3b3JzZSBpZlxuICAgIC8vIHdlICpkb24ndCogZW50YW5nbGUgd2hlbiB3ZSBzaG91bGQuXG5cbiAgICBxdWV1ZUxhbmVzID0gaW50ZXJzZWN0TGFuZXMocXVldWVMYW5lcywgcm9vdC5wZW5kaW5nTGFuZXMpOyAvLyBFbnRhbmdsZSB0aGUgbmV3IHRyYW5zaXRpb24gbGFuZSB3aXRoIHRoZSBvdGhlciB0cmFuc2l0aW9uIGxhbmVzLlxuXG4gICAgdmFyIG5ld1F1ZXVlTGFuZXMgPSBtZXJnZUxhbmVzKHF1ZXVlTGFuZXMsIGxhbmUpO1xuICAgIHF1ZXVlLmxhbmVzID0gbmV3UXVldWVMYW5lczsgLy8gRXZlbiBpZiBxdWV1ZS5sYW5lcyBhbHJlYWR5IGluY2x1ZGUgbGFuZSwgd2UgZG9uJ3Qga25vdyBmb3IgY2VydGFpbiBpZlxuICAgIC8vIHRoZSBsYW5lIGZpbmlzaGVkIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2UgZW50YW5nbGVkIGl0LiBTbyB3ZSBuZWVkIHRvXG4gICAgLy8gZW50YW5nbGUgaXQgYWdhaW4sIGp1c3QgdG8gYmUgc3VyZS5cblxuICAgIG1hcmtSb290RW50YW5nbGVkKHJvb3QsIG5ld1F1ZXVlTGFuZXMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hcmtVcGRhdGVJbkRldlRvb2xzKGZpYmVyLCBsYW5lLCBhY3Rpb24pIHtcblxuICB7XG4gICAgbWFya1N0YXRlVXBkYXRlU2NoZWR1bGVkKGZpYmVyLCBsYW5lKTtcbiAgfVxufVxuXG52YXIgQ29udGV4dE9ubHlEaXNwYXRjaGVyID0ge1xuICByZWFkQ29udGV4dDogcmVhZENvbnRleHQsXG4gIHVzZUNhbGxiYWNrOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUNvbnRleHQ6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlRWZmZWN0OiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUltcGVyYXRpdmVIYW5kbGU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlSW5zZXJ0aW9uRWZmZWN0OiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZUxheW91dEVmZmVjdDogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VNZW1vOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZVJlZHVjZXI6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlUmVmOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZVN0YXRlOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZURlYnVnVmFsdWU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlRGVmZXJyZWRWYWx1ZTogdGhyb3dJbnZhbGlkSG9va0Vycm9yLFxuICB1c2VUcmFuc2l0aW9uOiB0aHJvd0ludmFsaWRIb29rRXJyb3IsXG4gIHVzZU11dGFibGVTb3VyY2U6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlU3luY0V4dGVybmFsU3RvcmU6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdXNlSWQ6IHRocm93SW52YWxpZEhvb2tFcnJvcixcbiAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG59O1xuXG52YXIgSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWID0gbnVsbDtcbnZhciBIb29rc0Rpc3BhdGNoZXJPbk1vdW50V2l0aEhvb2tUeXBlc0luREVWID0gbnVsbDtcbnZhciBIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWID0gbnVsbDtcbnZhciBIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVYgPSBudWxsO1xudmFyIEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVYgPSBudWxsO1xudmFyIEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWID0gbnVsbDtcbnZhciBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWID0gbnVsbDtcblxue1xuICB2YXIgd2FybkludmFsaWRDb250ZXh0QWNjZXNzID0gZnVuY3Rpb24gKCkge1xuICAgIGVycm9yKCdDb250ZXh0IGNhbiBvbmx5IGJlIHJlYWQgd2hpbGUgUmVhY3QgaXMgcmVuZGVyaW5nLiAnICsgJ0luIGNsYXNzZXMsIHlvdSBjYW4gcmVhZCBpdCBpbiB0aGUgcmVuZGVyIG1ldGhvZCBvciBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMuICcgKyAnSW4gZnVuY3Rpb24gY29tcG9uZW50cywgeW91IGNhbiByZWFkIGl0IGRpcmVjdGx5IGluIHRoZSBmdW5jdGlvbiBib2R5LCBidXQgbm90ICcgKyAnaW5zaWRlIEhvb2tzIGxpa2UgdXNlUmVkdWNlcigpIG9yIHVzZU1lbW8oKS4nKTtcbiAgfTtcblxuICB2YXIgd2FybkludmFsaWRIb29rQWNjZXNzID0gZnVuY3Rpb24gKCkge1xuICAgIGVycm9yKCdEbyBub3QgY2FsbCBIb29rcyBpbnNpZGUgdXNlRWZmZWN0KC4uLiksIHVzZU1lbW8oLi4uKSwgb3Igb3RoZXIgYnVpbHQtaW4gSG9va3MuICcgKyAnWW91IGNhbiBvbmx5IGNhbGwgSG9va3MgYXQgdGhlIHRvcCBsZXZlbCBvZiB5b3VyIFJlYWN0IGZ1bmN0aW9uLiAnICsgJ0ZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvcnVsZXMtb2YtaG9va3MnKTtcbiAgfTtcblxuICBIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICByZXR1cm4gbW91bnRDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgcmV0dXJuIG1vdW50RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIGNoZWNrRGVwc0FyZUFycmF5RGV2KGRlcHMpO1xuICAgICAgcmV0dXJuIG1vdW50SW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICByZXR1cm4gbW91bnRJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICBjaGVja0RlcHNBcmVBcnJheURldihkZXBzKTtcbiAgICAgIHJldHVybiBtb3VudExheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgY2hlY2tEZXBzQXJlQXJyYXlEZXYoZGVwcyk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50TWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50UmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWY6IGZ1bmN0aW9uIChpbml0aWFsVmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZic7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50UmVmKGluaXRpYWxWYWx1ZSk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudERlYnVnVmFsdWUoKTtcbiAgICB9LFxuICAgIHVzZURlZmVycmVkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVmZXJyZWRWYWx1ZSc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRNdXRhYmxlU291cmNlKCk7XG4gICAgfSxcbiAgICB1c2VTeW5jRXh0ZXJuYWxTdG9yZTogZnVuY3Rpb24gKHN1YnNjcmliZSwgZ2V0U25hcHNob3QsIGdldFNlcnZlclNuYXBzaG90KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTeW5jRXh0ZXJuYWxTdG9yZSc7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50U3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSG9va3NEaXNwYXRjaGVyT25Nb3VudFdpdGhIb29rVHlwZXNJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNhbGxiYWNrJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50Q2FsbGJhY2soY2FsbGJhY2ssIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNvbnRleHQnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW1wZXJhdGl2ZUhhbmRsZTogZnVuY3Rpb24gKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbXBlcmF0aXZlSGFuZGxlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50SW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTGF5b3V0RWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VMYXlvdXRFZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZU1lbW86IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU1lbW8nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uTW91bnRJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG1vdW50TWVtbyhjcmVhdGUsIGRlcHMpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZHVjZXI6IGZ1bmN0aW9uIChyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWR1Y2VyJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRSZWYoaW5pdGlhbFZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVN0YXRlOiBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTdGF0ZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWZlcnJlZFZhbHVlKHZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVRyYW5zaXRpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVRyYW5zaXRpb24nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCk7XG4gICAgfSxcbiAgICB1c2VJZDogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSWQnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUNhbGxiYWNrOiBmdW5jdGlvbiAoY2FsbGJhY2ssIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUNhbGxiYWNrJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUNhbGxiYWNrKGNhbGxiYWNrLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUNvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDb250ZXh0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbXBlcmF0aXZlSGFuZGxlOiBmdW5jdGlvbiAocmVmLCBjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUltcGVyYXRpdmVIYW5kbGUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VJbnNlcnRpb25FZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUxheW91dEVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTWVtbzogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTWVtbyc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZU1lbW8oY3JlYXRlLCBkZXBzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWR1Y2VyOiBmdW5jdGlvbiAocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVkdWNlcic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlUmVmKCk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVTdGF0ZShpbml0aWFsU3RhdGUpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZURlYnVnVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSwgZm9ybWF0dGVyRm4pIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlYnVnVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlZmVycmVkVmFsdWUodmFsdWUpO1xuICAgIH0sXG4gICAgdXNlVHJhbnNpdGlvbjogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlVHJhbnNpdGlvbic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUlkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcblxuICBIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVYgPSB7XG4gICAgcmVhZENvbnRleHQ6IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiByZWFkQ29udGV4dChjb250ZXh0KTtcbiAgICB9LFxuICAgIHVzZUVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRWZmZWN0JztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW1wZXJhdGl2ZUhhbmRsZTogZnVuY3Rpb24gKHJlZiwgY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbXBlcmF0aXZlSGFuZGxlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlSW5zZXJ0aW9uRWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VMYXlvdXRFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUxheW91dEVmZmVjdCc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVMYXlvdXRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZU1lbW86IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU1lbW8nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZU1lbW8oY3JlYXRlLCBkZXBzKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWR1Y2VyOiBmdW5jdGlvbiAocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVkdWNlcic7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25SZXJlbmRlckluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gcmVyZW5kZXJSZWR1Y2VyKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBwcmV2RGlzcGF0Y2hlcjtcbiAgICAgIH1cbiAgICB9LFxuICAgIHVzZVJlZjogZnVuY3Rpb24gKGluaXRpYWxWYWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlUmVmJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVJlZigpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblJlcmVuZGVySW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiByZXJlbmRlclN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVEZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVyZW5kZXJEZWZlcnJlZFZhbHVlKHZhbHVlKTtcbiAgICB9LFxuICAgIHVzZVRyYW5zaXRpb246IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVRyYW5zaXRpb24nO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVyZW5kZXJUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVN5bmNFeHRlcm5hbFN0b3JlKHN1YnNjcmliZSwgZ2V0U25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUlkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcblxuICBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWID0ge1xuICAgIHJlYWRDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgd2FybkludmFsaWRDb250ZXh0QWNjZXNzKCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VDYWxsYmFjazogZnVuY3Rpb24gKGNhbGxiYWNrLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VDYWxsYmFjayc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVhZENvbnRleHQoY29udGV4dCk7XG4gICAgfSxcbiAgICB1c2VFZmZlY3Q6IGZ1bmN0aW9uIChjcmVhdGUsIGRlcHMpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUVmZmVjdCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnRJbXBlcmF0aXZlSGFuZGxlKHJlZiwgY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUluc2VydGlvbkVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW5zZXJ0aW9uRWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudEluc2VydGlvbkVmZmVjdChjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlTGF5b3V0RWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VMYXlvdXRFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25Nb3VudEluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbW91bnRNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50UmVmKGluaXRpYWxWYWx1ZSk7XG4gICAgfSxcbiAgICB1c2VTdGF0ZTogZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3RhdGUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPbk1vdW50SW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBtb3VudFN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIG1vdW50SG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gbW91bnREZWJ1Z1ZhbHVlKCk7XG4gICAgfSxcbiAgICB1c2VEZWZlcnJlZFZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZURlZmVycmVkVmFsdWUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50RGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudFRyYW5zaXRpb24oKTtcbiAgICB9LFxuICAgIHVzZU11dGFibGVTb3VyY2U6IGZ1bmN0aW9uIChzb3VyY2UsIGdldFNuYXBzaG90LCBzdWJzY3JpYmUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZU11dGFibGVTb3VyY2UnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50TXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICBtb3VudEhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIG1vdW50U3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpO1xuICAgIH0sXG4gICAgdXNlSWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZUlkJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgbW91bnRIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiBtb3VudElkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcblxuICBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHdhcm5JbnZhbGlkQ29udGV4dEFjY2VzcygpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVJlZHVjZXIocmVkdWNlciwgaW5pdGlhbEFyZywgaW5pdCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVmOiBmdW5jdGlvbiAoaW5pdGlhbFZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VSZWYnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVSZWYoKTtcbiAgICB9LFxuICAgIHVzZVN0YXRlOiBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VTdGF0ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgdmFyIHByZXZEaXNwYXRjaGVyID0gUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQ7XG4gICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IEludmFsaWROZXN0ZWRIb29rc0Rpc3BhdGNoZXJPblVwZGF0ZUluREVWO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gdXBkYXRlU3RhdGUoaW5pdGlhbFN0YXRlKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VEZWJ1Z1ZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIGZvcm1hdHRlckZuKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWJ1Z1ZhbHVlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVidWdWYWx1ZSgpO1xuICAgIH0sXG4gICAgdXNlRGVmZXJyZWRWYWx1ZTogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VEZWZlcnJlZFZhbHVlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlRGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlVHJhbnNpdGlvbigpO1xuICAgIH0sXG4gICAgdXNlTXV0YWJsZVNvdXJjZTogZnVuY3Rpb24gKHNvdXJjZSwgZ2V0U25hcHNob3QsIHN1YnNjcmliZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTXV0YWJsZVNvdXJjZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZU11dGFibGVTb3VyY2UoKTtcbiAgICB9LFxuICAgIHVzZVN5bmNFeHRlcm5hbFN0b3JlOiBmdW5jdGlvbiAoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCwgZ2V0U2VydmVyU25hcHNob3QpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN5bmNFeHRlcm5hbFN0b3JlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlU3luY0V4dGVybmFsU3RvcmUoc3Vic2NyaWJlLCBnZXRTbmFwc2hvdCk7XG4gICAgfSxcbiAgICB1c2VJZDogZnVuY3Rpb24gKCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSWQnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJZCgpO1xuICAgIH0sXG4gICAgdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiBlbmFibGVOZXdSZWNvbmNpbGVyXG4gIH07XG5cbiAgSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uUmVyZW5kZXJJbkRFViA9IHtcbiAgICByZWFkQ29udGV4dDogZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICAgIHdhcm5JbnZhbGlkQ29udGV4dEFjY2VzcygpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlQ2FsbGJhY2s6IGZ1bmN0aW9uIChjYWxsYmFjaywgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ2FsbGJhY2snO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVDYWxsYmFjayhjYWxsYmFjaywgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VDb250ZXh0OiBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlQ29udGV4dCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlYWRDb250ZXh0KGNvbnRleHQpO1xuICAgIH0sXG4gICAgdXNlRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VFZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVFZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUltcGVyYXRpdmVIYW5kbGU6IGZ1bmN0aW9uIChyZWYsIGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlSW1wZXJhdGl2ZUhhbmRsZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUltcGVyYXRpdmVIYW5kbGUocmVmLCBjcmVhdGUsIGRlcHMpO1xuICAgIH0sXG4gICAgdXNlSW5zZXJ0aW9uRWZmZWN0OiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJbnNlcnRpb25FZmZlY3QnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVJbnNlcnRpb25FZmZlY3QoY3JlYXRlLCBkZXBzKTtcbiAgICB9LFxuICAgIHVzZUxheW91dEVmZmVjdDogZnVuY3Rpb24gKGNyZWF0ZSwgZGVwcykge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTGF5b3V0RWZmZWN0KGNyZWF0ZSwgZGVwcyk7XG4gICAgfSxcbiAgICB1c2VNZW1vOiBmdW5jdGlvbiAoY3JlYXRlLCBkZXBzKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNZW1vJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB1cGRhdGVNZW1vKGNyZWF0ZSwgZGVwcyk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlUmVkdWNlcjogZnVuY3Rpb24gKHJlZHVjZXIsIGluaXRpYWxBcmcsIGluaXQpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZHVjZXInO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHZhciBwcmV2RGlzcGF0Y2hlciA9IFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50O1xuICAgICAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQxLmN1cnJlbnQgPSBJbnZhbGlkTmVzdGVkSG9va3NEaXNwYXRjaGVyT25VcGRhdGVJbkRFVjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHJlcmVuZGVyUmVkdWNlcihyZWR1Y2VyLCBpbml0aWFsQXJnLCBpbml0KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICB1c2VSZWY6IGZ1bmN0aW9uIChpbml0aWFsVmFsdWUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVJlZic7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZVJlZigpO1xuICAgIH0sXG4gICAgdXNlU3RhdGU6IGZ1bmN0aW9uIChpbml0aWFsU3RhdGUpIHtcbiAgICAgIGN1cnJlbnRIb29rTmFtZUluRGV2ID0gJ3VzZVN0YXRlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudDtcbiAgICAgIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMS5jdXJyZW50ID0gSW52YWxpZE5lc3RlZEhvb2tzRGlzcGF0Y2hlck9uVXBkYXRlSW5ERVY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiByZXJlbmRlclN0YXRlKGluaXRpYWxTdGF0ZSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDEuY3VycmVudCA9IHByZXZEaXNwYXRjaGVyO1xuICAgICAgfVxuICAgIH0sXG4gICAgdXNlRGVidWdWYWx1ZTogZnVuY3Rpb24gKHZhbHVlLCBmb3JtYXR0ZXJGbikge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVidWdWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZURlYnVnVmFsdWUoKTtcbiAgICB9LFxuICAgIHVzZURlZmVycmVkVmFsdWU6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlRGVmZXJyZWRWYWx1ZSc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHJlcmVuZGVyRGVmZXJyZWRWYWx1ZSh2YWx1ZSk7XG4gICAgfSxcbiAgICB1c2VUcmFuc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VUcmFuc2l0aW9uJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gcmVyZW5kZXJUcmFuc2l0aW9uKCk7XG4gICAgfSxcbiAgICB1c2VNdXRhYmxlU291cmNlOiBmdW5jdGlvbiAoc291cmNlLCBnZXRTbmFwc2hvdCwgc3Vic2NyaWJlKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VNdXRhYmxlU291cmNlJztcbiAgICAgIHdhcm5JbnZhbGlkSG9va0FjY2VzcygpO1xuICAgICAgdXBkYXRlSG9va1R5cGVzRGV2KCk7XG4gICAgICByZXR1cm4gdXBkYXRlTXV0YWJsZVNvdXJjZSgpO1xuICAgIH0sXG4gICAgdXNlU3luY0V4dGVybmFsU3RvcmU6IGZ1bmN0aW9uIChzdWJzY3JpYmUsIGdldFNuYXBzaG90LCBnZXRTZXJ2ZXJTbmFwc2hvdCkge1xuICAgICAgY3VycmVudEhvb2tOYW1lSW5EZXYgPSAndXNlU3luY0V4dGVybmFsU3RvcmUnO1xuICAgICAgd2FybkludmFsaWRIb29rQWNjZXNzKCk7XG4gICAgICB1cGRhdGVIb29rVHlwZXNEZXYoKTtcbiAgICAgIHJldHVybiB1cGRhdGVTeW5jRXh0ZXJuYWxTdG9yZShzdWJzY3JpYmUsIGdldFNuYXBzaG90KTtcbiAgICB9LFxuICAgIHVzZUlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICBjdXJyZW50SG9va05hbWVJbkRldiA9ICd1c2VJZCc7XG4gICAgICB3YXJuSW52YWxpZEhvb2tBY2Nlc3MoKTtcbiAgICAgIHVwZGF0ZUhvb2tUeXBlc0RldigpO1xuICAgICAgcmV0dXJuIHVwZGF0ZUlkKCk7XG4gICAgfSxcbiAgICB1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6IGVuYWJsZU5ld1JlY29uY2lsZXJcbiAgfTtcbn1cblxudmFyIG5vdyQxID0gU2NoZWR1bGVyLnVuc3RhYmxlX25vdztcbnZhciBjb21taXRUaW1lID0gMDtcbnZhciBsYXlvdXRFZmZlY3RTdGFydFRpbWUgPSAtMTtcbnZhciBwcm9maWxlclN0YXJ0VGltZSA9IC0xO1xudmFyIHBhc3NpdmVFZmZlY3RTdGFydFRpbWUgPSAtMTtcbi8qKlxuICogVHJhY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgdXBkYXRlIHdhcyBhIG5lc3RlZC9jYXNjYWRpbmcgdXBkYXRlIChzY2hlZHVsZWQgZnJvbSBhIGxheW91dCBlZmZlY3QpLlxuICpcbiAqIFRoZSBvdmVyYWxsIHNlcXVlbmNlIGlzOlxuICogICAxLiByZW5kZXJcbiAqICAgMi4gY29tbWl0IChhbmQgY2FsbCBgb25SZW5kZXJgLCBgb25Db21taXRgKVxuICogICAzLiBjaGVjayBmb3IgbmVzdGVkIHVwZGF0ZXNcbiAqICAgNC4gZmx1c2ggcGFzc2l2ZSBlZmZlY3RzIChhbmQgY2FsbCBgb25Qb3N0Q29tbWl0YClcbiAqXG4gKiBOZXN0ZWQgdXBkYXRlcyBhcmUgaWRlbnRpZmllZCBpbiBzdGVwIDMgYWJvdmUsXG4gKiBidXQgc3RlcCA0IHN0aWxsIGFwcGxpZXMgdG8gdGhlIHdvcmsgdGhhdCB3YXMganVzdCBjb21taXR0ZWQuXG4gKiBXZSB1c2UgdHdvIGZsYWdzIHRvIHRyYWNrIG5lc3RlZCB1cGRhdGVzIHRoZW46XG4gKiBvbmUgdHJhY2tzIHdoZXRoZXIgdGhlIHVwY29taW5nIHVwZGF0ZSBpcyBhIG5lc3RlZCB1cGRhdGUsXG4gKiBhbmQgdGhlIG90aGVyIHRyYWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IHVwZGF0ZSB3YXMgYSBuZXN0ZWQgdXBkYXRlLlxuICogVGhlIGZpcnN0IHZhbHVlIGdldHMgc3luY2VkIHRvIHRoZSBzZWNvbmQgYXQgdGhlIHN0YXJ0IG9mIHRoZSByZW5kZXIgcGhhc2UuXG4gKi9cblxudmFyIGN1cnJlbnRVcGRhdGVJc05lc3RlZCA9IGZhbHNlO1xudmFyIG5lc3RlZFVwZGF0ZVNjaGVkdWxlZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBpc0N1cnJlbnRVcGRhdGVOZXN0ZWQoKSB7XG4gIHJldHVybiBjdXJyZW50VXBkYXRlSXNOZXN0ZWQ7XG59XG5cbmZ1bmN0aW9uIG1hcmtOZXN0ZWRVcGRhdGVTY2hlZHVsZWQoKSB7XG4gIHtcbiAgICBuZXN0ZWRVcGRhdGVTY2hlZHVsZWQgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc2V0TmVzdGVkVXBkYXRlRmxhZygpIHtcbiAge1xuICAgIGN1cnJlbnRVcGRhdGVJc05lc3RlZCA9IGZhbHNlO1xuICAgIG5lc3RlZFVwZGF0ZVNjaGVkdWxlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN5bmNOZXN0ZWRVcGRhdGVGbGFnKCkge1xuICB7XG4gICAgY3VycmVudFVwZGF0ZUlzTmVzdGVkID0gbmVzdGVkVXBkYXRlU2NoZWR1bGVkO1xuICAgIG5lc3RlZFVwZGF0ZVNjaGVkdWxlZCA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldENvbW1pdFRpbWUoKSB7XG4gIHJldHVybiBjb21taXRUaW1lO1xufVxuXG5mdW5jdGlvbiByZWNvcmRDb21taXRUaW1lKCkge1xuXG4gIGNvbW1pdFRpbWUgPSBub3ckMSgpO1xufVxuXG5mdW5jdGlvbiBzdGFydFByb2ZpbGVyVGltZXIoZmliZXIpIHtcblxuICBwcm9maWxlclN0YXJ0VGltZSA9IG5vdyQxKCk7XG5cbiAgaWYgKGZpYmVyLmFjdHVhbFN0YXJ0VGltZSA8IDApIHtcbiAgICBmaWJlci5hY3R1YWxTdGFydFRpbWUgPSBub3ckMSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nKGZpYmVyKSB7XG5cbiAgcHJvZmlsZXJTdGFydFRpbWUgPSAtMTtcbn1cblxuZnVuY3Rpb24gc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YShmaWJlciwgb3ZlcnJpZGVCYXNlVGltZSkge1xuXG4gIGlmIChwcm9maWxlclN0YXJ0VGltZSA+PSAwKSB7XG4gICAgdmFyIGVsYXBzZWRUaW1lID0gbm93JDEoKSAtIHByb2ZpbGVyU3RhcnRUaW1lO1xuICAgIGZpYmVyLmFjdHVhbER1cmF0aW9uICs9IGVsYXBzZWRUaW1lO1xuXG4gICAgaWYgKG92ZXJyaWRlQmFzZVRpbWUpIHtcbiAgICAgIGZpYmVyLnNlbGZCYXNlRHVyYXRpb24gPSBlbGFwc2VkVGltZTtcbiAgICB9XG5cbiAgICBwcm9maWxlclN0YXJ0VGltZSA9IC0xO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpYmVyKSB7XG5cbiAgaWYgKGxheW91dEVmZmVjdFN0YXJ0VGltZSA+PSAwKSB7XG4gICAgdmFyIGVsYXBzZWRUaW1lID0gbm93JDEoKSAtIGxheW91dEVmZmVjdFN0YXJ0VGltZTtcbiAgICBsYXlvdXRFZmZlY3RTdGFydFRpbWUgPSAtMTsgLy8gU3RvcmUgZHVyYXRpb24gb24gdGhlIG5leHQgbmVhcmVzdCBQcm9maWxlciBhbmNlc3RvclxuICAgIC8vIE9yIHRoZSByb290IChmb3IgdGhlIERldlRvb2xzIFByb2ZpbGVyIHRvIHJlYWQpXG5cbiAgICB2YXIgcGFyZW50RmliZXIgPSBmaWJlci5yZXR1cm47XG5cbiAgICB3aGlsZSAocGFyZW50RmliZXIgIT09IG51bGwpIHtcbiAgICAgIHN3aXRjaCAocGFyZW50RmliZXIudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgdmFyIHJvb3QgPSBwYXJlbnRGaWJlci5zdGF0ZU5vZGU7XG4gICAgICAgICAgcm9vdC5lZmZlY3REdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICB2YXIgcGFyZW50U3RhdGVOb2RlID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuICAgICAgICAgIHBhcmVudFN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHBhcmVudEZpYmVyID0gcGFyZW50RmliZXIucmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWNvcmRQYXNzaXZlRWZmZWN0RHVyYXRpb24oZmliZXIpIHtcblxuICBpZiAocGFzc2l2ZUVmZmVjdFN0YXJ0VGltZSA+PSAwKSB7XG4gICAgdmFyIGVsYXBzZWRUaW1lID0gbm93JDEoKSAtIHBhc3NpdmVFZmZlY3RTdGFydFRpbWU7XG4gICAgcGFzc2l2ZUVmZmVjdFN0YXJ0VGltZSA9IC0xOyAvLyBTdG9yZSBkdXJhdGlvbiBvbiB0aGUgbmV4dCBuZWFyZXN0IFByb2ZpbGVyIGFuY2VzdG9yXG4gICAgLy8gT3IgdGhlIHJvb3QgKGZvciB0aGUgRGV2VG9vbHMgUHJvZmlsZXIgdG8gcmVhZClcblxuICAgIHZhciBwYXJlbnRGaWJlciA9IGZpYmVyLnJldHVybjtcblxuICAgIHdoaWxlIChwYXJlbnRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChwYXJlbnRGaWJlci50YWcpIHtcbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB2YXIgcm9vdCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByb290LnBhc3NpdmVFZmZlY3REdXJhdGlvbiArPSBlbGFwc2VkVGltZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICB2YXIgcGFyZW50U3RhdGVOb2RlID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgaWYgKHBhcmVudFN0YXRlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gRGV0YWNoZWQgZmliZXJzIGhhdmUgdGhlaXIgc3RhdGUgbm9kZSBjbGVhcmVkIG91dC5cbiAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgdGhlIHJldHVybiBwb2ludGVyIGlzIGFsc28gY2xlYXJlZCBvdXQsXG4gICAgICAgICAgICAvLyBzbyB3ZSB3b24ndCBiZSBhYmxlIHRvIHJlcG9ydCB0aGUgdGltZSBzcGVudCBpbiB0aGlzIFByb2ZpbGVyJ3Mgc3VidHJlZS5cbiAgICAgICAgICAgIHBhcmVudFN0YXRlTm9kZS5wYXNzaXZlRWZmZWN0RHVyYXRpb24gKz0gZWxhcHNlZFRpbWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBwYXJlbnRGaWJlciA9IHBhcmVudEZpYmVyLnJldHVybjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpIHtcblxuICBsYXlvdXRFZmZlY3RTdGFydFRpbWUgPSBub3ckMSgpO1xufVxuXG5mdW5jdGlvbiBzdGFydFBhc3NpdmVFZmZlY3RUaW1lcigpIHtcblxuICBwYXNzaXZlRWZmZWN0U3RhcnRUaW1lID0gbm93JDEoKTtcbn1cblxuZnVuY3Rpb24gdHJhbnNmZXJBY3R1YWxEdXJhdGlvbihmaWJlcikge1xuICAvLyBUcmFuc2ZlciB0aW1lIHNwZW50IHJlbmRlcmluZyB0aGVzZSBjaGlsZHJlbiBzbyB3ZSBkb24ndCBsb3NlIGl0XG4gIC8vIGFmdGVyIHdlIHJlcmVuZGVyLiBUaGlzIGlzIHVzZWQgYXMgYSBoZWxwZXIgaW4gc3BlY2lhbCBjYXNlc1xuICAvLyB3aGVyZSB3ZSBzaG91bGQgY291bnQgdGhlIHdvcmsgb2YgbXVsdGlwbGUgcGFzc2VzLlxuICB2YXIgY2hpbGQgPSBmaWJlci5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQpIHtcbiAgICBmaWJlci5hY3R1YWxEdXJhdGlvbiArPSBjaGlsZC5hY3R1YWxEdXJhdGlvbjtcbiAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2FwdHVyZWRWYWx1ZUF0RmliZXIodmFsdWUsIHNvdXJjZSkge1xuICAvLyBJZiB0aGUgdmFsdWUgaXMgYW4gZXJyb3IsIGNhbGwgdGhpcyBmdW5jdGlvbiBpbW1lZGlhdGVseSBhZnRlciBpdCBpcyB0aHJvd25cbiAgLy8gc28gdGhlIHN0YWNrIGlzIGFjY3VyYXRlLlxuICByZXR1cm4ge1xuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICBzdGFjazogZ2V0U3RhY2tCeUZpYmVySW5EZXZBbmRQcm9kKHNvdXJjZSksXG4gICAgZGlnZXN0OiBudWxsXG4gIH07XG59XG5mdW5jdGlvbiBjcmVhdGVDYXB0dXJlZFZhbHVlKHZhbHVlLCBkaWdlc3QsIHN0YWNrKSB7XG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHZhbHVlLFxuICAgIHNvdXJjZTogbnVsbCxcbiAgICBzdGFjazogc3RhY2sgIT0gbnVsbCA/IHN0YWNrIDogbnVsbCxcbiAgICBkaWdlc3Q6IGRpZ2VzdCAhPSBudWxsID8gZGlnZXN0IDogbnVsbFxuICB9O1xufVxuXG4vLyBUaGlzIG1vZHVsZSBpcyBmb3JrZWQgaW4gZGlmZmVyZW50IGVudmlyb25tZW50cy5cbi8vIEJ5IGRlZmF1bHQsIHJldHVybiBgdHJ1ZWAgdG8gbG9nIGVycm9ycyB0byB0aGUgY29uc29sZS5cbi8vIEZvcmtzIGNhbiByZXR1cm4gYGZhbHNlYCBpZiB0aGlzIGlzbid0IGRlc2lyYWJsZS5cbmZ1bmN0aW9uIHNob3dFcnJvckRpYWxvZyhib3VuZGFyeSwgZXJyb3JJbmZvKSB7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBsb2dDYXB0dXJlZEVycm9yKGJvdW5kYXJ5LCBlcnJvckluZm8pIHtcbiAgdHJ5IHtcbiAgICB2YXIgbG9nRXJyb3IgPSBzaG93RXJyb3JEaWFsb2coYm91bmRhcnksIGVycm9ySW5mbyk7IC8vIEFsbG93IGluamVjdGVkIHNob3dFcnJvckRpYWxvZygpIHRvIHByZXZlbnQgZGVmYXVsdCBjb25zb2xlLmVycm9yIGxvZ2dpbmcuXG4gICAgLy8gVGhpcyBlbmFibGVzIHJlbmRlcmVycyBsaWtlIFJlYWN0TmF0aXZlIHRvIGJldHRlciBtYW5hZ2UgcmVkYm94IGJlaGF2aW9yLlxuXG4gICAgaWYgKGxvZ0Vycm9yID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlcnJvciA9IGVycm9ySW5mby52YWx1ZTtcblxuICAgIGlmICh0cnVlKSB7XG4gICAgICB2YXIgc291cmNlID0gZXJyb3JJbmZvLnNvdXJjZTtcbiAgICAgIHZhciBzdGFjayA9IGVycm9ySW5mby5zdGFjaztcbiAgICAgIHZhciBjb21wb25lbnRTdGFjayA9IHN0YWNrICE9PSBudWxsID8gc3RhY2sgOiAnJzsgLy8gQnJvd3NlcnMgc3VwcG9ydCBzaWxlbmNpbmcgdW5jYXVnaHQgZXJyb3JzIGJ5IGNhbGxpbmdcbiAgICAgIC8vIGBwcmV2ZW50RGVmYXVsdCgpYCBpbiB3aW5kb3cgYGVycm9yYCBoYW5kbGVyLlxuICAgICAgLy8gV2UgcmVjb3JkIHRoaXMgaW5mb3JtYXRpb24gYXMgYW4gZXhwYW5kbyBvbiB0aGUgZXJyb3IuXG5cbiAgICAgIGlmIChlcnJvciAhPSBudWxsICYmIGVycm9yLl9zdXBwcmVzc0xvZ2dpbmcpIHtcbiAgICAgICAgaWYgKGJvdW5kYXJ5LnRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgICAgICAvLyBUaGUgZXJyb3IgaXMgcmVjb3ZlcmFibGUgYW5kIHdhcyBzaWxlbmNlZC5cbiAgICAgICAgICAvLyBJZ25vcmUgaXQgYW5kIGRvbid0IHByaW50IHRoZSBzdGFjayBhZGRlbmR1bS5cbiAgICAgICAgICAvLyBUaGlzIGlzIGhhbmR5IGZvciB0ZXN0aW5nIGVycm9yIGJvdW5kYXJpZXMgd2l0aG91dCBub2lzZS5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gLy8gVGhlIGVycm9yIGlzIGZhdGFsLiBTaW5jZSB0aGUgc2lsZW5jaW5nIG1pZ2h0IGhhdmVcbiAgICAgICAgLy8gYmVlbiBhY2NpZGVudGFsLCB3ZSdsbCBzdXJmYWNlIGl0IGFueXdheS5cbiAgICAgICAgLy8gSG93ZXZlciwgdGhlIGJyb3dzZXIgd291bGQgaGF2ZSBzaWxlbmNlZCB0aGUgb3JpZ2luYWwgZXJyb3JcbiAgICAgICAgLy8gc28gd2UnbGwgcHJpbnQgaXQgZmlyc3QsIGFuZCB0aGVuIHByaW50IHRoZSBzdGFjayBhZGRlbmR1bS5cblxuXG4gICAgICAgIGNvbnNvbGVbJ2Vycm9yJ10oZXJyb3IpOyAvLyBEb24ndCB0cmFuc2Zvcm0gdG8gb3VyIHdyYXBwZXJcbiAgICAgICAgLy8gRm9yIGEgbW9yZSBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGlzIGJsb2NrLCBzZWU6XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzEzMzg0XG4gICAgICB9XG5cbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gc291cmNlID8gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihzb3VyY2UpIDogbnVsbDtcbiAgICAgIHZhciBjb21wb25lbnROYW1lTWVzc2FnZSA9IGNvbXBvbmVudE5hbWUgPyBcIlRoZSBhYm92ZSBlcnJvciBvY2N1cnJlZCBpbiB0aGUgPFwiICsgY29tcG9uZW50TmFtZSArIFwiPiBjb21wb25lbnQ6XCIgOiAnVGhlIGFib3ZlIGVycm9yIG9jY3VycmVkIGluIG9uZSBvZiB5b3VyIFJlYWN0IGNvbXBvbmVudHM6JztcbiAgICAgIHZhciBlcnJvckJvdW5kYXJ5TWVzc2FnZTtcblxuICAgICAgaWYgKGJvdW5kYXJ5LnRhZyA9PT0gSG9zdFJvb3QpIHtcbiAgICAgICAgZXJyb3JCb3VuZGFyeU1lc3NhZ2UgPSAnQ29uc2lkZXIgYWRkaW5nIGFuIGVycm9yIGJvdW5kYXJ5IHRvIHlvdXIgdHJlZSB0byBjdXN0b21pemUgZXJyb3IgaGFuZGxpbmcgYmVoYXZpb3IuXFxuJyArICdWaXNpdCBodHRwczovL3JlYWN0anMub3JnL2xpbmsvZXJyb3ItYm91bmRhcmllcyB0byBsZWFybiBtb3JlIGFib3V0IGVycm9yIGJvdW5kYXJpZXMuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBlcnJvckJvdW5kYXJ5TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoYm91bmRhcnkpIHx8ICdBbm9ueW1vdXMnO1xuICAgICAgICBlcnJvckJvdW5kYXJ5TWVzc2FnZSA9IFwiUmVhY3Qgd2lsbCB0cnkgdG8gcmVjcmVhdGUgdGhpcyBjb21wb25lbnQgdHJlZSBmcm9tIHNjcmF0Y2ggXCIgKyAoXCJ1c2luZyB0aGUgZXJyb3IgYm91bmRhcnkgeW91IHByb3ZpZGVkLCBcIiArIGVycm9yQm91bmRhcnlOYW1lICsgXCIuXCIpO1xuICAgICAgfVxuXG4gICAgICB2YXIgY29tYmluZWRNZXNzYWdlID0gY29tcG9uZW50TmFtZU1lc3NhZ2UgKyBcIlxcblwiICsgY29tcG9uZW50U3RhY2sgKyBcIlxcblxcblwiICsgKFwiXCIgKyBlcnJvckJvdW5kYXJ5TWVzc2FnZSk7IC8vIEluIGRldmVsb3BtZW50LCB3ZSBwcm92aWRlIG91ciBvd24gbWVzc2FnZSB3aXRoIGp1c3QgdGhlIGNvbXBvbmVudCBzdGFjay5cbiAgICAgIC8vIFdlIGRvbid0IGluY2x1ZGUgdGhlIG9yaWdpbmFsIGVycm9yIG1lc3NhZ2UgYW5kIEpTIHN0YWNrIGJlY2F1c2UgdGhlIGJyb3dzZXJcbiAgICAgIC8vIGhhcyBhbHJlYWR5IHByaW50ZWQgaXQuIEV2ZW4gaWYgdGhlIGFwcGxpY2F0aW9uIHN3YWxsb3dzIHRoZSBlcnJvciwgaXQgaXMgc3RpbGxcbiAgICAgIC8vIGRpc3BsYXllZCBieSB0aGUgYnJvd3NlciB0aGFua3MgdG8gdGhlIERFVi1vbmx5IGZha2UgZXZlbnQgdHJpY2sgaW4gUmVhY3RFcnJvclV0aWxzLlxuXG4gICAgICBjb25zb2xlWydlcnJvciddKGNvbWJpbmVkTWVzc2FnZSk7IC8vIERvbid0IHRyYW5zZm9ybSB0byBvdXIgd3JhcHBlclxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJbiBwcm9kdWN0aW9uLCB3ZSBwcmludCB0aGUgZXJyb3IgZGlyZWN0bHkuXG4gICAgICAvLyBUaGlzIHdpbGwgaW5jbHVkZSB0aGUgbWVzc2FnZSwgdGhlIEpTIHN0YWNrLCBhbmQgYW55dGhpbmcgdGhlIGJyb3dzZXIgd2FudHMgdG8gc2hvdy5cbiAgICAgIC8vIFdlIHBhc3MgdGhlIGVycm9yIG9iamVjdCBpbnN0ZWFkIG9mIGN1c3RvbSBtZXNzYWdlIHNvIHRoYXQgdGhlIGJyb3dzZXIgZGlzcGxheXMgdGhlIGVycm9yIG5hdGl2ZWx5LlxuICAgICAgY29uc29sZVsnZXJyb3InXShlcnJvcik7IC8vIERvbid0IHRyYW5zZm9ybSB0byBvdXIgd3JhcHBlclxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIFRoaXMgbWV0aG9kIG11c3Qgbm90IHRocm93LCBvciBSZWFjdCBpbnRlcm5hbCBzdGF0ZSB3aWxsIGdldCBtZXNzZWQgdXAuXG4gICAgLy8gSWYgY29uc29sZS5lcnJvciBpcyBvdmVycmlkZGVuLCBvciBsb2dDYXB0dXJlZEVycm9yKCkgc2hvd3MgYSBkaWFsb2cgdGhhdCB0aHJvd3MsXG4gICAgLy8gd2Ugd2FudCB0byByZXBvcnQgdGhpcyBlcnJvciBvdXRzaWRlIG9mIHRoZSBub3JtYWwgc3RhY2sgYXMgYSBsYXN0IHJlc29ydC5cbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzEzMTg4XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xuICB9XG59XG5cbnZhciBQb3NzaWJseVdlYWtNYXAkMSA9IHR5cGVvZiBXZWFrTWFwID09PSAnZnVuY3Rpb24nID8gV2Vha01hcCA6IE1hcDtcblxuZnVuY3Rpb24gY3JlYXRlUm9vdEVycm9yVXBkYXRlKGZpYmVyLCBlcnJvckluZm8sIGxhbmUpIHtcbiAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShOb1RpbWVzdGFtcCwgbGFuZSk7IC8vIFVubW91bnQgdGhlIHJvb3QgYnkgcmVuZGVyaW5nIG51bGwuXG5cbiAgdXBkYXRlLnRhZyA9IENhcHR1cmVVcGRhdGU7IC8vIENhdXRpb246IFJlYWN0IERldlRvb2xzIGN1cnJlbnRseSBkZXBlbmRzIG9uIHRoaXMgcHJvcGVydHlcbiAgLy8gYmVpbmcgY2FsbGVkIFwiZWxlbWVudFwiLlxuXG4gIHVwZGF0ZS5wYXlsb2FkID0ge1xuICAgIGVsZW1lbnQ6IG51bGxcbiAgfTtcbiAgdmFyIGVycm9yID0gZXJyb3JJbmZvLnZhbHVlO1xuXG4gIHVwZGF0ZS5jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICBvblVuY2F1Z2h0RXJyb3IoZXJyb3IpO1xuICAgIGxvZ0NhcHR1cmVkRXJyb3IoZmliZXIsIGVycm9ySW5mbyk7XG4gIH07XG5cbiAgcmV0dXJuIHVwZGF0ZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2xhc3NFcnJvclVwZGF0ZShmaWJlciwgZXJyb3JJbmZvLCBsYW5lKSB7XG4gIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoTm9UaW1lc3RhbXAsIGxhbmUpO1xuICB1cGRhdGUudGFnID0gQ2FwdHVyZVVwZGF0ZTtcbiAgdmFyIGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciA9IGZpYmVyLnR5cGUuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yO1xuXG4gIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIGVycm9yJDEgPSBlcnJvckluZm8udmFsdWU7XG5cbiAgICB1cGRhdGUucGF5bG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoZXJyb3IkMSk7XG4gICAgfTtcblxuICAgIHVwZGF0ZS5jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHtcbiAgICAgICAgbWFya0ZhaWxlZEVycm9yQm91bmRhcnlGb3JIb3RSZWxvYWRpbmcoZmliZXIpO1xuICAgICAgfVxuXG4gICAgICBsb2dDYXB0dXJlZEVycm9yKGZpYmVyLCBlcnJvckluZm8pO1xuICAgIH07XG4gIH1cblxuICB2YXIgaW5zdCA9IGZpYmVyLnN0YXRlTm9kZTtcblxuICBpZiAoaW5zdCAhPT0gbnVsbCAmJiB0eXBlb2YgaW5zdC5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHVwZGF0ZS5jYWxsYmFjayA9IGZ1bmN0aW9uIGNhbGxiYWNrKCkge1xuICAgICAge1xuICAgICAgICBtYXJrRmFpbGVkRXJyb3JCb3VuZGFyeUZvckhvdFJlbG9hZGluZyhmaWJlcik7XG4gICAgICB9XG5cbiAgICAgIGxvZ0NhcHR1cmVkRXJyb3IoZmliZXIsIGVycm9ySW5mbyk7XG5cbiAgICAgIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIFRvIHByZXNlcnZlIHRoZSBwcmVleGlzdGluZyByZXRyeSBiZWhhdmlvciBvZiBlcnJvciBib3VuZGFyaWVzLFxuICAgICAgICAvLyB3ZSBrZWVwIHRyYWNrIG9mIHdoaWNoIG9uZXMgYWxyZWFkeSBmYWlsZWQgZHVyaW5nIHRoaXMgYmF0Y2guXG4gICAgICAgIC8vIFRoaXMgZ2V0cyByZXNldCBiZWZvcmUgd2UgeWllbGQgYmFjayB0byB0aGUgYnJvd3Nlci5cbiAgICAgICAgLy8gVE9ETzogV2FybiBpbiBzdHJpY3QgbW9kZSBpZiBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgaXNcbiAgICAgICAgLy8gbm90IGRlZmluZWQuXG4gICAgICAgIG1hcmtMZWdhY3lFcnJvckJvdW5kYXJ5QXNGYWlsZWQodGhpcyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBlcnJvciQxID0gZXJyb3JJbmZvLnZhbHVlO1xuICAgICAgdmFyIHN0YWNrID0gZXJyb3JJbmZvLnN0YWNrO1xuICAgICAgdGhpcy5jb21wb25lbnREaWRDYXRjaChlcnJvciQxLCB7XG4gICAgICAgIGNvbXBvbmVudFN0YWNrOiBzdGFjayAhPT0gbnVsbCA/IHN0YWNrIDogJydcbiAgICAgIH0pO1xuXG4gICAgICB7XG4gICAgICAgIGlmICh0eXBlb2YgZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgLy8gSWYgY29tcG9uZW50RGlkQ2F0Y2ggaXMgdGhlIG9ubHkgZXJyb3IgYm91bmRhcnkgbWV0aG9kIGRlZmluZWQsXG4gICAgICAgICAgLy8gdGhlbiBpdCBuZWVkcyB0byBjYWxsIHNldFN0YXRlIHRvIHJlY292ZXIgZnJvbSBlcnJvcnMuXG4gICAgICAgICAgLy8gSWYgbm8gc3RhdGUgdXBkYXRlIGlzIHNjaGVkdWxlZCB0aGVuIHRoZSBib3VuZGFyeSB3aWxsIHN3YWxsb3cgdGhlIGVycm9yLlxuICAgICAgICAgIGlmICghaW5jbHVkZXNTb21lTGFuZShmaWJlci5sYW5lcywgU3luY0xhbmUpKSB7XG4gICAgICAgICAgICBlcnJvcignJXM6IEVycm9yIGJvdW5kYXJpZXMgc2hvdWxkIGltcGxlbWVudCBnZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IoKS4gJyArICdJbiB0aGF0IG1ldGhvZCwgcmV0dXJuIGEgc3RhdGUgdXBkYXRlIHRvIGRpc3BsYXkgYW4gZXJyb3IgbWVzc2FnZSBvciBmYWxsYmFjayBVSS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpYmVyKSB8fCAnVW5rbm93bicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdXBkYXRlO1xufVxuXG5mdW5jdGlvbiBhdHRhY2hQaW5nTGlzdGVuZXIocm9vdCwgd2FrZWFibGUsIGxhbmVzKSB7XG4gIC8vIEF0dGFjaCBhIHBpbmcgbGlzdGVuZXJcbiAgLy9cbiAgLy8gVGhlIGRhdGEgbWlnaHQgcmVzb2x2ZSBiZWZvcmUgd2UgaGF2ZSBhIGNoYW5jZSB0byBjb21taXQgdGhlIGZhbGxiYWNrLiBPcixcbiAgLy8gaW4gdGhlIGNhc2Ugb2YgYSByZWZyZXNoLCB3ZSdsbCBuZXZlciBjb21taXQgYSBmYWxsYmFjay4gU28gd2UgbmVlZCB0b1xuICAvLyBhdHRhY2ggYSBsaXN0ZW5lciBub3cuIFdoZW4gaXQgcmVzb2x2ZXMgKFwicGluZ3NcIiksIHdlIGNhbiBkZWNpZGUgd2hldGhlciB0b1xuICAvLyB0cnkgcmVuZGVyaW5nIHRoZSB0cmVlIGFnYWluLlxuICAvL1xuICAvLyBPbmx5IGF0dGFjaCBhIGxpc3RlbmVyIGlmIG9uZSBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0IGZvciB0aGUgbGFuZXNcbiAgLy8gd2UncmUgY3VycmVudGx5IHJlbmRlcmluZyAod2hpY2ggYWN0cyBsaWtlIGEgXCJ0aHJlYWQgSURcIiBoZXJlKS5cbiAgLy9cbiAgLy8gV2Ugb25seSBuZWVkIHRvIGRvIHRoaXMgaW4gY29uY3VycmVudCBtb2RlLiBMZWdhY3kgU3VzcGVuc2UgYWx3YXlzXG4gIC8vIGNvbW1pdHMgZmFsbGJhY2tzIHN5bmNocm9ub3VzbHksIHNvIHRoZXJlIGFyZSBubyBwaW5ncy5cbiAgdmFyIHBpbmdDYWNoZSA9IHJvb3QucGluZ0NhY2hlO1xuICB2YXIgdGhyZWFkSURzO1xuXG4gIGlmIChwaW5nQ2FjaGUgPT09IG51bGwpIHtcbiAgICBwaW5nQ2FjaGUgPSByb290LnBpbmdDYWNoZSA9IG5ldyBQb3NzaWJseVdlYWtNYXAkMSgpO1xuICAgIHRocmVhZElEcyA9IG5ldyBTZXQoKTtcbiAgICBwaW5nQ2FjaGUuc2V0KHdha2VhYmxlLCB0aHJlYWRJRHMpO1xuICB9IGVsc2Uge1xuICAgIHRocmVhZElEcyA9IHBpbmdDYWNoZS5nZXQod2FrZWFibGUpO1xuXG4gICAgaWYgKHRocmVhZElEcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJlYWRJRHMgPSBuZXcgU2V0KCk7XG4gICAgICBwaW5nQ2FjaGUuc2V0KHdha2VhYmxlLCB0aHJlYWRJRHMpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhyZWFkSURzLmhhcyhsYW5lcykpIHtcbiAgICAvLyBNZW1vaXplIHVzaW5nIHRoZSB0aHJlYWQgSUQgdG8gcHJldmVudCByZWR1bmRhbnQgbGlzdGVuZXJzLlxuICAgIHRocmVhZElEcy5hZGQobGFuZXMpO1xuICAgIHZhciBwaW5nID0gcGluZ1N1c3BlbmRlZFJvb3QuYmluZChudWxsLCByb290LCB3YWtlYWJsZSwgbGFuZXMpO1xuXG4gICAge1xuICAgICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICAgIC8vIElmIHdlIGhhdmUgcGVuZGluZyB3b3JrIHN0aWxsLCByZXN0b3JlIHRoZSBvcmlnaW5hbCB1cGRhdGVyc1xuICAgICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIGxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB3YWtlYWJsZS50aGVuKHBpbmcsIHBpbmcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGF0dGFjaFJldHJ5TGlzdGVuZXIoc3VzcGVuc2VCb3VuZGFyeSwgcm9vdCwgd2FrZWFibGUsIGxhbmVzKSB7XG4gIC8vIFJldHJ5IGxpc3RlbmVyXG4gIC8vXG4gIC8vIElmIHRoZSBmYWxsYmFjayBkb2VzIGNvbW1pdCwgd2UgbmVlZCB0byBhdHRhY2ggYSBkaWZmZXJlbnQgdHlwZSBvZlxuICAvLyBsaXN0ZW5lci4gVGhpcyBvbmUgc2NoZWR1bGVzIGFuIHVwZGF0ZSBvbiB0aGUgU3VzcGVuc2UgYm91bmRhcnkgdG8gdHVyblxuICAvLyB0aGUgZmFsbGJhY2sgc3RhdGUgb2ZmLlxuICAvL1xuICAvLyBTdGFzaCB0aGUgd2FrZWFibGUgb24gdGhlIGJvdW5kYXJ5IGZpYmVyIHNvIHdlIGNhbiBhY2Nlc3MgaXQgaW4gdGhlXG4gIC8vIGNvbW1pdCBwaGFzZS5cbiAgLy9cbiAgLy8gV2hlbiB0aGUgd2FrZWFibGUgcmVzb2x2ZXMsIHdlJ2xsIGF0dGVtcHQgdG8gcmVuZGVyIHRoZSBib3VuZGFyeVxuICAvLyBhZ2FpbiAoXCJyZXRyeVwiKS5cbiAgdmFyIHdha2VhYmxlcyA9IHN1c3BlbnNlQm91bmRhcnkudXBkYXRlUXVldWU7XG5cbiAgaWYgKHdha2VhYmxlcyA9PT0gbnVsbCkge1xuICAgIHZhciB1cGRhdGVRdWV1ZSA9IG5ldyBTZXQoKTtcbiAgICB1cGRhdGVRdWV1ZS5hZGQod2FrZWFibGUpO1xuICAgIHN1c3BlbnNlQm91bmRhcnkudXBkYXRlUXVldWUgPSB1cGRhdGVRdWV1ZTtcbiAgfSBlbHNlIHtcbiAgICB3YWtlYWJsZXMuYWRkKHdha2VhYmxlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNldFN1c3BlbmRlZENvbXBvbmVudChzb3VyY2VGaWJlciwgcm9vdFJlbmRlckxhbmVzKSB7XG4gIC8vIEEgbGVnYWN5IG1vZGUgU3VzcGVuc2UgcXVpcmssIG9ubHkgcmVsZXZhbnQgdG8gaG9vayBjb21wb25lbnRzLlxuXG5cbiAgdmFyIHRhZyA9IHNvdXJjZUZpYmVyLnRhZztcblxuICBpZiAoKHNvdXJjZUZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSAmJiAodGFnID09PSBGdW5jdGlvbkNvbXBvbmVudCB8fCB0YWcgPT09IEZvcndhcmRSZWYgfHwgdGFnID09PSBTaW1wbGVNZW1vQ29tcG9uZW50KSkge1xuICAgIHZhciBjdXJyZW50U291cmNlID0gc291cmNlRmliZXIuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnRTb3VyY2UpIHtcbiAgICAgIHNvdXJjZUZpYmVyLnVwZGF0ZVF1ZXVlID0gY3VycmVudFNvdXJjZS51cGRhdGVRdWV1ZTtcbiAgICAgIHNvdXJjZUZpYmVyLm1lbW9pemVkU3RhdGUgPSBjdXJyZW50U291cmNlLm1lbW9pemVkU3RhdGU7XG4gICAgICBzb3VyY2VGaWJlci5sYW5lcyA9IGN1cnJlbnRTb3VyY2UubGFuZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNvdXJjZUZpYmVyLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICAgIHNvdXJjZUZpYmVyLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXROZWFyZXN0U3VzcGVuc2VCb3VuZGFyeVRvQ2FwdHVyZShyZXR1cm5GaWJlcikge1xuICB2YXIgbm9kZSA9IHJldHVybkZpYmVyO1xuXG4gIGRvIHtcbiAgICBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlQ29tcG9uZW50ICYmIHNob3VsZENhcHR1cmVTdXNwZW5zZShub2RlKSkge1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfSAvLyBUaGlzIGJvdW5kYXJ5IGFscmVhZHkgY2FwdHVyZWQgZHVyaW5nIHRoaXMgcmVuZGVyLiBDb250aW51ZSB0byB0aGUgbmV4dFxuICAgIC8vIGJvdW5kYXJ5LlxuXG5cbiAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gIH0gd2hpbGUgKG5vZGUgIT09IG51bGwpO1xuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBtYXJrU3VzcGVuc2VCb3VuZGFyeVNob3VsZENhcHR1cmUoc3VzcGVuc2VCb3VuZGFyeSwgcmV0dXJuRmliZXIsIHNvdXJjZUZpYmVyLCByb290LCByb290UmVuZGVyTGFuZXMpIHtcbiAgLy8gVGhpcyBtYXJrcyBhIFN1c3BlbnNlIGJvdW5kYXJ5IHNvIHRoYXQgd2hlbiB3ZSdyZSB1bndpbmRpbmcgdGhlIHN0YWNrLFxuICAvLyBpdCBjYXB0dXJlcyB0aGUgc3VzcGVuZGVkIFwiZXhjZXB0aW9uXCIgYW5kIGRvZXMgYSBzZWNvbmQgKGZhbGxiYWNrKSBwYXNzLlxuICBpZiAoKHN1c3BlbnNlQm91bmRhcnkubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgLy8gTGVnYWN5IE1vZGUgU3VzcGVuc2VcbiAgICAvL1xuICAgIC8vIElmIHRoZSBib3VuZGFyeSBpcyBpbiBsZWdhY3kgbW9kZSwgd2Ugc2hvdWxkICpub3QqXG4gICAgLy8gc3VzcGVuZCB0aGUgY29tbWl0LiBQcmV0ZW5kIGFzIGlmIHRoZSBzdXNwZW5kZWQgY29tcG9uZW50IHJlbmRlcmVkXG4gICAgLy8gbnVsbCBhbmQga2VlcCByZW5kZXJpbmcuIFdoZW4gdGhlIFN1c3BlbnNlIGJvdW5kYXJ5IGNvbXBsZXRlcyxcbiAgICAvLyB3ZSdsbCBkbyBhIHNlY29uZCBwYXNzIHRvIHJlbmRlciB0aGUgZmFsbGJhY2suXG4gICAgaWYgKHN1c3BlbnNlQm91bmRhcnkgPT09IHJldHVybkZpYmVyKSB7XG4gICAgICAvLyBTcGVjaWFsIGNhc2Ugd2hlcmUgd2Ugc3VzcGVuZGVkIHdoaWxlIHJlY29uY2lsaW5nIHRoZSBjaGlsZHJlbiBvZlxuICAgICAgLy8gYSBTdXNwZW5zZSBib3VuZGFyeSdzIGlubmVyIE9mZnNjcmVlbiB3cmFwcGVyIGZpYmVyLiBUaGlzIGhhcHBlbnNcbiAgICAgIC8vIHdoZW4gYSBSZWFjdC5sYXp5IGNvbXBvbmVudCBpcyBhIGRpcmVjdCBjaGlsZCBvZiBhXG4gICAgICAvLyBTdXNwZW5zZSBib3VuZGFyeS5cbiAgICAgIC8vXG4gICAgICAvLyBTdXNwZW5zZSBib3VuZGFyaWVzIGFyZSBpbXBsZW1lbnRlZCBhcyBtdWx0aXBsZSBmaWJlcnMsIGJ1dCB0aGV5XG4gICAgICAvLyBhcmUgYSBzaW5nbGUgY29uY2VwdHVhbCB1bml0LiBUaGUgbGVnYWN5IG1vZGUgYmVoYXZpb3Igd2hlcmUgd2VcbiAgICAgIC8vIHByZXRlbmQgdGhlIHN1c3BlbmRlZCBmaWJlciBjb21taXR0ZWQgYXMgYG51bGxgIHdvbid0IHdvcmssXG4gICAgICAvLyBiZWNhdXNlIGluIHRoaXMgY2FzZSB0aGUgXCJzdXNwZW5kZWRcIiBmaWJlciBpcyB0aGUgaW5uZXJcbiAgICAgIC8vIE9mZnNjcmVlbiB3cmFwcGVyLlxuICAgICAgLy9cbiAgICAgIC8vIEJlY2F1c2UgdGhlIGNvbnRlbnRzIG9mIHRoZSBib3VuZGFyeSBoYXZlbid0IHN0YXJ0ZWQgcmVuZGVyaW5nXG4gICAgICAvLyB5ZXQgKGkuZS4gbm90aGluZyBpbiB0aGUgdHJlZSBoYXMgcGFydGlhbGx5IHJlbmRlcmVkKSB3ZSBjYW5cbiAgICAgIC8vIHN3aXRjaCB0byB0aGUgcmVndWxhciwgY29uY3VycmVudCBtb2RlIGJlaGF2aW9yOiBtYXJrIHRoZVxuICAgICAgLy8gYm91bmRhcnkgd2l0aCBTaG91bGRDYXB0dXJlIGFuZCBlbnRlciB0aGUgdW53aW5kIHBoYXNlLlxuICAgICAgc3VzcGVuc2VCb3VuZGFyeS5mbGFncyB8PSBTaG91bGRDYXB0dXJlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdXNwZW5zZUJvdW5kYXJ5LmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICBzb3VyY2VGaWJlci5mbGFncyB8PSBGb3JjZVVwZGF0ZUZvckxlZ2FjeVN1c3BlbnNlOyAvLyBXZSdyZSBnb2luZyB0byBjb21taXQgdGhpcyBmaWJlciBldmVuIHRob3VnaCBpdCBkaWRuJ3QgY29tcGxldGUuXG4gICAgICAvLyBCdXQgd2Ugc2hvdWxkbid0IGNhbGwgYW55IGxpZmVjeWNsZSBtZXRob2RzIG9yIGNhbGxiYWNrcy4gUmVtb3ZlXG4gICAgICAvLyBhbGwgbGlmZWN5Y2xlIGVmZmVjdCB0YWdzLlxuXG4gICAgICBzb3VyY2VGaWJlci5mbGFncyAmPSB+KExpZmVjeWNsZUVmZmVjdE1hc2sgfCBJbmNvbXBsZXRlKTtcblxuICAgICAgaWYgKHNvdXJjZUZpYmVyLnRhZyA9PT0gQ2xhc3NDb21wb25lbnQpIHtcbiAgICAgICAgdmFyIGN1cnJlbnRTb3VyY2VGaWJlciA9IHNvdXJjZUZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICBpZiAoY3VycmVudFNvdXJjZUZpYmVyID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBhIG5ldyBtb3VudC4gQ2hhbmdlIHRoZSB0YWcgc28gaXQncyBub3QgbWlzdGFrZW4gZm9yIGFcbiAgICAgICAgICAvLyBjb21wbGV0ZWQgY2xhc3MgY29tcG9uZW50LiBGb3IgZXhhbXBsZSwgd2Ugc2hvdWxkIG5vdCBjYWxsXG4gICAgICAgICAgLy8gY29tcG9uZW50V2lsbFVubW91bnQgaWYgaXQgaXMgZGVsZXRlZC5cbiAgICAgICAgICBzb3VyY2VGaWJlci50YWcgPSBJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gV2hlbiB3ZSB0cnkgcmVuZGVyaW5nIGFnYWluLCB3ZSBzaG91bGQgbm90IHJldXNlIHRoZSBjdXJyZW50IGZpYmVyLFxuICAgICAgICAgIC8vIHNpbmNlIGl0J3Mga25vd24gdG8gYmUgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBVc2UgYSBmb3JjZSB1cGRhdGUgdG9cbiAgICAgICAgICAvLyBwcmV2ZW50IGEgYmFpbCBvdXQuXG4gICAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShOb1RpbWVzdGFtcCwgU3luY0xhbmUpO1xuICAgICAgICAgIHVwZGF0ZS50YWcgPSBGb3JjZVVwZGF0ZTtcbiAgICAgICAgICBlbnF1ZXVlVXBkYXRlKHNvdXJjZUZpYmVyLCB1cGRhdGUsIFN5bmNMYW5lKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBUaGUgc291cmNlIGZpYmVyIGRpZCBub3QgY29tcGxldGUuIE1hcmsgaXQgd2l0aCBTeW5jIHByaW9yaXR5IHRvXG4gICAgICAvLyBpbmRpY2F0ZSB0aGF0IGl0IHN0aWxsIGhhcyBwZW5kaW5nIHdvcmsuXG5cblxuICAgICAgc291cmNlRmliZXIubGFuZXMgPSBtZXJnZUxhbmVzKHNvdXJjZUZpYmVyLmxhbmVzLCBTeW5jTGFuZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1c3BlbnNlQm91bmRhcnk7XG4gIH0gLy8gQ29uZmlybWVkIHRoYXQgdGhlIGJvdW5kYXJ5IGlzIGluIGEgY29uY3VycmVudCBtb2RlIHRyZWUuIENvbnRpbnVlXG4gIC8vIHdpdGggdGhlIG5vcm1hbCBzdXNwZW5kIHBhdGguXG4gIC8vXG4gIC8vIEFmdGVyIHRoaXMgd2UnbGwgdXNlIGEgc2V0IG9mIGhldXJpc3RpY3MgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhpc1xuICAvLyByZW5kZXIgcGFzcyB3aWxsIHJ1biB0byBjb21wbGV0aW9uIG9yIHJlc3RhcnQgb3IgXCJzdXNwZW5kXCIgdGhlIGNvbW1pdC5cbiAgLy8gVGhlIGFjdHVhbCBsb2dpYyBmb3IgdGhpcyBpcyBzcHJlYWQgb3V0IGluIGRpZmZlcmVudCBwbGFjZXMuXG4gIC8vXG4gIC8vIFRoaXMgZmlyc3QgcHJpbmNpcGxlIGlzIHRoYXQgaWYgd2UncmUgZ29pbmcgdG8gc3VzcGVuZCB3aGVuIHdlIGNvbXBsZXRlXG4gIC8vIGEgcm9vdCwgdGhlbiB3ZSBzaG91bGQgYWxzbyByZXN0YXJ0IGlmIHdlIGdldCBhbiB1cGRhdGUgb3IgcGluZyB0aGF0XG4gIC8vIG1pZ2h0IHVuc3VzcGVuZCBpdCwgYW5kIHZpY2UgdmVyc2EuIFRoZSBvbmx5IHJlYXNvbiB0byBzdXNwZW5kIGlzXG4gIC8vIGJlY2F1c2UgeW91IHRoaW5rIHlvdSBtaWdodCB3YW50IHRvIHJlc3RhcnQgYmVmb3JlIGNvbW1pdHRpbmcuIEhvd2V2ZXIsXG4gIC8vIGl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byByZXN0YXJ0IG9ubHkgd2hpbGUgaW4gdGhlIHBlcmlvZCB3ZSdyZSBzdXNwZW5kZWQuXG4gIC8vXG4gIC8vIFJlc3RhcnRpbmcgdG9vIGFnZ3Jlc3NpdmVseSBpcyBhbHNvIG5vdCBnb29kIGJlY2F1c2UgaXQgc3RhcnZlcyBvdXQgYW55XG4gIC8vIGludGVybWVkaWF0ZSBsb2FkaW5nIHN0YXRlLiBTbyB3ZSB1c2UgaGV1cmlzdGljcyB0byBkZXRlcm1pbmUgd2hlbi5cbiAgLy8gU3VzcGVuc2UgSGV1cmlzdGljc1xuICAvL1xuICAvLyBJZiBub3RoaW5nIHRocmV3IGEgUHJvbWlzZSBvciBhbGwgdGhlIHNhbWUgZmFsbGJhY2tzIGFyZSBhbHJlYWR5IHNob3dpbmcsXG4gIC8vIHRoZW4gZG9uJ3Qgc3VzcGVuZC9yZXN0YXJ0LlxuICAvL1xuICAvLyBJZiB0aGlzIGlzIGFuIGluaXRpYWwgcmVuZGVyIG9mIGEgbmV3IHRyZWUgb2YgU3VzcGVuc2UgYm91bmRhcmllcyBhbmRcbiAgLy8gdGhvc2UgdHJpZ2dlciBhIGZhbGxiYWNrLCB0aGVuIGRvbid0IHN1c3BlbmQvcmVzdGFydC4gV2Ugd2FudCB0byBlbnN1cmVcbiAgLy8gdGhhdCB3ZSBjYW4gc2hvdyB0aGUgaW5pdGlhbCBsb2FkaW5nIHN0YXRlIGFzIHF1aWNrbHkgYXMgcG9zc2libGUuXG4gIC8vXG4gIC8vIElmIHdlIGhpdCBhIFwiRGVsYXllZFwiIGNhc2UsIHN1Y2ggYXMgd2hlbiB3ZSdkIHN3aXRjaCBmcm9tIGNvbnRlbnQgYmFjayBpbnRvXG4gIC8vIGEgZmFsbGJhY2ssIHRoZW4gd2Ugc2hvdWxkIGFsd2F5cyBzdXNwZW5kL3Jlc3RhcnQuIFRyYW5zaXRpb25zIGFwcGx5XG4gIC8vIHRvIHRoaXMgY2FzZS4gSWYgbm9uZSBpcyBkZWZpbmVkLCBKTkQgaXMgdXNlZCBpbnN0ZWFkLlxuICAvL1xuICAvLyBJZiB3ZSdyZSBhbHJlYWR5IHNob3dpbmcgYSBmYWxsYmFjayBhbmQgaXQgZ2V0cyBcInJldHJpZWRcIiwgYWxsb3dpbmcgdXMgdG8gc2hvd1xuICAvLyBhbm90aGVyIGxldmVsLCBidXQgdGhlcmUncyBzdGlsbCBhbiBpbm5lciBib3VuZGFyeSB0aGF0IHdvdWxkIHNob3cgYSBmYWxsYmFjayxcbiAgLy8gdGhlbiB3ZSBzdXNwZW5kL3Jlc3RhcnQgZm9yIDUwMG1zIHNpbmNlIHRoZSBsYXN0IHRpbWUgd2Ugc2hvd2VkIGEgZmFsbGJhY2tcbiAgLy8gYW55d2hlcmUgaW4gdGhlIHRyZWUuIFRoaXMgZWZmZWN0aXZlbHkgdGhyb3R0bGVzIHByb2dyZXNzaXZlIGxvYWRpbmcgaW50byBhXG4gIC8vIGNvbnNpc3RlbnQgdHJhaW4gb2YgY29tbWl0cy4gVGhpcyBhbHNvIGdpdmVzIHVzIGFuIG9wcG9ydHVuaXR5IHRvIHJlc3RhcnQgdG9cbiAgLy8gZ2V0IHRvIHRoZSBjb21wbGV0ZWQgc3RhdGUgc2xpZ2h0bHkgZWFybGllci5cbiAgLy9cbiAgLy8gSWYgdGhlcmUncyBhbWJpZ3VpdHkgZHVlIHRvIGJhdGNoaW5nIGl0J3MgcmVzb2x2ZWQgaW4gcHJlZmVyZW5jZSBvZjpcbiAgLy8gMSkgXCJkZWxheWVkXCIsIDIpIFwiaW5pdGlhbCByZW5kZXJcIiwgMykgXCJyZXRyeVwiLlxuICAvL1xuICAvLyBXZSB3YW50IHRvIGVuc3VyZSB0aGF0IGEgXCJidXN5XCIgc3RhdGUgZG9lc24ndCBnZXQgZm9yY2UgY29tbWl0dGVkLiBXZSB3YW50IHRvXG4gIC8vIGVuc3VyZSB0aGF0IG5ldyBpbml0aWFsIGxvYWRpbmcgc3RhdGVzIGNhbiBjb21taXQgYXMgc29vbiBhcyBwb3NzaWJsZS5cblxuXG4gIHN1c3BlbnNlQm91bmRhcnkuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTsgLy8gVE9ETzogSSB0aGluayB3ZSBjYW4gcmVtb3ZlIHRoaXMsIHNpbmNlIHdlIG5vdyB1c2UgYERpZENhcHR1cmVgIGluXG4gIC8vIHRoZSBiZWdpbiBwaGFzZSB0byBwcmV2ZW50IGFuIGVhcmx5IGJhaWxvdXQuXG5cbiAgc3VzcGVuc2VCb3VuZGFyeS5sYW5lcyA9IHJvb3RSZW5kZXJMYW5lcztcbiAgcmV0dXJuIHN1c3BlbnNlQm91bmRhcnk7XG59XG5cbmZ1bmN0aW9uIHRocm93RXhjZXB0aW9uKHJvb3QsIHJldHVybkZpYmVyLCBzb3VyY2VGaWJlciwgdmFsdWUsIHJvb3RSZW5kZXJMYW5lcykge1xuICAvLyBUaGUgc291cmNlIGZpYmVyIGRpZCBub3QgY29tcGxldGUuXG4gIHNvdXJjZUZpYmVyLmZsYWdzIHw9IEluY29tcGxldGU7XG5cbiAge1xuICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBwZW5kaW5nIHdvcmsgc3RpbGwsIHJlc3RvcmUgdGhlIG9yaWdpbmFsIHVwZGF0ZXJzXG4gICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKHJvb3QsIHJvb3RSZW5kZXJMYW5lcyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBUaGlzIGlzIGEgd2FrZWFibGUuIFRoZSBjb21wb25lbnQgc3VzcGVuZGVkLlxuICAgIHZhciB3YWtlYWJsZSA9IHZhbHVlO1xuICAgIHJlc2V0U3VzcGVuZGVkQ29tcG9uZW50KHNvdXJjZUZpYmVyKTtcblxuICAgIHtcbiAgICAgIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIHNvdXJjZUZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICBtYXJrRGlkVGhyb3dXaGlsZUh5ZHJhdGluZ0RFVigpO1xuICAgICAgfVxuICAgIH1cblxuXG4gICAgdmFyIHN1c3BlbnNlQm91bmRhcnkgPSBnZXROZWFyZXN0U3VzcGVuc2VCb3VuZGFyeVRvQ2FwdHVyZShyZXR1cm5GaWJlcik7XG5cbiAgICBpZiAoc3VzcGVuc2VCb3VuZGFyeSAhPT0gbnVsbCkge1xuICAgICAgc3VzcGVuc2VCb3VuZGFyeS5mbGFncyAmPSB+Rm9yY2VDbGllbnRSZW5kZXI7XG4gICAgICBtYXJrU3VzcGVuc2VCb3VuZGFyeVNob3VsZENhcHR1cmUoc3VzcGVuc2VCb3VuZGFyeSwgcmV0dXJuRmliZXIsIHNvdXJjZUZpYmVyLCByb290LCByb290UmVuZGVyTGFuZXMpOyAvLyBXZSBvbmx5IGF0dGFjaCBwaW5nIGxpc3RlbmVycyBpbiBjb25jdXJyZW50IG1vZGUuIExlZ2FjeSBTdXNwZW5zZSBhbHdheXNcbiAgICAgIC8vIGNvbW1pdHMgZmFsbGJhY2tzIHN5bmNocm9ub3VzbHksIHNvIHRoZXJlIGFyZSBubyBwaW5ncy5cblxuICAgICAgaWYgKHN1c3BlbnNlQm91bmRhcnkubW9kZSAmIENvbmN1cnJlbnRNb2RlKSB7XG4gICAgICAgIGF0dGFjaFBpbmdMaXN0ZW5lcihyb290LCB3YWtlYWJsZSwgcm9vdFJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgICAgYXR0YWNoUmV0cnlMaXN0ZW5lcihzdXNwZW5zZUJvdW5kYXJ5LCByb290LCB3YWtlYWJsZSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIGJvdW5kYXJ5IHdhcyBmb3VuZC4gVW5sZXNzIHRoaXMgaXMgYSBzeW5jIHVwZGF0ZSwgdGhpcyBpcyBPSy5cbiAgICAgIC8vIFdlIGNhbiBzdXNwZW5kIGFuZCB3YWl0IGZvciBtb3JlIGRhdGEgdG8gYXJyaXZlLlxuICAgICAgaWYgKCFpbmNsdWRlc1N5bmNMYW5lKHJvb3RSZW5kZXJMYW5lcykpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBub3QgYSBzeW5jIHVwZGF0ZS4gU3VzcGVuZC4gU2luY2Ugd2UncmUgbm90IGFjdGl2YXRpbmcgYVxuICAgICAgICAvLyBTdXNwZW5zZSBib3VuZGFyeSwgdGhpcyB3aWxsIHVud2luZCBhbGwgdGhlIHdheSB0byB0aGUgcm9vdCB3aXRob3V0XG4gICAgICAgIC8vIHBlcmZvcm1pbmcgYSBzZWNvbmQgcGFzcyB0byByZW5kZXIgYSBmYWxsYmFjay4gKFRoaXMgaXMgYXJndWFibHkgaG93XG4gICAgICAgIC8vIHJlZnJlc2ggdHJhbnNpdGlvbnMgc2hvdWxkIHdvcmssIHRvbywgc2luY2Ugd2UncmUgbm90IGdvaW5nIHRvIGNvbW1pdFxuICAgICAgICAvLyB0aGUgZmFsbGJhY2tzIGFueXdheS4pXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFRoaXMgY2FzZSBhbHNvIGFwcGxpZXMgdG8gaW5pdGlhbCBoeWRyYXRpb24uXG4gICAgICAgIGF0dGFjaFBpbmdMaXN0ZW5lcihyb290LCB3YWtlYWJsZSwgcm9vdFJlbmRlckxhbmVzKTtcbiAgICAgICAgcmVuZGVyRGlkU3VzcGVuZERlbGF5SWZQb3NzaWJsZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IC8vIFRoaXMgaXMgYSBzeW5jL2Rpc2NyZXRlIHVwZGF0ZS4gV2UgdHJlYXQgdGhpcyBjYXNlIGxpa2UgYW4gZXJyb3JcbiAgICAgIC8vIGJlY2F1c2UgZGlzY3JldGUgcmVuZGVycyBhcmUgZXhwZWN0ZWQgdG8gcHJvZHVjZSBhIGNvbXBsZXRlIHRyZWVcbiAgICAgIC8vIHN5bmNocm9ub3VzbHkgdG8gbWFpbnRhaW4gY29uc2lzdGVuY3kgd2l0aCBleHRlcm5hbCBzdGF0ZS5cblxuXG4gICAgICB2YXIgdW5jYXVnaHRTdXNwZW5zZUVycm9yID0gbmV3IEVycm9yKCdBIGNvbXBvbmVudCBzdXNwZW5kZWQgd2hpbGUgcmVzcG9uZGluZyB0byBzeW5jaHJvbm91cyBpbnB1dC4gVGhpcyAnICsgJ3dpbGwgY2F1c2UgdGhlIFVJIHRvIGJlIHJlcGxhY2VkIHdpdGggYSBsb2FkaW5nIGluZGljYXRvci4gVG8gJyArICdmaXgsIHVwZGF0ZXMgdGhhdCBzdXNwZW5kIHNob3VsZCBiZSB3cmFwcGVkICcgKyAnd2l0aCBzdGFydFRyYW5zaXRpb24uJyk7IC8vIElmIHdlJ3JlIG91dHNpZGUgYSB0cmFuc2l0aW9uLCBmYWxsIHRocm91Z2ggdG8gdGhlIHJlZ3VsYXIgZXJyb3IgcGF0aC5cbiAgICAgIC8vIFRoZSBlcnJvciB3aWxsIGJlIGNhdWdodCBieSB0aGUgbmVhcmVzdCBzdXNwZW5zZSBib3VuZGFyeS5cblxuICAgICAgdmFsdWUgPSB1bmNhdWdodFN1c3BlbnNlRXJyb3I7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYSByZWd1bGFyIGVycm9yLCBub3QgYSBTdXNwZW5zZSB3YWtlYWJsZS5cbiAgICBpZiAoZ2V0SXNIeWRyYXRpbmcoKSAmJiBzb3VyY2VGaWJlci5tb2RlICYgQ29uY3VycmVudE1vZGUpIHtcbiAgICAgIG1hcmtEaWRUaHJvd1doaWxlSHlkcmF0aW5nREVWKCk7XG5cbiAgICAgIHZhciBfc3VzcGVuc2VCb3VuZGFyeSA9IGdldE5lYXJlc3RTdXNwZW5zZUJvdW5kYXJ5VG9DYXB0dXJlKHJldHVybkZpYmVyKTsgLy8gSWYgdGhlIGVycm9yIHdhcyB0aHJvd24gZHVyaW5nIGh5ZHJhdGlvbiwgd2UgbWF5IGJlIGFibGUgdG8gcmVjb3ZlciBieVxuICAgICAgLy8gZGlzY2FyZGluZyB0aGUgZGVoeWRyYXRlZCBjb250ZW50IGFuZCBzd2l0Y2hpbmcgdG8gYSBjbGllbnQgcmVuZGVyLlxuICAgICAgLy8gSW5zdGVhZCBvZiBzdXJmYWNpbmcgdGhlIGVycm9yLCBmaW5kIHRoZSBuZWFyZXN0IFN1c3BlbnNlIGJvdW5kYXJ5XG4gICAgICAvLyBhbmQgcmVuZGVyIGl0IGFnYWluIHdpdGhvdXQgaHlkcmF0aW9uLlxuXG5cbiAgICAgIGlmIChfc3VzcGVuc2VCb3VuZGFyeSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoKF9zdXNwZW5zZUJvdW5kYXJ5LmZsYWdzICYgU2hvdWxkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAvLyBTZXQgYSBmbGFnIHRvIGluZGljYXRlIHRoYXQgd2Ugc2hvdWxkIHRyeSByZW5kZXJpbmcgdGhlIG5vcm1hbFxuICAgICAgICAgIC8vIGNoaWxkcmVuIGFnYWluLCBub3QgdGhlIGZhbGxiYWNrLlxuICAgICAgICAgIF9zdXNwZW5zZUJvdW5kYXJ5LmZsYWdzIHw9IEZvcmNlQ2xpZW50UmVuZGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFya1N1c3BlbnNlQm91bmRhcnlTaG91bGRDYXB0dXJlKF9zdXNwZW5zZUJvdW5kYXJ5LCByZXR1cm5GaWJlciwgc291cmNlRmliZXIsIHJvb3QsIHJvb3RSZW5kZXJMYW5lcyk7IC8vIEV2ZW4gdGhvdWdoIHRoZSB1c2VyIG1heSBub3QgYmUgYWZmZWN0ZWQgYnkgdGhpcyBlcnJvciwgd2Ugc2hvdWxkXG4gICAgICAgIC8vIHN0aWxsIGxvZyBpdCBzbyBpdCBjYW4gYmUgZml4ZWQuXG5cbiAgICAgICAgcXVldWVIeWRyYXRpb25FcnJvcihjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcih2YWx1ZSwgc291cmNlRmliZXIpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZUF0RmliZXIodmFsdWUsIHNvdXJjZUZpYmVyKTtcbiAgcmVuZGVyRGlkRXJyb3IodmFsdWUpOyAvLyBXZSBkaWRuJ3QgZmluZCBhIGJvdW5kYXJ5IHRoYXQgY291bGQgaGFuZGxlIHRoaXMgdHlwZSBvZiBleGNlcHRpb24uIFN0YXJ0XG4gIC8vIG92ZXIgYW5kIHRyYXZlcnNlIHBhcmVudCBwYXRoIGFnYWluLCB0aGlzIHRpbWUgdHJlYXRpbmcgdGhlIGV4Y2VwdGlvblxuICAvLyBhcyBhbiBlcnJvci5cblxuICB2YXIgd29ya0luUHJvZ3Jlc3MgPSByZXR1cm5GaWJlcjtcblxuICBkbyB7XG4gICAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgX2Vycm9ySW5mbyA9IHZhbHVlO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFNob3VsZENhcHR1cmU7XG4gICAgICAgICAgdmFyIGxhbmUgPSBwaWNrQXJiaXRyYXJ5TGFuZShyb290UmVuZGVyTGFuZXMpO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzcy5sYW5lcywgbGFuZSk7XG4gICAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVJvb3RFcnJvclVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgX2Vycm9ySW5mbywgbGFuZSk7XG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCB1cGRhdGUpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICAvLyBDYXB0dXJlIGFuZCByZXRyeVxuICAgICAgICB2YXIgZXJyb3JJbmZvID0gdmFsdWU7XG4gICAgICAgIHZhciBjdG9yID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmICgod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncyAmJiAodHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nIHx8IGluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiAhaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkpKSB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTtcblxuICAgICAgICAgIHZhciBfbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJvb3RSZW5kZXJMYW5lcyk7XG5cbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMsIF9sYW5lKTsgLy8gU2NoZWR1bGUgdGhlIGVycm9yIGJvdW5kYXJ5IHRvIHJlLXJlbmRlciB1c2luZyB1cGRhdGVkIHN0YXRlXG5cbiAgICAgICAgICB2YXIgX3VwZGF0ZSA9IGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUod29ya0luUHJvZ3Jlc3MsIGVycm9ySW5mbywgX2xhbmUpO1xuXG4gICAgICAgICAgZW5xdWV1ZUNhcHR1cmVkVXBkYXRlKHdvcmtJblByb2dyZXNzLCBfdXBkYXRlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcyA9IHdvcmtJblByb2dyZXNzLnJldHVybjtcbiAgfSB3aGlsZSAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpO1xufVxuXG5mdW5jdGlvbiBnZXRTdXNwZW5kZWRDYWNoZSgpIHtcbiAge1xuICAgIHJldHVybiBudWxsO1xuICB9IC8vIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYSBTdXNwZW5zZSBib3VuZGFyeSBzdXNwZW5kcy4gSXQgcmV0dXJucyB0aGVcbn1cblxudmFyIFJlYWN0Q3VycmVudE93bmVyJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7XG52YXIgZGlkV2FybkFib3V0QmFkQ2xhc3M7XG52YXIgZGlkV2FybkFib3V0TW9kdWxlUGF0dGVybkNvbXBvbmVudDtcbnZhciBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZU9uRnVuY3Rpb25Db21wb25lbnQ7XG52YXIgZGlkV2FybkFib3V0R2V0RGVyaXZlZFN0YXRlT25GdW5jdGlvbkNvbXBvbmVudDtcbnZhciBkaWRXYXJuQWJvdXRGdW5jdGlvblJlZnM7XG52YXIgZGlkV2FybkFib3V0UmVhc3NpZ25pbmdQcm9wcztcbnZhciBkaWRXYXJuQWJvdXRSZXZlYWxPcmRlcjtcbnZhciBkaWRXYXJuQWJvdXRUYWlsT3B0aW9ucztcblxue1xuICBkaWRXYXJuQWJvdXRCYWRDbGFzcyA9IHt9O1xuICBkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50ID0ge307XG4gIGRpZFdhcm5BYm91dENvbnRleHRUeXBlT25GdW5jdGlvbkNvbXBvbmVudCA9IHt9O1xuICBkaWRXYXJuQWJvdXRHZXREZXJpdmVkU3RhdGVPbkZ1bmN0aW9uQ29tcG9uZW50ID0ge307XG4gIGRpZFdhcm5BYm91dEZ1bmN0aW9uUmVmcyA9IHt9O1xuICBkaWRXYXJuQWJvdXRSZWFzc2lnbmluZ1Byb3BzID0gZmFsc2U7XG4gIGRpZFdhcm5BYm91dFJldmVhbE9yZGVyID0ge307XG4gIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zID0ge307XG59XG5cbmZ1bmN0aW9uIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKSB7XG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgLy8gSWYgdGhpcyBpcyBhIGZyZXNoIG5ldyBjb21wb25lbnQgdGhhdCBoYXNuJ3QgYmVlbiByZW5kZXJlZCB5ZXQsIHdlXG4gICAgLy8gd29uJ3QgdXBkYXRlIGl0cyBjaGlsZCBzZXQgYnkgYXBwbHlpbmcgbWluaW1hbCBzaWRlLWVmZmVjdHMuIEluc3RlYWQsXG4gICAgLy8gd2Ugd2lsbCBhZGQgdGhlbSBhbGwgdG8gdGhlIGNoaWxkIGJlZm9yZSBpdCBnZXRzIHJlbmRlcmVkLiBUaGF0IG1lYW5zXG4gICAgLy8gd2UgY2FuIG9wdGltaXplIHRoaXMgcmVjb25jaWxpYXRpb24gcGFzcyBieSBub3QgdHJhY2tpbmcgc2lkZS1lZmZlY3RzLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbW91bnRDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgbnVsbCwgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gSWYgdGhlIGN1cnJlbnQgY2hpbGQgaXMgdGhlIHNhbWUgYXMgdGhlIHdvcmsgaW4gcHJvZ3Jlc3MsIGl0IG1lYW5zIHRoYXRcbiAgICAvLyB3ZSBoYXZlbid0IHlldCBzdGFydGVkIGFueSB3b3JrIG9uIHRoZXNlIGNoaWxkcmVuLiBUaGVyZWZvcmUsIHdlIHVzZVxuICAgIC8vIHRoZSBjbG9uZSBhbGdvcml0aG0gdG8gY3JlYXRlIGEgY29weSBvZiBhbGwgdGhlIGN1cnJlbnQgY2hpbGRyZW4uXG4gICAgLy8gSWYgd2UgaGFkIGFueSBwcm9ncmVzc2VkIHdvcmsgYWxyZWFkeSwgdGhhdCBpcyBpbnZhbGlkIGF0IHRoaXMgcG9pbnQgc29cbiAgICAvLyBsZXQncyB0aHJvdyBpdCBvdXQuXG4gICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9yY2VVbm1vdW50Q3VycmVudEFuZFJlY29uY2lsZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcykge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGZvcmsgb2YgcmVjb25jaWxlQ2hpbGRyZW4uIEl0J3MgdXNlZCBpbiBjYXNlcyB3aGVyZSB3ZVxuICAvLyB3YW50IHRvIHJlY29uY2lsZSB3aXRob3V0IG1hdGNoaW5nIGFnYWluc3QgdGhlIGV4aXN0aW5nIHNldC4gVGhpcyBoYXMgdGhlXG4gIC8vIGVmZmVjdCBvZiBhbGwgY3VycmVudCBjaGlsZHJlbiBiZWluZyB1bm1vdW50ZWQ7IGV2ZW4gaWYgdGhlIHR5cGUgYW5kIGtleVxuICAvLyBhcmUgdGhlIHNhbWUsIHRoZSBvbGQgY2hpbGQgaXMgdW5tb3VudGVkIGFuZCBhIG5ldyBjaGlsZCBpcyBjcmVhdGVkLlxuICAvL1xuICAvLyBUbyBkbyB0aGlzLCB3ZSdyZSBnb2luZyB0byBnbyB0aHJvdWdoIHRoZSByZWNvbmNpbGUgYWxnb3JpdGhtIHR3aWNlLiBJblxuICAvLyB0aGUgZmlyc3QgcGFzcywgd2Ugc2NoZWR1bGUgYSBkZWxldGlvbiBmb3IgYWxsIHRoZSBjdXJyZW50IGNoaWxkcmVuIGJ5XG4gIC8vIHBhc3NpbmcgbnVsbC5cbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbnVsbCwgcmVuZGVyTGFuZXMpOyAvLyBJbiB0aGUgc2Vjb25kIHBhc3MsIHdlIG1vdW50IHRoZSBuZXcgY2hpbGRyZW4uIFRoZSB0cmljayBoZXJlIGlzIHRoYXQgd2VcbiAgLy8gcGFzcyBudWxsIGluIHBsYWNlIG9mIHdoZXJlIHdlIHVzdWFsbHkgcGFzcyB0aGUgY3VycmVudCBjaGlsZCBzZXQuIFRoaXMgaGFzXG4gIC8vIHRoZSBlZmZlY3Qgb2YgcmVtb3VudGluZyBhbGwgY2hpbGRyZW4gcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZWlyXG4gIC8vIGlkZW50aXRpZXMgbWF0Y2guXG5cbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgbnVsbCwgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUZvcndhcmRSZWYoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICAvLyBUT0RPOiBjdXJyZW50IGNhbiBiZSBub24tbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIGNvbXBvbmVudFxuICAvLyBoYXNuJ3QgeWV0IG1vdW50ZWQuIFRoaXMgaGFwcGVucyBhZnRlciB0aGUgZmlyc3QgcmVuZGVyIHN1c3BlbmRzLlxuICAvLyBXZSdsbCBuZWVkIHRvIGZpZ3VyZSBvdXQgaWYgdGhpcyBpcyBmaW5lIG9yIGNhbiBjYXVzZSBpc3N1ZXMuXG4gIHtcbiAgICBpZiAod29ya0luUHJvZ3Jlc3MudHlwZSAhPT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUpIHtcbiAgICAgIC8vIExhenkgY29tcG9uZW50IHByb3BzIGNhbid0IGJlIHZhbGlkYXRlZCBpbiBjcmVhdGVFbGVtZW50XG4gICAgICAvLyBiZWNhdXNlIHRoZXkncmUgb25seSBndWFyYW50ZWVkIHRvIGJlIHJlc29sdmVkIGhlcmUuXG4gICAgICB2YXIgaW5uZXJQcm9wVHlwZXMgPSBDb21wb25lbnQucHJvcFR5cGVzO1xuXG4gICAgICBpZiAoaW5uZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgY2hlY2tQcm9wVHlwZXMoaW5uZXJQcm9wVHlwZXMsIG5leHRQcm9wcywgLy8gUmVzb2x2ZWQgcHJvcHNcbiAgICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUoQ29tcG9uZW50KSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHJlbmRlciA9IENvbXBvbmVudC5yZW5kZXI7XG4gIHZhciByZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7IC8vIFRoZSByZXN0IGlzIGEgZm9yayBvZiB1cGRhdGVGdW5jdGlvbkNvbXBvbmVudFxuXG4gIHZhciBuZXh0Q2hpbGRyZW47XG4gIHZhciBoYXNJZDtcbiAgcHJlcGFyZVRvUmVhZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAge1xuICAgIFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCA9IHdvcmtJblByb2dyZXNzO1xuICAgIHNldElzUmVuZGVyaW5nKHRydWUpO1xuICAgIG5leHRDaGlsZHJlbiA9IHJlbmRlcldpdGhIb29rcyhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyLCBuZXh0UHJvcHMsIHJlZiwgcmVuZGVyTGFuZXMpO1xuICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBuZXh0Q2hpbGRyZW4gPSByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlciwgbmV4dFByb3BzLCByZWYsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgaGFzSWQgPSBjaGVja0RpZFJlbmRlcklkSG9vaygpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldElzUmVuZGVyaW5nKGZhbHNlKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpO1xuICB9XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwgJiYgIWRpZFJlY2VpdmVVcGRhdGUpIHtcbiAgICBiYWlsb3V0SG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgaWYgKGdldElzSHlkcmF0aW5nKCkgJiYgaGFzSWQpIHtcbiAgICBwdXNoTWF0ZXJpYWxpemVkVHJlZUlkKHdvcmtJblByb2dyZXNzKTtcbiAgfSAvLyBSZWFjdCBEZXZUb29scyByZWFkcyB0aGlzIGZsYWcuXG5cblxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQZXJmb3JtZWRXb3JrO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlTWVtb0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKSB7XG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdmFyIHR5cGUgPSBDb21wb25lbnQudHlwZTtcblxuICAgIGlmIChpc1NpbXBsZUZ1bmN0aW9uQ29tcG9uZW50KHR5cGUpICYmIENvbXBvbmVudC5jb21wYXJlID09PSBudWxsICYmIC8vIFNpbXBsZU1lbW9Db21wb25lbnQgY29kZXBhdGggZG9lc24ndCByZXNvbHZlIG91dGVyIHByb3BzIGVpdGhlci5cbiAgICBDb21wb25lbnQuZGVmYXVsdFByb3BzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciByZXNvbHZlZFR5cGUgPSB0eXBlO1xuXG4gICAgICB7XG4gICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyh0eXBlKTtcbiAgICAgIH0gLy8gSWYgdGhpcyBpcyBhIHBsYWluIGZ1bmN0aW9uIGNvbXBvbmVudCB3aXRob3V0IGRlZmF1bHQgcHJvcHMsXG4gICAgICAvLyBhbmQgd2l0aCBvbmx5IHRoZSBkZWZhdWx0IHNoYWxsb3cgY29tcGFyaXNvbiwgd2UgdXBncmFkZSBpdFxuICAgICAgLy8gdG8gYSBTaW1wbGVNZW1vQ29tcG9uZW50IHRvIGFsbG93IGZhc3QgcGF0aCB1cGRhdGVzLlxuXG5cbiAgICAgIHdvcmtJblByb2dyZXNzLnRhZyA9IFNpbXBsZU1lbW9Db21wb25lbnQ7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gcmVzb2x2ZWRUeXBlO1xuXG4gICAgICB7XG4gICAgICAgIHZhbGlkYXRlRnVuY3Rpb25Db21wb25lbnRJbkRldih3b3JrSW5Qcm9ncmVzcywgdHlwZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB1cGRhdGVTaW1wbGVNZW1vQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZXNvbHZlZFR5cGUsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgIH1cblxuICAgIHtcbiAgICAgIHZhciBpbm5lclByb3BUeXBlcyA9IHR5cGUucHJvcFR5cGVzO1xuXG4gICAgICBpZiAoaW5uZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgLy8gSW5uZXIgbWVtbyBjb21wb25lbnQgcHJvcHMgYXJlbid0IGN1cnJlbnRseSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudC5cbiAgICAgICAgLy8gV2UgY291bGQgbW92ZSBpdCB0aGVyZSwgYnV0IHdlJ2Qgc3RpbGwgbmVlZCB0aGlzIGZvciBsYXp5IGNvZGUgcGF0aC5cbiAgICAgICAgY2hlY2tQcm9wVHlwZXMoaW5uZXJQcm9wVHlwZXMsIG5leHRQcm9wcywgLy8gUmVzb2x2ZWQgcHJvcHNcbiAgICAgICAgJ3Byb3AnLCBnZXRDb21wb25lbnROYW1lRnJvbVR5cGUodHlwZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjaGlsZCA9IGNyZWF0ZUZpYmVyRnJvbVR5cGVBbmRQcm9wcyhDb21wb25lbnQudHlwZSwgbnVsbCwgbmV4dFByb3BzLCB3b3JrSW5Qcm9ncmVzcywgd29ya0luUHJvZ3Jlc3MubW9kZSwgcmVuZGVyTGFuZXMpO1xuICAgIGNoaWxkLnJlZiA9IHdvcmtJblByb2dyZXNzLnJlZjtcbiAgICBjaGlsZC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGNoaWxkO1xuICAgIHJldHVybiBjaGlsZDtcbiAgfVxuXG4gIHtcbiAgICB2YXIgX3R5cGUgPSBDb21wb25lbnQudHlwZTtcbiAgICB2YXIgX2lubmVyUHJvcFR5cGVzID0gX3R5cGUucHJvcFR5cGVzO1xuXG4gICAgaWYgKF9pbm5lclByb3BUeXBlcykge1xuICAgICAgLy8gSW5uZXIgbWVtbyBjb21wb25lbnQgcHJvcHMgYXJlbid0IGN1cnJlbnRseSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudC5cbiAgICAgIC8vIFdlIGNvdWxkIG1vdmUgaXQgdGhlcmUsIGJ1dCB3ZSdkIHN0aWxsIG5lZWQgdGhpcyBmb3IgbGF6eSBjb2RlIHBhdGguXG4gICAgICBjaGVja1Byb3BUeXBlcyhfaW5uZXJQcm9wVHlwZXMsIG5leHRQcm9wcywgLy8gUmVzb2x2ZWQgcHJvcHNcbiAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKF90eXBlKSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGN1cnJlbnRDaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFRoaXMgaXMgYWx3YXlzIGV4YWN0bHkgb25lIGNoaWxkXG5cbiAgdmFyIGhhc1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dCA9IGNoZWNrU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0KGN1cnJlbnQsIHJlbmRlckxhbmVzKTtcblxuICBpZiAoIWhhc1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dCkge1xuICAgIC8vIFRoaXMgd2lsbCBiZSB0aGUgcHJvcHMgd2l0aCByZXNvbHZlZCBkZWZhdWx0UHJvcHMsXG4gICAgLy8gdW5saWtlIGN1cnJlbnQubWVtb2l6ZWRQcm9wcyB3aGljaCB3aWxsIGJlIHRoZSB1bnJlc29sdmVkIG9uZXMuXG4gICAgdmFyIHByZXZQcm9wcyA9IGN1cnJlbnRDaGlsZC5tZW1vaXplZFByb3BzOyAvLyBEZWZhdWx0IHRvIHNoYWxsb3cgY29tcGFyaXNvblxuXG4gICAgdmFyIGNvbXBhcmUgPSBDb21wb25lbnQuY29tcGFyZTtcbiAgICBjb21wYXJlID0gY29tcGFyZSAhPT0gbnVsbCA/IGNvbXBhcmUgOiBzaGFsbG93RXF1YWw7XG5cbiAgICBpZiAoY29tcGFyZShwcmV2UHJvcHMsIG5leHRQcm9wcykgJiYgY3VycmVudC5yZWYgPT09IHdvcmtJblByb2dyZXNzLnJlZikge1xuICAgICAgcmV0dXJuIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICB9XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgdmFyIG5ld0NoaWxkID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoY3VycmVudENoaWxkLCBuZXh0UHJvcHMpO1xuICBuZXdDaGlsZC5yZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7XG4gIG5ld0NoaWxkLnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IG5ld0NoaWxkO1xuICByZXR1cm4gbmV3Q2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVNpbXBsZU1lbW9Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICAvLyBUT0RPOiBjdXJyZW50IGNhbiBiZSBub24tbnVsbCBoZXJlIGV2ZW4gaWYgdGhlIGNvbXBvbmVudFxuICAvLyBoYXNuJ3QgeWV0IG1vdW50ZWQuIFRoaXMgaGFwcGVucyB3aGVuIHRoZSBpbm5lciByZW5kZXIgc3VzcGVuZHMuXG4gIC8vIFdlJ2xsIG5lZWQgdG8gZmlndXJlIG91dCBpZiB0aGlzIGlzIGZpbmUgb3IgY2FuIGNhdXNlIGlzc3Vlcy5cbiAge1xuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSkge1xuICAgICAgLy8gTGF6eSBjb21wb25lbnQgcHJvcHMgY2FuJ3QgYmUgdmFsaWRhdGVkIGluIGNyZWF0ZUVsZW1lbnRcbiAgICAgIC8vIGJlY2F1c2UgdGhleSdyZSBvbmx5IGd1YXJhbnRlZWQgdG8gYmUgcmVzb2x2ZWQgaGVyZS5cbiAgICAgIHZhciBvdXRlck1lbW9UeXBlID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGU7XG5cbiAgICAgIGlmIChvdXRlck1lbW9UeXBlLiQkdHlwZW9mID09PSBSRUFDVF9MQVpZX1RZUEUpIHtcbiAgICAgICAgLy8gV2Ugd2FybiB3aGVuIHlvdSBkZWZpbmUgcHJvcFR5cGVzIG9uIGxhenkoKVxuICAgICAgICAvLyBzbyBsZXQncyBqdXN0IHNraXAgb3ZlciBpdCB0byBmaW5kIG1lbW8oKSBvdXRlciB3cmFwcGVyLlxuICAgICAgICAvLyBJbm5lciBwcm9wcyBmb3IgbWVtbyBhcmUgdmFsaWRhdGVkIGxhdGVyLlxuICAgICAgICB2YXIgbGF6eUNvbXBvbmVudCA9IG91dGVyTWVtb1R5cGU7XG4gICAgICAgIHZhciBwYXlsb2FkID0gbGF6eUNvbXBvbmVudC5fcGF5bG9hZDtcbiAgICAgICAgdmFyIGluaXQgPSBsYXp5Q29tcG9uZW50Ll9pbml0O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgb3V0ZXJNZW1vVHlwZSA9IGluaXQocGF5bG9hZCk7XG4gICAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgICBvdXRlck1lbW9UeXBlID0gbnVsbDtcbiAgICAgICAgfSAvLyBJbm5lciBwcm9wVHlwZXMgd2lsbCBiZSB2YWxpZGF0ZWQgaW4gdGhlIGZ1bmN0aW9uIGNvbXBvbmVudCBwYXRoLlxuXG5cbiAgICAgICAgdmFyIG91dGVyUHJvcFR5cGVzID0gb3V0ZXJNZW1vVHlwZSAmJiBvdXRlck1lbW9UeXBlLnByb3BUeXBlcztcblxuICAgICAgICBpZiAob3V0ZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgICBjaGVja1Byb3BUeXBlcyhvdXRlclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCAoU2ltcGxlTWVtb0NvbXBvbmVudCBoYXMgbm8gZGVmYXVsdFByb3BzKVxuICAgICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKG91dGVyTWVtb1R5cGUpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgdmFyIHByZXZQcm9wcyA9IGN1cnJlbnQubWVtb2l6ZWRQcm9wcztcblxuICAgIGlmIChzaGFsbG93RXF1YWwocHJldlByb3BzLCBuZXh0UHJvcHMpICYmIGN1cnJlbnQucmVmID09PSB3b3JrSW5Qcm9ncmVzcy5yZWYgJiYgKCAvLyBQcmV2ZW50IGJhaWxvdXQgaWYgdGhlIGltcGxlbWVudGF0aW9uIGNoYW5nZWQgZHVlIHRvIGhvdCByZWxvYWQuXG4gICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPT09IGN1cnJlbnQudHlwZSApKSB7XG4gICAgICBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7IC8vIFRoZSBwcm9wcyBhcmUgc2hhbGxvd2x5IGVxdWFsLiBSZXVzZSB0aGUgcHJldmlvdXMgcHJvcHMgb2JqZWN0LCBsaWtlIHdlXG4gICAgICAvLyB3b3VsZCBkdXJpbmcgYSBub3JtYWwgZmliZXIgYmFpbG91dC5cbiAgICAgIC8vXG4gICAgICAvLyBXZSBkb24ndCBoYXZlIHN0cm9uZyBndWFyYW50ZWVzIHRoYXQgdGhlIHByb3BzIG9iamVjdCBpcyByZWZlcmVudGlhbGx5XG4gICAgICAvLyBlcXVhbCBkdXJpbmcgdXBkYXRlcyB3aGVyZSB3ZSBjYW4ndCBiYWlsIG91dCBhbnl3YXkg4oCUIGxpa2UgaWYgdGhlIHByb3BzXG4gICAgICAvLyBhcmUgc2hhbGxvd2x5IGVxdWFsLCBidXQgdGhlcmUncyBhIGxvY2FsIHN0YXRlIG9yIGNvbnRleHQgdXBkYXRlIGluIHRoZVxuICAgICAgLy8gc2FtZSBiYXRjaC5cbiAgICAgIC8vXG4gICAgICAvLyBIb3dldmVyLCBhcyBhIHByaW5jaXBsZSwgd2Ugc2hvdWxkIGFpbSB0byBtYWtlIHRoZSBiZWhhdmlvciBjb25zaXN0ZW50XG4gICAgICAvLyBhY3Jvc3MgZGlmZmVyZW50IHdheXMgb2YgbWVtb2l6aW5nIGEgY29tcG9uZW50LiBGb3IgZXhhbXBsZSwgUmVhY3QubWVtb1xuICAgICAgLy8gaGFzIGEgZGlmZmVyZW50IGludGVybmFsIEZpYmVyIGxheW91dCBpZiB5b3UgcGFzcyBhIG5vcm1hbCBmdW5jdGlvblxuICAgICAgLy8gY29tcG9uZW50IChTaW1wbGVNZW1vQ29tcG9uZW50KSB2ZXJzdXMgaWYgeW91IHBhc3MgYSBkaWZmZXJlbnQgdHlwZVxuICAgICAgLy8gbGlrZSBmb3J3YXJkUmVmIChNZW1vQ29tcG9uZW50KS4gQnV0IHRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLlxuICAgICAgLy8gV3JhcHBpbmcgYSBjb21wb25lbnQgaW4gZm9yd2FyZFJlZiAob3IgUmVhY3QubGF6eSwgZXRjKSBzaG91bGRuJ3RcbiAgICAgIC8vIGFmZmVjdCB3aGV0aGVyIHRoZSBwcm9wcyBvYmplY3QgaXMgcmV1c2VkIGR1cmluZyBhIGJhaWxvdXQuXG5cbiAgICAgIHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcyA9IG5leHRQcm9wcyA9IHByZXZQcm9wcztcblxuICAgICAgaWYgKCFjaGVja1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dChjdXJyZW50LCByZW5kZXJMYW5lcykpIHtcbiAgICAgICAgLy8gVGhlIHBlbmRpbmcgbGFuZXMgd2VyZSBjbGVhcmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgYmVnaW5Xb3JrLiBXZSdyZVxuICAgICAgICAvLyBhYm91dCB0byBiYWlsIG91dCwgYnV0IHRoZXJlIG1pZ2h0IGJlIG90aGVyIGxhbmVzIHRoYXQgd2VyZW4ndFxuICAgICAgICAvLyBpbmNsdWRlZCBpbiB0aGUgY3VycmVudCByZW5kZXIuIFVzdWFsbHksIHRoZSBwcmlvcml0eSBsZXZlbCBvZiB0aGVcbiAgICAgICAgLy8gcmVtYWluaW5nIHVwZGF0ZXMgaXMgYWNjdW11bGF0ZWQgZHVyaW5nIHRoZSBldmFsdWF0aW9uIG9mIHRoZVxuICAgICAgICAvLyBjb21wb25lbnQgKGkuZS4gd2hlbiBwcm9jZXNzaW5nIHRoZSB1cGRhdGUgcXVldWUpLiBCdXQgc2luY2Ugc2luY2VcbiAgICAgICAgLy8gd2UncmUgYmFpbGluZyBvdXQgZWFybHkgKndpdGhvdXQqIGV2YWx1YXRpbmcgdGhlIGNvbXBvbmVudCwgd2UgbmVlZFxuICAgICAgICAvLyB0byBhY2NvdW50IGZvciBpdCBoZXJlLCB0b28uIFJlc2V0IHRvIHRoZSB2YWx1ZSBvZiB0aGUgY3VycmVudCBmaWJlci5cbiAgICAgICAgLy8gTk9URTogVGhpcyBvbmx5IGFwcGxpZXMgdG8gU2ltcGxlTWVtb0NvbXBvbmVudCwgbm90IE1lbW9Db21wb25lbnQsXG4gICAgICAgIC8vIGJlY2F1c2UgYSBNZW1vQ29tcG9uZW50IGZpYmVyIGRvZXMgbm90IGhhdmUgaG9va3Mgb3IgYW4gdXBkYXRlIHF1ZXVlO1xuICAgICAgICAvLyByYXRoZXIsIGl0IHdyYXBzIGFyb3VuZCBhbiBpbm5lciBjb21wb25lbnQsIHdoaWNoIG1heSBvciBtYXkgbm90XG4gICAgICAgIC8vIGNvbnRhaW5zIGhvb2tzLlxuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoZSByZXNldCBhdCBpbiBiZWdpbldvcmsgb3V0IG9mIHRoZSBjb21tb24gcGF0aCBzbyB0aGF0XG4gICAgICAgIC8vIHRoaXMgaXMgbm8gbG9uZ2VyIG5lY2Vzc2FyeS5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBjdXJyZW50LmxhbmVzO1xuICAgICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfSBlbHNlIGlmICgoY3VycmVudC5mbGFncyAmIEZvcmNlVXBkYXRlRm9yTGVnYWN5U3VzcGVuc2UpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UgdGhhdCBvbmx5IGV4aXN0cyBmb3IgbGVnYWN5IG1vZGUuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvcHVsbC8xOTIxNi5cbiAgICAgICAgZGlkUmVjZWl2ZVVwZGF0ZSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZUZ1bmN0aW9uQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVPZmZzY3JlZW5Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHZhciBwcmV2U3RhdGUgPSBjdXJyZW50ICE9PSBudWxsID8gY3VycmVudC5tZW1vaXplZFN0YXRlIDogbnVsbDtcblxuICBpZiAobmV4dFByb3BzLm1vZGUgPT09ICdoaWRkZW4nIHx8IGVuYWJsZUxlZ2FjeUhpZGRlbiApIHtcbiAgICAvLyBSZW5kZXJpbmcgYSBoaWRkZW4gdHJlZS5cbiAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgICAgLy8gSW4gbGVnYWN5IHN5bmMgbW9kZSwgZG9uJ3QgZGVmZXIgdGhlIHN1YnRyZWUuIFJlbmRlciBpdCBub3cuXG4gICAgICAvLyBUT0RPOiBDb25zaWRlciBob3cgT2Zmc2NyZWVuIHNob3VsZCB3b3JrIHdpdGggdHJhbnNpdGlvbnMgaW4gdGhlIGZ1dHVyZVxuICAgICAgdmFyIG5leHRTdGF0ZSA9IHtcbiAgICAgICAgYmFzZUxhbmVzOiBOb0xhbmVzLFxuICAgICAgICBjYWNoZVBvb2w6IG51bGwsXG4gICAgICAgIHRyYW5zaXRpb25zOiBudWxsXG4gICAgICB9O1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IG5leHRTdGF0ZTtcblxuICAgICAgcHVzaFJlbmRlckxhbmVzKHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgfSBlbHNlIGlmICghaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgT2Zmc2NyZWVuTGFuZSkpIHtcbiAgICAgIHZhciBzcGF3bmVkQ2FjaGVQb29sID0gbnVsbDsgLy8gV2UncmUgaGlkZGVuLCBhbmQgd2UncmUgbm90IHJlbmRlcmluZyBhdCBPZmZzY3JlZW4uIFdlIHdpbGwgYmFpbCBvdXRcbiAgICAgIC8vIGFuZCByZXN1bWUgdGhpcyB0cmVlIGxhdGVyLlxuXG4gICAgICB2YXIgbmV4dEJhc2VMYW5lcztcblxuICAgICAgaWYgKHByZXZTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgcHJldkJhc2VMYW5lcyA9IHByZXZTdGF0ZS5iYXNlTGFuZXM7XG4gICAgICAgIG5leHRCYXNlTGFuZXMgPSBtZXJnZUxhbmVzKHByZXZCYXNlTGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRCYXNlTGFuZXMgPSByZW5kZXJMYW5lcztcbiAgICAgIH0gLy8gU2NoZWR1bGUgdGhpcyBmaWJlciB0byByZS1yZW5kZXIgYXQgb2Zmc2NyZWVuIHByaW9yaXR5LiBUaGVuIGJhaWxvdXQuXG5cblxuICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzID0gbGFuZVRvTGFuZXMoT2Zmc2NyZWVuTGFuZSk7XG4gICAgICB2YXIgX25leHRTdGF0ZSA9IHtcbiAgICAgICAgYmFzZUxhbmVzOiBuZXh0QmFzZUxhbmVzLFxuICAgICAgICBjYWNoZVBvb2w6IHNwYXduZWRDYWNoZVBvb2wsXG4gICAgICAgIHRyYW5zaXRpb25zOiBudWxsXG4gICAgICB9O1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IF9uZXh0U3RhdGU7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IG51bGw7XG4gICAgICAvLyB0byBhdm9pZCBhIHB1c2gvcG9wIG1pc2FsaWdubWVudC5cblxuXG4gICAgICBwdXNoUmVuZGVyTGFuZXMod29ya0luUHJvZ3Jlc3MsIG5leHRCYXNlTGFuZXMpO1xuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhpcyBpcyB0aGUgc2Vjb25kIHJlbmRlci4gVGhlIHN1cnJvdW5kaW5nIHZpc2libGUgY29udGVudCBoYXMgYWxyZWFkeVxuICAgICAgLy8gY29tbWl0dGVkLiBOb3cgd2UgcmVzdW1lIHJlbmRlcmluZyB0aGUgaGlkZGVuIHRyZWUuXG4gICAgICAvLyBSZW5kZXJpbmcgYXQgb2Zmc2NyZWVuLCBzbyB3ZSBjYW4gY2xlYXIgdGhlIGJhc2UgbGFuZXMuXG4gICAgICB2YXIgX25leHRTdGF0ZTIgPSB7XG4gICAgICAgIGJhc2VMYW5lczogTm9MYW5lcyxcbiAgICAgICAgY2FjaGVQb29sOiBudWxsLFxuICAgICAgICB0cmFuc2l0aW9uczogbnVsbFxuICAgICAgfTtcbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBfbmV4dFN0YXRlMjsgLy8gUHVzaCB0aGUgbGFuZXMgdGhhdCB3ZXJlIHNraXBwZWQgd2hlbiB3ZSBiYWlsZWQgb3V0LlxuXG4gICAgICB2YXIgc3VidHJlZVJlbmRlckxhbmVzID0gcHJldlN0YXRlICE9PSBudWxsID8gcHJldlN0YXRlLmJhc2VMYW5lcyA6IHJlbmRlckxhbmVzO1xuXG4gICAgICBwdXNoUmVuZGVyTGFuZXMod29ya0luUHJvZ3Jlc3MsIHN1YnRyZWVSZW5kZXJMYW5lcyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFJlbmRlcmluZyBhIHZpc2libGUgdHJlZS5cbiAgICB2YXIgX3N1YnRyZWVSZW5kZXJMYW5lcztcblxuICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFdlJ3JlIGdvaW5nIGZyb20gaGlkZGVuIC0+IHZpc2libGUuXG4gICAgICBfc3VidHJlZVJlbmRlckxhbmVzID0gbWVyZ2VMYW5lcyhwcmV2U3RhdGUuYmFzZUxhbmVzLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSB3ZXJlbid0IHByZXZpb3VzbHkgaGlkZGVuLCBhbmQgd2Ugc3RpbGwgYXJlbid0LCBzbyB0aGVyZSdzIG5vdGhpbmdcbiAgICAgIC8vIHNwZWNpYWwgdG8gZG8uIE5lZWQgdG8gcHVzaCB0byB0aGUgc3RhY2sgcmVnYXJkbGVzcywgdGhvdWdoLCB0byBhdm9pZFxuICAgICAgLy8gYSBwdXNoL3BvcCBtaXNhbGlnbm1lbnQuXG4gICAgICBfc3VidHJlZVJlbmRlckxhbmVzID0gcmVuZGVyTGFuZXM7XG4gICAgfVxuXG4gICAgcHVzaFJlbmRlckxhbmVzKHdvcmtJblByb2dyZXNzLCBfc3VidHJlZVJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufSAvLyBOb3RlOiBUaGVzZSBoYXBwZW4gdG8gaGF2ZSBpZGVudGljYWwgYmVnaW4gcGhhc2VzLCBmb3Igbm93LiBXZSBzaG91bGRuJ3QgaG9sZFxuXG5mdW5jdGlvbiB1cGRhdGVGcmFnbWVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG5leHRDaGlsZHJlbiA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZU1vZGUoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHMuY2hpbGRyZW47XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVQcm9maWxlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcblxuICAgIHtcbiAgICAgIC8vIFJlc2V0IGVmZmVjdCBkdXJhdGlvbnMgZm9yIHRoZSBuZXh0IGV2ZW50dWFsIGVmZmVjdCBwaGFzZS5cbiAgICAgIC8vIFRoZXNlIGFyZSByZXNldCBkdXJpbmcgcmVuZGVyIHRvIGFsbG93IHRoZSBEZXZUb29scyBjb21taXQgaG9vayBhIGNoYW5jZSB0byByZWFkIHRoZW0sXG4gICAgICB2YXIgc3RhdGVOb2RlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgICAgc3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uID0gMDtcbiAgICAgIHN0YXRlTm9kZS5wYXNzaXZlRWZmZWN0RHVyYXRpb24gPSAwO1xuICAgIH1cbiAgfVxuXG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiBtYXJrUmVmKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIHZhciByZWYgPSB3b3JrSW5Qcm9ncmVzcy5yZWY7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwgJiYgcmVmICE9PSBudWxsIHx8IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5yZWYgIT09IHJlZikge1xuICAgIC8vIFNjaGVkdWxlIGEgUmVmIGVmZmVjdFxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZjtcblxuICAgIHtcbiAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZlN0YXRpYztcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcykge1xuICB7XG4gICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAvLyBMYXp5IGNvbXBvbmVudCBwcm9wcyBjYW4ndCBiZSB2YWxpZGF0ZWQgaW4gY3JlYXRlRWxlbWVudFxuICAgICAgLy8gYmVjYXVzZSB0aGV5J3JlIG9ubHkgZ3VhcmFudGVlZCB0byBiZSByZXNvbHZlZCBoZXJlLlxuICAgICAgdmFyIGlubmVyUHJvcFR5cGVzID0gQ29tcG9uZW50LnByb3BUeXBlcztcblxuICAgICAgaWYgKGlubmVyUHJvcFR5cGVzKSB7XG4gICAgICAgIGNoZWNrUHJvcFR5cGVzKGlubmVyUHJvcFR5cGVzLCBuZXh0UHJvcHMsIC8vIFJlc29sdmVkIHByb3BzXG4gICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBjb250ZXh0O1xuXG4gIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHRydWUpO1xuICAgIGNvbnRleHQgPSBnZXRNYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCB1bm1hc2tlZENvbnRleHQpO1xuICB9XG5cbiAgdmFyIG5leHRDaGlsZHJlbjtcbiAgdmFyIGhhc0lkO1xuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cblxuICB7XG4gICAgUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50ID0gd29ya0luUHJvZ3Jlc3M7XG4gICAgc2V0SXNSZW5kZXJpbmcodHJ1ZSk7XG4gICAgbmV4dENoaWxkcmVuID0gcmVuZGVyV2l0aEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgY29udGV4dCwgcmVuZGVyTGFuZXMpO1xuICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBuZXh0Q2hpbGRyZW4gPSByZW5kZXJXaXRoSG9va3MoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCBjb250ZXh0LCByZW5kZXJMYW5lcyk7XG4gICAgICAgIGhhc0lkID0gY2hlY2tEaWRSZW5kZXJJZEhvb2soKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRJc1JlbmRlcmluZyhmYWxzZSk7XG4gIH1cblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0b3BwZWQoKTtcbiAgfVxuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsICYmICFkaWRSZWNlaXZlVXBkYXRlKSB7XG4gICAgYmFpbG91dEhvb2tzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgcmV0dXJuIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIGlmIChnZXRJc0h5ZHJhdGluZygpICYmIGhhc0lkKSB7XG4gICAgcHVzaE1hdGVyaWFsaXplZFRyZWVJZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNsYXNzQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIC8vIFRoaXMgaXMgdXNlZCBieSBEZXZUb29scyB0byBmb3JjZSBhIGJvdW5kYXJ5IHRvIGVycm9yLlxuICAgIHN3aXRjaCAoc2hvdWxkRXJyb3Iod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICBjYXNlIGZhbHNlOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIF9pbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgICAgICAgICB2YXIgY3RvciA9IHdvcmtJblByb2dyZXNzLnR5cGU7IC8vIFRPRE8gVGhpcyB3YXkgb2YgcmVzZXR0aW5nIHRoZSBlcnJvciBib3VuZGFyeSBzdGF0ZSBpcyBhIGhhY2suXG4gICAgICAgICAgLy8gSXMgdGhlcmUgYSBiZXR0ZXIgd2F5IHRvIGRvIHRoaXM/XG5cbiAgICAgICAgICB2YXIgdGVtcEluc3RhbmNlID0gbmV3IGN0b3Iod29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRQcm9wcywgX2luc3RhbmNlLmNvbnRleHQpO1xuICAgICAgICAgIHZhciBzdGF0ZSA9IHRlbXBJbnN0YW5jZS5zdGF0ZTtcblxuICAgICAgICAgIF9pbnN0YW5jZS51cGRhdGVyLmVucXVldWVTZXRTdGF0ZShfaW5zdGFuY2UsIHN0YXRlLCBudWxsKTtcblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgdHJ1ZTpcbiAgICAgICAge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU2hvdWxkQ2FwdHVyZTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXNcblxuICAgICAgICAgIHZhciBlcnJvciQxID0gbmV3IEVycm9yKCdTaW11bGF0ZWQgZXJyb3IgY29taW5nIGZyb20gRGV2VG9vbHMnKTtcbiAgICAgICAgICB2YXIgbGFuZSA9IHBpY2tBcmJpdHJhcnlMYW5lKHJlbmRlckxhbmVzKTtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMsIGxhbmUpOyAvLyBTY2hlZHVsZSB0aGUgZXJyb3IgYm91bmRhcnkgdG8gcmUtcmVuZGVyIHVzaW5nIHVwZGF0ZWQgc3RhdGVcblxuICAgICAgICAgIHZhciB1cGRhdGUgPSBjcmVhdGVDbGFzc0Vycm9yVXBkYXRlKHdvcmtJblByb2dyZXNzLCBjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcihlcnJvciQxLCB3b3JrSW5Qcm9ncmVzcyksIGxhbmUpO1xuICAgICAgICAgIGVucXVldWVDYXB0dXJlZFVwZGF0ZSh3b3JrSW5Qcm9ncmVzcywgdXBkYXRlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy50eXBlICE9PSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSkge1xuICAgICAgLy8gTGF6eSBjb21wb25lbnQgcHJvcHMgY2FuJ3QgYmUgdmFsaWRhdGVkIGluIGNyZWF0ZUVsZW1lbnRcbiAgICAgIC8vIGJlY2F1c2UgdGhleSdyZSBvbmx5IGd1YXJhbnRlZWQgdG8gYmUgcmVzb2x2ZWQgaGVyZS5cbiAgICAgIHZhciBpbm5lclByb3BUeXBlcyA9IENvbXBvbmVudC5wcm9wVHlwZXM7XG5cbiAgICAgIGlmIChpbm5lclByb3BUeXBlcykge1xuICAgICAgICBjaGVja1Byb3BUeXBlcyhpbm5lclByb3BUeXBlcywgbmV4dFByb3BzLCAvLyBSZXNvbHZlZCBwcm9wc1xuICAgICAgICAncHJvcCcsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH0gLy8gUHVzaCBjb250ZXh0IHByb3ZpZGVycyBlYXJseSB0byBwcmV2ZW50IGNvbnRleHQgc3RhY2sgbWlzbWF0Y2hlcy5cbiAgLy8gRHVyaW5nIG1vdW50aW5nIHdlIGRvbid0IGtub3cgdGhlIGNoaWxkIGNvbnRleHQgeWV0IGFzIHRoZSBpbnN0YW5jZSBkb2Vzbid0IGV4aXN0LlxuICAvLyBXZSB3aWxsIGludmFsaWRhdGUgdGhlIGNoaWxkIGNvbnRleHQgaW4gZmluaXNoQ2xhc3NDb21wb25lbnQoKSByaWdodCBhZnRlciByZW5kZXJpbmcuXG5cblxuICB2YXIgaGFzQ29udGV4dDtcblxuICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgIGhhc0NvbnRleHQgPSB0cnVlO1xuICAgIHB1c2hDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MpO1xuICB9IGVsc2Uge1xuICAgIGhhc0NvbnRleHQgPSBmYWxzZTtcbiAgfVxuXG4gIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gIHZhciBpbnN0YW5jZSA9IHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZTtcbiAgdmFyIHNob3VsZFVwZGF0ZTtcblxuICBpZiAoaW5zdGFuY2UgPT09IG51bGwpIHtcbiAgICByZXNldFN1c3BlbmRlZEN1cnJlbnRPbk1vdW50SW5MZWdhY3lNb2RlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTsgLy8gSW4gdGhlIGluaXRpYWwgcGFzcyB3ZSBtaWdodCBuZWVkIHRvIGNvbnN0cnVjdCB0aGUgaW5zdGFuY2UuXG5cbiAgICBjb25zdHJ1Y3RDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcyk7XG4gICAgbW91bnRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgIHNob3VsZFVwZGF0ZSA9IHRydWU7XG4gIH0gZWxzZSBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgIC8vIEluIGEgcmVzdW1lLCB3ZSdsbCBhbHJlYWR5IGhhdmUgYW4gaW5zdGFuY2Ugd2UgY2FuIHJldXNlLlxuICAgIHNob3VsZFVwZGF0ZSA9IHJlc3VtZU1vdW50Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICBzaG91bGRVcGRhdGUgPSB1cGRhdGVDbGFzc0luc3RhbmNlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgdmFyIG5leHRVbml0T2ZXb3JrID0gZmluaXNoQ2xhc3NDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgc2hvdWxkVXBkYXRlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcyk7XG5cbiAge1xuICAgIHZhciBpbnN0ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuXG4gICAgaWYgKHNob3VsZFVwZGF0ZSAmJiBpbnN0LnByb3BzICE9PSBuZXh0UHJvcHMpIHtcbiAgICAgIGlmICghZGlkV2FybkFib3V0UmVhc3NpZ25pbmdQcm9wcykge1xuICAgICAgICBlcnJvcignSXQgbG9va3MgbGlrZSAlcyBpcyByZWFzc2lnbmluZyBpdHMgb3duIGB0aGlzLnByb3BzYCB3aGlsZSByZW5kZXJpbmcuICcgKyAnVGhpcyBpcyBub3Qgc3VwcG9ydGVkIGFuZCBjYW4gbGVhZCB0byBjb25mdXNpbmcgYnVncy4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKHdvcmtJblByb2dyZXNzKSB8fCAnYSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgZGlkV2FybkFib3V0UmVhc3NpZ25pbmdQcm9wcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHRVbml0T2ZXb3JrO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hDbGFzc0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBzaG91bGRVcGRhdGUsIGhhc0NvbnRleHQsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFJlZnMgc2hvdWxkIHVwZGF0ZSBldmVuIGlmIHNob3VsZENvbXBvbmVudFVwZGF0ZSByZXR1cm5zIGZhbHNlXG4gIG1hcmtSZWYoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgZGlkQ2FwdHVyZUVycm9yID0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3M7XG5cbiAgaWYgKCFzaG91bGRVcGRhdGUgJiYgIWRpZENhcHR1cmVFcnJvcikge1xuICAgIC8vIENvbnRleHQgcHJvdmlkZXJzIHNob3VsZCBkZWZlciB0byBzQ1UgZm9yIHJlbmRlcmluZ1xuICAgIGlmIChoYXNDb250ZXh0KSB7XG4gICAgICBpbnZhbGlkYXRlQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIGZhbHNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlOyAvLyBSZXJlbmRlclxuXG4gIFJlYWN0Q3VycmVudE93bmVyJDEuY3VycmVudCA9IHdvcmtJblByb2dyZXNzO1xuICB2YXIgbmV4dENoaWxkcmVuO1xuXG4gIGlmIChkaWRDYXB0dXJlRXJyb3IgJiYgdHlwZW9mIENvbXBvbmVudC5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBJZiB3ZSBjYXB0dXJlZCBhbiBlcnJvciwgYnV0IGdldERlcml2ZWRTdGF0ZUZyb21FcnJvciBpcyBub3QgZGVmaW5lZCxcbiAgICAvLyB1bm1vdW50IGFsbCB0aGUgY2hpbGRyZW4uIGNvbXBvbmVudERpZENhdGNoIHdpbGwgc2NoZWR1bGUgYW4gdXBkYXRlIHRvXG4gICAgLy8gcmUtcmVuZGVyIGEgZmFsbGJhY2suIFRoaXMgaXMgdGVtcG9yYXJ5IHVudGlsIHdlIG1pZ3JhdGUgZXZlcnlvbmUgdG9cbiAgICAvLyB0aGUgbmV3IEFQSS5cbiAgICAvLyBUT0RPOiBXYXJuIGluIGEgZnV0dXJlIHJlbGVhc2UuXG4gICAgbmV4dENoaWxkcmVuID0gbnVsbDtcblxuICAgIHtcbiAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nKCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHtcbiAgICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdGFydGVkKHdvcmtJblByb2dyZXNzKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBzZXRJc1JlbmRlcmluZyh0cnVlKTtcbiAgICAgIG5leHRDaGlsZHJlbiA9IGluc3RhbmNlLnJlbmRlcigpO1xuXG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaW5zdGFuY2UucmVuZGVyKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHNldElzUmVuZGVyaW5nKGZhbHNlKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RvcHBlZCgpO1xuICAgIH1cbiAgfSAvLyBSZWFjdCBEZXZUb29scyByZWFkcyB0aGlzIGZsYWcuXG5cblxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQZXJmb3JtZWRXb3JrO1xuXG4gIGlmIChjdXJyZW50ICE9PSBudWxsICYmIGRpZENhcHR1cmVFcnJvcikge1xuICAgIC8vIElmIHdlJ3JlIHJlY292ZXJpbmcgZnJvbSBhbiBlcnJvciwgcmVjb25jaWxlIHdpdGhvdXQgcmV1c2luZyBhbnkgb2ZcbiAgICAvLyB0aGUgZXhpc3RpbmcgY2hpbGRyZW4uIENvbmNlcHR1YWxseSwgdGhlIG5vcm1hbCBjaGlsZHJlbiBhbmQgdGhlIGNoaWxkcmVuXG4gICAgLy8gdGhhdCBhcmUgc2hvd24gb24gZXJyb3IgYXJlIHR3byBkaWZmZXJlbnQgc2V0cywgc28gd2Ugc2hvdWxkbid0IHJldXNlXG4gICAgLy8gbm9ybWFsIGNoaWxkcmVuIGV2ZW4gaWYgdGhlaXIgaWRlbnRpdGllcyBtYXRjaC5cbiAgICBmb3JjZVVubW91bnRDdXJyZW50QW5kUmVjb25jaWxlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dENoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIH0gLy8gTWVtb2l6ZSBzdGF0ZSB1c2luZyB0aGUgdmFsdWVzIHdlIGp1c3QgdXNlZCB0byByZW5kZXIuXG4gIC8vIFRPRE86IFJlc3RydWN0dXJlIHNvIHdlIG5ldmVyIHJlYWQgdmFsdWVzIGZyb20gdGhlIGluc3RhbmNlLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IGluc3RhbmNlLnN0YXRlOyAvLyBUaGUgY29udGV4dCBtaWdodCBoYXZlIGNoYW5nZWQgc28gd2UgbmVlZCB0byByZWNhbGN1bGF0ZSBpdC5cblxuICBpZiAoaGFzQ29udGV4dCkge1xuICAgIGludmFsaWRhdGVDb250ZXh0UHJvdmlkZXIod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgdHJ1ZSk7XG4gIH1cblxuICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG59XG5cbmZ1bmN0aW9uIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpIHtcbiAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAgaWYgKHJvb3QucGVuZGluZ0NvbnRleHQpIHtcbiAgICBwdXNoVG9wTGV2ZWxDb250ZXh0T2JqZWN0KHdvcmtJblByb2dyZXNzLCByb290LnBlbmRpbmdDb250ZXh0LCByb290LnBlbmRpbmdDb250ZXh0ICE9PSByb290LmNvbnRleHQpO1xuICB9IGVsc2UgaWYgKHJvb3QuY29udGV4dCkge1xuICAgIC8vIFNob3VsZCBhbHdheXMgYmUgc2V0XG4gICAgcHVzaFRvcExldmVsQ29udGV4dE9iamVjdCh3b3JrSW5Qcm9ncmVzcywgcm9vdC5jb250ZXh0LCBmYWxzZSk7XG4gIH1cblxuICBwdXNoSG9zdENvbnRhaW5lcih3b3JrSW5Qcm9ncmVzcywgcm9vdC5jb250YWluZXJJbmZvKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlSG9zdFJvb3QoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgaGF2ZSBhIGN1cnJlbnQgZmliZXIuIFRoaXMgaXMgYSBidWcgaW4gUmVhY3QuJyk7XG4gIH1cblxuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJldlN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgdmFyIHByZXZDaGlsZHJlbiA9IHByZXZTdGF0ZS5lbGVtZW50O1xuICBjbG9uZVVwZGF0ZVF1ZXVlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgcHJvY2Vzc1VwZGF0ZVF1ZXVlKHdvcmtJblByb2dyZXNzLCBuZXh0UHJvcHMsIG51bGwsIHJlbmRlckxhbmVzKTtcbiAgdmFyIG5leHRTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG4gIHZhciByb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAvLyBiZWluZyBjYWxsZWQgXCJlbGVtZW50XCIuXG5cblxuICB2YXIgbmV4dENoaWxkcmVuID0gbmV4dFN0YXRlLmVsZW1lbnQ7XG5cbiAgaWYgKCBwcmV2U3RhdGUuaXNEZWh5ZHJhdGVkKSB7XG4gICAgLy8gVGhpcyBpcyBhIGh5ZHJhdGlvbiByb290IHdob3NlIHNoZWxsIGhhcyBub3QgeWV0IGh5ZHJhdGVkLiBXZSBzaG91bGRcbiAgICAvLyBhdHRlbXB0IHRvIGh5ZHJhdGUuXG4gICAgLy8gRmxpcCBpc0RlaHlkcmF0ZWQgdG8gZmFsc2UgdG8gaW5kaWNhdGUgdGhhdCB3aGVuIHRoaXMgcmVuZGVyXG4gICAgLy8gZmluaXNoZXMsIHRoZSByb290IHdpbGwgbm8gbG9uZ2VyIGJlIGRlaHlkcmF0ZWQuXG4gICAgdmFyIG92ZXJyaWRlU3RhdGUgPSB7XG4gICAgICBlbGVtZW50OiBuZXh0Q2hpbGRyZW4sXG4gICAgICBpc0RlaHlkcmF0ZWQ6IGZhbHNlLFxuICAgICAgY2FjaGU6IG5leHRTdGF0ZS5jYWNoZSxcbiAgICAgIHBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXM6IG5leHRTdGF0ZS5wZW5kaW5nU3VzcGVuc2VCb3VuZGFyaWVzLFxuICAgICAgdHJhbnNpdGlvbnM6IG5leHRTdGF0ZS50cmFuc2l0aW9uc1xuICAgIH07XG4gICAgdmFyIHVwZGF0ZVF1ZXVlID0gd29ya0luUHJvZ3Jlc3MudXBkYXRlUXVldWU7IC8vIGBiYXNlU3RhdGVgIGNhbiBhbHdheXMgYmUgdGhlIGxhc3Qgc3RhdGUgYmVjYXVzZSB0aGUgcm9vdCBkb2Vzbid0XG4gICAgLy8gaGF2ZSByZWR1Y2VyIGZ1bmN0aW9ucyBzbyBpdCBkb2Vzbid0IG5lZWQgcmViYXNpbmcuXG5cbiAgICB1cGRhdGVRdWV1ZS5iYXNlU3RhdGUgPSBvdmVycmlkZVN0YXRlO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBvdmVycmlkZVN0YXRlO1xuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRm9yY2VDbGllbnRSZW5kZXIpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBlcnJvcmVkIGR1cmluZyBhIHByZXZpb3VzIGF0dGVtcHQgdG8gaHlkcmF0ZSB0aGUgc2hlbGwsIHNvIHdlXG4gICAgICAvLyBmb3JjZWQgYSBjbGllbnQgcmVuZGVyLlxuICAgICAgdmFyIHJlY292ZXJhYmxlRXJyb3IgPSBjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcihuZXcgRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBoeWRyYXRpbmcuIEJlY2F1c2UgdGhlIGVycm9yIGhhcHBlbmVkIG91dHNpZGUgJyArICdvZiBhIFN1c3BlbnNlIGJvdW5kYXJ5LCB0aGUgZW50aXJlIHJvb3Qgd2lsbCBzd2l0Y2ggdG8gJyArICdjbGllbnQgcmVuZGVyaW5nLicpLCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbW91bnRIb3N0Um9vdFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMsIHJlY292ZXJhYmxlRXJyb3IpO1xuICAgIH0gZWxzZSBpZiAobmV4dENoaWxkcmVuICE9PSBwcmV2Q2hpbGRyZW4pIHtcbiAgICAgIHZhciBfcmVjb3ZlcmFibGVFcnJvciA9IGNyZWF0ZUNhcHR1cmVkVmFsdWVBdEZpYmVyKG5ldyBFcnJvcignVGhpcyByb290IHJlY2VpdmVkIGFuIGVhcmx5IHVwZGF0ZSwgYmVmb3JlIGFueXRoaW5nIHdhcyBhYmxlICcgKyAnaHlkcmF0ZS4gU3dpdGNoZWQgdGhlIGVudGlyZSByb290IHRvIGNsaWVudCByZW5kZXJpbmcuJyksIHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgcmV0dXJuIG1vdW50SG9zdFJvb3RXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzLCBfcmVjb3ZlcmFibGVFcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZSBvdXRlcm1vc3Qgc2hlbGwgaGFzIG5vdCBoeWRyYXRlZCB5ZXQuIFN0YXJ0IGh5ZHJhdGluZy5cbiAgICAgIGVudGVySHlkcmF0aW9uU3RhdGUod29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICB2YXIgY2hpbGQgPSBtb3VudENoaWxkRmliZXJzKHdvcmtJblByb2dyZXNzLCBudWxsLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gY2hpbGQ7XG4gICAgICB2YXIgbm9kZSA9IGNoaWxkO1xuXG4gICAgICB3aGlsZSAobm9kZSkge1xuICAgICAgICAvLyBNYXJrIGVhY2ggY2hpbGQgYXMgaHlkcmF0aW5nLiBUaGlzIGlzIGEgZmFzdCBwYXRoIHRvIGtub3cgd2hldGhlciB0aGlzXG4gICAgICAgIC8vIHRyZWUgaXMgcGFydCBvZiBhIGh5ZHJhdGluZyB0cmVlLiBUaGlzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIGlmIGEgY2hpbGRcbiAgICAgICAgLy8gbm9kZSBoYXMgZnVsbHkgbW91bnRlZCB5ZXQsIGFuZCBmb3Igc2NoZWR1bGluZyBldmVudCByZXBsYXlpbmcuXG4gICAgICAgIC8vIENvbmNlcHR1YWxseSB0aGlzIGlzIHNpbWlsYXIgdG8gUGxhY2VtZW50IGluIHRoYXQgYSBuZXcgc3VidHJlZSBpc1xuICAgICAgICAvLyBpbnNlcnRlZCBpbnRvIHRoZSBSZWFjdCB0cmVlIGhlcmUuIEl0IGp1c3QgaGFwcGVucyB0byBub3QgbmVlZCBET01cbiAgICAgICAgLy8gbXV0YXRpb25zIGJlY2F1c2UgaXQgYWxyZWFkeSBleGlzdHMuXG4gICAgICAgIG5vZGUuZmxhZ3MgPSBub2RlLmZsYWdzICYgflBsYWNlbWVudCB8IEh5ZHJhdGluZztcbiAgICAgICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gUm9vdCBpcyBub3QgZGVoeWRyYXRlZC4gRWl0aGVyIHRoaXMgaXMgYSBjbGllbnQtb25seSByb290LCBvciBpdFxuICAgIC8vIGFscmVhZHkgaHlkcmF0ZWQuXG4gICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuXG4gICAgaWYgKG5leHRDaGlsZHJlbiA9PT0gcHJldkNoaWxkcmVuKSB7XG4gICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgIH1cblxuICAgIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gbW91bnRIb3N0Um9vdFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMsIHJlY292ZXJhYmxlRXJyb3IpIHtcbiAgLy8gUmV2ZXJ0IHRvIGNsaWVudCByZW5kZXJpbmcuXG4gIHJlc2V0SHlkcmF0aW9uU3RhdGUoKTtcbiAgcXVldWVIeWRyYXRpb25FcnJvcihyZWNvdmVyYWJsZUVycm9yKTtcbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRm9yY2VDbGllbnRSZW5kZXI7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVIb3N0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICBwdXNoSG9zdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgdHJ5VG9DbGFpbU5leHRIeWRyYXRhYmxlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJldlByb3BzID0gY3VycmVudCAhPT0gbnVsbCA/IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyA6IG51bGw7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSBuZXh0UHJvcHMuY2hpbGRyZW47XG4gIHZhciBpc0RpcmVjdFRleHRDaGlsZCA9IHNob3VsZFNldFRleHRDb250ZW50KHR5cGUsIG5leHRQcm9wcyk7XG5cbiAgaWYgKGlzRGlyZWN0VGV4dENoaWxkKSB7XG4gICAgLy8gV2Ugc3BlY2lhbCBjYXNlIGEgZGlyZWN0IHRleHQgY2hpbGQgb2YgYSBob3N0IG5vZGUuIFRoaXMgaXMgYSBjb21tb25cbiAgICAvLyBjYXNlLiBXZSB3b24ndCBoYW5kbGUgaXQgYXMgYSByZWlmaWVkIGNoaWxkLiBXZSB3aWxsIGluc3RlYWQgaGFuZGxlXG4gICAgLy8gdGhpcyBpbiB0aGUgaG9zdCBlbnZpcm9ubWVudCB0aGF0IGFsc28gaGFzIGFjY2VzcyB0byB0aGlzIHByb3AuIFRoYXRcbiAgICAvLyBhdm9pZHMgYWxsb2NhdGluZyBhbm90aGVyIEhvc3RUZXh0IGZpYmVyIGFuZCB0cmF2ZXJzaW5nIGl0LlxuICAgIG5leHRDaGlsZHJlbiA9IG51bGw7XG4gIH0gZWxzZSBpZiAocHJldlByb3BzICE9PSBudWxsICYmIHNob3VsZFNldFRleHRDb250ZW50KHR5cGUsIHByZXZQcm9wcykpIHtcbiAgICAvLyBJZiB3ZSdyZSBzd2l0Y2hpbmcgZnJvbSBhIGRpcmVjdCB0ZXh0IGNoaWxkIHRvIGEgbm9ybWFsIGNoaWxkLCBvciB0b1xuICAgIC8vIGVtcHR5LCB3ZSBuZWVkIHRvIHNjaGVkdWxlIHRoZSB0ZXh0IGNvbnRlbnQgdG8gYmUgcmVzZXQuXG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gQ29udGVudFJlc2V0O1xuICB9XG5cbiAgbWFya1JlZihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcyk7XG4gIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVIb3N0VGV4dChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcykge1xuICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgIHRyeVRvQ2xhaW1OZXh0SHlkcmF0YWJsZUluc3RhbmNlKHdvcmtJblByb2dyZXNzKTtcbiAgfSAvLyBOb3RoaW5nIHRvIGRvIGhlcmUuIFRoaXMgaXMgdGVybWluYWwuIFdlJ2xsIGRvIHRoZSBjb21wbGV0aW9uIHN0ZXBcbiAgLy8gaW1tZWRpYXRlbHkgYWZ0ZXIuXG5cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gbW91bnRMYXp5Q29tcG9uZW50KF9jdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgZWxlbWVudFR5cGUsIHJlbmRlckxhbmVzKSB7XG4gIHJlc2V0U3VzcGVuZGVkQ3VycmVudE9uTW91bnRJbkxlZ2FjeU1vZGUoX2N1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgdmFyIHByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgbGF6eUNvbXBvbmVudCA9IGVsZW1lbnRUeXBlO1xuICB2YXIgcGF5bG9hZCA9IGxhenlDb21wb25lbnQuX3BheWxvYWQ7XG4gIHZhciBpbml0ID0gbGF6eUNvbXBvbmVudC5faW5pdDtcbiAgdmFyIENvbXBvbmVudCA9IGluaXQocGF5bG9hZCk7IC8vIFN0b3JlIHRoZSB1bndyYXBwZWQgY29tcG9uZW50IGluIHRoZSB0eXBlLlxuXG4gIHdvcmtJblByb2dyZXNzLnR5cGUgPSBDb21wb25lbnQ7XG4gIHZhciByZXNvbHZlZFRhZyA9IHdvcmtJblByb2dyZXNzLnRhZyA9IHJlc29sdmVMYXp5Q29tcG9uZW50VGFnKENvbXBvbmVudCk7XG4gIHZhciByZXNvbHZlZFByb3BzID0gcmVzb2x2ZURlZmF1bHRQcm9wcyhDb21wb25lbnQsIHByb3BzKTtcbiAgdmFyIGNoaWxkO1xuXG4gIHN3aXRjaCAocmVzb2x2ZWRUYWcpIHtcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgdmFsaWRhdGVGdW5jdGlvbkNvbXBvbmVudEluRGV2KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQpO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSBDb21wb25lbnQgPSByZXNvbHZlRnVuY3Rpb25Gb3JIb3RSZWxvYWRpbmcoQ29tcG9uZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVzb2x2ZWRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICB9XG5cbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IENvbXBvbmVudCA9IHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyhDb21wb25lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSB1cGRhdGVDbGFzc0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCByZXNvbHZlZFByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgIHJldHVybiBjaGlsZDtcbiAgICAgIH1cblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHtcbiAgICAgICAge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSBDb21wb25lbnQgPSByZXNvbHZlRm9yd2FyZFJlZkZvckhvdFJlbG9hZGluZyhDb21wb25lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY2hpbGQgPSB1cGRhdGVGb3J3YXJkUmVmKG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHJlc29sdmVkUHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuXG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKHdvcmtJblByb2dyZXNzLnR5cGUgIT09IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlKSB7XG4gICAgICAgICAgICB2YXIgb3V0ZXJQcm9wVHlwZXMgPSBDb21wb25lbnQucHJvcFR5cGVzO1xuXG4gICAgICAgICAgICBpZiAob3V0ZXJQcm9wVHlwZXMpIHtcbiAgICAgICAgICAgICAgY2hlY2tQcm9wVHlwZXMob3V0ZXJQcm9wVHlwZXMsIHJlc29sdmVkUHJvcHMsIC8vIFJlc29sdmVkIGZvciBvdXRlciBvbmx5XG4gICAgICAgICAgICAgICdwcm9wJywgZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNoaWxkID0gdXBkYXRlTWVtb0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCByZXNvbHZlRGVmYXVsdFByb3BzKENvbXBvbmVudC50eXBlLCByZXNvbHZlZFByb3BzKSwgLy8gVGhlIGlubmVyIHR5cGUgY2FuIGhhdmUgZGVmYXVsdHMgdG9vXG4gICAgICAgIHJlbmRlckxhbmVzKTtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuICB9XG5cbiAgdmFyIGhpbnQgPSAnJztcblxuICB7XG4gICAgaWYgKENvbXBvbmVudCAhPT0gbnVsbCAmJiB0eXBlb2YgQ29tcG9uZW50ID09PSAnb2JqZWN0JyAmJiBDb21wb25lbnQuJCR0eXBlb2YgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgaGludCA9ICcgRGlkIHlvdSB3cmFwIGEgY29tcG9uZW50IGluIFJlYWN0LmxhenkoKSBtb3JlIHRoYW4gb25jZT8nO1xuICAgIH1cbiAgfSAvLyBUaGlzIG1lc3NhZ2UgaW50ZW50aW9uYWxseSBkb2Vzbid0IG1lbnRpb24gRm9yd2FyZFJlZiBvciBNZW1vQ29tcG9uZW50XG4gIC8vIGJlY2F1c2UgdGhlIGZhY3QgdGhhdCBpdCdzIGEgc2VwYXJhdGUgdHlwZSBvZiB3b3JrIGlzIGFuXG4gIC8vIGltcGxlbWVudGF0aW9uIGRldGFpbC5cblxuXG4gIHRocm93IG5ldyBFcnJvcihcIkVsZW1lbnQgdHlwZSBpcyBpbnZhbGlkLiBSZWNlaXZlZCBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0bzogXCIgKyBDb21wb25lbnQgKyBcIi4gXCIgKyAoXCJMYXp5IGVsZW1lbnQgdHlwZSBtdXN0IHJlc29sdmUgdG8gYSBjbGFzcyBvciBmdW5jdGlvbi5cIiArIGhpbnQpKTtcbn1cblxuZnVuY3Rpb24gbW91bnRJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQoX2N1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIG5leHRQcm9wcywgcmVuZGVyTGFuZXMpIHtcbiAgcmVzZXRTdXNwZW5kZWRDdXJyZW50T25Nb3VudEluTGVnYWN5TW9kZShfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpOyAvLyBQcm9tb3RlIHRoZSBmaWJlciB0byBhIGNsYXNzIGFuZCB0cnkgcmVuZGVyaW5nIGFnYWluLlxuXG4gIHdvcmtJblByb2dyZXNzLnRhZyA9IENsYXNzQ29tcG9uZW50OyAvLyBUaGUgcmVzdCBvZiB0aGlzIGZ1bmN0aW9uIGlzIGEgZm9yayBvZiBgdXBkYXRlQ2xhc3NDb21wb25lbnRgXG4gIC8vIFB1c2ggY29udGV4dCBwcm92aWRlcnMgZWFybHkgdG8gcHJldmVudCBjb250ZXh0IHN0YWNrIG1pc21hdGNoZXMuXG4gIC8vIER1cmluZyBtb3VudGluZyB3ZSBkb24ndCBrbm93IHRoZSBjaGlsZCBjb250ZXh0IHlldCBhcyB0aGUgaW5zdGFuY2UgZG9lc24ndCBleGlzdC5cbiAgLy8gV2Ugd2lsbCBpbnZhbGlkYXRlIHRoZSBjaGlsZCBjb250ZXh0IGluIGZpbmlzaENsYXNzQ29tcG9uZW50KCkgcmlnaHQgYWZ0ZXIgcmVuZGVyaW5nLlxuXG4gIHZhciBoYXNDb250ZXh0O1xuXG4gIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgaGFzQ29udGV4dCA9IHRydWU7XG4gICAgcHVzaENvbnRleHRQcm92aWRlcih3b3JrSW5Qcm9ncmVzcyk7XG4gIH0gZWxzZSB7XG4gICAgaGFzQ29udGV4dCA9IGZhbHNlO1xuICB9XG5cbiAgcHJlcGFyZVRvUmVhZENvbnRleHQod29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgY29uc3RydWN0Q2xhc3NJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCBuZXh0UHJvcHMpO1xuICBtb3VudENsYXNzSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgbmV4dFByb3BzLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiBmaW5pc2hDbGFzc0NvbXBvbmVudChudWxsLCB3b3JrSW5Qcm9ncmVzcywgQ29tcG9uZW50LCB0cnVlLCBoYXNDb250ZXh0LCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIG1vdW50SW5kZXRlcm1pbmF0ZUNvbXBvbmVudChfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVuZGVyTGFuZXMpIHtcbiAgcmVzZXRTdXNwZW5kZWRDdXJyZW50T25Nb3VudEluTGVnYWN5TW9kZShfY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICB2YXIgcHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBjb250ZXh0O1xuXG4gIHtcbiAgICB2YXIgdW5tYXNrZWRDb250ZXh0ID0gZ2V0VW5tYXNrZWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIGZhbHNlKTtcbiAgICBjb250ZXh0ID0gZ2V0TWFza2VkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgdW5tYXNrZWRDb250ZXh0KTtcbiAgfVxuXG4gIHByZXBhcmVUb1JlYWRDb250ZXh0KHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gIHZhciB2YWx1ZTtcbiAgdmFyIGhhc0lkO1xuXG4gIHtcbiAgICBtYXJrQ29tcG9uZW50UmVuZGVyU3RhcnRlZCh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cblxuICB7XG4gICAgaWYgKENvbXBvbmVudC5wcm90b3R5cGUgJiYgdHlwZW9mIENvbXBvbmVudC5wcm90b3R5cGUucmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgY29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRCYWRDbGFzc1tjb21wb25lbnROYW1lXSkge1xuICAgICAgICBlcnJvcihcIlRoZSA8JXMgLz4gY29tcG9uZW50IGFwcGVhcnMgdG8gaGF2ZSBhIHJlbmRlciBtZXRob2QsIGJ1dCBkb2Vzbid0IGV4dGVuZCBSZWFjdC5Db21wb25lbnQuIFwiICsgJ1RoaXMgaXMgbGlrZWx5IHRvIGNhdXNlIGVycm9ycy4gQ2hhbmdlICVzIHRvIGV4dGVuZCBSZWFjdC5Db21wb25lbnQgaW5zdGVhZC4nLCBjb21wb25lbnROYW1lLCBjb21wb25lbnROYW1lKTtcblxuICAgICAgICBkaWRXYXJuQWJvdXRCYWRDbGFzc1tjb21wb25lbnROYW1lXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5yZWNvcmRMZWdhY3lDb250ZXh0V2FybmluZyh3b3JrSW5Qcm9ncmVzcywgbnVsbCk7XG4gICAgfVxuXG4gICAgc2V0SXNSZW5kZXJpbmcodHJ1ZSk7XG4gICAgUmVhY3RDdXJyZW50T3duZXIkMS5jdXJyZW50ID0gd29ya0luUHJvZ3Jlc3M7XG4gICAgdmFsdWUgPSByZW5kZXJXaXRoSG9va3MobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcHJvcHMsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICBoYXNJZCA9IGNoZWNrRGlkUmVuZGVySWRIb29rKCk7XG4gICAgc2V0SXNSZW5kZXJpbmcoZmFsc2UpO1xuICB9XG5cbiAge1xuICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcblxuICB7XG4gICAgLy8gU3VwcG9ydCBmb3IgbW9kdWxlIGNvbXBvbmVudHMgaXMgZGVwcmVjYXRlZCBhbmQgaXMgcmVtb3ZlZCBiZWhpbmQgYSBmbGFnLlxuICAgIC8vIFdoZXRoZXIgb3Igbm90IGl0IHdvdWxkIGNyYXNoIGxhdGVyLCB3ZSB3YW50IHRvIHNob3cgYSBnb29kIG1lc3NhZ2UgaW4gREVWIGZpcnN0LlxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZS5yZW5kZXIgPT09ICdmdW5jdGlvbicgJiYgdmFsdWUuJCR0eXBlb2YgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21UeXBlKENvbXBvbmVudCkgfHwgJ1Vua25vd24nO1xuXG4gICAgICBpZiAoIWRpZFdhcm5BYm91dE1vZHVsZVBhdHRlcm5Db21wb25lbnRbX2NvbXBvbmVudE5hbWVdKSB7XG4gICAgICAgIGVycm9yKCdUaGUgPCVzIC8+IGNvbXBvbmVudCBhcHBlYXJzIHRvIGJlIGEgZnVuY3Rpb24gY29tcG9uZW50IHRoYXQgcmV0dXJucyBhIGNsYXNzIGluc3RhbmNlLiAnICsgJ0NoYW5nZSAlcyB0byBhIGNsYXNzIHRoYXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQgaW5zdGVhZC4gJyArIFwiSWYgeW91IGNhbid0IHVzZSBhIGNsYXNzIHRyeSBhc3NpZ25pbmcgdGhlIHByb3RvdHlwZSBvbiB0aGUgZnVuY3Rpb24gYXMgYSB3b3JrYXJvdW5kLiBcIiArIFwiYCVzLnByb3RvdHlwZSA9IFJlYWN0LkNvbXBvbmVudC5wcm90b3R5cGVgLiBEb24ndCB1c2UgYW4gYXJyb3cgZnVuY3Rpb24gc2luY2UgaXQgXCIgKyAnY2Fubm90IGJlIGNhbGxlZCB3aXRoIGBuZXdgIGJ5IFJlYWN0LicsIF9jb21wb25lbnROYW1lLCBfY29tcG9uZW50TmFtZSwgX2NvbXBvbmVudE5hbWUpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dE1vZHVsZVBhdHRlcm5Db21wb25lbnRbX2NvbXBvbmVudE5hbWVdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoIC8vIFJ1biB0aGVzZSBjaGVja3MgaW4gcHJvZHVjdGlvbiBvbmx5IGlmIHRoZSBmbGFnIGlzIG9mZi5cbiAgLy8gRXZlbnR1YWxseSB3ZSdsbCBkZWxldGUgdGhpcyBicmFuY2ggYWx0b2dldGhlci5cbiAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJyAmJiB2YWx1ZS4kJHR5cGVvZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lMiA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRNb2R1bGVQYXR0ZXJuQ29tcG9uZW50W19jb21wb25lbnROYW1lMl0pIHtcbiAgICAgICAgZXJyb3IoJ1RoZSA8JXMgLz4gY29tcG9uZW50IGFwcGVhcnMgdG8gYmUgYSBmdW5jdGlvbiBjb21wb25lbnQgdGhhdCByZXR1cm5zIGEgY2xhc3MgaW5zdGFuY2UuICcgKyAnQ2hhbmdlICVzIHRvIGEgY2xhc3MgdGhhdCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCBpbnN0ZWFkLiAnICsgXCJJZiB5b3UgY2FuJ3QgdXNlIGEgY2xhc3MgdHJ5IGFzc2lnbmluZyB0aGUgcHJvdG90eXBlIG9uIHRoZSBmdW5jdGlvbiBhcyBhIHdvcmthcm91bmQuIFwiICsgXCJgJXMucHJvdG90eXBlID0gUmVhY3QuQ29tcG9uZW50LnByb3RvdHlwZWAuIERvbid0IHVzZSBhbiBhcnJvdyBmdW5jdGlvbiBzaW5jZSBpdCBcIiArICdjYW5ub3QgYmUgY2FsbGVkIHdpdGggYG5ld2AgYnkgUmVhY3QuJywgX2NvbXBvbmVudE5hbWUyLCBfY29tcG9uZW50TmFtZTIsIF9jb21wb25lbnROYW1lMik7XG5cbiAgICAgICAgZGlkV2FybkFib3V0TW9kdWxlUGF0dGVybkNvbXBvbmVudFtfY29tcG9uZW50TmFtZTJdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9IC8vIFByb2NlZWQgdW5kZXIgdGhlIGFzc3VtcHRpb24gdGhhdCB0aGlzIGlzIGEgY2xhc3MgaW5zdGFuY2VcblxuXG4gICAgd29ya0luUHJvZ3Jlc3MudGFnID0gQ2xhc3NDb21wb25lbnQ7IC8vIFRocm93IG91dCBhbnkgaG9va3MgdGhhdCB3ZXJlIHVzZWQuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IG51bGw7IC8vIFB1c2ggY29udGV4dCBwcm92aWRlcnMgZWFybHkgdG8gcHJldmVudCBjb250ZXh0IHN0YWNrIG1pc21hdGNoZXMuXG4gICAgLy8gRHVyaW5nIG1vdW50aW5nIHdlIGRvbid0IGtub3cgdGhlIGNoaWxkIGNvbnRleHQgeWV0IGFzIHRoZSBpbnN0YW5jZSBkb2Vzbid0IGV4aXN0LlxuICAgIC8vIFdlIHdpbGwgaW52YWxpZGF0ZSB0aGUgY2hpbGQgY29udGV4dCBpbiBmaW5pc2hDbGFzc0NvbXBvbmVudCgpIHJpZ2h0IGFmdGVyIHJlbmRlcmluZy5cblxuICAgIHZhciBoYXNDb250ZXh0ID0gZmFsc2U7XG5cbiAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgaGFzQ29udGV4dCA9IHRydWU7XG4gICAgICBwdXNoQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGFzQ29udGV4dCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSB2YWx1ZS5zdGF0ZSAhPT0gbnVsbCAmJiB2YWx1ZS5zdGF0ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUuc3RhdGUgOiBudWxsO1xuICAgIGluaXRpYWxpemVVcGRhdGVRdWV1ZSh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgYWRvcHRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCB2YWx1ZSk7XG4gICAgbW91bnRDbGFzc0luc3RhbmNlKHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHByb3BzLCByZW5kZXJMYW5lcyk7XG4gICAgcmV0dXJuIGZpbmlzaENsYXNzQ29tcG9uZW50KG51bGwsIHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQsIHRydWUsIGhhc0NvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBQcm9jZWVkIHVuZGVyIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhpcyBpcyBhIGZ1bmN0aW9uIGNvbXBvbmVudFxuICAgIHdvcmtJblByb2dyZXNzLnRhZyA9IEZ1bmN0aW9uQ29tcG9uZW50O1xuXG4gICAge1xuXG4gICAgICBpZiAoIHdvcmtJblByb2dyZXNzLm1vZGUgJiBTdHJpY3RMZWdhY3lNb2RlKSB7XG4gICAgICAgIHNldElzU3RyaWN0TW9kZUZvckRldnRvb2xzKHRydWUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFsdWUgPSByZW5kZXJXaXRoSG9va3MobnVsbCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcHJvcHMsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICAgICAgICBoYXNJZCA9IGNoZWNrRGlkUmVuZGVySWRIb29rKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgc2V0SXNTdHJpY3RNb2RlRm9yRGV2dG9vbHMoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkgJiYgaGFzSWQpIHtcbiAgICAgIHB1c2hNYXRlcmlhbGl6ZWRUcmVlSWQod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIHJlY29uY2lsZUNoaWxkcmVuKG51bGwsIHdvcmtJblByb2dyZXNzLCB2YWx1ZSwgcmVuZGVyTGFuZXMpO1xuXG4gICAge1xuICAgICAgdmFsaWRhdGVGdW5jdGlvbkNvbXBvbmVudEluRGV2KHdvcmtJblByb2dyZXNzLCBDb21wb25lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUZ1bmN0aW9uQ29tcG9uZW50SW5EZXYod29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCkge1xuICB7XG4gICAgaWYgKENvbXBvbmVudCkge1xuICAgICAgaWYgKENvbXBvbmVudC5jaGlsZENvbnRleHRUeXBlcykge1xuICAgICAgICBlcnJvcignJXMoLi4uKTogY2hpbGRDb250ZXh0VHlwZXMgY2Fubm90IGJlIGRlZmluZWQgb24gYSBmdW5jdGlvbiBjb21wb25lbnQuJywgQ29tcG9uZW50LmRpc3BsYXlOYW1lIHx8IENvbXBvbmVudC5uYW1lIHx8ICdDb21wb25lbnQnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3MucmVmICE9PSBudWxsKSB7XG4gICAgICB2YXIgaW5mbyA9ICcnO1xuICAgICAgdmFyIG93bmVyTmFtZSA9IGdldEN1cnJlbnRGaWJlck93bmVyTmFtZUluRGV2T3JOdWxsKCk7XG5cbiAgICAgIGlmIChvd25lck5hbWUpIHtcbiAgICAgICAgaW5mbyArPSAnXFxuXFxuQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBvd25lck5hbWUgKyAnYC4nO1xuICAgICAgfVxuXG4gICAgICB2YXIgd2FybmluZ0tleSA9IG93bmVyTmFtZSB8fCAnJztcbiAgICAgIHZhciBkZWJ1Z1NvdXJjZSA9IHdvcmtJblByb2dyZXNzLl9kZWJ1Z1NvdXJjZTtcblxuICAgICAgaWYgKGRlYnVnU291cmNlKSB7XG4gICAgICAgIHdhcm5pbmdLZXkgPSBkZWJ1Z1NvdXJjZS5maWxlTmFtZSArICc6JyArIGRlYnVnU291cmNlLmxpbmVOdW1iZXI7XG4gICAgICB9XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0RnVuY3Rpb25SZWZzW3dhcm5pbmdLZXldKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dEZ1bmN0aW9uUmVmc1t3YXJuaW5nS2V5XSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ0Z1bmN0aW9uIGNvbXBvbmVudHMgY2Fubm90IGJlIGdpdmVuIHJlZnMuICcgKyAnQXR0ZW1wdHMgdG8gYWNjZXNzIHRoaXMgcmVmIHdpbGwgZmFpbC4gJyArICdEaWQgeW91IG1lYW4gdG8gdXNlIFJlYWN0LmZvcndhcmRSZWYoKT8lcycsIGluZm8pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgQ29tcG9uZW50LmdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lMyA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRHZXREZXJpdmVkU3RhdGVPbkZ1bmN0aW9uQ29tcG9uZW50W19jb21wb25lbnROYW1lM10pIHtcbiAgICAgICAgZXJyb3IoJyVzOiBGdW5jdGlvbiBjb21wb25lbnRzIGRvIG5vdCBzdXBwb3J0IGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcy4nLCBfY29tcG9uZW50TmFtZTMpO1xuXG4gICAgICAgIGRpZFdhcm5BYm91dEdldERlcml2ZWRTdGF0ZU9uRnVuY3Rpb25Db21wb25lbnRbX2NvbXBvbmVudE5hbWUzXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBDb21wb25lbnQuY29udGV4dFR5cGUgPT09ICdvYmplY3QnICYmIENvbXBvbmVudC5jb250ZXh0VHlwZSAhPT0gbnVsbCkge1xuICAgICAgdmFyIF9jb21wb25lbnROYW1lNCA9IGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShDb21wb25lbnQpIHx8ICdVbmtub3duJztcblxuICAgICAgaWYgKCFkaWRXYXJuQWJvdXRDb250ZXh0VHlwZU9uRnVuY3Rpb25Db21wb25lbnRbX2NvbXBvbmVudE5hbWU0XSkge1xuICAgICAgICBlcnJvcignJXM6IEZ1bmN0aW9uIGNvbXBvbmVudHMgZG8gbm90IHN1cHBvcnQgY29udGV4dFR5cGUuJywgX2NvbXBvbmVudE5hbWU0KTtcblxuICAgICAgICBkaWRXYXJuQWJvdXRDb250ZXh0VHlwZU9uRnVuY3Rpb25Db21wb25lbnRbX2NvbXBvbmVudE5hbWU0XSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBTVVNQRU5ERURfTUFSS0VSID0ge1xuICBkZWh5ZHJhdGVkOiBudWxsLFxuICB0cmVlQ29udGV4dDogbnVsbCxcbiAgcmV0cnlMYW5lOiBOb0xhbmVcbn07XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VPZmZzY3JlZW5TdGF0ZShyZW5kZXJMYW5lcykge1xuICByZXR1cm4ge1xuICAgIGJhc2VMYW5lczogcmVuZGVyTGFuZXMsXG4gICAgY2FjaGVQb29sOiBnZXRTdXNwZW5kZWRDYWNoZSgpLFxuICAgIHRyYW5zaXRpb25zOiBudWxsXG4gIH07XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocHJldk9mZnNjcmVlblN0YXRlLCByZW5kZXJMYW5lcykge1xuICB2YXIgY2FjaGVQb29sID0gbnVsbDtcblxuICByZXR1cm4ge1xuICAgIGJhc2VMYW5lczogbWVyZ2VMYW5lcyhwcmV2T2Zmc2NyZWVuU3RhdGUuYmFzZUxhbmVzLCByZW5kZXJMYW5lcyksXG4gICAgY2FjaGVQb29sOiBjYWNoZVBvb2wsXG4gICAgdHJhbnNpdGlvbnM6IHByZXZPZmZzY3JlZW5TdGF0ZS50cmFuc2l0aW9uc1xuICB9O1xufSAvLyBUT0RPOiBQcm9iYWJseSBzaG91bGQgaW5saW5lIHRoaXMgYmFja1xuXG5cbmZ1bmN0aW9uIHNob3VsZFJlbWFpbk9uRmFsbGJhY2soc3VzcGVuc2VDb250ZXh0LCBjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgLy8gSWYgd2UncmUgYWxyZWFkeSBzaG93aW5nIGEgZmFsbGJhY2ssIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB3ZSBuZWVkIHRvXG4gIC8vIHJlbWFpbiBvbiB0aGF0IGZhbGxiYWNrIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgY29udGVudCBoYXMgcmVzb2x2ZWQuXG4gIC8vIEZvciBleGFtcGxlLCBTdXNwZW5zZUxpc3QgY29vcmRpbmF0ZXMgd2hlbiBuZXN0ZWQgY29udGVudCBhcHBlYXJzLlxuICBpZiAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgIHZhciBzdXNwZW5zZVN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuXG4gICAgaWYgKHN1c3BlbnNlU3RhdGUgPT09IG51bGwpIHtcbiAgICAgIC8vIEN1cnJlbnRseSBzaG93aW5nIGNvbnRlbnQuIERvbid0IGhpZGUgaXQsIGV2ZW4gaWYgRm9yY2VTdXNwZW5zZUZhbGxiYWNrXG4gICAgICAvLyBpcyB0cnVlLiBNb3JlIHByZWNpc2UgbmFtZSBtaWdodCBiZSBcIkZvcmNlUmVtYWluU3VzcGVuc2VGYWxsYmFja1wiLlxuICAgICAgLy8gTm90ZTogVGhpcyBpcyBhIGZhY3RvcmluZyBzbWVsbC4gQ2FuJ3QgcmVtYWluIG9uIGEgZmFsbGJhY2sgaWYgdGhlcmUnc1xuICAgICAgLy8gbm8gZmFsbGJhY2sgdG8gcmVtYWluIG9uLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSAvLyBOb3QgY3VycmVudGx5IHNob3dpbmcgY29udGVudC4gQ29uc3VsdCB0aGUgU3VzcGVuc2UgY29udGV4dC5cblxuXG4gIHJldHVybiBoYXNTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spO1xufVxuXG5mdW5jdGlvbiBnZXRSZW1haW5pbmdXb3JrSW5QcmltYXJ5VHJlZShjdXJyZW50LCByZW5kZXJMYW5lcykge1xuICAvLyBUT0RPOiBTaG91bGQgbm90IHJlbW92ZSByZW5kZXIgbGFuZXMgdGhhdCB3ZXJlIHBpbmdlZCBkdXJpbmcgdGhpcyByZW5kZXJcbiAgcmV0dXJuIHJlbW92ZUxhbmVzKGN1cnJlbnQuY2hpbGRMYW5lcywgcmVuZGVyTGFuZXMpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdXNwZW5zZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG5leHRQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wczsgLy8gVGhpcyBpcyB1c2VkIGJ5IERldlRvb2xzIHRvIGZvcmNlIGEgYm91bmRhcnkgdG8gc3VzcGVuZC5cblxuICB7XG4gICAgaWYgKHNob3VsZFN1c3BlbmQod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdXNwZW5zZUNvbnRleHQgPSBzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQ7XG4gIHZhciBzaG93RmFsbGJhY2sgPSBmYWxzZTtcbiAgdmFyIGRpZFN1c3BlbmQgPSAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICBpZiAoZGlkU3VzcGVuZCB8fCBzaG91bGRSZW1haW5PbkZhbGxiYWNrKHN1c3BlbnNlQ29udGV4dCwgY3VycmVudCkpIHtcbiAgICAvLyBTb21ldGhpbmcgaW4gdGhpcyBib3VuZGFyeSdzIHN1YnRyZWUgYWxyZWFkeSBzdXNwZW5kZWQuIFN3aXRjaCB0b1xuICAgIC8vIHJlbmRlcmluZyB0aGUgZmFsbGJhY2sgY2hpbGRyZW4uXG4gICAgc2hvd0ZhbGxiYWNrID0gdHJ1ZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyAmPSB+RGlkQ2FwdHVyZTtcbiAgfSBlbHNlIHtcbiAgICAvLyBBdHRlbXB0aW5nIHRoZSBtYWluIGNvbnRlbnRcbiAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaXMgYSBuZXcgbW91bnQgb3IgdGhpcyBib3VuZGFyeSBpcyBhbHJlYWR5IHNob3dpbmcgYSBmYWxsYmFjayBzdGF0ZS5cbiAgICAgIC8vIE1hcmsgdGhpcyBzdWJ0cmVlIGNvbnRleHQgYXMgaGF2aW5nIGF0IGxlYXN0IG9uZSBpbnZpc2libGUgcGFyZW50IHRoYXQgY291bGRcbiAgICAgIC8vIGhhbmRsZSB0aGUgZmFsbGJhY2sgc3RhdGUuXG4gICAgICAvLyBBdm9pZGVkIGJvdW5kYXJpZXMgYXJlIG5vdCBjb25zaWRlcmVkIHNpbmNlIHRoZXkgY2Fubm90IGhhbmRsZSBwcmVmZXJyZWQgZmFsbGJhY2sgc3RhdGVzLlxuICAgICAge1xuICAgICAgICBzdXNwZW5zZUNvbnRleHQgPSBhZGRTdWJ0cmVlU3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlQ29udGV4dCwgSW52aXNpYmxlUGFyZW50U3VzcGVuc2VDb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdXNwZW5zZUNvbnRleHQgPSBzZXREZWZhdWx0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQpO1xuICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzdXNwZW5zZUNvbnRleHQpOyAvLyBPSywgdGhlIG5leHQgcGFydCBpcyBjb25mdXNpbmcuIFdlJ3JlIGFib3V0IHRvIHJlY29uY2lsZSB0aGUgU3VzcGVuc2VcbiAgLy8gYm91bmRhcnkncyBjaGlsZHJlbi4gVGhpcyBpbnZvbHZlcyBzb21lIGN1c3RvbSByZWNvbmNpbGlhdGlvbiBsb2dpYy4gVHdvXG4gIC8vIG1haW4gcmVhc29ucyB0aGlzIGlzIHNvIGNvbXBsaWNhdGVkLlxuICAvL1xuICAvLyBGaXJzdCwgTGVnYWN5IE1vZGUgaGFzIGRpZmZlcmVudCBzZW1hbnRpY3MgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LiBUaGVcbiAgLy8gcHJpbWFyeSB0cmVlIHdpbGwgY29tbWl0IGluIGFuIGluY29uc2lzdGVudCBzdGF0ZSwgc28gd2hlbiB3ZSBkbyB0aGVcbiAgLy8gc2Vjb25kIHBhc3MgdG8gcmVuZGVyIHRoZSBmYWxsYmFjaywgd2UgZG8gc29tZSBleGNlZWRpbmdseSwgdWgsIGNsZXZlclxuICAvLyBoYWNrcyB0byBtYWtlIHRoYXQgbm90IHRvdGFsbHkgYnJlYWsuIExpa2UgdHJhbnNmZXJyaW5nIGVmZmVjdHMgYW5kXG4gIC8vIGRlbGV0aW9ucyBmcm9tIGhpZGRlbiB0cmVlLiBJbiBDb25jdXJyZW50IE1vZGUsIGl0J3MgbXVjaCBzaW1wbGVyLFxuICAvLyBiZWNhdXNlIHdlIGJhaWxvdXQgb24gdGhlIHByaW1hcnkgdHJlZSBjb21wbGV0ZWx5IGFuZCBsZWF2ZSBpdCBpbiBpdHMgb2xkXG4gIC8vIHN0YXRlLCBubyBlZmZlY3RzLiBTYW1lIGFzIHdoYXQgd2UgZG8gZm9yIE9mZnNjcmVlbiAoZXhjZXB0IHRoYXRcbiAgLy8gT2Zmc2NyZWVuIGRvZXNuJ3QgaGF2ZSB0aGUgZmlyc3QgcmVuZGVyIHBhc3MpLlxuICAvL1xuICAvLyBTZWNvbmQgaXMgaHlkcmF0aW9uLiBEdXJpbmcgaHlkcmF0aW9uLCB0aGUgU3VzcGVuc2UgZmliZXIgaGFzIGEgc2xpZ2h0bHlcbiAgLy8gZGlmZmVyZW50IGxheW91dCwgd2hlcmUgdGhlIGNoaWxkIHBvaW50cyB0byBhIGRlaHlkcmF0ZWQgZnJhZ21lbnQsIHdoaWNoXG4gIC8vIGNvbnRhaW5zIHRoZSBET00gcmVuZGVyZWQgYnkgdGhlIHNlcnZlci5cbiAgLy9cbiAgLy8gVGhpcmQsIGV2ZW4gaWYgeW91IHNldCBhbGwgdGhhdCBhc2lkZSwgU3VzcGVuc2UgaXMgbGlrZSBlcnJvciBib3VuZGFyaWVzIGluXG4gIC8vIHRoYXQgd2UgZmlyc3Qgd2UgdHJ5IHRvIHJlbmRlciBvbmUgdHJlZSwgYW5kIGlmIHRoYXQgZmFpbHMsIHdlIHJlbmRlciBhZ2FpblxuICAvLyBhbmQgc3dpdGNoIHRvIGEgZGlmZmVyZW50IHRyZWUuIExpa2UgYSB0cnkvY2F0Y2ggYmxvY2suIFNvIHdlIGhhdmUgdG8gdHJhY2tcbiAgLy8gd2hpY2ggYnJhbmNoIHdlJ3JlIGN1cnJlbnRseSByZW5kZXJpbmcuIElkZWFsbHkgd2Ugd291bGQgbW9kZWwgdGhpcyB1c2luZ1xuICAvLyBhIHN0YWNrLlxuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgLy8gSW5pdGlhbCBtb3VudFxuICAgIC8vIFNwZWNpYWwgcGF0aCBmb3IgaHlkcmF0aW9uXG4gICAgLy8gSWYgd2UncmUgY3VycmVudGx5IGh5ZHJhdGluZywgdHJ5IHRvIGh5ZHJhdGUgdGhpcyBib3VuZGFyeS5cbiAgICB0cnlUb0NsYWltTmV4dEh5ZHJhdGFibGVJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcyk7IC8vIFRoaXMgY291bGQndmUgYmVlbiBhIGRlaHlkcmF0ZWQgc3VzcGVuc2UgY29tcG9uZW50LlxuXG4gICAgdmFyIHN1c3BlbnNlU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgaWYgKHN1c3BlbnNlU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBkZWh5ZHJhdGVkID0gc3VzcGVuc2VTdGF0ZS5kZWh5ZHJhdGVkO1xuXG4gICAgICBpZiAoZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbW91bnREZWh5ZHJhdGVkU3VzcGVuc2VDb21wb25lbnQod29ya0luUHJvZ3Jlc3MsIGRlaHlkcmF0ZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuZXh0UHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICAgIHZhciBuZXh0RmFsbGJhY2tDaGlsZHJlbiA9IG5leHRQcm9wcy5mYWxsYmFjaztcblxuICAgIGlmIChzaG93RmFsbGJhY2spIHtcbiAgICAgIHZhciBmYWxsYmFja0ZyYWdtZW50ID0gbW91bnRTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIG5leHRQcmltYXJ5Q2hpbGRyZW4sIG5leHRGYWxsYmFja0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gICAgICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50Lm1lbW9pemVkU3RhdGUgPSBtb3VudFN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocmVuZGVyTGFuZXMpO1xuICAgICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IFNVU1BFTkRFRF9NQVJLRVI7XG5cbiAgICAgIHJldHVybiBmYWxsYmFja0ZyYWdtZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW91bnRTdXNwZW5zZVByaW1hcnlDaGlsZHJlbih3b3JrSW5Qcm9ncmVzcywgbmV4dFByaW1hcnlDaGlsZHJlbik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgaXMgYW4gdXBkYXRlLlxuICAgIC8vIFNwZWNpYWwgcGF0aCBmb3IgaHlkcmF0aW9uXG4gICAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBfZGVoeWRyYXRlZCA9IHByZXZTdGF0ZS5kZWh5ZHJhdGVkO1xuXG4gICAgICBpZiAoX2RlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZURlaHlkcmF0ZWRTdXNwZW5zZUNvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgZGlkU3VzcGVuZCwgbmV4dFByb3BzLCBfZGVoeWRyYXRlZCwgcHJldlN0YXRlLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNob3dGYWxsYmFjaykge1xuICAgICAgdmFyIF9uZXh0RmFsbGJhY2tDaGlsZHJlbiA9IG5leHRQcm9wcy5mYWxsYmFjaztcbiAgICAgIHZhciBfbmV4dFByaW1hcnlDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgICAgIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSB1cGRhdGVTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIF9uZXh0UHJpbWFyeUNoaWxkcmVuLCBfbmV4dEZhbGxiYWNrQ2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgICAgIHZhciBfcHJpbWFyeUNoaWxkRnJhZ21lbnQyID0gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gICAgICB2YXIgcHJldk9mZnNjcmVlblN0YXRlID0gY3VycmVudC5jaGlsZC5tZW1vaXplZFN0YXRlO1xuICAgICAgX3ByaW1hcnlDaGlsZEZyYWdtZW50Mi5tZW1vaXplZFN0YXRlID0gcHJldk9mZnNjcmVlblN0YXRlID09PSBudWxsID8gbW91bnRTdXNwZW5zZU9mZnNjcmVlblN0YXRlKHJlbmRlckxhbmVzKSA6IHVwZGF0ZVN1c3BlbnNlT2Zmc2NyZWVuU3RhdGUocHJldk9mZnNjcmVlblN0YXRlLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDIuY2hpbGRMYW5lcyA9IGdldFJlbWFpbmluZ1dvcmtJblByaW1hcnlUcmVlKGN1cnJlbnQsIHJlbmRlckxhbmVzKTtcbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBTVVNQRU5ERURfTUFSS0VSO1xuICAgICAgcmV0dXJuIGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9uZXh0UHJpbWFyeUNoaWxkcmVuMiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcblxuICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDMgPSB1cGRhdGVTdXNwZW5zZVByaW1hcnlDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX25leHRQcmltYXJ5Q2hpbGRyZW4yLCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDM7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfTtcbiAgdmFyIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBtb2RlKTtcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHJldHVybiBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gbW91bnRTdXNwZW5zZUZhbGxiYWNrQ2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgZmFsbGJhY2tDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIG1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ2hpZGRlbicsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHZhciBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKChtb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgIC8vIEluIGxlZ2FjeSBtb2RlLCB3ZSBjb21taXQgdGhlIHByaW1hcnkgdHJlZSBhcyBpZiBpdCBzdWNjZXNzZnVsbHlcbiAgICAvLyBjb21wbGV0ZWQsIGV2ZW4gdGhvdWdoIGl0J3MgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLlxuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudDtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5wZW5kaW5nUHJvcHMgPSBwcmltYXJ5Q2hpbGRQcm9wcztcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAvLyBSZXNldCB0aGUgZHVyYXRpb25zIGZyb20gdGhlIGZpcnN0IHBhc3Mgc28gdGhleSBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlXG4gICAgICAvLyBmaW5hbCBhbW91bnRzLiBUaGlzIHNlZW1zIGNvdW50ZXJpbnR1aXRpdmUsIHNpbmNlIHdlJ3JlIGludGVudGlvbmFsbHlcbiAgICAgIC8vIG5vdCBtZWFzdXJpbmcgcGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLCBidXQgdGhpcyBtYWtlcyBpdCBtYXRjaCB3aGF0IHdlXG4gICAgICAvLyBkbyBpbiBDb25jdXJyZW50IE1vZGUuXG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnNlbGZCYXNlRHVyYXRpb24gPSAwO1xuICAgICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgbW9kZSwgcmVuZGVyTGFuZXMsIG51bGwpO1xuICB9IGVsc2Uge1xuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBtb2RlKTtcbiAgICBmYWxsYmFja0NoaWxkRnJhZ21lbnQgPSBjcmVhdGVGaWJlckZyb21GcmFnbWVudChmYWxsYmFja0NoaWxkcmVuLCBtb2RlLCByZW5kZXJMYW5lcywgbnVsbCk7XG4gIH1cblxuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5zaWJsaW5nID0gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICByZXR1cm4gZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xufVxuXG5mdW5jdGlvbiBtb3VudFdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIob2Zmc2NyZWVuUHJvcHMsIG1vZGUsIHJlbmRlckxhbmVzKSB7XG4gIC8vIFRoZSBwcm9wcyBhcmd1bWVudCB0byBgY3JlYXRlRmliZXJGcm9tT2Zmc2NyZWVuYCBpcyBgYW55YCB0eXBlZCwgc28gd2UgdXNlXG4gIC8vIHRoaXMgd3JhcHBlciBmdW5jdGlvbiB0byBjb25zdHJhaW4gaXQuXG4gIHJldHVybiBjcmVhdGVGaWJlckZyb21PZmZzY3JlZW4ob2Zmc2NyZWVuUHJvcHMsIG1vZGUsIE5vTGFuZXMsIG51bGwpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKGN1cnJlbnQsIG9mZnNjcmVlblByb3BzKSB7XG4gIC8vIFRoZSBwcm9wcyBhcmd1bWVudCB0byBgY3JlYXRlV29ya0luUHJvZ3Jlc3NgIGlzIGBhbnlgIHR5cGVkLCBzbyB3ZSB1c2UgdGhpc1xuICAvLyB3cmFwcGVyIGZ1bmN0aW9uIHRvIGNvbnN0cmFpbiBpdC5cbiAgcmV0dXJuIGNyZWF0ZVdvcmtJblByb2dyZXNzKGN1cnJlbnQsIG9mZnNjcmVlblByb3BzKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlU3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbiwgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudCA9IGN1cnJlbnQuY2hpbGQ7XG4gIHZhciBjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmc7XG4gIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHVwZGF0ZVdvcmtJblByb2dyZXNzT2Zmc2NyZWVuRmliZXIoY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LCB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfSk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5sYW5lcyA9IHJlbmRlckxhbmVzO1xuICB9XG5cbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBudWxsO1xuXG4gIGlmIChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgLy8gRGVsZXRlIHRoZSBmYWxsYmFjayBjaGlsZCBmcmFnbWVudFxuICAgIHZhciBkZWxldGlvbnMgPSB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnM7XG5cbiAgICBpZiAoZGVsZXRpb25zID09PSBudWxsKSB7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnMgPSBbY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudF07XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGlvbnMucHVzaChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50KTtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IHByaW1hcnlDaGlsZEZyYWdtZW50O1xuICByZXR1cm4gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZVN1c3BlbnNlRmFsbGJhY2tDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcHJpbWFyeUNoaWxkcmVuLCBmYWxsYmFja0NoaWxkcmVuLCByZW5kZXJMYW5lcykge1xuICB2YXIgbW9kZSA9IHdvcmtJblByb2dyZXNzLm1vZGU7XG4gIHZhciBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBjdXJyZW50LmNoaWxkO1xuICB2YXIgY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudC5zaWJsaW5nO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ2hpZGRlbicsXG4gICAgY2hpbGRyZW46IHByaW1hcnlDaGlsZHJlblxuICB9O1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKCAvLyBJbiBsZWdhY3kgbW9kZSwgd2UgY29tbWl0IHRoZSBwcmltYXJ5IHRyZWUgYXMgaWYgaXQgc3VjY2Vzc2Z1bGx5XG4gIC8vIGNvbXBsZXRlZCwgZXZlbiB0aG91Z2ggaXQncyBpbiBhbiBpbmNvbnNpc3RlbnQgc3RhdGUuXG4gIChtb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUgJiYgLy8gTWFrZSBzdXJlIHdlJ3JlIG9uIHRoZSBzZWNvbmQgcGFzcywgaS5lLiB0aGUgcHJpbWFyeSBjaGlsZCBmcmFnbWVudCB3YXNcbiAgLy8gYWxyZWFkeSBjbG9uZWQuIEluIGxlZ2FjeSBtb2RlLCB0aGUgb25seSBjYXNlIHdoZXJlIHRoaXMgaXNuJ3QgdHJ1ZSBpc1xuICAvLyB3aGVuIERldlRvb2xzIGZvcmNlcyB1cyB0byBkaXNwbGF5IGEgZmFsbGJhY2s7IHdlIHNraXAgdGhlIGZpcnN0IHJlbmRlclxuICAvLyBwYXNzIGVudGlyZWx5IGFuZCBnbyBzdHJhaWdodCB0byByZW5kZXJpbmcgdGhlIGZhbGxiYWNrLiAoSW4gQ29uY3VycmVudFxuICAvLyBNb2RlLCBTdXNwZW5zZUxpc3QgY2FuIGFsc28gdHJpZ2dlciB0aGlzIHNjZW5hcmlvLCBidXQgdGhpcyBpcyBhIGxlZ2FjeS1cbiAgLy8gb25seSBjb2RlcGF0aC4pXG4gIHdvcmtJblByb2dyZXNzLmNoaWxkICE9PSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQpIHtcbiAgICB2YXIgcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gcHJvZ3Jlc3NlZFByaW1hcnlGcmFnbWVudDtcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5wZW5kaW5nUHJvcHMgPSBwcmltYXJ5Q2hpbGRQcm9wcztcblxuICAgIGlmICggd29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAvLyBSZXNldCB0aGUgZHVyYXRpb25zIGZyb20gdGhlIGZpcnN0IHBhc3Mgc28gdGhleSBhcmVuJ3QgaW5jbHVkZWQgaW4gdGhlXG4gICAgICAvLyBmaW5hbCBhbW91bnRzLiBUaGlzIHNlZW1zIGNvdW50ZXJpbnR1aXRpdmUsIHNpbmNlIHdlJ3JlIGludGVudGlvbmFsbHlcbiAgICAgIC8vIG5vdCBtZWFzdXJpbmcgcGFydCBvZiB0aGUgcmVuZGVyIHBoYXNlLCBidXQgdGhpcyBtYWtlcyBpdCBtYXRjaCB3aGF0IHdlXG4gICAgICAvLyBkbyBpbiBDb25jdXJyZW50IE1vZGUuXG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxEdXJhdGlvbiA9IDA7XG4gICAgICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5hY3R1YWxTdGFydFRpbWUgPSAtMTtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnNlbGZCYXNlRHVyYXRpb24gPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LnRyZWVCYXNlRHVyYXRpb24gPSBjdXJyZW50UHJpbWFyeUNoaWxkRnJhZ21lbnQudHJlZUJhc2VEdXJhdGlvbjtcbiAgICB9IC8vIFRoZSBmYWxsYmFjayBmaWJlciB3YXMgYWRkZWQgYXMgYSBkZWxldGlvbiBkdXJpbmcgdGhlIGZpcnN0IHBhc3MuXG4gICAgLy8gSG93ZXZlciwgc2luY2Ugd2UncmUgZ29pbmcgdG8gcmVtYWluIG9uIHRoZSBmYWxsYmFjaywgd2Ugbm8gbG9uZ2VyIHdhbnRcbiAgICAvLyB0byBkZWxldGUgaXQuXG5cblxuICAgIHdvcmtJblByb2dyZXNzLmRlbGV0aW9ucyA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB1cGRhdGVXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKGN1cnJlbnRQcmltYXJ5Q2hpbGRGcmFnbWVudCwgcHJpbWFyeUNoaWxkUHJvcHMpOyAvLyBTaW5jZSB3ZSdyZSByZXVzaW5nIGEgY3VycmVudCB0cmVlLCB3ZSBuZWVkIHRvIHJldXNlIHRoZSBmbGFncywgdG9vLlxuICAgIC8vIChXZSBkb24ndCBkbyB0aGlzIGluIGxlZ2FjeSBtb2RlLCBiZWNhdXNlIGluIGxlZ2FjeSBtb2RlIHdlIGRvbid0IHJlLXVzZVxuICAgIC8vIHRoZSBjdXJyZW50IHRyZWU7IHNlZSBwcmV2aW91cyBicmFuY2guKVxuXG4gICAgcHJpbWFyeUNoaWxkRnJhZ21lbnQuc3VidHJlZUZsYWdzID0gY3VycmVudFByaW1hcnlDaGlsZEZyYWdtZW50LnN1YnRyZWVGbGFncyAmIFN0YXRpY01hc2s7XG4gIH1cblxuICB2YXIgZmFsbGJhY2tDaGlsZEZyYWdtZW50O1xuXG4gIGlmIChjdXJyZW50RmFsbGJhY2tDaGlsZEZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlV29ya0luUHJvZ3Jlc3MoY3VycmVudEZhbGxiYWNrQ2hpbGRGcmFnbWVudCwgZmFsbGJhY2tDaGlsZHJlbik7XG4gIH0gZWxzZSB7XG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgbW9kZSwgcmVuZGVyTGFuZXMsIG51bGwpOyAvLyBOZWVkcyBhIHBsYWNlbWVudCBlZmZlY3QgYmVjYXVzZSB0aGUgcGFyZW50ICh0aGUgU3VzcGVuc2UgYm91bmRhcnkpIGFscmVhZHlcbiAgICAvLyBtb3VudGVkIGJ1dCB0aGlzIGlzIGEgbmV3IGZpYmVyLlxuXG4gICAgZmFsbGJhY2tDaGlsZEZyYWdtZW50LmZsYWdzIHw9IFBsYWNlbWVudDtcbiAgfVxuXG4gIGZhbGxiYWNrQ2hpbGRGcmFnbWVudC5yZXR1cm4gPSB3b3JrSW5Qcm9ncmVzcztcbiAgcHJpbWFyeUNoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG4gIHJldHVybiBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgcmVjb3ZlcmFibGVFcnJvcikge1xuICAvLyBGYWxsaW5nIGJhY2sgdG8gY2xpZW50IHJlbmRlcmluZy4gQmVjYXVzZSB0aGlzIGhhcyBwZXJmb3JtYW5jZVxuICAvLyBpbXBsaWNhdGlvbnMsIGl0J3MgY29uc2lkZXJlZCBhIHJlY292ZXJhYmxlIGVycm9yLCBldmVuIHRob3VnaCB0aGUgdXNlclxuICAvLyBsaWtlbHkgd29uJ3Qgb2JzZXJ2ZSBhbnl0aGluZyB3cm9uZyB3aXRoIHRoZSBVSS5cbiAgLy9cbiAgLy8gVGhlIGVycm9yIGlzIHBhc3NlZCBpbiBhcyBhbiBhcmd1bWVudCB0byBlbmZvcmNlIHRoYXQgZXZlcnkgY2FsbGVyIHByb3ZpZGVcbiAgLy8gYSBjdXN0b20gbWVzc2FnZSwgb3IgZXhwbGljaXRseSBvcHQgb3V0IChjdXJyZW50bHkgdGhlIG9ubHkgcGF0aCB0aGF0IG9wdHNcbiAgLy8gb3V0IGlzIGxlZ2FjeSBtb2RlOyBldmVyeSBjb25jdXJyZW50IHBhdGggcHJvdmlkZXMgYW4gZXJyb3IpLlxuICBpZiAocmVjb3ZlcmFibGVFcnJvciAhPT0gbnVsbCkge1xuICAgIHF1ZXVlSHlkcmF0aW9uRXJyb3IocmVjb3ZlcmFibGVFcnJvcik7XG4gIH0gLy8gVGhpcyB3aWxsIGFkZCB0aGUgb2xkIGZpYmVyIHRvIHRoZSBkZWxldGlvbiBsaXN0XG5cblxuICByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbnVsbCwgcmVuZGVyTGFuZXMpOyAvLyBXZSdyZSBub3cgbm90IHN1c3BlbmRlZCBub3IgZGVoeWRyYXRlZC5cblxuICB2YXIgbmV4dFByb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSBtb3VudFN1c3BlbnNlUHJpbWFyeUNoaWxkcmVuKHdvcmtJblByb2dyZXNzLCBwcmltYXJ5Q2hpbGRyZW4pOyAvLyBOZWVkcyBhIHBsYWNlbWVudCBlZmZlY3QgYmVjYXVzZSB0aGUgcGFyZW50ICh0aGUgU3VzcGVuc2UgYm91bmRhcnkpIGFscmVhZHlcbiAgLy8gbW91bnRlZCBidXQgdGhpcyBpcyBhIG5ldyBmaWJlci5cblxuICBwcmltYXJ5Q2hpbGRGcmFnbWVudC5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICByZXR1cm4gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG59XG5cbmZ1bmN0aW9uIG1vdW50U3VzcGVuc2VGYWxsYmFja0FmdGVyUmV0cnlXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBwcmltYXJ5Q2hpbGRyZW4sIGZhbGxiYWNrQ2hpbGRyZW4sIHJlbmRlckxhbmVzKSB7XG4gIHZhciBmaWJlck1vZGUgPSB3b3JrSW5Qcm9ncmVzcy5tb2RlO1xuICB2YXIgcHJpbWFyeUNoaWxkUHJvcHMgPSB7XG4gICAgbW9kZTogJ3Zpc2libGUnLFxuICAgIGNoaWxkcmVuOiBwcmltYXJ5Q2hpbGRyZW5cbiAgfTtcbiAgdmFyIHByaW1hcnlDaGlsZEZyYWdtZW50ID0gbW91bnRXb3JrSW5Qcm9ncmVzc09mZnNjcmVlbkZpYmVyKHByaW1hcnlDaGlsZFByb3BzLCBmaWJlck1vZGUpO1xuICB2YXIgZmFsbGJhY2tDaGlsZEZyYWdtZW50ID0gY3JlYXRlRmliZXJGcm9tRnJhZ21lbnQoZmFsbGJhY2tDaGlsZHJlbiwgZmliZXJNb2RlLCByZW5kZXJMYW5lcywgbnVsbCk7IC8vIE5lZWRzIGEgcGxhY2VtZW50IGVmZmVjdCBiZWNhdXNlIHRoZSBwYXJlbnQgKHRoZSBTdXNwZW5zZVxuICAvLyBib3VuZGFyeSkgYWxyZWFkeSBtb3VudGVkIGJ1dCB0aGlzIGlzIGEgbmV3IGZpYmVyLlxuXG4gIGZhbGxiYWNrQ2hpbGRGcmFnbWVudC5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnJldHVybiA9IHdvcmtJblByb2dyZXNzO1xuICBmYWxsYmFja0NoaWxkRnJhZ21lbnQucmV0dXJuID0gd29ya0luUHJvZ3Jlc3M7XG4gIHByaW1hcnlDaGlsZEZyYWdtZW50LnNpYmxpbmcgPSBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcHJpbWFyeUNoaWxkRnJhZ21lbnQ7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAvLyBXZSB3aWxsIGhhdmUgZHJvcHBlZCB0aGUgZWZmZWN0IGxpc3Qgd2hpY2ggY29udGFpbnMgdGhlXG4gICAgLy8gZGVsZXRpb24uIFdlIG5lZWQgdG8gcmVjb25jaWxlIHRvIGRlbGV0ZSB0aGUgY3VycmVudCBjaGlsZC5cbiAgICByZWNvbmNpbGVDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgY3VycmVudC5jaGlsZCwgbnVsbCwgcmVuZGVyTGFuZXMpO1xuICB9XG5cbiAgcmV0dXJuIGZhbGxiYWNrQ2hpbGRGcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gbW91bnREZWh5ZHJhdGVkU3VzcGVuc2VDb21wb25lbnQod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlSW5zdGFuY2UsIHJlbmRlckxhbmVzKSB7XG4gIC8vIER1cmluZyB0aGUgZmlyc3QgcGFzcywgd2UnbGwgYmFpbCBvdXQgYW5kIG5vdCBkcmlsbCBpbnRvIHRoZSBjaGlsZHJlbi5cbiAgLy8gSW5zdGVhZCwgd2UnbGwgbGVhdmUgdGhlIGNvbnRlbnQgaW4gcGxhY2UgYW5kIHRyeSB0byBoeWRyYXRlIGl0IGxhdGVyLlxuICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgIHtcbiAgICAgIGVycm9yKCdDYW5ub3QgaHlkcmF0ZSBTdXNwZW5zZSBpbiBsZWdhY3kgbW9kZS4gU3dpdGNoIGZyb20gJyArICdSZWFjdERPTS5oeWRyYXRlKGVsZW1lbnQsIGNvbnRhaW5lcikgdG8gJyArICdSZWFjdERPTUNsaWVudC5oeWRyYXRlUm9vdChjb250YWluZXIsIDxBcHAgLz4pJyArICcucmVuZGVyKGVsZW1lbnQpIG9yIHJlbW92ZSB0aGUgU3VzcGVuc2UgY29tcG9uZW50cyBmcm9tICcgKyAndGhlIHNlcnZlciByZW5kZXJlZCBjb21wb25lbnRzLicpO1xuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbGFuZVRvTGFuZXMoU3luY0xhbmUpO1xuICB9IGVsc2UgaWYgKGlzU3VzcGVuc2VJbnN0YW5jZUZhbGxiYWNrKHN1c3BlbnNlSW5zdGFuY2UpKSB7XG4gICAgLy8gVGhpcyBpcyBhIGNsaWVudC1vbmx5IGJvdW5kYXJ5LiBTaW5jZSB3ZSB3b24ndCBnZXQgYW55IGNvbnRlbnQgZnJvbSB0aGUgc2VydmVyXG4gICAgLy8gZm9yIHRoaXMsIHdlIG5lZWQgdG8gc2NoZWR1bGUgdGhhdCBhdCBhIGhpZ2hlciBwcmlvcml0eSBiYXNlZCBvbiB3aGVuIGl0IHdvdWxkXG4gICAgLy8gaGF2ZSB0aW1lZCBvdXQuIEluIHRoZW9yeSB3ZSBjb3VsZCByZW5kZXIgaXQgaW4gdGhpcyBwYXNzIGJ1dCBpdCB3b3VsZCBoYXZlIHRoZVxuICAgIC8vIHdyb25nIHByaW9yaXR5IGFzc29jaWF0ZWQgd2l0aCBpdCBhbmQgd2lsbCBwcmV2ZW50IGh5ZHJhdGlvbiBvZiBwYXJlbnQgcGF0aC5cbiAgICAvLyBJbnN0ZWFkLCB3ZSdsbCBsZWF2ZSB3b3JrIGxlZnQgb24gaXQgdG8gcmVuZGVyIGl0IGluIGEgc2VwYXJhdGUgY29tbWl0LlxuICAgIC8vIFRPRE8gVGhpcyB0aW1lIHNob3VsZCBiZSB0aGUgdGltZSBhdCB3aGljaCB0aGUgc2VydmVyIHJlbmRlcmVkIHJlc3BvbnNlIHRoYXQgaXNcbiAgICAvLyBhIHBhcmVudCB0byB0aGlzIGJvdW5kYXJ5IHdhcyBkaXNwbGF5ZWQuIEhvd2V2ZXIsIHNpbmNlIHdlIGN1cnJlbnRseSBkb24ndCBoYXZlXG4gICAgLy8gYSBwcm90b2NvbCB0byB0cmFuc2ZlciB0aGF0IHRpbWUsIHdlJ2xsIGp1c3QgZXN0aW1hdGUgaXQgYnkgdXNpbmcgdGhlIGN1cnJlbnRcbiAgICAvLyB0aW1lLiBUaGlzIHdpbGwgbWVhbiB0aGF0IFN1c3BlbnNlIHRpbWVvdXRzIGFyZSBzbGlnaHRseSBzaGlmdGVkIHRvIGxhdGVyIHRoYW5cbiAgICAvLyB0aGV5IHNob3VsZCBiZS5cbiAgICAvLyBTY2hlZHVsZSBhIG5vcm1hbCBwcmkgdXBkYXRlIHRvIHJlbmRlciB0aGlzIGNvbnRlbnQuXG4gICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBsYW5lVG9MYW5lcyhEZWZhdWx0SHlkcmF0aW9uTGFuZSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gV2UnbGwgY29udGludWUgaHlkcmF0aW5nIHRoZSByZXN0IGF0IG9mZnNjcmVlbiBwcmlvcml0eSBzaW5jZSB3ZSdsbCBhbHJlYWR5XG4gICAgLy8gYmUgc2hvd2luZyB0aGUgcmlnaHQgY29udGVudCBjb21pbmcgZnJvbSB0aGUgc2VydmVyLCBpdCBpcyBubyBydXNoLlxuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gbGFuZVRvTGFuZXMoT2Zmc2NyZWVuTGFuZSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRGVoeWRyYXRlZFN1c3BlbnNlQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBkaWRTdXNwZW5kLCBuZXh0UHJvcHMsIHN1c3BlbnNlSW5zdGFuY2UsIHN1c3BlbnNlU3RhdGUsIHJlbmRlckxhbmVzKSB7XG4gIGlmICghZGlkU3VzcGVuZCkge1xuICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IHJlbmRlciBwYXNzLiBBdHRlbXB0IHRvIGh5ZHJhdGUuXG4gICAgLy8gV2Ugc2hvdWxkIG5ldmVyIGJlIGh5ZHJhdGluZyBhdCB0aGlzIHBvaW50IGJlY2F1c2UgaXQgaXMgdGhlIGZpcnN0IHBhc3MsXG4gICAgLy8gYnV0IGFmdGVyIHdlJ3ZlIGFscmVhZHkgY29tbWl0dGVkIG9uY2UuXG4gICAgd2FybklmSHlkcmF0aW5nKCk7XG5cbiAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgPT09IE5vTW9kZSkge1xuICAgICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgLy8gVE9ETzogV2hlbiB3ZSBkZWxldGUgbGVnYWN5IG1vZGUsIHdlIHNob3VsZCBtYWtlIHRoaXMgZXJyb3IgYXJndW1lbnRcbiAgICAgIC8vIHJlcXVpcmVkIOKAlCBldmVyeSBjb25jdXJyZW50IG1vZGUgcGF0aCB0aGF0IGNhdXNlcyBoeWRyYXRpb24gdG9cbiAgICAgIC8vIGRlLW9wdCB0byBjbGllbnQgcmVuZGVyaW5nIHNob3VsZCBoYXZlIGFuIGVycm9yIG1lc3NhZ2UuXG4gICAgICBudWxsKTtcbiAgICB9XG5cbiAgICBpZiAoaXNTdXNwZW5zZUluc3RhbmNlRmFsbGJhY2soc3VzcGVuc2VJbnN0YW5jZSkpIHtcbiAgICAgIC8vIFRoaXMgYm91bmRhcnkgaXMgaW4gYSBwZXJtYW5lbnQgZmFsbGJhY2sgc3RhdGUuIEluIHRoaXMgY2FzZSwgd2UnbGwgbmV2ZXJcbiAgICAgIC8vIGdldCBhbiB1cGRhdGUgYW5kIHdlJ2xsIG5ldmVyIGJlIGFibGUgdG8gaHlkcmF0ZSB0aGUgZmluYWwgY29udGVudC4gTGV0J3MganVzdCB0cnkgdGhlXG4gICAgICAvLyBjbGllbnQgc2lkZSByZW5kZXIgaW5zdGVhZC5cbiAgICAgIHZhciBkaWdlc3QsIG1lc3NhZ2UsIHN0YWNrO1xuXG4gICAgICB7XG4gICAgICAgIHZhciBfZ2V0U3VzcGVuc2VJbnN0YW5jZUYgPSBnZXRTdXNwZW5zZUluc3RhbmNlRmFsbGJhY2tFcnJvckRldGFpbHMoc3VzcGVuc2VJbnN0YW5jZSk7XG5cbiAgICAgICAgZGlnZXN0ID0gX2dldFN1c3BlbnNlSW5zdGFuY2VGLmRpZ2VzdDtcbiAgICAgICAgbWVzc2FnZSA9IF9nZXRTdXNwZW5zZUluc3RhbmNlRi5tZXNzYWdlO1xuICAgICAgICBzdGFjayA9IF9nZXRTdXNwZW5zZUluc3RhbmNlRi5zdGFjaztcbiAgICAgIH1cblxuICAgICAgdmFyIGVycm9yO1xuXG4gICAgICBpZiAobWVzc2FnZSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICBlcnJvciA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yID0gbmV3IEVycm9yKCdUaGUgc2VydmVyIGNvdWxkIG5vdCBmaW5pc2ggdGhpcyBTdXNwZW5zZSBib3VuZGFyeSwgbGlrZWx5ICcgKyAnZHVlIHRvIGFuIGVycm9yIGR1cmluZyBzZXJ2ZXIgcmVuZGVyaW5nLiBTd2l0Y2hlZCB0byAnICsgJ2NsaWVudCByZW5kZXJpbmcuJyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjYXB0dXJlZFZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZShlcnJvciwgZGlnZXN0LCBzdGFjayk7XG4gICAgICByZXR1cm4gcmV0cnlTdXNwZW5zZUNvbXBvbmVudFdpdGhvdXRIeWRyYXRpbmcoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzLCBjYXB0dXJlZFZhbHVlKTtcbiAgICB9XG4gICAgLy8gYW55IGNvbnRleHQgaGFzIGNoYW5nZWQsIHdlIG5lZWQgdG8gdHJlYXQgaXMgYXMgaWYgdGhlIGlucHV0IG1pZ2h0IGhhdmUgY2hhbmdlZC5cblxuXG4gICAgdmFyIGhhc0NvbnRleHRDaGFuZ2VkID0gaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgY3VycmVudC5jaGlsZExhbmVzKTtcblxuICAgIGlmIChkaWRSZWNlaXZlVXBkYXRlIHx8IGhhc0NvbnRleHRDaGFuZ2VkKSB7XG4gICAgICAvLyBUaGlzIGJvdW5kYXJ5IGhhcyBjaGFuZ2VkIHNpbmNlIHRoZSBmaXJzdCByZW5kZXIuIFRoaXMgbWVhbnMgdGhhdCB3ZSBhcmUgbm93IHVuYWJsZSB0b1xuICAgICAgLy8gaHlkcmF0ZSBpdC4gV2UgbWlnaHQgc3RpbGwgYmUgYWJsZSB0byBoeWRyYXRlIGl0IHVzaW5nIGEgaGlnaGVyIHByaW9yaXR5IGxhbmUuXG4gICAgICB2YXIgcm9vdCA9IGdldFdvcmtJblByb2dyZXNzUm9vdCgpO1xuXG4gICAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgYXR0ZW1wdEh5ZHJhdGlvbkF0TGFuZSA9IGdldEJ1bXBlZExhbmVGb3JIeWRyYXRpb24ocm9vdCwgcmVuZGVyTGFuZXMpO1xuXG4gICAgICAgIGlmIChhdHRlbXB0SHlkcmF0aW9uQXRMYW5lICE9PSBOb0xhbmUgJiYgYXR0ZW1wdEh5ZHJhdGlvbkF0TGFuZSAhPT0gc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmUpIHtcbiAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IG11dGF0aW5nIHNpbmNlIHRoaXMgcmVuZGVyIHdpbGwgZ2V0IGludGVycnVwdGVkLiBUaGlzXG4gICAgICAgICAgLy8gaXMgb25lIG9mIHRoZSB2ZXJ5IHJhcmUgdGltZXMgd2hlcmUgd2UgbXV0YXRlIHRoZSBjdXJyZW50IHRyZWVcbiAgICAgICAgICAvLyBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS5cbiAgICAgICAgICBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSA9IGF0dGVtcHRIeWRyYXRpb25BdExhbmU7IC8vIFRPRE86IElkZWFsbHkgdGhpcyB3b3VsZCBpbmhlcml0IHRoZSBldmVudCB0aW1lIG9mIHRoZSBjdXJyZW50IHJlbmRlclxuXG4gICAgICAgICAgdmFyIGV2ZW50VGltZSA9IE5vVGltZXN0YW1wO1xuICAgICAgICAgIGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShjdXJyZW50LCBhdHRlbXB0SHlkcmF0aW9uQXRMYW5lKTtcbiAgICAgICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgY3VycmVudCwgYXR0ZW1wdEh5ZHJhdGlvbkF0TGFuZSwgZXZlbnRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBJZiB3ZSBoYXZlIHNjaGVkdWxlZCBoaWdoZXIgcHJpIHdvcmsgYWJvdmUsIHRoaXMgd2lsbCBwcm9iYWJseSBqdXN0IGFib3J0IHRoZSByZW5kZXJcbiAgICAgIC8vIHNpbmNlIHdlIG5vdyBoYXZlIGhpZ2hlciBwcmlvcml0eSB3b3JrLCBidXQgaW4gY2FzZSBpdCBkb2Vzbid0LCB3ZSBuZWVkIHRvIHByZXBhcmUgdG9cbiAgICAgIC8vIHJlbmRlciBzb21ldGhpbmcsIGlmIHdlIHRpbWUgb3V0LiBFdmVuIGlmIHRoYXQgcmVxdWlyZXMgdXMgdG8gZGVsZXRlIGV2ZXJ5dGhpbmcgYW5kXG4gICAgICAvLyBza2lwIGh5ZHJhdGlvbi5cbiAgICAgIC8vIERlbGF5IGhhdmluZyB0byBkbyB0aGlzIGFzIGxvbmcgYXMgdGhlIHN1c3BlbnNlIHRpbWVvdXQgYWxsb3dzIHVzLlxuXG5cbiAgICAgIHJlbmRlckRpZFN1c3BlbmREZWxheUlmUG9zc2libGUoKTtcblxuICAgICAgdmFyIF9jYXB0dXJlZFZhbHVlID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZShuZXcgRXJyb3IoJ1RoaXMgU3VzcGVuc2UgYm91bmRhcnkgcmVjZWl2ZWQgYW4gdXBkYXRlIGJlZm9yZSBpdCBmaW5pc2hlZCAnICsgJ2h5ZHJhdGluZy4gVGhpcyBjYXVzZWQgdGhlIGJvdW5kYXJ5IHRvIHN3aXRjaCB0byBjbGllbnQgcmVuZGVyaW5nLiAnICsgJ1RoZSB1c3VhbCB3YXkgdG8gZml4IHRoaXMgaXMgdG8gd3JhcCB0aGUgb3JpZ2luYWwgdXBkYXRlICcgKyAnaW4gc3RhcnRUcmFuc2l0aW9uLicpKTtcblxuICAgICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgX2NhcHR1cmVkVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoaXNTdXNwZW5zZUluc3RhbmNlUGVuZGluZyhzdXNwZW5zZUluc3RhbmNlKSkge1xuICAgICAgLy8gVGhpcyBjb21wb25lbnQgaXMgc3RpbGwgcGVuZGluZyBtb3JlIGRhdGEgZnJvbSB0aGUgc2VydmVyLCBzbyB3ZSBjYW4ndCBoeWRyYXRlIGl0c1xuICAgICAgLy8gY29udGVudC4gV2UgdHJlYXQgaXQgYXMgaWYgdGhpcyBjb21wb25lbnQgc3VzcGVuZGVkIGl0c2VsZi4gSXQgbWlnaHQgc2VlbSBhcyBpZlxuICAgICAgLy8gd2UgY291bGQganVzdCB0cnkgdG8gcmVuZGVyIGl0IGNsaWVudC1zaWRlIGluc3RlYWQuIEhvd2V2ZXIsIHRoaXMgd2lsbCBwZXJmb3JtIGFcbiAgICAgIC8vIGxvdCBvZiB1bm5lY2Vzc2FyeSB3b3JrIGFuZCBpcyB1bmxpa2VseSB0byBjb21wbGV0ZSBzaW5jZSBpdCBvZnRlbiB3aWxsIHN1c3BlbmRcbiAgICAgIC8vIG9uIG1pc3NpbmcgZGF0YSBhbnl3YXkuIEFkZGl0aW9uYWxseSwgdGhlIHNlcnZlciBtaWdodCBiZSBhYmxlIHRvIHJlbmRlciBtb3JlXG4gICAgICAvLyB0aGFuIHdlIGNhbiBvbiB0aGUgY2xpZW50IHlldC4gSW4gdGhhdCBjYXNlIHdlJ2QgZW5kIHVwIHdpdGggbW9yZSBmYWxsYmFjayBzdGF0ZXNcbiAgICAgIC8vIG9uIHRoZSBjbGllbnQgdGhhbiBpZiB3ZSBqdXN0IGxlYXZlIGl0IGFsb25lLiBJZiB0aGUgc2VydmVyIHRpbWVzIG91dCBvciBlcnJvcnNcbiAgICAgIC8vIHRoZXNlIHNob3VsZCB1cGRhdGUgdGhpcyBib3VuZGFyeSB0byB0aGUgcGVybWFuZW50IEZhbGxiYWNrIHN0YXRlIGluc3RlYWQuXG4gICAgICAvLyBNYXJrIGl0IGFzIGhhdmluZyBjYXB0dXJlZCAoaS5lLiBzdXNwZW5kZWQpLlxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTsgLy8gTGVhdmUgdGhlIGNoaWxkIGluIHBsYWNlLiBJLmUuIHRoZSBkZWh5ZHJhdGVkIGZyYWdtZW50LlxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFJlZ2lzdGVyIGEgY2FsbGJhY2sgdG8gcmV0cnkgdGhpcyBib3VuZGFyeSBvbmNlIHRoZSBzZXJ2ZXIgaGFzIHNlbnQgdGhlIHJlc3VsdC5cblxuICAgICAgdmFyIHJldHJ5ID0gcmV0cnlEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeS5iaW5kKG51bGwsIGN1cnJlbnQpO1xuICAgICAgcmVnaXN0ZXJTdXNwZW5zZUluc3RhbmNlUmV0cnkoc3VzcGVuc2VJbnN0YW5jZSwgcmV0cnkpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IGF0dGVtcHQuXG4gICAgICByZWVudGVySHlkcmF0aW9uU3RhdGVGcm9tRGVoeWRyYXRlZFN1c3BlbnNlSW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlSW5zdGFuY2UsIHN1c3BlbnNlU3RhdGUudHJlZUNvbnRleHQpO1xuICAgICAgdmFyIHByaW1hcnlDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IG1vdW50U3VzcGVuc2VQcmltYXJ5Q2hpbGRyZW4od29ya0luUHJvZ3Jlc3MsIHByaW1hcnlDaGlsZHJlbik7IC8vIE1hcmsgdGhlIGNoaWxkcmVuIGFzIGh5ZHJhdGluZy4gVGhpcyBpcyBhIGZhc3QgcGF0aCB0byBrbm93IHdoZXRoZXIgdGhpc1xuICAgICAgLy8gdHJlZSBpcyBwYXJ0IG9mIGEgaHlkcmF0aW5nIHRyZWUuIFRoaXMgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgYSBjaGlsZFxuICAgICAgLy8gbm9kZSBoYXMgZnVsbHkgbW91bnRlZCB5ZXQsIGFuZCBmb3Igc2NoZWR1bGluZyBldmVudCByZXBsYXlpbmcuXG4gICAgICAvLyBDb25jZXB0dWFsbHkgdGhpcyBpcyBzaW1pbGFyIHRvIFBsYWNlbWVudCBpbiB0aGF0IGEgbmV3IHN1YnRyZWUgaXNcbiAgICAgIC8vIGluc2VydGVkIGludG8gdGhlIFJlYWN0IHRyZWUgaGVyZS4gSXQganVzdCBoYXBwZW5zIHRvIG5vdCBuZWVkIERPTVxuICAgICAgLy8gbXV0YXRpb25zIGJlY2F1c2UgaXQgYWxyZWFkeSBleGlzdHMuXG5cbiAgICAgIHByaW1hcnlDaGlsZEZyYWdtZW50LmZsYWdzIHw9IEh5ZHJhdGluZztcbiAgICAgIHJldHVybiBwcmltYXJ5Q2hpbGRGcmFnbWVudDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyB0aGUgc2Vjb25kIHJlbmRlciBwYXNzLiBXZSBhbHJlYWR5IGF0dGVtcHRlZCB0byBoeWRyYXRlZCwgYnV0XG4gICAgLy8gc29tZXRoaW5nIGVpdGhlciBzdXNwZW5kZWQgb3IgZXJyb3JlZC5cbiAgICBpZiAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBGb3JjZUNsaWVudFJlbmRlcikge1xuICAgICAgLy8gU29tZXRoaW5nIGVycm9yZWQgZHVyaW5nIGh5ZHJhdGlvbi4gVHJ5IGFnYWluIHdpdGhvdXQgaHlkcmF0aW5nLlxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgJj0gfkZvcmNlQ2xpZW50UmVuZGVyO1xuXG4gICAgICB2YXIgX2NhcHR1cmVkVmFsdWUyID0gY3JlYXRlQ2FwdHVyZWRWYWx1ZShuZXcgRXJyb3IoJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSBoeWRyYXRpbmcgdGhpcyBTdXNwZW5zZSBib3VuZGFyeS4gJyArICdTd2l0Y2hlZCB0byBjbGllbnQgcmVuZGVyaW5nLicpKTtcblxuICAgICAgcmV0dXJuIHJldHJ5U3VzcGVuc2VDb21wb25lbnRXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcywgX2NhcHR1cmVkVmFsdWUyKTtcbiAgICB9IGVsc2UgaWYgKHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgIT09IG51bGwpIHtcbiAgICAgIC8vIFNvbWV0aGluZyBzdXNwZW5kZWQgYW5kIHdlIHNob3VsZCBzdGlsbCBiZSBpbiBkZWh5ZHJhdGVkIG1vZGUuXG4gICAgICAvLyBMZWF2ZSB0aGUgZXhpc3RpbmcgY2hpbGQgaW4gcGxhY2UuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7IC8vIFRoZSBkZWh5ZHJhdGVkIGNvbXBsZXRpb24gcGFzcyBleHBlY3RzIHRoaXMgZmxhZyB0byBiZSB0aGVyZVxuICAgICAgLy8gYnV0IHRoZSBub3JtYWwgc3VzcGVuc2UgcGFzcyBkb2Vzbid0LlxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFN1c3BlbmRlZCBidXQgd2Ugc2hvdWxkIG5vIGxvbmdlciBiZSBpbiBkZWh5ZHJhdGVkIG1vZGUuXG4gICAgICAvLyBUaGVyZWZvcmUgd2Ugbm93IGhhdmUgdG8gcmVuZGVyIHRoZSBmYWxsYmFjay5cbiAgICAgIHZhciBuZXh0UHJpbWFyeUNoaWxkcmVuID0gbmV4dFByb3BzLmNoaWxkcmVuO1xuICAgICAgdmFyIG5leHRGYWxsYmFja0NoaWxkcmVuID0gbmV4dFByb3BzLmZhbGxiYWNrO1xuICAgICAgdmFyIGZhbGxiYWNrQ2hpbGRGcmFnbWVudCA9IG1vdW50U3VzcGVuc2VGYWxsYmFja0FmdGVyUmV0cnlXaXRob3V0SHlkcmF0aW5nKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0UHJpbWFyeUNoaWxkcmVuLCBuZXh0RmFsbGJhY2tDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICAgICAgdmFyIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgIF9wcmltYXJ5Q2hpbGRGcmFnbWVudDQubWVtb2l6ZWRTdGF0ZSA9IG1vdW50U3VzcGVuc2VPZmZzY3JlZW5TdGF0ZShyZW5kZXJMYW5lcyk7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gU1VTUEVOREVEX01BUktFUjtcbiAgICAgIHJldHVybiBmYWxsYmFja0NoaWxkRnJhZ21lbnQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNjaGVkdWxlU3VzcGVuc2VXb3JrT25GaWJlcihmaWJlciwgcmVuZGVyTGFuZXMsIHByb3BhZ2F0aW9uUm9vdCkge1xuICBmaWJlci5sYW5lcyA9IG1lcmdlTGFuZXMoZmliZXIubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLmxhbmVzID0gbWVyZ2VMYW5lcyhhbHRlcm5hdGUubGFuZXMsIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHNjaGVkdWxlQ29udGV4dFdvcmtPblBhcmVudFBhdGgoZmliZXIucmV0dXJuLCByZW5kZXJMYW5lcywgcHJvcGFnYXRpb25Sb290KTtcbn1cblxuZnVuY3Rpb24gcHJvcGFnYXRlU3VzcGVuc2VDb250ZXh0Q2hhbmdlKHdvcmtJblByb2dyZXNzLCBmaXJzdENoaWxkLCByZW5kZXJMYW5lcykge1xuICAvLyBNYXJrIGFueSBTdXNwZW5zZSBib3VuZGFyaWVzIHdpdGggZmFsbGJhY2tzIGFzIGhhdmluZyB3b3JrIHRvIGRvLlxuICAvLyBJZiB0aGV5IHdlcmUgcHJldmlvdXNseSBmb3JjZWQgaW50byBmYWxsYmFja3MsIHRoZXkgbWF5IG5vdyBiZSBhYmxlXG4gIC8vIHRvIHVuYmxvY2suXG4gIHZhciBub2RlID0gZmlyc3RDaGlsZDtcblxuICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgIGlmIChub2RlLnRhZyA9PT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAgIHZhciBzdGF0ZSA9IG5vZGUubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgaWYgKHN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlU3VzcGVuc2VXb3JrT25GaWJlcihub2RlLCByZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IFN1c3BlbnNlTGlzdENvbXBvbmVudCkge1xuICAgICAgLy8gSWYgdGhlIHRhaWwgaXMgaGlkZGVuIHRoZXJlIG1pZ2h0IG5vdCBiZSBhbiBTdXNwZW5zZSBib3VuZGFyaWVzXG4gICAgICAvLyB0byBzY2hlZHVsZSB3b3JrIG9uLiBJbiB0aGlzIGNhc2Ugd2UgaGF2ZSB0byBzY2hlZHVsZSBpdCBvbiB0aGVcbiAgICAgIC8vIGxpc3QgaXRzZWxmLlxuICAgICAgLy8gV2UgZG9uJ3QgaGF2ZSB0byB0cmF2ZXJzZSB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIGxpc3Qgc2luY2VcbiAgICAgIC8vIHRoZSBsaXN0IHdpbGwgcHJvcGFnYXRlIHRoZSBjaGFuZ2Ugd2hlbiBpdCByZXJlbmRlcnMuXG4gICAgICBzY2hlZHVsZVN1c3BlbnNlV29ya09uRmliZXIobm9kZSwgcmVuZGVyTGFuZXMsIHdvcmtJblByb2dyZXNzKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUuY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUgPT09IHdvcmtJblByb2dyZXNzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSB3b3JrSW5Qcm9ncmVzcykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kTGFzdENvbnRlbnRSb3coZmlyc3RDaGlsZCkge1xuICAvLyBUaGlzIGlzIGdvaW5nIHRvIGZpbmQgdGhlIGxhc3Qgcm93IGFtb25nIHRoZXNlIGNoaWxkcmVuIHRoYXQgaXMgYWxyZWFkeVxuICAvLyBzaG93aW5nIGNvbnRlbnQgb24gdGhlIHNjcmVlbiwgYXMgb3Bwb3NlZCB0byBiZWluZyBpbiBmYWxsYmFjayBzdGF0ZSBvclxuICAvLyBuZXcuIElmIGEgcm93IGhhcyBtdWx0aXBsZSBTdXNwZW5zZSBib3VuZGFyaWVzLCBhbnkgb2YgdGhlbSBiZWluZyBpbiB0aGVcbiAgLy8gZmFsbGJhY2sgc3RhdGUsIGNvdW50cyBhcyB0aGUgd2hvbGUgcm93IGJlaW5nIGluIGEgZmFsbGJhY2sgc3RhdGUuXG4gIC8vIE5vdGUgdGhhdCB0aGUgXCJyb3dzXCIgd2lsbCBiZSB3b3JrSW5Qcm9ncmVzcywgYnV0IGFueSBuZXN0ZWQgY2hpbGRyZW5cbiAgLy8gd2lsbCBzdGlsbCBiZSBjdXJyZW50IHNpbmNlIHdlIGhhdmVuJ3QgcmVuZGVyZWQgdGhlbSB5ZXQuIFRoZSBtb3VudGVkXG4gIC8vIG9yZGVyIG1heSBub3QgYmUgdGhlIHNhbWUgYXMgdGhlIG5ldyBvcmRlci4gV2UgdXNlIHRoZSBuZXcgb3JkZXIuXG4gIHZhciByb3cgPSBmaXJzdENoaWxkO1xuICB2YXIgbGFzdENvbnRlbnRSb3cgPSBudWxsO1xuXG4gIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICB2YXIgY3VycmVudFJvdyA9IHJvdy5hbHRlcm5hdGU7IC8vIE5ldyByb3dzIGNhbid0IGJlIGNvbnRlbnQgcm93cy5cblxuICAgIGlmIChjdXJyZW50Um93ICE9PSBudWxsICYmIGZpbmRGaXJzdFN1c3BlbmRlZChjdXJyZW50Um93KSA9PT0gbnVsbCkge1xuICAgICAgbGFzdENvbnRlbnRSb3cgPSByb3c7XG4gICAgfVxuXG4gICAgcm93ID0gcm93LnNpYmxpbmc7XG4gIH1cblxuICByZXR1cm4gbGFzdENvbnRlbnRSb3c7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUmV2ZWFsT3JkZXIocmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmIChyZXZlYWxPcmRlciAhPT0gdW5kZWZpbmVkICYmIHJldmVhbE9yZGVyICE9PSAnZm9yd2FyZHMnICYmIHJldmVhbE9yZGVyICE9PSAnYmFja3dhcmRzJyAmJiByZXZlYWxPcmRlciAhPT0gJ3RvZ2V0aGVyJyAmJiAhZGlkV2FybkFib3V0UmV2ZWFsT3JkZXJbcmV2ZWFsT3JkZXJdKSB7XG4gICAgICBkaWRXYXJuQWJvdXRSZXZlYWxPcmRlcltyZXZlYWxPcmRlcl0gPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIHJldmVhbE9yZGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBzd2l0Y2ggKHJldmVhbE9yZGVyLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICBjYXNlICd0b2dldGhlcic6XG4gICAgICAgICAgY2FzZSAnZm9yd2FyZHMnOlxuICAgICAgICAgIGNhc2UgJ2JhY2t3YXJkcyc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yKCdcIiVzXCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHJldmVhbE9yZGVyIG9uIDxTdXNwZW5zZUxpc3QgLz4uICcgKyAnVXNlIGxvd2VyY2FzZSBcIiVzXCIgaW5zdGVhZC4nLCByZXZlYWxPcmRlciwgcmV2ZWFsT3JkZXIudG9Mb3dlckNhc2UoKSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBjYXNlICdmb3J3YXJkJzpcbiAgICAgICAgICBjYXNlICdiYWNrd2FyZCc6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yKCdcIiVzXCIgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHJldmVhbE9yZGVyIG9uIDxTdXNwZW5zZUxpc3QgLz4uICcgKyAnUmVhY3QgdXNlcyB0aGUgLXMgc3VmZml4IGluIHRoZSBzcGVsbGluZy4gVXNlIFwiJXNzXCIgaW5zdGVhZC4nLCByZXZlYWxPcmRlciwgcmV2ZWFsT3JkZXIudG9Mb3dlckNhc2UoKSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgZXJyb3IoJ1wiJXNcIiBpcyBub3QgYSBzdXBwb3J0ZWQgcmV2ZWFsT3JkZXIgb24gPFN1c3BlbnNlTGlzdCAvPi4gJyArICdEaWQgeW91IG1lYW4gXCJ0b2dldGhlclwiLCBcImZvcndhcmRzXCIgb3IgXCJiYWNrd2FyZHNcIj8nLCByZXZlYWxPcmRlcik7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlcnJvcignJXMgaXMgbm90IGEgc3VwcG9ydGVkIHZhbHVlIGZvciByZXZlYWxPcmRlciBvbiA8U3VzcGVuc2VMaXN0IC8+LiAnICsgJ0RpZCB5b3UgbWVhbiBcInRvZ2V0aGVyXCIsIFwiZm9yd2FyZHNcIiBvciBcImJhY2t3YXJkc1wiPycsIHJldmVhbE9yZGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVUYWlsT3B0aW9ucyh0YWlsTW9kZSwgcmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmICh0YWlsTW9kZSAhPT0gdW5kZWZpbmVkICYmICFkaWRXYXJuQWJvdXRUYWlsT3B0aW9uc1t0YWlsTW9kZV0pIHtcbiAgICAgIGlmICh0YWlsTW9kZSAhPT0gJ2NvbGxhcHNlZCcgJiYgdGFpbE1vZGUgIT09ICdoaWRkZW4nKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zW3RhaWxNb2RlXSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1wiJXNcIiBpcyBub3QgYSBzdXBwb3J0ZWQgdmFsdWUgZm9yIHRhaWwgb24gPFN1c3BlbnNlTGlzdCAvPi4gJyArICdEaWQgeW91IG1lYW4gXCJjb2xsYXBzZWRcIiBvciBcImhpZGRlblwiPycsIHRhaWxNb2RlKTtcbiAgICAgIH0gZWxzZSBpZiAocmV2ZWFsT3JkZXIgIT09ICdmb3J3YXJkcycgJiYgcmV2ZWFsT3JkZXIgIT09ICdiYWNrd2FyZHMnKSB7XG4gICAgICAgIGRpZFdhcm5BYm91dFRhaWxPcHRpb25zW3RhaWxNb2RlXSA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJzxTdXNwZW5zZUxpc3QgdGFpbD1cIiVzXCIgLz4gaXMgb25seSB2YWxpZCBpZiByZXZlYWxPcmRlciBpcyAnICsgJ1wiZm9yd2FyZHNcIiBvciBcImJhY2t3YXJkc1wiLiAnICsgJ0RpZCB5b3UgbWVhbiB0byBzcGVjaWZ5IHJldmVhbE9yZGVyPVwiZm9yd2FyZHNcIj8nLCB0YWlsTW9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoY2hpbGRTbG90LCBpbmRleCkge1xuICB7XG4gICAgdmFyIGlzQW5BcnJheSA9IGlzQXJyYXkoY2hpbGRTbG90KTtcbiAgICB2YXIgaXNJdGVyYWJsZSA9ICFpc0FuQXJyYXkgJiYgdHlwZW9mIGdldEl0ZXJhdG9yRm4oY2hpbGRTbG90KSA9PT0gJ2Z1bmN0aW9uJztcblxuICAgIGlmIChpc0FuQXJyYXkgfHwgaXNJdGVyYWJsZSkge1xuICAgICAgdmFyIHR5cGUgPSBpc0FuQXJyYXkgPyAnYXJyYXknIDogJ2l0ZXJhYmxlJztcblxuICAgICAgZXJyb3IoJ0EgbmVzdGVkICVzIHdhcyBwYXNzZWQgdG8gcm93ICMlcyBpbiA8U3VzcGVuc2VMaXN0IC8+LiBXcmFwIGl0IGluICcgKyAnYW4gYWRkaXRpb25hbCBTdXNwZW5zZUxpc3QgdG8gY29uZmlndXJlIGl0cyByZXZlYWxPcmRlcjogJyArICc8U3VzcGVuc2VMaXN0IHJldmVhbE9yZGVyPS4uLj4gLi4uICcgKyAnPFN1c3BlbnNlTGlzdCByZXZlYWxPcmRlcj0uLi4+eyVzfTwvU3VzcGVuc2VMaXN0PiAuLi4gJyArICc8L1N1c3BlbnNlTGlzdD4nLCB0eXBlLCBpbmRleCwgdHlwZSk7XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVTdXNwZW5zZUxpc3RDaGlsZHJlbihjaGlsZHJlbiwgcmV2ZWFsT3JkZXIpIHtcbiAge1xuICAgIGlmICgocmV2ZWFsT3JkZXIgPT09ICdmb3J3YXJkcycgfHwgcmV2ZWFsT3JkZXIgPT09ICdiYWNrd2FyZHMnKSAmJiBjaGlsZHJlbiAhPT0gdW5kZWZpbmVkICYmIGNoaWxkcmVuICE9PSBudWxsICYmIGNoaWxkcmVuICE9PSBmYWxzZSkge1xuICAgICAgaWYgKGlzQXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoIXZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoY2hpbGRyZW5baV0sIGkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaXRlcmF0b3JGbiA9IGdldEl0ZXJhdG9yRm4oY2hpbGRyZW4pO1xuXG4gICAgICAgIGlmICh0eXBlb2YgaXRlcmF0b3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHZhciBjaGlsZHJlbkl0ZXJhdG9yID0gaXRlcmF0b3JGbi5jYWxsKGNoaWxkcmVuKTtcblxuICAgICAgICAgIGlmIChjaGlsZHJlbkl0ZXJhdG9yKSB7XG4gICAgICAgICAgICB2YXIgc3RlcCA9IGNoaWxkcmVuSXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgdmFyIF9pID0gMDtcblxuICAgICAgICAgICAgZm9yICg7ICFzdGVwLmRvbmU7IHN0ZXAgPSBjaGlsZHJlbkl0ZXJhdG9yLm5leHQoKSkge1xuICAgICAgICAgICAgICBpZiAoIXZhbGlkYXRlU3VzcGVuc2VMaXN0TmVzdGVkQ2hpbGQoc3RlcC52YWx1ZSwgX2kpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgX2krKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZXJyb3IoJ0Egc2luZ2xlIHJvdyB3YXMgcGFzc2VkIHRvIGEgPFN1c3BlbnNlTGlzdCByZXZlYWxPcmRlcj1cIiVzXCIgLz4uICcgKyAnVGhpcyBpcyBub3QgdXNlZnVsIHNpbmNlIGl0IG5lZWRzIG11bHRpcGxlIHJvd3MuICcgKyAnRGlkIHlvdSBtZWFuIHRvIHBhc3MgbXVsdGlwbGUgY2hpbGRyZW4gb3IgYW4gYXJyYXk/JywgcmV2ZWFsT3JkZXIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGluaXRTdXNwZW5zZUxpc3RSZW5kZXJTdGF0ZSh3b3JrSW5Qcm9ncmVzcywgaXNCYWNrd2FyZHMsIHRhaWwsIGxhc3RDb250ZW50Um93LCB0YWlsTW9kZSkge1xuICB2YXIgcmVuZGVyU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gIGlmIChyZW5kZXJTdGF0ZSA9PT0gbnVsbCkge1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSB7XG4gICAgICBpc0JhY2t3YXJkczogaXNCYWNrd2FyZHMsXG4gICAgICByZW5kZXJpbmc6IG51bGwsXG4gICAgICByZW5kZXJpbmdTdGFydFRpbWU6IDAsXG4gICAgICBsYXN0OiBsYXN0Q29udGVudFJvdyxcbiAgICAgIHRhaWw6IHRhaWwsXG4gICAgICB0YWlsTW9kZTogdGFpbE1vZGVcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIFdlIGNhbiByZXVzZSB0aGUgZXhpc3Rpbmcgb2JqZWN0IGZyb20gcHJldmlvdXMgcmVuZGVycy5cbiAgICByZW5kZXJTdGF0ZS5pc0JhY2t3YXJkcyA9IGlzQmFja3dhcmRzO1xuICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZyA9IG51bGw7XG4gICAgcmVuZGVyU3RhdGUucmVuZGVyaW5nU3RhcnRUaW1lID0gMDtcbiAgICByZW5kZXJTdGF0ZS5sYXN0ID0gbGFzdENvbnRlbnRSb3c7XG4gICAgcmVuZGVyU3RhdGUudGFpbCA9IHRhaWw7XG4gICAgcmVuZGVyU3RhdGUudGFpbE1vZGUgPSB0YWlsTW9kZTtcbiAgfVxufSAvLyBUaGlzIGNhbiBlbmQgdXAgcmVuZGVyaW5nIHRoaXMgY29tcG9uZW50IG11bHRpcGxlIHBhc3Nlcy5cbi8vIFRoZSBmaXJzdCBwYXNzIHNwbGl0cyB0aGUgY2hpbGRyZW4gZmliZXJzIGludG8gdHdvIHNldHMuIEEgaGVhZCBhbmQgdGFpbC5cbi8vIFdlIGZpcnN0IHJlbmRlciB0aGUgaGVhZC4gSWYgYW55dGhpbmcgaXMgaW4gZmFsbGJhY2sgc3RhdGUsIHdlIGRvIGFub3RoZXJcbi8vIHBhc3MgdGhyb3VnaCBiZWdpbldvcmsgdG8gcmVyZW5kZXIgYWxsIGNoaWxkcmVuIChpbmNsdWRpbmcgdGhlIHRhaWwpIHdpdGhcbi8vIHRoZSBmb3JjZSBzdXNwZW5kIGNvbnRleHQuIElmIHRoZSBmaXJzdCByZW5kZXIgZGlkbid0IGhhdmUgYW55dGhpbmcgaW5cbi8vIGluIGZhbGxiYWNrIHN0YXRlLiBUaGVuIHdlIHJlbmRlciBlYWNoIHJvdyBpbiB0aGUgdGFpbCBvbmUtYnktb25lLlxuLy8gVGhhdCBoYXBwZW5zIGluIHRoZSBjb21wbGV0ZVdvcmsgcGhhc2Ugd2l0aG91dCBnb2luZyBiYWNrIHRvIGJlZ2luV29yay5cblxuXG5mdW5jdGlvbiB1cGRhdGVTdXNwZW5zZUxpc3RDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBuZXh0UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciByZXZlYWxPcmRlciA9IG5leHRQcm9wcy5yZXZlYWxPcmRlcjtcbiAgdmFyIHRhaWxNb2RlID0gbmV4dFByb3BzLnRhaWw7XG4gIHZhciBuZXdDaGlsZHJlbiA9IG5leHRQcm9wcy5jaGlsZHJlbjtcbiAgdmFsaWRhdGVSZXZlYWxPcmRlcihyZXZlYWxPcmRlcik7XG4gIHZhbGlkYXRlVGFpbE9wdGlvbnModGFpbE1vZGUsIHJldmVhbE9yZGVyKTtcbiAgdmFsaWRhdGVTdXNwZW5zZUxpc3RDaGlsZHJlbihuZXdDaGlsZHJlbiwgcmV2ZWFsT3JkZXIpO1xuICByZWNvbmNpbGVDaGlsZHJlbihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV3Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgdmFyIHN1c3BlbnNlQ29udGV4dCA9IHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudDtcbiAgdmFyIHNob3VsZEZvcmNlRmFsbGJhY2sgPSBoYXNTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spO1xuXG4gIGlmIChzaG91bGRGb3JjZUZhbGxiYWNrKSB7XG4gICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQsIEZvcmNlU3VzcGVuc2VGYWxsYmFjayk7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGlkU3VzcGVuZEJlZm9yZSA9IGN1cnJlbnQgIT09IG51bGwgJiYgKGN1cnJlbnQuZmxhZ3MgJiBEaWRDYXB0dXJlKSAhPT0gTm9GbGFncztcblxuICAgIGlmIChkaWRTdXNwZW5kQmVmb3JlKSB7XG4gICAgICAvLyBJZiB3ZSBwcmV2aW91c2x5IGZvcmNlZCBhIGZhbGxiYWNrLCB3ZSBuZWVkIHRvIHNjaGVkdWxlIHdvcmtcbiAgICAgIC8vIG9uIGFueSBuZXN0ZWQgYm91bmRhcmllcyB0byBsZXQgdGhlbSBrbm93IHRvIHRyeSB0byByZW5kZXJcbiAgICAgIC8vIGFnYWluLiBUaGlzIGlzIHRoZSBzYW1lIGFzIGNvbnRleHQgdXBkYXRpbmcuXG4gICAgICBwcm9wYWdhdGVTdXNwZW5zZUNvbnRleHRDaGFuZ2Uod29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLmNoaWxkLCByZW5kZXJMYW5lcyk7XG4gICAgfVxuXG4gICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0RGVmYXVsdFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VDb250ZXh0KTtcbiAgfVxuXG4gIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHN1c3BlbnNlQ29udGV4dCk7XG5cbiAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICAvLyBJbiBsZWdhY3kgbW9kZSwgU3VzcGVuc2VMaXN0IGRvZXNuJ3Qgd29yayBzbyB3ZSBqdXN0XG4gICAgLy8gdXNlIG1ha2UgaXQgYSBub29wIGJ5IHRyZWF0aW5nIGl0IGFzIHRoZSBkZWZhdWx0IHJldmVhbE9yZGVyLlxuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHN3aXRjaCAocmV2ZWFsT3JkZXIpIHtcbiAgICAgIGNhc2UgJ2ZvcndhcmRzJzpcbiAgICAgICAge1xuICAgICAgICAgIHZhciBsYXN0Q29udGVudFJvdyA9IGZpbmRMYXN0Q29udGVudFJvdyh3b3JrSW5Qcm9ncmVzcy5jaGlsZCk7XG4gICAgICAgICAgdmFyIHRhaWw7XG5cbiAgICAgICAgICBpZiAobGFzdENvbnRlbnRSb3cgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFRoZSB3aG9sZSBsaXN0IGlzIHBhcnQgb2YgdGhlIHRhaWwuXG4gICAgICAgICAgICAvLyBUT0RPOiBXZSBjb3VsZCBmYXN0IHBhdGggYnkganVzdCByZW5kZXJpbmcgdGhlIHRhaWwgbm93LlxuICAgICAgICAgICAgdGFpbCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBudWxsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBEaXNjb25uZWN0IHRoZSB0YWlsIHJvd3MgYWZ0ZXIgdGhlIGNvbnRlbnQgcm93LlxuICAgICAgICAgICAgLy8gV2UncmUgZ29pbmcgdG8gcmVuZGVyIHRoZW0gc2VwYXJhdGVseSBsYXRlci5cbiAgICAgICAgICAgIHRhaWwgPSBsYXN0Q29udGVudFJvdy5zaWJsaW5nO1xuICAgICAgICAgICAgbGFzdENvbnRlbnRSb3cuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaW5pdFN1c3BlbnNlTGlzdFJlbmRlclN0YXRlKHdvcmtJblByb2dyZXNzLCBmYWxzZSwgLy8gaXNCYWNrd2FyZHNcbiAgICAgICAgICB0YWlsLCBsYXN0Q29udGVudFJvdywgdGFpbE1vZGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgJ2JhY2t3YXJkcyc6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBXZSdyZSBnb2luZyB0byBmaW5kIHRoZSBmaXJzdCByb3cgdGhhdCBoYXMgZXhpc3RpbmcgY29udGVudC5cbiAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lIHdlJ3JlIGdvaW5nIHRvIHJldmVyc2UgdGhlIGxpc3Qgb2YgZXZlcnl0aGluZ1xuICAgICAgICAgIC8vIHdlIHBhc3MgaW4gdGhlIG1lYW50aW1lLiBUaGF0J3MgZ29pbmcgdG8gYmUgb3VyIHRhaWwgaW4gcmV2ZXJzZVxuICAgICAgICAgIC8vIG9yZGVyLlxuICAgICAgICAgIHZhciBfdGFpbCA9IG51bGw7XG4gICAgICAgICAgdmFyIHJvdyA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbnVsbDtcblxuICAgICAgICAgIHdoaWxlIChyb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBjdXJyZW50Um93ID0gcm93LmFsdGVybmF0ZTsgLy8gTmV3IHJvd3MgY2FuJ3QgYmUgY29udGVudCByb3dzLlxuXG4gICAgICAgICAgICBpZiAoY3VycmVudFJvdyAhPT0gbnVsbCAmJiBmaW5kRmlyc3RTdXNwZW5kZWQoY3VycmVudFJvdykgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBtYWluIGNvbnRlbnQuXG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcm93O1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIG5leHRSb3cgPSByb3cuc2libGluZztcbiAgICAgICAgICAgIHJvdy5zaWJsaW5nID0gX3RhaWw7XG4gICAgICAgICAgICBfdGFpbCA9IHJvdztcbiAgICAgICAgICAgIHJvdyA9IG5leHRSb3c7XG4gICAgICAgICAgfSAvLyBUT0RPOiBJZiB3b3JrSW5Qcm9ncmVzcy5jaGlsZCBpcyBudWxsLCB3ZSBjYW4gY29udGludWUgb24gdGhlIHRhaWwgaW1tZWRpYXRlbHkuXG5cblxuICAgICAgICAgIGluaXRTdXNwZW5zZUxpc3RSZW5kZXJTdGF0ZSh3b3JrSW5Qcm9ncmVzcywgdHJ1ZSwgLy8gaXNCYWNrd2FyZHNcbiAgICAgICAgICBfdGFpbCwgbnVsbCwgLy8gbGFzdFxuICAgICAgICAgIHRhaWxNb2RlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlICd0b2dldGhlcic6XG4gICAgICAgIHtcbiAgICAgICAgICBpbml0U3VzcGVuc2VMaXN0UmVuZGVyU3RhdGUod29ya0luUHJvZ3Jlc3MsIGZhbHNlLCAvLyBpc0JhY2t3YXJkc1xuICAgICAgICAgIG51bGwsIC8vIHRhaWxcbiAgICAgICAgICBudWxsLCAvLyBsYXN0XG4gICAgICAgICAgdW5kZWZpbmVkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVGhlIGRlZmF1bHQgcmV2ZWFsIG9yZGVyIGlzIHRoZSBzYW1lIGFzIG5vdCBoYXZpbmdcbiAgICAgICAgICAvLyBhIGJvdW5kYXJ5LlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVQb3J0YWxDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHB1c2hIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyk7XG4gIHZhciBuZXh0Q2hpbGRyZW4gPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG5cbiAgaWYgKGN1cnJlbnQgPT09IG51bGwpIHtcbiAgICAvLyBQb3J0YWxzIGFyZSBzcGVjaWFsIGJlY2F1c2Ugd2UgZG9uJ3QgYXBwZW5kIHRoZSBjaGlsZHJlbiBkdXJpbmcgbW91bnRcbiAgICAvLyBidXQgYXQgY29tbWl0LiBUaGVyZWZvcmUgd2UgbmVlZCB0byB0cmFjayBpbnNlcnRpb25zIHdoaWNoIHRoZSBub3JtYWxcbiAgICAvLyBmbG93IGRvZXNuJ3QgZG8gZHVyaW5nIG1vdW50LiBUaGlzIGRvZXNuJ3QgaGFwcGVuIGF0IHRoZSByb290IGJlY2F1c2VcbiAgICAvLyB0aGUgcm9vdCBhbHdheXMgc3RhcnRzIHdpdGggYSBcImN1cnJlbnRcIiB3aXRoIGEgbnVsbCBjaGlsZC5cbiAgICAvLyBUT0RPOiBDb25zaWRlciB1bmlmeWluZyB0aGlzIHdpdGggaG93IHRoZSByb290IHdvcmtzLlxuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVjb25jaWxlQ2hpbGRGaWJlcnMod29ya0luUHJvZ3Jlc3MsIG51bGwsIG5leHRDaGlsZHJlbiwgcmVuZGVyTGFuZXMpO1xuICB9IGVsc2Uge1xuICAgIHJlY29uY2lsZUNoaWxkcmVuKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBuZXh0Q2hpbGRyZW4sIHJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxudmFyIGhhc1dhcm5lZEFib3V0VXNpbmdOb1ZhbHVlUHJvcE9uQ29udGV4dFByb3ZpZGVyID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRleHRQcm92aWRlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgdmFyIHByb3ZpZGVyVHlwZSA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gIHZhciBjb250ZXh0ID0gcHJvdmlkZXJUeXBlLl9jb250ZXh0O1xuICB2YXIgbmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gIHZhciBvbGRQcm9wcyA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHM7XG4gIHZhciBuZXdWYWx1ZSA9IG5ld1Byb3BzLnZhbHVlO1xuXG4gIHtcbiAgICBpZiAoISgndmFsdWUnIGluIG5ld1Byb3BzKSkge1xuICAgICAgaWYgKCFoYXNXYXJuZWRBYm91dFVzaW5nTm9WYWx1ZVByb3BPbkNvbnRleHRQcm92aWRlcikge1xuICAgICAgICBoYXNXYXJuZWRBYm91dFVzaW5nTm9WYWx1ZVByb3BPbkNvbnRleHRQcm92aWRlciA9IHRydWU7XG5cbiAgICAgICAgZXJyb3IoJ1RoZSBgdmFsdWVgIHByb3AgaXMgcmVxdWlyZWQgZm9yIHRoZSBgPENvbnRleHQuUHJvdmlkZXI+YC4gRGlkIHlvdSBtaXNzcGVsbCBpdCBvciBmb3JnZXQgdG8gcGFzcyBpdD8nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJvdmlkZXJQcm9wVHlwZXMgPSB3b3JrSW5Qcm9ncmVzcy50eXBlLnByb3BUeXBlcztcblxuICAgIGlmIChwcm92aWRlclByb3BUeXBlcykge1xuICAgICAgY2hlY2tQcm9wVHlwZXMocHJvdmlkZXJQcm9wVHlwZXMsIG5ld1Byb3BzLCAncHJvcCcsICdDb250ZXh0LlByb3ZpZGVyJyk7XG4gICAgfVxuICB9XG5cbiAgcHVzaFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCBuZXdWYWx1ZSk7XG5cbiAge1xuICAgIGlmIChvbGRQcm9wcyAhPT0gbnVsbCkge1xuICAgICAgdmFyIG9sZFZhbHVlID0gb2xkUHJvcHMudmFsdWU7XG5cbiAgICAgIGlmIChvYmplY3RJcyhvbGRWYWx1ZSwgbmV3VmFsdWUpKSB7XG4gICAgICAgIC8vIE5vIGNoYW5nZS4gQmFpbG91dCBlYXJseSBpZiBjaGlsZHJlbiBhcmUgdGhlIHNhbWUuXG4gICAgICAgIGlmIChvbGRQcm9wcy5jaGlsZHJlbiA9PT0gbmV3UHJvcHMuY2hpbGRyZW4gJiYgIWhhc0NvbnRleHRDaGFuZ2VkKCkpIHtcbiAgICAgICAgICByZXR1cm4gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUaGUgY29udGV4dCB2YWx1ZSBjaGFuZ2VkLiBTZWFyY2ggZm9yIG1hdGNoaW5nIGNvbnN1bWVycyBhbmQgc2NoZWR1bGVcbiAgICAgICAgLy8gdGhlbSB0byB1cGRhdGUuXG4gICAgICAgIHByb3BhZ2F0ZUNvbnRleHRDaGFuZ2Uod29ya0luUHJvZ3Jlc3MsIGNvbnRleHQsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgbmV3Q2hpbGRyZW4gPSBuZXdQcm9wcy5jaGlsZHJlbjtcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5ld0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxudmFyIGhhc1dhcm5lZEFib3V0VXNpbmdDb250ZXh0QXNDb25zdW1lciA9IGZhbHNlO1xuXG5mdW5jdGlvbiB1cGRhdGVDb250ZXh0Q29uc3VtZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZTsgLy8gVGhlIGxvZ2ljIGJlbG93IGZvciBDb250ZXh0IGRpZmZlcnMgZGVwZW5kaW5nIG9uIFBST0Qgb3IgREVWIG1vZGUuIEluXG4gIC8vIERFViBtb2RlLCB3ZSBjcmVhdGUgYSBzZXBhcmF0ZSBvYmplY3QgZm9yIENvbnRleHQuQ29uc3VtZXIgdGhhdCBhY3RzXG4gIC8vIGxpa2UgYSBwcm94eSB0byBDb250ZXh0LiBUaGlzIHByb3h5IG9iamVjdCBhZGRzIHVubmVjZXNzYXJ5IGNvZGUgaW4gUFJPRFxuICAvLyBzbyB3ZSB1c2UgdGhlIG9sZCBiZWhhdmlvdXIgKENvbnRleHQuQ29uc3VtZXIgcmVmZXJlbmNlcyBDb250ZXh0KSB0b1xuICAvLyByZWR1Y2Ugc2l6ZSBhbmQgb3ZlcmhlYWQuIFRoZSBzZXBhcmF0ZSBvYmplY3QgcmVmZXJlbmNlcyBjb250ZXh0IHZpYVxuICAvLyBhIHByb3BlcnR5IGNhbGxlZCBcIl9jb250ZXh0XCIsIHdoaWNoIGFsc28gZ2l2ZXMgdXMgdGhlIGFiaWxpdHkgdG8gY2hlY2tcbiAgLy8gaW4gREVWIG1vZGUgaWYgdGhpcyBwcm9wZXJ0eSBleGlzdHMgb3Igbm90IGFuZCB3YXJuIGlmIGl0IGRvZXMgbm90LlxuXG4gIHtcbiAgICBpZiAoY29udGV4dC5fY29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBUaGlzIG1heSBiZSBiZWNhdXNlIGl0J3MgYSBDb250ZXh0IChyYXRoZXIgdGhhbiBhIENvbnN1bWVyKS5cbiAgICAgIC8vIE9yIGl0IG1heSBiZSBiZWNhdXNlIGl0J3Mgb2xkZXIgUmVhY3Qgd2hlcmUgdGhleSdyZSB0aGUgc2FtZSB0aGluZy5cbiAgICAgIC8vIFdlIG9ubHkgd2FudCB0byB3YXJuIGlmIHdlJ3JlIHN1cmUgaXQncyBhIG5ldyBSZWFjdC5cbiAgICAgIGlmIChjb250ZXh0ICE9PSBjb250ZXh0LkNvbnN1bWVyKSB7XG4gICAgICAgIGlmICghaGFzV2FybmVkQWJvdXRVc2luZ0NvbnRleHRBc0NvbnN1bWVyKSB7XG4gICAgICAgICAgaGFzV2FybmVkQWJvdXRVc2luZ0NvbnRleHRBc0NvbnN1bWVyID0gdHJ1ZTtcblxuICAgICAgICAgIGVycm9yKCdSZW5kZXJpbmcgPENvbnRleHQ+IGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAnICsgJ2EgZnV0dXJlIG1ham9yIHJlbGVhc2UuIERpZCB5b3UgbWVhbiB0byByZW5kZXIgPENvbnRleHQuQ29uc3VtZXI+IGluc3RlYWQ/Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29udGV4dCA9IGNvbnRleHQuX2NvbnRleHQ7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5ld1Byb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuICB2YXIgcmVuZGVyID0gbmV3UHJvcHMuY2hpbGRyZW47XG5cbiAge1xuICAgIGlmICh0eXBlb2YgcmVuZGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcignQSBjb250ZXh0IGNvbnN1bWVyIHdhcyByZW5kZXJlZCB3aXRoIG11bHRpcGxlIGNoaWxkcmVuLCBvciBhIGNoaWxkICcgKyBcInRoYXQgaXNuJ3QgYSBmdW5jdGlvbi4gQSBjb250ZXh0IGNvbnN1bWVyIGV4cGVjdHMgYSBzaW5nbGUgY2hpbGQgXCIgKyAndGhhdCBpcyBhIGZ1bmN0aW9uLiBJZiB5b3UgZGlkIHBhc3MgYSBmdW5jdGlvbiwgbWFrZSBzdXJlIHRoZXJlICcgKyAnaXMgbm8gdHJhaWxpbmcgb3IgbGVhZGluZyB3aGl0ZXNwYWNlIGFyb3VuZCBpdC4nKTtcbiAgICB9XG4gIH1cblxuICBwcmVwYXJlVG9SZWFkQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICB2YXIgbmV3VmFsdWUgPSByZWFkQ29udGV4dChjb250ZXh0KTtcblxuICB7XG4gICAgbWFya0NvbXBvbmVudFJlbmRlclN0YXJ0ZWQod29ya0luUHJvZ3Jlc3MpO1xuICB9XG5cbiAgdmFyIG5ld0NoaWxkcmVuO1xuXG4gIHtcbiAgICBSZWFjdEN1cnJlbnRPd25lciQxLmN1cnJlbnQgPSB3b3JrSW5Qcm9ncmVzcztcbiAgICBzZXRJc1JlbmRlcmluZyh0cnVlKTtcbiAgICBuZXdDaGlsZHJlbiA9IHJlbmRlcihuZXdWYWx1ZSk7XG4gICAgc2V0SXNSZW5kZXJpbmcoZmFsc2UpO1xuICB9XG5cbiAge1xuICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG4gIH0gLy8gUmVhY3QgRGV2VG9vbHMgcmVhZHMgdGhpcyBmbGFnLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUGVyZm9ybWVkV29yaztcbiAgcmVjb25jaWxlQ2hpbGRyZW4oY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG5ld0NoaWxkcmVuLCByZW5kZXJMYW5lcyk7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbn1cblxuZnVuY3Rpb24gbWFya1dvcmtJblByb2dyZXNzUmVjZWl2ZWRVcGRhdGUoKSB7XG4gIGRpZFJlY2VpdmVVcGRhdGUgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiByZXNldFN1c3BlbmRlZEN1cnJlbnRPbk1vdW50SW5MZWdhY3lNb2RlKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKSB7XG4gIGlmICgod29ya0luUHJvZ3Jlc3MubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIC8vIEEgbGF6eSBjb21wb25lbnQgb25seSBtb3VudHMgaWYgaXQgc3VzcGVuZGVkIGluc2lkZSBhIG5vbi1cbiAgICAgIC8vIGNvbmN1cnJlbnQgdHJlZSwgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLiBXZSB3YW50IHRvIHRyZWF0IGl0IGxpa2VcbiAgICAgIC8vIGEgbmV3IG1vdW50LCBldmVuIHRob3VnaCBhbiBlbXB0eSB2ZXJzaW9uIG9mIGl0IGFscmVhZHkgY29tbWl0dGVkLlxuICAgICAgLy8gRGlzY29ubmVjdCB0aGUgYWx0ZXJuYXRlIHBvaW50ZXJzLlxuICAgICAgY3VycmVudC5hbHRlcm5hdGUgPSBudWxsO1xuICAgICAgd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlID0gbnVsbDsgLy8gU2luY2UgdGhpcyBpcyBjb25jZXB0dWFsbHkgYSBuZXcgZmliZXIsIHNjaGVkdWxlIGEgUGxhY2VtZW50IGVmZmVjdFxuXG4gICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgLy8gUmV1c2UgcHJldmlvdXMgZGVwZW5kZW5jaWVzXG4gICAgd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzID0gY3VycmVudC5kZXBlbmRlbmNpZXM7XG4gIH1cblxuICB7XG4gICAgLy8gRG9uJ3QgdXBkYXRlIFwiYmFzZVwiIHJlbmRlciB0aW1lcyBmb3IgYmFpbG91dHMuXG4gICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmcoKTtcbiAgfVxuXG4gIG1hcmtTa2lwcGVkVXBkYXRlTGFuZXMod29ya0luUHJvZ3Jlc3MubGFuZXMpOyAvLyBDaGVjayBpZiB0aGUgY2hpbGRyZW4gaGF2ZSBhbnkgcGVuZGluZyB3b3JrLlxuXG4gIGlmICghaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MuY2hpbGRMYW5lcykpIHtcbiAgICAvLyBUaGUgY2hpbGRyZW4gZG9uJ3QgaGF2ZSBhbnkgd29yayBlaXRoZXIuIFdlIGNhbiBza2lwIHRoZW0uXG4gICAgLy8gVE9ETzogT25jZSB3ZSBhZGQgYmFjayByZXN1bWluZywgd2Ugc2hvdWxkIGNoZWNrIGlmIHRoZSBjaGlsZHJlbiBhcmVcbiAgICAvLyBhIHdvcmstaW4tcHJvZ3Jlc3Mgc2V0LiBJZiBzbywgd2UgbmVlZCB0byB0cmFuc2ZlciB0aGVpciBlZmZlY3RzLlxuICAgIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSAvLyBUaGlzIGZpYmVyIGRvZXNuJ3QgaGF2ZSB3b3JrLCBidXQgaXRzIHN1YnRyZWUgZG9lcy4gQ2xvbmUgdGhlIGNoaWxkXG4gIC8vIGZpYmVycyBhbmQgY29udGludWUuXG5cblxuICBjbG9uZUNoaWxkRmliZXJzKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzLmNoaWxkO1xufVxuXG5mdW5jdGlvbiByZW1vdW50RmliZXIoY3VycmVudCwgb2xkV29ya0luUHJvZ3Jlc3MsIG5ld1dvcmtJblByb2dyZXNzKSB7XG4gIHtcbiAgICB2YXIgcmV0dXJuRmliZXIgPSBvbGRXb3JrSW5Qcm9ncmVzcy5yZXR1cm47XG5cbiAgICBpZiAocmV0dXJuRmliZXIgPT09IG51bGwpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzd2FwIHRoZSByb290IGZpYmVyLicpO1xuICAgIH0gLy8gRGlzY29ubmVjdCBmcm9tIHRoZSBvbGQgY3VycmVudC5cbiAgICAvLyBJdCB3aWxsIGdldCBkZWxldGVkLlxuXG5cbiAgICBjdXJyZW50LmFsdGVybmF0ZSA9IG51bGw7XG4gICAgb2xkV29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlID0gbnVsbDsgLy8gQ29ubmVjdCB0byB0aGUgbmV3IHRyZWUuXG5cbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5pbmRleCA9IG9sZFdvcmtJblByb2dyZXNzLmluZGV4O1xuICAgIG5ld1dvcmtJblByb2dyZXNzLnNpYmxpbmcgPSBvbGRXb3JrSW5Qcm9ncmVzcy5zaWJsaW5nO1xuICAgIG5ld1dvcmtJblByb2dyZXNzLnJldHVybiA9IG9sZFdvcmtJblByb2dyZXNzLnJldHVybjtcbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5yZWYgPSBvbGRXb3JrSW5Qcm9ncmVzcy5yZWY7IC8vIFJlcGxhY2UgdGhlIGNoaWxkL3NpYmxpbmcgcG9pbnRlcnMgYWJvdmUgaXQuXG5cbiAgICBpZiAob2xkV29ya0luUHJvZ3Jlc3MgPT09IHJldHVybkZpYmVyLmNoaWxkKSB7XG4gICAgICByZXR1cm5GaWJlci5jaGlsZCA9IG5ld1dvcmtJblByb2dyZXNzO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcHJldlNpYmxpbmcgPSByZXR1cm5GaWJlci5jaGlsZDtcblxuICAgICAgaWYgKHByZXZTaWJsaW5nID09PSBudWxsKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1pbnRlcm5hbC9wcm9kLWVycm9yLWNvZGVzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgcGFyZW50IHRvIGhhdmUgYSBjaGlsZC4nKTtcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKHByZXZTaWJsaW5nLnNpYmxpbmcgIT09IG9sZFdvcmtJblByb2dyZXNzKSB7XG4gICAgICAgIHByZXZTaWJsaW5nID0gcHJldlNpYmxpbmcuc2libGluZztcblxuICAgICAgICBpZiAocHJldlNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvcHJvZC1lcnJvci1jb2Rlc1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gZmluZCB0aGUgcHJldmlvdXMgc2libGluZy4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwcmV2U2libGluZy5zaWJsaW5nID0gbmV3V29ya0luUHJvZ3Jlc3M7XG4gICAgfSAvLyBEZWxldGUgdGhlIG9sZCBmaWJlciBhbmQgcGxhY2UgdGhlIG5ldyBvbmUuXG4gICAgLy8gU2luY2UgdGhlIG9sZCBmaWJlciBpcyBkaXNjb25uZWN0ZWQsIHdlIGhhdmUgdG8gc2NoZWR1bGUgaXQgbWFudWFsbHkuXG5cblxuICAgIHZhciBkZWxldGlvbnMgPSByZXR1cm5GaWJlci5kZWxldGlvbnM7XG5cbiAgICBpZiAoZGVsZXRpb25zID09PSBudWxsKSB7XG4gICAgICByZXR1cm5GaWJlci5kZWxldGlvbnMgPSBbY3VycmVudF07XG4gICAgICByZXR1cm5GaWJlci5mbGFncyB8PSBDaGlsZERlbGV0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGlvbnMucHVzaChjdXJyZW50KTtcbiAgICB9XG5cbiAgICBuZXdXb3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBQbGFjZW1lbnQ7IC8vIFJlc3RhcnQgd29yayBmcm9tIHRoZSBuZXcgZmliZXIuXG5cbiAgICByZXR1cm4gbmV3V29ya0luUHJvZ3Jlc3M7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2hlY2tTY2hlZHVsZWRVcGRhdGVPckNvbnRleHQoY3VycmVudCwgcmVuZGVyTGFuZXMpIHtcbiAgLy8gQmVmb3JlIHBlcmZvcm1pbmcgYW4gZWFybHkgYmFpbG91dCwgd2UgbXVzdCBjaGVjayBpZiB0aGVyZSBhcmUgcGVuZGluZ1xuICAvLyB1cGRhdGVzIG9yIGNvbnRleHQuXG4gIHZhciB1cGRhdGVMYW5lcyA9IGN1cnJlbnQubGFuZXM7XG5cbiAgaWYgKGluY2x1ZGVzU29tZUxhbmUodXBkYXRlTGFuZXMsIHJlbmRlckxhbmVzKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IC8vIE5vIHBlbmRpbmcgdXBkYXRlLCBidXQgYmVjYXVzZSBjb250ZXh0IGlzIHByb3BhZ2F0ZWQgbGF6aWx5LCB3ZSBuZWVkXG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBhdHRlbXB0RWFybHlCYWlsb3V0SWZOb1NjaGVkdWxlZFVwZGF0ZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAgLy8gVGhpcyBmaWJlciBkb2VzIG5vdCBoYXZlIGFueSBwZW5kaW5nIHdvcmsuIEJhaWxvdXQgd2l0aG91dCBlbnRlcmluZ1xuICAvLyB0aGUgYmVnaW4gcGhhc2UuIFRoZXJlJ3Mgc3RpbGwgc29tZSBib29ra2VlcGluZyB3ZSB0aGF0IG5lZWRzIHRvIGJlIGRvbmVcbiAgLy8gaW4gdGhpcyBvcHRpbWl6ZWQgcGF0aCwgbW9zdGx5IHB1c2hpbmcgc3R1ZmYgb250byB0aGUgc3RhY2suXG4gIHN3aXRjaCAod29ya0luUHJvZ3Jlc3MudGFnKSB7XG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHB1c2hIb3N0Um9vdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG5cbiAgICAgIHJlc2V0SHlkcmF0aW9uU3RhdGUoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAgcHVzaEhvc3RDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIENvbXBvbmVudCA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG5cbiAgICAgICAgaWYgKGlzQ29udGV4dFByb3ZpZGVyKENvbXBvbmVudCkpIHtcbiAgICAgICAgICBwdXNoQ29udGV4dFByb3ZpZGVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgcHVzaEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB7XG4gICAgICAgIHZhciBuZXdWYWx1ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMudmFsdWU7XG4gICAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgICAgcHVzaFByb3ZpZGVyKHdvcmtJblByb2dyZXNzLCBjb250ZXh0LCBuZXdWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBQcm9maWxlcjpcbiAgICAgIHtcbiAgICAgICAgLy8gUHJvZmlsZXIgc2hvdWxkIG9ubHkgY2FsbCBvblJlbmRlciB3aGVuIG9uZSBvZiBpdHMgZGVzY2VuZGFudHMgYWN0dWFsbHkgcmVuZGVyZWQuXG4gICAgICAgIHZhciBoYXNDaGlsZFdvcmsgPSBpbmNsdWRlc1NvbWVMYW5lKHJlbmRlckxhbmVzLCB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzKTtcblxuICAgICAgICBpZiAoaGFzQ2hpbGRXb3JrKSB7XG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIC8vIFJlc2V0IGVmZmVjdCBkdXJhdGlvbnMgZm9yIHRoZSBuZXh0IGV2ZW50dWFsIGVmZmVjdCBwaGFzZS5cbiAgICAgICAgICAvLyBUaGVzZSBhcmUgcmVzZXQgZHVyaW5nIHJlbmRlciB0byBhbGxvdyB0aGUgRGV2VG9vbHMgY29tbWl0IGhvb2sgYSBjaGFuY2UgdG8gcmVhZCB0aGVtLFxuICAgICAgICAgIHZhciBzdGF0ZU5vZGUgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgICAgICAgc3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uID0gMDtcbiAgICAgICAgICBzdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uID0gMDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBzdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgaWYgKHN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgaWYgKHN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCkpOyAvLyBXZSBrbm93IHRoYXQgdGhpcyBjb21wb25lbnQgd2lsbCBzdXNwZW5kIGFnYWluIGJlY2F1c2UgaWYgaXQgaGFzXG4gICAgICAgICAgICAvLyBiZWVuIHVuc3VzcGVuZGVkIGl0IGhhcyBjb21taXR0ZWQgYXMgYSByZXNvbHZlZCBTdXNwZW5zZSBjb21wb25lbnQuXG4gICAgICAgICAgICAvLyBJZiBpdCBuZWVkcyB0byBiZSByZXRyaWVkLCBpdCBzaG91bGQgaGF2ZSB3b3JrIHNjaGVkdWxlZCBvbiBpdC5cblxuICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTsgLy8gV2Ugc2hvdWxkIG5ldmVyIHJlbmRlciB0aGUgY2hpbGRyZW4gb2YgYSBkZWh5ZHJhdGVkIGJvdW5kYXJ5IHVudGlsIHdlXG4gICAgICAgICAgICAvLyB1cGdyYWRlIGl0LiBXZSByZXR1cm4gbnVsbCBpbnN0ZWFkIG9mIGJhaWxvdXRPbkFscmVhZHlGaW5pc2hlZFdvcmsuXG5cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH0gLy8gSWYgdGhpcyBib3VuZGFyeSBpcyBjdXJyZW50bHkgdGltZWQgb3V0LCB3ZSBuZWVkIHRvIGRlY2lkZVxuICAgICAgICAgIC8vIHdoZXRoZXIgdG8gcmV0cnkgdGhlIHByaW1hcnkgY2hpbGRyZW4sIG9yIHRvIHNraXAgb3ZlciBpdCBhbmRcbiAgICAgICAgICAvLyBnbyBzdHJhaWdodCB0byB0aGUgZmFsbGJhY2suIENoZWNrIHRoZSBwcmlvcml0eSBvZiB0aGUgcHJpbWFyeVxuICAgICAgICAgIC8vIGNoaWxkIGZyYWdtZW50LlxuXG5cbiAgICAgICAgICB2YXIgcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgICB2YXIgcHJpbWFyeUNoaWxkTGFuZXMgPSBwcmltYXJ5Q2hpbGRGcmFnbWVudC5jaGlsZExhbmVzO1xuXG4gICAgICAgICAgaWYgKGluY2x1ZGVzU29tZUxhbmUocmVuZGVyTGFuZXMsIHByaW1hcnlDaGlsZExhbmVzKSkge1xuICAgICAgICAgICAgLy8gVGhlIHByaW1hcnkgY2hpbGRyZW4gaGF2ZSBwZW5kaW5nIHdvcmsuIFVzZSB0aGUgbm9ybWFsIHBhdGhcbiAgICAgICAgICAgIC8vIHRvIGF0dGVtcHQgdG8gcmVuZGVyIHRoZSBwcmltYXJ5IGNoaWxkcmVuIGFnYWluLlxuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZVN1c3BlbnNlQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoZSBwcmltYXJ5IGNoaWxkIGZyYWdtZW50IGRvZXMgbm90IGhhdmUgcGVuZGluZyB3b3JrIG1hcmtlZFxuICAgICAgICAgICAgLy8gb24gaXRcbiAgICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCkpOyAvLyBUaGUgcHJpbWFyeSBjaGlsZHJlbiBkbyBub3QgaGF2ZSBwZW5kaW5nIHdvcmsgd2l0aCBzdWZmaWNpZW50XG4gICAgICAgICAgICAvLyBwcmlvcml0eS4gQmFpbG91dC5cblxuICAgICAgICAgICAgdmFyIGNoaWxkID0gYmFpbG91dE9uQWxyZWFkeUZpbmlzaGVkV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgICAgICAgICBpZiAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gVGhlIGZhbGxiYWNrIGNoaWxkcmVuIGhhdmUgcGVuZGluZyB3b3JrLiBTa2lwIG92ZXIgdGhlXG4gICAgICAgICAgICAgIC8vIHByaW1hcnkgY2hpbGRyZW4gYW5kIHdvcmsgb24gdGhlIGZhbGxiYWNrLlxuICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuc2libGluZztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIE5vdGU6IFdlIGNhbiByZXR1cm4gYG51bGxgIGhlcmUgYmVjYXVzZSB3ZSBhbHJlYWR5IGNoZWNrZWRcbiAgICAgICAgICAgICAgLy8gd2hldGhlciB0aGVyZSB3ZXJlIG5lc3RlZCBjb250ZXh0IGNvbnN1bWVycywgdmlhIHRoZSBjYWxsIHRvXG4gICAgICAgICAgICAgIC8vIGBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrYCBhYm92ZS5cbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIGRpZFN1c3BlbmRCZWZvcmUgPSAoY3VycmVudC5mbGFncyAmIERpZENhcHR1cmUpICE9PSBOb0ZsYWdzO1xuXG4gICAgICAgIHZhciBfaGFzQ2hpbGRXb3JrID0gaW5jbHVkZXNTb21lTGFuZShyZW5kZXJMYW5lcywgd29ya0luUHJvZ3Jlc3MuY2hpbGRMYW5lcyk7XG5cbiAgICAgICAgaWYgKGRpZFN1c3BlbmRCZWZvcmUpIHtcbiAgICAgICAgICBpZiAoX2hhc0NoaWxkV29yaykge1xuICAgICAgICAgICAgLy8gSWYgc29tZXRoaW5nIHdhcyBpbiBmYWxsYmFjayBzdGF0ZSBsYXN0IHRpbWUsIGFuZCB3ZSBoYXZlIGFsbCB0aGVcbiAgICAgICAgICAgIC8vIHNhbWUgY2hpbGRyZW4gdGhlbiB3ZSdyZSBzdGlsbCBpbiBwcm9ncmVzc2l2ZSBsb2FkaW5nIHN0YXRlLlxuICAgICAgICAgICAgLy8gU29tZXRoaW5nIG1pZ2h0IGdldCB1bmJsb2NrZWQgYnkgc3RhdGUgdXBkYXRlcyBvciByZXRyaWVzIGluIHRoZVxuICAgICAgICAgICAgLy8gdHJlZSB3aGljaCB3aWxsIGFmZmVjdCB0aGUgdGFpbC4gU28gd2UgbmVlZCB0byB1c2UgdGhlIG5vcm1hbFxuICAgICAgICAgICAgLy8gcGF0aCB0byBjb21wdXRlIHRoZSBjb3JyZWN0IHRhaWwuXG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlU3VzcGVuc2VMaXN0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICAgICAgfSAvLyBJZiBub25lIG9mIHRoZSBjaGlsZHJlbiBoYWQgYW55IHdvcmssIHRoYXQgbWVhbnMgdGhhdCBub25lIG9mXG4gICAgICAgICAgLy8gdGhlbSBnb3QgcmV0cmllZCBzbyB0aGV5J2xsIHN0aWxsIGJlIGJsb2NrZWQgaW4gdGhlIHNhbWUgd2F5XG4gICAgICAgICAgLy8gYXMgYmVmb3JlLiBXZSBjYW4gZmFzdCBiYWlsIG91dC5cblxuXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgfSAvLyBJZiBub3RoaW5nIHN1c3BlbmRlZCBiZWZvcmUgYW5kIHdlJ3JlIHJlbmRlcmluZyB0aGUgc2FtZSBjaGlsZHJlbixcbiAgICAgICAgLy8gdGhlbiB0aGUgdGFpbCBkb2Vzbid0IG1hdHRlci4gQW55dGhpbmcgbmV3IHRoYXQgc3VzcGVuZHMgd2lsbCB3b3JrXG4gICAgICAgIC8vIGluIHRoZSBcInRvZ2V0aGVyXCIgbW9kZSwgc28gd2UgY2FuIGNvbnRpbnVlIGZyb20gdGhlIHN0YXRlIHdlIGhhZC5cblxuXG4gICAgICAgIHZhciByZW5kZXJTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgaWYgKHJlbmRlclN0YXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gUmVzZXQgdG8gdGhlIFwidG9nZXRoZXJcIiBtb2RlIGluIGNhc2Ugd2UndmUgc3RhcnRlZCBhIGRpZmZlcmVudFxuICAgICAgICAgIC8vIHVwZGF0ZSBpbiB0aGUgcGFzdCBidXQgZGlkbid0IGNvbXBsZXRlIGl0LlxuICAgICAgICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZyA9IG51bGw7XG4gICAgICAgICAgcmVuZGVyU3RhdGUudGFpbCA9IG51bGw7XG4gICAgICAgICAgcmVuZGVyU3RhdGUubGFzdEVmZmVjdCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBwdXNoU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzLCBzdXNwZW5zZVN0YWNrQ3Vyc29yLmN1cnJlbnQpO1xuXG4gICAgICAgIGlmIChfaGFzQ2hpbGRXb3JrKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gSWYgbm9uZSBvZiB0aGUgY2hpbGRyZW4gaGFkIGFueSB3b3JrLCB0aGF0IG1lYW5zIHRoYXQgbm9uZSBvZlxuICAgICAgICAgIC8vIHRoZW0gZ290IHJldHJpZWQgc28gdGhleSdsbCBzdGlsbCBiZSBibG9ja2VkIGluIHRoZSBzYW1lIHdheVxuICAgICAgICAgIC8vIGFzIGJlZm9yZS4gV2UgY2FuIGZhc3QgYmFpbCBvdXQuXG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICAvLyBOZWVkIHRvIGNoZWNrIGlmIHRoZSB0cmVlIHN0aWxsIG5lZWRzIHRvIGJlIGRlZmVycmVkLiBUaGlzIGlzXG4gICAgICAgIC8vIGFsbW9zdCBpZGVudGljYWwgdG8gdGhlIGxvZ2ljIHVzZWQgaW4gdGhlIG5vcm1hbCB1cGRhdGUgcGF0aCxcbiAgICAgICAgLy8gc28gd2UnbGwganVzdCBlbnRlciB0aGF0LiBUaGUgb25seSBkaWZmZXJlbmNlIGlzIHdlJ2xsIGJhaWwgb3V0XG4gICAgICAgIC8vIGF0IHRoZSBuZXh0IGxldmVsIGluc3RlYWQgb2YgdGhpcyBvbmUsIGJlY2F1c2UgdGhlIGNoaWxkIHByb3BzXG4gICAgICAgIC8vIGhhdmUgbm90IGNoYW5nZWQuIFdoaWNoIGlzIGZpbmUuXG4gICAgICAgIC8vIFRPRE86IFByb2JhYmx5IHNob3VsZCByZWZhY3RvciBgYmVnaW5Xb3JrYCB0byBzcGxpdCB0aGUgYmFpbG91dFxuICAgICAgICAvLyBwYXRoIGZyb20gdGhlIG5vcm1hbCBwYXRoLiBJJ20gdGVtcHRlZCB0byBkbyBhIGxhYmVsZWQgYnJlYWsgaGVyZVxuICAgICAgICAvLyBidXQgSSB3b24ndCA6KVxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IE5vTGFuZXM7XG4gICAgICAgIHJldHVybiB1cGRhdGVPZmZzY3JlZW5Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBiYWlsb3V0T25BbHJlYWR5RmluaXNoZWRXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG59XG5cbmZ1bmN0aW9uIGJlZ2luV29yayhjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpIHtcbiAge1xuICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5fZGVidWdOZWVkc1JlbW91bnQgJiYgY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVGhpcyB3aWxsIHJlc3RhcnQgdGhlIGJlZ2luIHBoYXNlIHdpdGggYSBuZXcgZmliZXIuXG4gICAgICByZXR1cm4gcmVtb3VudEZpYmVyKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBjcmVhdGVGaWJlckZyb21UeXBlQW5kUHJvcHMod29ya0luUHJvZ3Jlc3MudHlwZSwgd29ya0luUHJvZ3Jlc3Mua2V5LCB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHMsIHdvcmtJblByb2dyZXNzLl9kZWJ1Z093bmVyIHx8IG51bGwsIHdvcmtJblByb2dyZXNzLm1vZGUsIHdvcmtJblByb2dyZXNzLmxhbmVzKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICB2YXIgb2xkUHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgdmFyIG5ld1Byb3BzID0gd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzO1xuXG4gICAgaWYgKG9sZFByb3BzICE9PSBuZXdQcm9wcyB8fCBoYXNDb250ZXh0Q2hhbmdlZCgpIHx8ICggLy8gRm9yY2UgYSByZS1yZW5kZXIgaWYgdGhlIGltcGxlbWVudGF0aW9uIGNoYW5nZWQgZHVlIHRvIGhvdCByZWxvYWQ6XG4gICAgIHdvcmtJblByb2dyZXNzLnR5cGUgIT09IGN1cnJlbnQudHlwZSApKSB7XG4gICAgICAvLyBJZiBwcm9wcyBvciBjb250ZXh0IGNoYW5nZWQsIG1hcmsgdGhlIGZpYmVyIGFzIGhhdmluZyBwZXJmb3JtZWQgd29yay5cbiAgICAgIC8vIFRoaXMgbWF5IGJlIHVuc2V0IGlmIHRoZSBwcm9wcyBhcmUgZGV0ZXJtaW5lZCB0byBiZSBlcXVhbCBsYXRlciAobWVtbykuXG4gICAgICBkaWRSZWNlaXZlVXBkYXRlID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmVpdGhlciBwcm9wcyBub3IgbGVnYWN5IGNvbnRleHQgY2hhbmdlcy4gQ2hlY2sgaWYgdGhlcmUncyBhIHBlbmRpbmdcbiAgICAgIC8vIHVwZGF0ZSBvciBjb250ZXh0IGNoYW5nZS5cbiAgICAgIHZhciBoYXNTY2hlZHVsZWRVcGRhdGVPckNvbnRleHQgPSBjaGVja1NjaGVkdWxlZFVwZGF0ZU9yQ29udGV4dChjdXJyZW50LCByZW5kZXJMYW5lcyk7XG5cbiAgICAgIGlmICghaGFzU2NoZWR1bGVkVXBkYXRlT3JDb250ZXh0ICYmIC8vIElmIHRoaXMgaXMgdGhlIHNlY29uZCBwYXNzIG9mIGFuIGVycm9yIG9yIHN1c3BlbnNlIGJvdW5kYXJ5LCB0aGVyZVxuICAgICAgLy8gbWF5IG5vdCBiZSB3b3JrIHNjaGVkdWxlZCBvbiBgY3VycmVudGAsIHNvIHdlIGNoZWNrIGZvciB0aGlzIGZsYWcuXG4gICAgICAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncykge1xuICAgICAgICAvLyBObyBwZW5kaW5nIHVwZGF0ZXMgb3IgY29udGV4dC4gQmFpbCBvdXQgbm93LlxuICAgICAgICBkaWRSZWNlaXZlVXBkYXRlID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBhdHRlbXB0RWFybHlCYWlsb3V0SWZOb1NjaGVkdWxlZFVwZGF0ZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGN1cnJlbnQuZmxhZ3MgJiBGb3JjZVVwZGF0ZUZvckxlZ2FjeVN1c3BlbnNlKSAhPT0gTm9GbGFncykge1xuICAgICAgICAvLyBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlIHRoYXQgb25seSBleGlzdHMgZm9yIGxlZ2FjeSBtb2RlLlxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L3B1bGwvMTkyMTYuXG4gICAgICAgIGRpZFJlY2VpdmVVcGRhdGUgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQW4gdXBkYXRlIHdhcyBzY2hlZHVsZWQgb24gdGhpcyBmaWJlciwgYnV0IHRoZXJlIGFyZSBubyBuZXcgcHJvcHNcbiAgICAgICAgLy8gbm9yIGxlZ2FjeSBjb250ZXh0LiBTZXQgdGhpcyB0byBmYWxzZS4gSWYgYW4gdXBkYXRlIHF1ZXVlIG9yIGNvbnRleHRcbiAgICAgICAgLy8gY29uc3VtZXIgcHJvZHVjZXMgYSBjaGFuZ2VkIHZhbHVlLCBpdCB3aWxsIHNldCB0aGlzIHRvIHRydWUuIE90aGVyd2lzZSxcbiAgICAgICAgLy8gdGhlIGNvbXBvbmVudCB3aWxsIGFzc3VtZSB0aGUgY2hpbGRyZW4gaGF2ZSBub3QgY2hhbmdlZCBhbmQgYmFpbCBvdXQuXG4gICAgICAgIGRpZFJlY2VpdmVVcGRhdGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZGlkUmVjZWl2ZVVwZGF0ZSA9IGZhbHNlO1xuXG4gICAgaWYgKGdldElzSHlkcmF0aW5nKCkgJiYgaXNGb3JrZWRDaGlsZCh3b3JrSW5Qcm9ncmVzcykpIHtcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgY2hpbGQgYmVsb25ncyB0byBhIGxpc3Qgb2YgbXVsaXBsZSBjaGlsZHJlbiBpblxuICAgICAgLy8gaXRzIHBhcmVudC5cbiAgICAgIC8vXG4gICAgICAvLyBJbiBhIHRydWUgbXVsdGktdGhyZWFkZWQgaW1wbGVtZW50YXRpb24sIHdlIHdvdWxkIHJlbmRlciBjaGlsZHJlbiBvblxuICAgICAgLy8gcGFyYWxsZWwgdGhyZWFkcy4gVGhpcyB3b3VsZCByZXByZXNlbnQgdGhlIGJlZ2lubmluZyBvZiBhIG5ldyByZW5kZXJcbiAgICAgIC8vIHRocmVhZCBmb3IgdGhpcyBzdWJ0cmVlLlxuICAgICAgLy9cbiAgICAgIC8vIFdlIG9ubHkgdXNlIHRoaXMgZm9yIGlkIGdlbmVyYXRpb24gZHVyaW5nIGh5ZHJhdGlvbiwgd2hpY2ggaXMgd2h5IHRoZVxuICAgICAgLy8gbG9naWMgaXMgbG9jYXRlZCBpbiB0aGlzIHNwZWNpYWwgYnJhbmNoLlxuICAgICAgdmFyIHNsb3RJbmRleCA9IHdvcmtJblByb2dyZXNzLmluZGV4O1xuICAgICAgdmFyIG51bWJlck9mRm9ya3MgPSBnZXRGb3Jrc0F0TGV2ZWwoKTtcbiAgICAgIHB1c2hUcmVlSWQod29ya0luUHJvZ3Jlc3MsIG51bWJlck9mRm9ya3MsIHNsb3RJbmRleCk7XG4gICAgfVxuICB9IC8vIEJlZm9yZSBlbnRlcmluZyB0aGUgYmVnaW4gcGhhc2UsIGNsZWFyIHBlbmRpbmcgdXBkYXRlIHByaW9yaXR5LlxuICAvLyBUT0RPOiBUaGlzIGFzc3VtZXMgdGhhdCB3ZSdyZSBhYm91dCB0byBldmFsdWF0ZSB0aGUgY29tcG9uZW50IGFuZCBwcm9jZXNzXG4gIC8vIHRoZSB1cGRhdGUgcXVldWUuIEhvd2V2ZXIsIHRoZXJlJ3MgYW4gZXhjZXB0aW9uOiBTaW1wbGVNZW1vQ29tcG9uZW50XG4gIC8vIHNvbWV0aW1lcyBiYWlscyBvdXQgbGF0ZXIgaW4gdGhlIGJlZ2luIHBoYXNlLiBUaGlzIGluZGljYXRlcyB0aGF0IHdlIHNob3VsZFxuICAvLyBtb3ZlIHRoaXMgYXNzaWdubWVudCBvdXQgb2YgdGhlIGNvbW1vbiBwYXRoIGFuZCBpbnRvIGVhY2ggYnJhbmNoLlxuXG5cbiAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBOb0xhbmVzO1xuXG4gIHN3aXRjaCAod29ya0luUHJvZ3Jlc3MudGFnKSB7XG4gICAgY2FzZSBJbmRldGVybWluYXRlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZXR1cm4gbW91bnRJbmRldGVybWluYXRlQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB3b3JrSW5Qcm9ncmVzcy50eXBlLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBlbGVtZW50VHlwZSA9IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlO1xuICAgICAgICByZXR1cm4gbW91bnRMYXp5Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBlbGVtZW50VHlwZSwgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIENvbXBvbmVudCA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciB1bnJlc29sdmVkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG4gICAgICAgIHZhciByZXNvbHZlZFByb3BzID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPT09IENvbXBvbmVudCA/IHVucmVzb2x2ZWRQcm9wcyA6IHJlc29sdmVEZWZhdWx0UHJvcHMoQ29tcG9uZW50LCB1bnJlc29sdmVkUHJvcHMpO1xuICAgICAgICByZXR1cm4gdXBkYXRlRnVuY3Rpb25Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIENvbXBvbmVudCwgcmVzb2x2ZWRQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIF9Db21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICAgICAgICB2YXIgX3VucmVzb2x2ZWRQcm9wcyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcblxuICAgICAgICB2YXIgX3Jlc29sdmVkUHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSA9PT0gX0NvbXBvbmVudCA/IF91bnJlc29sdmVkUHJvcHMgOiByZXNvbHZlRGVmYXVsdFByb3BzKF9Db21wb25lbnQsIF91bnJlc29sdmVkUHJvcHMpO1xuXG4gICAgICAgIHJldHVybiB1cGRhdGVDbGFzc0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX0NvbXBvbmVudCwgX3Jlc29sdmVkUHJvcHMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICByZXR1cm4gdXBkYXRlSG9zdFJvb3QoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHJldHVybiB1cGRhdGVIb3N0Q29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAgcmV0dXJuIHVwZGF0ZUhvc3RUZXh0KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzKTtcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICByZXR1cm4gdXBkYXRlU3VzcGVuc2VDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHJldHVybiB1cGRhdGVQb3J0YWxDb21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIHtcbiAgICAgICAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuICAgICAgICB2YXIgX3VucmVzb2x2ZWRQcm9wczIgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7XG5cbiAgICAgICAgdmFyIF9yZXNvbHZlZFByb3BzMiA9IHdvcmtJblByb2dyZXNzLmVsZW1lbnRUeXBlID09PSB0eXBlID8gX3VucmVzb2x2ZWRQcm9wczIgOiByZXNvbHZlRGVmYXVsdFByb3BzKHR5cGUsIF91bnJlc29sdmVkUHJvcHMyKTtcblxuICAgICAgICByZXR1cm4gdXBkYXRlRm9yd2FyZFJlZihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgdHlwZSwgX3Jlc29sdmVkUHJvcHMyLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIEZyYWdtZW50OlxuICAgICAgcmV0dXJuIHVwZGF0ZUZyYWdtZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIE1vZGU6XG4gICAgICByZXR1cm4gdXBkYXRlTW9kZShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBQcm9maWxlcjpcbiAgICAgIHJldHVybiB1cGRhdGVQcm9maWxlcihjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICByZXR1cm4gdXBkYXRlQ29udGV4dFByb3ZpZGVyKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG5cbiAgICBjYXNlIENvbnRleHRDb25zdW1lcjpcbiAgICAgIHJldHVybiB1cGRhdGVDb250ZXh0Q29uc3VtZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKTtcblxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIF90eXBlMiA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciBfdW5yZXNvbHZlZFByb3BzMyA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wczsgLy8gUmVzb2x2ZSBvdXRlciBwcm9wcyBmaXJzdCwgdGhlbiByZXNvbHZlIGlubmVyIHByb3BzLlxuXG4gICAgICAgIHZhciBfcmVzb2x2ZWRQcm9wczMgPSByZXNvbHZlRGVmYXVsdFByb3BzKF90eXBlMiwgX3VucmVzb2x2ZWRQcm9wczMpO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAod29ya0luUHJvZ3Jlc3MudHlwZSAhPT0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUpIHtcbiAgICAgICAgICAgIHZhciBvdXRlclByb3BUeXBlcyA9IF90eXBlMi5wcm9wVHlwZXM7XG5cbiAgICAgICAgICAgIGlmIChvdXRlclByb3BUeXBlcykge1xuICAgICAgICAgICAgICBjaGVja1Byb3BUeXBlcyhvdXRlclByb3BUeXBlcywgX3Jlc29sdmVkUHJvcHMzLCAvLyBSZXNvbHZlZCBmb3Igb3V0ZXIgb25seVxuICAgICAgICAgICAgICAncHJvcCcsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShfdHlwZTIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBfcmVzb2x2ZWRQcm9wczMgPSByZXNvbHZlRGVmYXVsdFByb3BzKF90eXBlMi50eXBlLCBfcmVzb2x2ZWRQcm9wczMpO1xuICAgICAgICByZXR1cm4gdXBkYXRlTWVtb0NvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgX3R5cGUyLCBfcmVzb2x2ZWRQcm9wczMsIHJlbmRlckxhbmVzKTtcbiAgICAgIH1cblxuICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVNpbXBsZU1lbW9Db21wb25lbnQoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHdvcmtJblByb2dyZXNzLnR5cGUsIHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBJbmNvbXBsZXRlQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBfQ29tcG9uZW50MiA9IHdvcmtJblByb2dyZXNzLnR5cGU7XG4gICAgICAgIHZhciBfdW5yZXNvbHZlZFByb3BzNCA9IHdvcmtJblByb2dyZXNzLnBlbmRpbmdQcm9wcztcblxuICAgICAgICB2YXIgX3Jlc29sdmVkUHJvcHM0ID0gd29ya0luUHJvZ3Jlc3MuZWxlbWVudFR5cGUgPT09IF9Db21wb25lbnQyID8gX3VucmVzb2x2ZWRQcm9wczQgOiByZXNvbHZlRGVmYXVsdFByb3BzKF9Db21wb25lbnQyLCBfdW5yZXNvbHZlZFByb3BzNCk7XG5cbiAgICAgICAgcmV0dXJuIG1vdW50SW5jb21wbGV0ZUNsYXNzQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBfQ29tcG9uZW50MiwgX3Jlc29sdmVkUHJvcHM0LCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZVN1c3BlbnNlTGlzdENvbXBvbmVudChjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpO1xuICAgICAgfVxuXG4gICAgY2FzZSBTY29wZUNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZXR1cm4gdXBkYXRlT2Zmc2NyZWVuQ29tcG9uZW50KGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcyk7XG4gICAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHVuaXQgb2Ygd29yayB0YWcgKFwiICsgd29ya0luUHJvZ3Jlc3MudGFnICsgXCIpLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gXCIgKyAnUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xufVxuXG5mdW5jdGlvbiBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKSB7XG4gIC8vIFRhZyB0aGUgZmliZXIgd2l0aCBhbiB1cGRhdGUgZWZmZWN0LiBUaGlzIHR1cm5zIGEgUGxhY2VtZW50IGludG9cbiAgLy8gYSBQbGFjZW1lbnRBbmRVcGRhdGUuXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFVwZGF0ZTtcbn1cblxuZnVuY3Rpb24gbWFya1JlZiQxKHdvcmtJblByb2dyZXNzKSB7XG4gIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IFJlZjtcblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gUmVmU3RhdGljO1xuICB9XG59XG5cbnZhciBhcHBlbmRBbGxDaGlsZHJlbjtcbnZhciB1cGRhdGVIb3N0Q29udGFpbmVyO1xudmFyIHVwZGF0ZUhvc3RDb21wb25lbnQkMTtcbnZhciB1cGRhdGVIb3N0VGV4dCQxO1xuXG57XG4gIC8vIE11dGF0aW9uIG1vZGVcbiAgYXBwZW5kQWxsQ2hpbGRyZW4gPSBmdW5jdGlvbiAocGFyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmVlZHNWaXNpYmlsaXR5VG9nZ2xlLCBpc0hpZGRlbikge1xuICAgIC8vIFdlIG9ubHkgaGF2ZSB0aGUgdG9wIEZpYmVyIHRoYXQgd2FzIGNyZWF0ZWQgYnV0IHdlIG5lZWQgcmVjdXJzZSBkb3duIGl0c1xuICAgIC8vIGNoaWxkcmVuIHRvIGZpbmQgYWxsIHRoZSB0ZXJtaW5hbCBub2Rlcy5cbiAgICB2YXIgbm9kZSA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCBub2RlLnRhZyA9PT0gSG9zdFRleHQpIHtcbiAgICAgICAgYXBwZW5kSW5pdGlhbENoaWxkKHBhcmVudCwgbm9kZS5zdGF0ZU5vZGUpO1xuICAgICAgfSBlbHNlIGlmIChub2RlLnRhZyA9PT0gSG9zdFBvcnRhbCkgOyBlbHNlIGlmIChub2RlLmNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZSA9PT0gd29ya0luUHJvZ3Jlc3MpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3aGlsZSAobm9kZS5zaWJsaW5nID09PSBudWxsKSB7XG4gICAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBub2RlLnJldHVybiA9PT0gd29ya0luUHJvZ3Jlc3MpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBub2RlID0gbm9kZS5yZXR1cm47XG4gICAgICB9XG5cbiAgICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICAgIG5vZGUgPSBub2RlLnNpYmxpbmc7XG4gICAgfVxuICB9O1xuXG4gIHVwZGF0ZUhvc3RDb250YWluZXIgPSBmdW5jdGlvbiAoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpIHsvLyBOb29wXG4gIH07XG5cbiAgdXBkYXRlSG9zdENvbXBvbmVudCQxID0gZnVuY3Rpb24gKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB0eXBlLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBhbiBhbHRlcm5hdGUsIHRoYXQgbWVhbnMgdGhpcyBpcyBhbiB1cGRhdGUgYW5kIHdlIG5lZWQgdG9cbiAgICAvLyBzY2hlZHVsZSBhIHNpZGUtZWZmZWN0IHRvIGRvIHRoZSB1cGRhdGVzLlxuICAgIHZhciBvbGRQcm9wcyA9IGN1cnJlbnQubWVtb2l6ZWRQcm9wcztcblxuICAgIGlmIChvbGRQcm9wcyA9PT0gbmV3UHJvcHMpIHtcbiAgICAgIC8vIEluIG11dGF0aW9uIG1vZGUsIHRoaXMgaXMgc3VmZmljaWVudCBmb3IgYSBiYWlsb3V0IGJlY2F1c2VcbiAgICAgIC8vIHdlIHdvbid0IHRvdWNoIHRoaXMgbm9kZSBldmVuIGlmIGNoaWxkcmVuIGNoYW5nZWQuXG4gICAgICByZXR1cm47XG4gICAgfSAvLyBJZiB3ZSBnZXQgdXBkYXRlZCBiZWNhdXNlIG9uZSBvZiBvdXIgY2hpbGRyZW4gdXBkYXRlZCwgd2UgZG9uJ3RcbiAgICAvLyBoYXZlIG5ld1Byb3BzIHNvIHdlJ2xsIGhhdmUgdG8gcmV1c2UgdGhlbS5cbiAgICAvLyBUT0RPOiBTcGxpdCB0aGUgdXBkYXRlIEFQSSBhcyBzZXBhcmF0ZSBmb3IgdGhlIHByb3BzIHZzLiBjaGlsZHJlbi5cbiAgICAvLyBFdmVuIGJldHRlciB3b3VsZCBiZSBpZiBjaGlsZHJlbiB3ZXJlbid0IHNwZWNpYWwgY2FzZWQgYXQgYWxsIHRoby5cblxuXG4gICAgdmFyIGluc3RhbmNlID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgIHZhciBjdXJyZW50SG9zdENvbnRleHQgPSBnZXRIb3N0Q29udGV4dCgpOyAvLyBUT0RPOiBFeHBlcmllbmNpbmcgYW4gZXJyb3Igd2hlcmUgb2xkUHJvcHMgaXMgbnVsbC4gU3VnZ2VzdHMgYSBob3N0XG4gICAgLy8gY29tcG9uZW50IGlzIGhpdHRpbmcgdGhlIHJlc3VtZSBwYXRoLiBGaWd1cmUgb3V0IHdoeS4gUG9zc2libHlcbiAgICAvLyByZWxhdGVkIHRvIGBoaWRkZW5gLlxuXG4gICAgdmFyIHVwZGF0ZVBheWxvYWQgPSBwcmVwYXJlVXBkYXRlKGluc3RhbmNlLCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgY3VycmVudEhvc3RDb250ZXh0KTsgLy8gVE9ETzogVHlwZSB0aGlzIHNwZWNpZmljIHRvIHRoaXMgdHlwZSBvZiBjb21wb25lbnQuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IHVwZGF0ZVBheWxvYWQ7IC8vIElmIHRoZSB1cGRhdGUgcGF5bG9hZCBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBhIGNoYW5nZSBvciBpZiB0aGVyZVxuICAgIC8vIGlzIGEgbmV3IHJlZiB3ZSBtYXJrIHRoaXMgYXMgYW4gdXBkYXRlLiBBbGwgdGhlIHdvcmsgaXMgZG9uZSBpbiBjb21taXRXb3JrLlxuXG4gICAgaWYgKHVwZGF0ZVBheWxvYWQpIHtcbiAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfTtcblxuICB1cGRhdGVIb3N0VGV4dCQxID0gZnVuY3Rpb24gKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCBvbGRUZXh0LCBuZXdUZXh0KSB7XG4gICAgLy8gSWYgdGhlIHRleHQgZGlmZmVycywgbWFyayBpdCBhcyBhbiB1cGRhdGUuIEFsbCB0aGUgd29yayBpbiBkb25lIGluIGNvbW1pdFdvcmsuXG4gICAgaWYgKG9sZFRleHQgIT09IG5ld1RleHQpIHtcbiAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBoYXNSZW5kZXJlZEFUYWlsRmFsbGJhY2spIHtcbiAgaWYgKGdldElzSHlkcmF0aW5nKCkpIHtcbiAgICAvLyBJZiB3ZSdyZSBoeWRyYXRpbmcsIHdlIHNob3VsZCBjb25zdW1lIGFzIG1hbnkgaXRlbXMgYXMgd2UgY2FuXG4gICAgLy8gc28gd2UgZG9uJ3QgbGVhdmUgYW55IGJlaGluZC5cbiAgICByZXR1cm47XG4gIH1cblxuICBzd2l0Y2ggKHJlbmRlclN0YXRlLnRhaWxNb2RlKSB7XG4gICAgY2FzZSAnaGlkZGVuJzpcbiAgICAgIHtcbiAgICAgICAgLy8gQW55IGluc2VydGlvbnMgYXQgdGhlIGVuZCBvZiB0aGUgdGFpbCBsaXN0IGFmdGVyIHRoaXMgcG9pbnRcbiAgICAgICAgLy8gc2hvdWxkIGJlIGludmlzaWJsZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkgbW91bnRlZCBib3VuZGFyaWVzXG4gICAgICAgIC8vIGFueXRoaW5nIGJlZm9yZSB0aGVtIGFyZSBub3QgY29uc2lkZXJlZCBmb3IgY29sbGFwc2luZy5cbiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCB0aGUgd2hvbGUgdGFpbCB0byBmaW5kIGlmXG4gICAgICAgIC8vIHRoZXJlIGFyZSBhbnkuXG4gICAgICAgIHZhciB0YWlsTm9kZSA9IHJlbmRlclN0YXRlLnRhaWw7XG4gICAgICAgIHZhciBsYXN0VGFpbE5vZGUgPSBudWxsO1xuXG4gICAgICAgIHdoaWxlICh0YWlsTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmICh0YWlsTm9kZS5hbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGxhc3RUYWlsTm9kZSA9IHRhaWxOb2RlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRhaWxOb2RlID0gdGFpbE5vZGUuc2libGluZztcbiAgICAgICAgfSAvLyBOZXh0IHdlJ3JlIHNpbXBseSBnb2luZyB0byBkZWxldGUgYWxsIGluc2VydGlvbnMgYWZ0ZXIgdGhlXG4gICAgICAgIC8vIGxhc3QgcmVuZGVyZWQgaXRlbS5cblxuXG4gICAgICAgIGlmIChsYXN0VGFpbE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBBbGwgcmVtYWluaW5nIGl0ZW1zIGluIHRoZSB0YWlsIGFyZSBpbnNlcnRpb25zLlxuICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIERldGFjaCB0aGUgaW5zZXJ0aW9uIGFmdGVyIHRoZSBsYXN0IG5vZGUgdGhhdCB3YXMgYWxyZWFkeVxuICAgICAgICAgIC8vIGluc2VydGVkLlxuICAgICAgICAgIGxhc3RUYWlsTm9kZS5zaWJsaW5nID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSAnY29sbGFwc2VkJzpcbiAgICAgIHtcbiAgICAgICAgLy8gQW55IGluc2VydGlvbnMgYXQgdGhlIGVuZCBvZiB0aGUgdGFpbCBsaXN0IGFmdGVyIHRoaXMgcG9pbnRcbiAgICAgICAgLy8gc2hvdWxkIGJlIGludmlzaWJsZS4gSWYgdGhlcmUgYXJlIGFscmVhZHkgbW91bnRlZCBib3VuZGFyaWVzXG4gICAgICAgIC8vIGFueXRoaW5nIGJlZm9yZSB0aGVtIGFyZSBub3QgY29uc2lkZXJlZCBmb3IgY29sbGFwc2luZy5cbiAgICAgICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCB0aGUgd2hvbGUgdGFpbCB0byBmaW5kIGlmXG4gICAgICAgIC8vIHRoZXJlIGFyZSBhbnkuXG4gICAgICAgIHZhciBfdGFpbE5vZGUgPSByZW5kZXJTdGF0ZS50YWlsO1xuICAgICAgICB2YXIgX2xhc3RUYWlsTm9kZSA9IG51bGw7XG5cbiAgICAgICAgd2hpbGUgKF90YWlsTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChfdGFpbE5vZGUuYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBfbGFzdFRhaWxOb2RlID0gX3RhaWxOb2RlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIF90YWlsTm9kZSA9IF90YWlsTm9kZS5zaWJsaW5nO1xuICAgICAgICB9IC8vIE5leHQgd2UncmUgc2ltcGx5IGdvaW5nIHRvIGRlbGV0ZSBhbGwgaW5zZXJ0aW9ucyBhZnRlciB0aGVcbiAgICAgICAgLy8gbGFzdCByZW5kZXJlZCBpdGVtLlxuXG5cbiAgICAgICAgaWYgKF9sYXN0VGFpbE5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBBbGwgcmVtYWluaW5nIGl0ZW1zIGluIHRoZSB0YWlsIGFyZSBpbnNlcnRpb25zLlxuICAgICAgICAgIGlmICghaGFzUmVuZGVyZWRBVGFpbEZhbGxiYWNrICYmIHJlbmRlclN0YXRlLnRhaWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFdlIHN1c3BlbmRlZCBkdXJpbmcgdGhlIGhlYWQuIFdlIHdhbnQgdG8gc2hvdyBhdCBsZWFzdCBvbmVcbiAgICAgICAgICAgIC8vIHJvdyBhdCB0aGUgdGFpbC4gU28gd2UnbGwga2VlcCBvbiBhbmQgY3V0IG9mZiB0aGUgcmVzdC5cbiAgICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbmRlclN0YXRlLnRhaWwgPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEZXRhY2ggdGhlIGluc2VydGlvbiBhZnRlciB0aGUgbGFzdCBub2RlIHRoYXQgd2FzIGFscmVhZHlcbiAgICAgICAgICAvLyBpbnNlcnRlZC5cbiAgICAgICAgICBfbGFzdFRhaWxOb2RlLnNpYmxpbmcgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYnViYmxlUHJvcGVydGllcyhjb21wbGV0ZWRXb3JrKSB7XG4gIHZhciBkaWRCYWlsb3V0ID0gY29tcGxldGVkV29yay5hbHRlcm5hdGUgIT09IG51bGwgJiYgY29tcGxldGVkV29yay5hbHRlcm5hdGUuY2hpbGQgPT09IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG4gIHZhciBuZXdDaGlsZExhbmVzID0gTm9MYW5lcztcbiAgdmFyIHN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG5cbiAgaWYgKCFkaWRCYWlsb3V0KSB7XG4gICAgLy8gQnViYmxlIHVwIHRoZSBlYXJsaWVzdCBleHBpcmF0aW9uIHRpbWUuXG4gICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgIC8vIEluIHByb2ZpbGluZyBtb2RlLCByZXNldENoaWxkRXhwaXJhdGlvblRpbWUgaXMgYWxzbyB1c2VkIHRvIHJlc2V0XG4gICAgICAvLyBwcm9maWxlciBkdXJhdGlvbnMuXG4gICAgICB2YXIgYWN0dWFsRHVyYXRpb24gPSBjb21wbGV0ZWRXb3JrLmFjdHVhbER1cmF0aW9uO1xuICAgICAgdmFyIHRyZWVCYXNlRHVyYXRpb24gPSBjb21wbGV0ZWRXb3JrLnNlbGZCYXNlRHVyYXRpb247XG4gICAgICB2YXIgY2hpbGQgPSBjb21wbGV0ZWRXb3JrLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbmV3Q2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobmV3Q2hpbGRMYW5lcywgbWVyZ2VMYW5lcyhjaGlsZC5sYW5lcywgY2hpbGQuY2hpbGRMYW5lcykpO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gY2hpbGQuc3VidHJlZUZsYWdzO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gY2hpbGQuZmxhZ3M7IC8vIFdoZW4gYSBmaWJlciBpcyBjbG9uZWQsIGl0cyBhY3R1YWxEdXJhdGlvbiBpcyByZXNldCB0byAwLiBUaGlzIHZhbHVlIHdpbGxcbiAgICAgICAgLy8gb25seSBiZSB1cGRhdGVkIGlmIHdvcmsgaXMgZG9uZSBvbiB0aGUgZmliZXIgKGkuZS4gaXQgZG9lc24ndCBiYWlsb3V0KS5cbiAgICAgICAgLy8gV2hlbiB3b3JrIGlzIGRvbmUsIGl0IHNob3VsZCBidWJibGUgdG8gdGhlIHBhcmVudCdzIGFjdHVhbER1cmF0aW9uLiBJZlxuICAgICAgICAvLyB0aGUgZmliZXIgaGFzIG5vdCBiZWVuIGNsb25lZCB0aG91Z2gsIChtZWFuaW5nIG5vIHdvcmsgd2FzIGRvbmUpLCB0aGVuXG4gICAgICAgIC8vIHRoaXMgdmFsdWUgd2lsbCByZWZsZWN0IHRoZSBhbW91bnQgb2YgdGltZSBzcGVudCB3b3JraW5nIG9uIGEgcHJldmlvdXNcbiAgICAgICAgLy8gcmVuZGVyLiBJbiB0aGF0IGNhc2UgaXQgc2hvdWxkIG5vdCBidWJibGUuIFdlIGRldGVybWluZSB3aGV0aGVyIGl0IHdhc1xuICAgICAgICAvLyBjbG9uZWQgYnkgY29tcGFyaW5nIHRoZSBjaGlsZCBwb2ludGVyLlxuXG4gICAgICAgIGFjdHVhbER1cmF0aW9uICs9IGNoaWxkLmFjdHVhbER1cmF0aW9uO1xuICAgICAgICB0cmVlQmFzZUR1cmF0aW9uICs9IGNoaWxkLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgICAgIH1cblxuICAgICAgY29tcGxldGVkV29yay5hY3R1YWxEdXJhdGlvbiA9IGFjdHVhbER1cmF0aW9uO1xuICAgICAgY29tcGxldGVkV29yay50cmVlQmFzZUR1cmF0aW9uID0gdHJlZUJhc2VEdXJhdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9jaGlsZCA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChfY2hpbGQgIT09IG51bGwpIHtcbiAgICAgICAgbmV3Q2hpbGRMYW5lcyA9IG1lcmdlTGFuZXMobmV3Q2hpbGRMYW5lcywgbWVyZ2VMYW5lcyhfY2hpbGQubGFuZXMsIF9jaGlsZC5jaGlsZExhbmVzKSk7XG4gICAgICAgIHN1YnRyZWVGbGFncyB8PSBfY2hpbGQuc3VidHJlZUZsYWdzO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkLmZsYWdzOyAvLyBVcGRhdGUgdGhlIHJldHVybiBwb2ludGVyIHNvIHRoZSB0cmVlIGlzIGNvbnNpc3RlbnQuIFRoaXMgaXMgYSBjb2RlXG4gICAgICAgIC8vIHNtZWxsIGJlY2F1c2UgaXQgYXNzdW1lcyB0aGUgY29tbWl0IHBoYXNlIGlzIG5ldmVyIGNvbmN1cnJlbnQgd2l0aFxuICAgICAgICAvLyB0aGUgcmVuZGVyIHBoYXNlLiBXaWxsIGFkZHJlc3MgZHVyaW5nIHJlZmFjdG9yIHRvIGFsdGVybmF0ZSBtb2RlbC5cblxuICAgICAgICBfY2hpbGQucmV0dXJuID0gY29tcGxldGVkV29yaztcbiAgICAgICAgX2NoaWxkID0gX2NoaWxkLnNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29tcGxldGVkV29yay5zdWJ0cmVlRmxhZ3MgfD0gc3VidHJlZUZsYWdzO1xuICB9IGVsc2Uge1xuICAgIC8vIEJ1YmJsZSB1cCB0aGUgZWFybGllc3QgZXhwaXJhdGlvbiB0aW1lLlxuICAgIGlmICggKGNvbXBsZXRlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAvLyBJbiBwcm9maWxpbmcgbW9kZSwgcmVzZXRDaGlsZEV4cGlyYXRpb25UaW1lIGlzIGFsc28gdXNlZCB0byByZXNldFxuICAgICAgLy8gcHJvZmlsZXIgZHVyYXRpb25zLlxuICAgICAgdmFyIF90cmVlQmFzZUR1cmF0aW9uID0gY29tcGxldGVkV29yay5zZWxmQmFzZUR1cmF0aW9uO1xuICAgICAgdmFyIF9jaGlsZDIgPSBjb21wbGV0ZWRXb3JrLmNoaWxkO1xuXG4gICAgICB3aGlsZSAoX2NoaWxkMiAhPT0gbnVsbCkge1xuICAgICAgICBuZXdDaGlsZExhbmVzID0gbWVyZ2VMYW5lcyhuZXdDaGlsZExhbmVzLCBtZXJnZUxhbmVzKF9jaGlsZDIubGFuZXMsIF9jaGlsZDIuY2hpbGRMYW5lcykpOyAvLyBcIlN0YXRpY1wiIGZsYWdzIHNoYXJlIHRoZSBsaWZldGltZSBvZiB0aGUgZmliZXIvaG9vayB0aGV5IGJlbG9uZyB0byxcbiAgICAgICAgLy8gc28gd2Ugc2hvdWxkIGJ1YmJsZSB0aG9zZSB1cCBldmVuIGR1cmluZyBhIGJhaWxvdXQuIEFsbCB0aGUgb3RoZXJcbiAgICAgICAgLy8gZmxhZ3MgaGF2ZSBhIGxpZmV0aW1lIG9ubHkgb2YgYSBzaW5nbGUgcmVuZGVyICsgY29tbWl0LCBzbyB3ZSBzaG91bGRcbiAgICAgICAgLy8gaWdub3JlIHRoZW0uXG5cbiAgICAgICAgc3VidHJlZUZsYWdzIHw9IF9jaGlsZDIuc3VidHJlZUZsYWdzICYgU3RhdGljTWFzaztcbiAgICAgICAgc3VidHJlZUZsYWdzIHw9IF9jaGlsZDIuZmxhZ3MgJiBTdGF0aWNNYXNrO1xuICAgICAgICBfdHJlZUJhc2VEdXJhdGlvbiArPSBfY2hpbGQyLnRyZWVCYXNlRHVyYXRpb247XG4gICAgICAgIF9jaGlsZDIgPSBfY2hpbGQyLnNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIGNvbXBsZXRlZFdvcmsudHJlZUJhc2VEdXJhdGlvbiA9IF90cmVlQmFzZUR1cmF0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgX2NoaWxkMyA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgIHdoaWxlIChfY2hpbGQzICE9PSBudWxsKSB7XG4gICAgICAgIG5ld0NoaWxkTGFuZXMgPSBtZXJnZUxhbmVzKG5ld0NoaWxkTGFuZXMsIG1lcmdlTGFuZXMoX2NoaWxkMy5sYW5lcywgX2NoaWxkMy5jaGlsZExhbmVzKSk7IC8vIFwiU3RhdGljXCIgZmxhZ3Mgc2hhcmUgdGhlIGxpZmV0aW1lIG9mIHRoZSBmaWJlci9ob29rIHRoZXkgYmVsb25nIHRvLFxuICAgICAgICAvLyBzbyB3ZSBzaG91bGQgYnViYmxlIHRob3NlIHVwIGV2ZW4gZHVyaW5nIGEgYmFpbG91dC4gQWxsIHRoZSBvdGhlclxuICAgICAgICAvLyBmbGFncyBoYXZlIGEgbGlmZXRpbWUgb25seSBvZiBhIHNpbmdsZSByZW5kZXIgKyBjb21taXQsIHNvIHdlIHNob3VsZFxuICAgICAgICAvLyBpZ25vcmUgdGhlbS5cblxuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkMy5zdWJ0cmVlRmxhZ3MgJiBTdGF0aWNNYXNrO1xuICAgICAgICBzdWJ0cmVlRmxhZ3MgfD0gX2NoaWxkMy5mbGFncyAmIFN0YXRpY01hc2s7IC8vIFVwZGF0ZSB0aGUgcmV0dXJuIHBvaW50ZXIgc28gdGhlIHRyZWUgaXMgY29uc2lzdGVudC4gVGhpcyBpcyBhIGNvZGVcbiAgICAgICAgLy8gc21lbGwgYmVjYXVzZSBpdCBhc3N1bWVzIHRoZSBjb21taXQgcGhhc2UgaXMgbmV2ZXIgY29uY3VycmVudCB3aXRoXG4gICAgICAgIC8vIHRoZSByZW5kZXIgcGhhc2UuIFdpbGwgYWRkcmVzcyBkdXJpbmcgcmVmYWN0b3IgdG8gYWx0ZXJuYXRlIG1vZGVsLlxuXG4gICAgICAgIF9jaGlsZDMucmV0dXJuID0gY29tcGxldGVkV29yaztcbiAgICAgICAgX2NoaWxkMyA9IF9jaGlsZDMuc2libGluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wbGV0ZWRXb3JrLnN1YnRyZWVGbGFncyB8PSBzdWJ0cmVlRmxhZ3M7XG4gIH1cblxuICBjb21wbGV0ZWRXb3JrLmNoaWxkTGFuZXMgPSBuZXdDaGlsZExhbmVzO1xuICByZXR1cm4gZGlkQmFpbG91dDtcbn1cblxuZnVuY3Rpb24gY29tcGxldGVEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dFN0YXRlKSB7XG4gIGlmIChoYXNVbmh5ZHJhdGVkVGFpbE5vZGVzKCkgJiYgKHdvcmtJblByb2dyZXNzLm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSAmJiAod29ya0luUHJvZ3Jlc3MuZmxhZ3MgJiBEaWRDYXB0dXJlKSA9PT0gTm9GbGFncykge1xuICAgIHdhcm5JZlVuaHlkcmF0ZWRUYWlsTm9kZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgIHJlc2V0SHlkcmF0aW9uU3RhdGUoKTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBGb3JjZUNsaWVudFJlbmRlciB8IEluY29tcGxldGUgfCBTaG91bGRDYXB0dXJlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB3YXNIeWRyYXRlZCA9IHBvcEh5ZHJhdGlvblN0YXRlKHdvcmtJblByb2dyZXNzKTtcblxuICBpZiAobmV4dFN0YXRlICE9PSBudWxsICYmIG5leHRTdGF0ZS5kZWh5ZHJhdGVkICE9PSBudWxsKSB7XG4gICAgLy8gV2UgbWlnaHQgYmUgaW5zaWRlIGEgaHlkcmF0aW9uIHN0YXRlIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIHBpY2tpbmcgdXAgdGhpc1xuICAgIC8vIFN1c3BlbnNlIGJvdW5kYXJ5LCBhbmQgYWxzbyBhZnRlciB3ZSd2ZSByZWVudGVyZWQgaXQgZm9yIGZ1cnRoZXIgaHlkcmF0aW9uLlxuICAgIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgICBpZiAoIXdhc0h5ZHJhdGVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQSBkZWh5ZHJhdGVkIHN1c3BlbnNlIGNvbXBvbmVudCB3YXMgY29tcGxldGVkIHdpdGhvdXQgYSBoeWRyYXRlZCBub2RlLiAnICsgJ1RoaXMgaXMgcHJvYmFibHkgYSBidWcgaW4gUmVhY3QuJyk7XG4gICAgICB9XG5cbiAgICAgIHByZXBhcmVUb0h5ZHJhdGVIb3N0U3VzcGVuc2VJbnN0YW5jZSh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAge1xuICAgICAgICBpZiAoKHdvcmtJblByb2dyZXNzLm1vZGUgJiBQcm9maWxlTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgIHZhciBpc1RpbWVkT3V0U3VzcGVuc2UgPSBuZXh0U3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgICBpZiAoaXNUaW1lZE91dFN1c3BlbnNlKSB7XG4gICAgICAgICAgICAvLyBEb24ndCBjb3VudCB0aW1lIHNwZW50IGluIGEgdGltZWQgb3V0IFN1c3BlbnNlIHN1YnRyZWUgYXMgcGFydCBvZiB0aGUgYmFzZSBkdXJhdGlvbi5cbiAgICAgICAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgICAgICAgICBpZiAocHJpbWFyeUNoaWxkRnJhZ21lbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gJEZsb3dGaXhNZSBGbG93IGRvZXNuJ3Qgc3VwcG9ydCB0eXBlIGNhc3RpbmcgaW4gY29tYmluYXRpb24gd2l0aCB0aGUgLT0gb3BlcmF0b3JcbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHJlZUJhc2VEdXJhdGlvbiAtPSBwcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIG1pZ2h0IGhhdmUgcmVlbnRlcmVkIHRoaXMgYm91bmRhcnkgdG8gaHlkcmF0ZSBpdC4gSWYgc28sIHdlIG5lZWQgdG8gcmVzZXQgdGhlIGh5ZHJhdGlvblxuICAgICAgLy8gc3RhdGUgc2luY2Ugd2UncmUgbm93IGV4aXRpbmcgb3V0IG9mIGl0LiBwb3BIeWRyYXRpb25TdGF0ZSBkb2Vzbid0IGRvIHRoYXQgZm9yIHVzLlxuICAgICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuXG4gICAgICBpZiAoKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpIHtcbiAgICAgICAgLy8gVGhpcyBib3VuZGFyeSBkaWQgbm90IHN1c3BlbmQgc28gaXQncyBub3cgaHlkcmF0ZWQgYW5kIHVuc3VzcGVuZGVkLlxuICAgICAgICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgICAgIH0gLy8gSWYgbm90aGluZyBzdXNwZW5kZWQsIHdlIG5lZWQgdG8gc2NoZWR1bGUgYW4gZWZmZWN0IHRvIG1hcmsgdGhpcyBib3VuZGFyeVxuICAgICAgLy8gYXMgaGF2aW5nIGh5ZHJhdGVkIHNvIGV2ZW50cyBrbm93IHRoYXQgdGhleSdyZSBmcmVlIHRvIGJlIGludm9rZWQuXG4gICAgICAvLyBJdCdzIGFsc28gYSBzaWduYWwgdG8gcmVwbGF5IGV2ZW50cyBhbmQgdGhlIHN1c3BlbnNlIGNhbGxiYWNrLlxuICAgICAgLy8gSWYgc29tZXRoaW5nIHN1c3BlbmRlZCwgc2NoZWR1bGUgYW4gZWZmZWN0IHRvIGF0dGFjaCByZXRyeSBsaXN0ZW5lcnMuXG4gICAgICAvLyBTbyB3ZSBtaWdodCBhcyB3ZWxsIGFsd2F5cyBtYXJrIHRoaXMuXG5cblxuICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgIHtcbiAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICB2YXIgX2lzVGltZWRPdXRTdXNwZW5zZSA9IG5leHRTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgIGlmIChfaXNUaW1lZE91dFN1c3BlbnNlKSB7XG4gICAgICAgICAgICAvLyBEb24ndCBjb3VudCB0aW1lIHNwZW50IGluIGEgdGltZWQgb3V0IFN1c3BlbnNlIHN1YnRyZWUgYXMgcGFydCBvZiB0aGUgYmFzZSBkdXJhdGlvbi5cbiAgICAgICAgICAgIHZhciBfcHJpbWFyeUNoaWxkRnJhZ21lbnQgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgaWYgKF9wcmltYXJ5Q2hpbGRGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyAkRmxvd0ZpeE1lIEZsb3cgZG9lc24ndCBzdXBwb3J0IHR5cGUgY2FzdGluZyBpbiBjb21iaW5hdGlvbiB3aXRoIHRoZSAtPSBvcGVyYXRvclxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uIC09IF9wcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgdGhpcyB0cmVlLiBJZiB0aGlzIHdhcyBhIGZvcmNlZCBjbGllbnQgcmVuZGVyLFxuICAgIC8vIHRoZXJlIG1heSBoYXZlIGJlZW4gcmVjb3ZlcmFibGUgZXJyb3JzIGR1cmluZyBmaXJzdCBoeWRyYXRpb25cbiAgICAvLyBhdHRlbXB0LiBJZiBzbywgYWRkIHRoZW0gdG8gYSBxdWV1ZSBzbyB3ZSBjYW4gbG9nIHRoZW0gaW4gdGhlXG4gICAgLy8gY29tbWl0IHBoYXNlLlxuICAgIHVwZ3JhZGVIeWRyYXRpb25FcnJvcnNUb1JlY292ZXJhYmxlKCk7IC8vIEZhbGwgdGhyb3VnaCB0byBub3JtYWwgU3VzcGVuc2UgcGF0aFxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tcGxldGVXb3JrKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICB2YXIgbmV3UHJvcHMgPSB3b3JrSW5Qcm9ncmVzcy5wZW5kaW5nUHJvcHM7IC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuXG4gIHBvcFRyZWVDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcblxuICBzd2l0Y2ggKHdvcmtJblByb2dyZXNzLnRhZykge1xuICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICBjYXNlIExhenlDb21wb25lbnQ6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgRnJhZ21lbnQ6XG4gICAgY2FzZSBNb2RlOlxuICAgIGNhc2UgUHJvZmlsZXI6XG4gICAgY2FzZSBDb250ZXh0Q29uc3VtZXI6XG4gICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBDb21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihDb21wb25lbnQpKSB7XG4gICAgICAgICAgcG9wQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAge1xuICAgICAgICB2YXIgZmliZXJSb290ID0gd29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlO1xuICAgICAgICBwb3BIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmVzZXRXb3JrSW5Qcm9ncmVzc1ZlcnNpb25zKCk7XG5cbiAgICAgICAgaWYgKGZpYmVyUm9vdC5wZW5kaW5nQ29udGV4dCkge1xuICAgICAgICAgIGZpYmVyUm9vdC5jb250ZXh0ID0gZmliZXJSb290LnBlbmRpbmdDb250ZXh0O1xuICAgICAgICAgIGZpYmVyUm9vdC5wZW5kaW5nQ29udGV4dCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCB8fCBjdXJyZW50LmNoaWxkID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gSWYgd2UgaHlkcmF0ZWQsIHBvcCBzbyB0aGF0IHdlIGNhbiBkZWxldGUgYW55IHJlbWFpbmluZyBjaGlsZHJlblxuICAgICAgICAgIC8vIHRoYXQgd2VyZW4ndCBoeWRyYXRlZC5cbiAgICAgICAgICB2YXIgd2FzSHlkcmF0ZWQgPSBwb3BIeWRyYXRpb25TdGF0ZSh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICBpZiAod2FzSHlkcmF0ZWQpIHtcbiAgICAgICAgICAgIC8vIElmIHdlIGh5ZHJhdGVkLCB0aGVuIHdlJ2xsIG5lZWQgdG8gc2NoZWR1bGUgYW4gdXBkYXRlIGZvclxuICAgICAgICAgICAgLy8gdGhlIGNvbW1pdCBzaWRlLWVmZmVjdHMgb24gdGhlIHJvb3QuXG4gICAgICAgICAgICBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIHByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcblxuICAgICAgICAgICAgICBpZiAoIC8vIENoZWNrIGlmIHRoaXMgaXMgYSBjbGllbnQgcm9vdFxuICAgICAgICAgICAgICAhcHJldlN0YXRlLmlzRGVoeWRyYXRlZCB8fCAvLyBDaGVjayBpZiB3ZSByZXZlcnRlZCB0byBjbGllbnQgcmVuZGVyaW5nIChlLmcuIGR1ZSB0byBhbiBlcnJvcilcbiAgICAgICAgICAgICAgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRm9yY2VDbGllbnRSZW5kZXIpICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgICAgICAgLy8gU2NoZWR1bGUgYW4gZWZmZWN0IHRvIGNsZWFyIHRoaXMgY29udGFpbmVyIGF0IHRoZSBzdGFydCBvZiB0aGVcbiAgICAgICAgICAgICAgICAvLyBuZXh0IGNvbW1pdC4gVGhpcyBoYW5kbGVzIHRoZSBjYXNlIG9mIFJlYWN0IHJlbmRlcmluZyBpbnRvIGFcbiAgICAgICAgICAgICAgICAvLyBjb250YWluZXIgd2l0aCBwcmV2aW91cyBjaGlsZHJlbi4gSXQncyBhbHNvIHNhZmUgdG8gZG8gZm9yXG4gICAgICAgICAgICAgICAgLy8gdXBkYXRlcyB0b28sIGJlY2F1c2UgY3VycmVudC5jaGlsZCB3b3VsZCBvbmx5IGJlIG51bGwgaWYgdGhlXG4gICAgICAgICAgICAgICAgLy8gcHJldmlvdXMgcmVuZGVyIHdhcyBudWxsIChzbyB0aGUgY29udGFpbmVyIHdvdWxkIGFscmVhZHlcbiAgICAgICAgICAgICAgICAvLyBiZSBlbXB0eSkuXG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gU25hcHNob3Q7IC8vIElmIHRoaXMgd2FzIGEgZm9yY2VkIGNsaWVudCByZW5kZXIsIHRoZXJlIG1heSBoYXZlIGJlZW5cbiAgICAgICAgICAgICAgICAvLyByZWNvdmVyYWJsZSBlcnJvcnMgZHVyaW5nIGZpcnN0IGh5ZHJhdGlvbiBhdHRlbXB0LiBJZiBzbywgYWRkXG4gICAgICAgICAgICAgICAgLy8gdGhlbSB0byBhIHF1ZXVlIHNvIHdlIGNhbiBsb2cgdGhlbSBpbiB0aGUgY29tbWl0IHBoYXNlLlxuXG4gICAgICAgICAgICAgICAgdXBncmFkZUh5ZHJhdGlvbkVycm9yc1RvUmVjb3ZlcmFibGUoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHVwZGF0ZUhvc3RDb250YWluZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wSG9zdENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB2YXIgcm9vdENvbnRhaW5lckluc3RhbmNlID0gZ2V0Um9vdEhvc3RDb250YWluZXIoKTtcbiAgICAgICAgdmFyIHR5cGUgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICE9PSBudWxsICYmIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgdXBkYXRlSG9zdENvbXBvbmVudCQxKGN1cnJlbnQsIHdvcmtJblByb2dyZXNzLCB0eXBlLCBuZXdQcm9wcywgcm9vdENvbnRhaW5lckluc3RhbmNlKTtcblxuICAgICAgICAgIGlmIChjdXJyZW50LnJlZiAhPT0gd29ya0luUHJvZ3Jlc3MucmVmKSB7XG4gICAgICAgICAgICBtYXJrUmVmJDEod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIW5ld1Byb3BzKSB7XG4gICAgICAgICAgICBpZiAod29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2UgbXVzdCBoYXZlIG5ldyBwcm9wcyBmb3IgbmV3IG1vdW50cy4gVGhpcyBlcnJvciBpcyBsaWtlbHkgJyArICdjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICAgICAgfSAvLyBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSBhYm9ydCB3b3JrLlxuXG5cbiAgICAgICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIGN1cnJlbnRIb3N0Q29udGV4dCA9IGdldEhvc3RDb250ZXh0KCk7IC8vIFRPRE86IE1vdmUgY3JlYXRlSW5zdGFuY2UgdG8gYmVnaW5Xb3JrIGFuZCBrZWVwIGl0IG9uIGEgY29udGV4dFxuICAgICAgICAgIC8vIFwic3RhY2tcIiBhcyB0aGUgcGFyZW50LiBUaGVuIGFwcGVuZCBjaGlsZHJlbiBhcyB3ZSBnbyBpbiBiZWdpbldvcmtcbiAgICAgICAgICAvLyBvciBjb21wbGV0ZVdvcmsgZGVwZW5kaW5nIG9uIHdoZXRoZXIgd2Ugd2FudCB0byBhZGQgdGhlbSB0b3AtPmRvd24gb3JcbiAgICAgICAgICAvLyBib3R0b20tPnVwLiBUb3AtPmRvd24gaXMgZmFzdGVyIGluIElFMTEuXG5cbiAgICAgICAgICB2YXIgX3dhc0h5ZHJhdGVkID0gcG9wSHlkcmF0aW9uU3RhdGUod29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICAgICAgaWYgKF93YXNIeWRyYXRlZCkge1xuICAgICAgICAgICAgLy8gVE9ETzogTW92ZSB0aGlzIGFuZCBjcmVhdGVJbnN0YW5jZSBzdGVwIGludG8gdGhlIGJlZ2luUGhhc2VcbiAgICAgICAgICAgIC8vIHRvIGNvbnNvbGlkYXRlLlxuICAgICAgICAgICAgaWYgKHByZXBhcmVUb0h5ZHJhdGVIb3N0SW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgY3VycmVudEhvc3RDb250ZXh0KSkge1xuICAgICAgICAgICAgICAvLyBJZiBjaGFuZ2VzIHRvIHRoZSBoeWRyYXRlZCBub2RlIG5lZWQgdG8gYmUgYXBwbGllZCBhdCB0aGVcbiAgICAgICAgICAgICAgLy8gY29tbWl0LXBoYXNlIHdlIG1hcmsgdGhpcyBhcyBzdWNoLlxuICAgICAgICAgICAgICBtYXJrVXBkYXRlKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gY3JlYXRlSW5zdGFuY2UodHlwZSwgbmV3UHJvcHMsIHJvb3RDb250YWluZXJJbnN0YW5jZSwgY3VycmVudEhvc3RDb250ZXh0LCB3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICBhcHBlbmRBbGxDaGlsZHJlbihpbnN0YW5jZSwgd29ya0luUHJvZ3Jlc3MsIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBpbnN0YW5jZTsgLy8gQ2VydGFpbiByZW5kZXJlcnMgcmVxdWlyZSBjb21taXQtdGltZSBlZmZlY3RzIGZvciBpbml0aWFsIG1vdW50LlxuICAgICAgICAgICAgLy8gKGVnIERPTSByZW5kZXJlciBzdXBwb3J0cyBhdXRvLWZvY3VzIGZvciBjZXJ0YWluIGVsZW1lbnRzKS5cbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSBzdWNoIHJlbmRlcmVycyBnZXQgc2NoZWR1bGVkIGZvciBsYXRlciB3b3JrLlxuXG4gICAgICAgICAgICBpZiAoZmluYWxpemVJbml0aWFsQ2hpbGRyZW4oaW5zdGFuY2UsIHR5cGUsIG5ld1Byb3BzLCByb290Q29udGFpbmVySW5zdGFuY2UpKSB7XG4gICAgICAgICAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5yZWYgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGEgcmVmIG9uIGEgaG9zdCBub2RlIHdlIG5lZWQgdG8gc2NoZWR1bGUgYSBjYWxsYmFja1xuICAgICAgICAgICAgbWFya1JlZiQxKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RUZXh0OlxuICAgICAge1xuICAgICAgICB2YXIgbmV3VGV4dCA9IG5ld1Byb3BzO1xuXG4gICAgICAgIGlmIChjdXJyZW50ICYmIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSAhPSBudWxsKSB7XG4gICAgICAgICAgdmFyIG9sZFRleHQgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7IC8vIElmIHdlIGhhdmUgYW4gYWx0ZXJuYXRlLCB0aGF0IG1lYW5zIHRoaXMgaXMgYW4gdXBkYXRlIGFuZCB3ZSBuZWVkXG4gICAgICAgICAgLy8gdG8gc2NoZWR1bGUgYSBzaWRlLWVmZmVjdCB0byBkbyB0aGUgdXBkYXRlcy5cblxuICAgICAgICAgIHVwZGF0ZUhvc3RUZXh0JDEoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIG9sZFRleHQsIG5ld1RleHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmV3VGV4dCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZSBtdXN0IGhhdmUgbmV3IHByb3BzIGZvciBuZXcgbW91bnRzLiBUaGlzIGVycm9yIGlzIGxpa2VseSAnICsgJ2NhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgICB9IC8vIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIGFib3J0IHdvcmsuXG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgX3Jvb3RDb250YWluZXJJbnN0YW5jZSA9IGdldFJvb3RIb3N0Q29udGFpbmVyKCk7XG5cbiAgICAgICAgICB2YXIgX2N1cnJlbnRIb3N0Q29udGV4dCA9IGdldEhvc3RDb250ZXh0KCk7XG5cbiAgICAgICAgICB2YXIgX3dhc0h5ZHJhdGVkMiA9IHBvcEh5ZHJhdGlvblN0YXRlKHdvcmtJblByb2dyZXNzKTtcblxuICAgICAgICAgIGlmIChfd2FzSHlkcmF0ZWQyKSB7XG4gICAgICAgICAgICBpZiAocHJlcGFyZVRvSHlkcmF0ZUhvc3RUZXh0SW5zdGFuY2Uod29ya0luUHJvZ3Jlc3MpKSB7XG4gICAgICAgICAgICAgIG1hcmtVcGRhdGUod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBjcmVhdGVUZXh0SW5zdGFuY2UobmV3VGV4dCwgX3Jvb3RDb250YWluZXJJbnN0YW5jZSwgX2N1cnJlbnRIb3N0Q29udGV4dCwgd29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHBvcFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHZhciBuZXh0U3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlOyAvLyBTcGVjaWFsIHBhdGggZm9yIGRlaHlkcmF0ZWQgYm91bmRhcmllcy4gV2UgbWF5IGV2ZW50dWFsbHkgbW92ZSB0aGlzXG4gICAgICAgIC8vIHRvIGl0cyBvd24gZmliZXIgdHlwZSBzbyB0aGF0IHdlIGNhbiBhZGQgb3RoZXIga2luZHMgb2YgaHlkcmF0aW9uXG4gICAgICAgIC8vIGJvdW5kYXJpZXMgdGhhdCBhcmVuJ3QgYXNzb2NpYXRlZCB3aXRoIGEgU3VzcGVuc2UgdHJlZS4gSW4gYW50aWNpcGF0aW9uXG4gICAgICAgIC8vIG9mIHN1Y2ggYSByZWZhY3RvciwgYWxsIHRoZSBoeWRyYXRpb24gbG9naWMgaXMgY29udGFpbmVkIGluXG4gICAgICAgIC8vIHRoaXMgYnJhbmNoLlxuXG4gICAgICAgIGlmIChjdXJyZW50ID09PSBudWxsIHx8IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUuZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBmYWxsdGhyb3VnaFRvTm9ybWFsU3VzcGVuc2VQYXRoID0gY29tcGxldGVEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeShjdXJyZW50LCB3b3JrSW5Qcm9ncmVzcywgbmV4dFN0YXRlKTtcblxuICAgICAgICAgIGlmICghZmFsbHRocm91Z2hUb05vcm1hbFN1c3BlbnNlUGF0aCkge1xuICAgICAgICAgICAgaWYgKHdvcmtJblByb2dyZXNzLmZsYWdzICYgU2hvdWxkQ2FwdHVyZSkge1xuICAgICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UuIFRoZXJlIHdlcmUgcmVtYWluaW5nIHVuaHlkcmF0ZWQgbm9kZXMuIFdlIHRyZWF0XG4gICAgICAgICAgICAgIC8vIHRoaXMgYXMgYSBtaXNtYXRjaC4gUmV2ZXJ0IHRvIGNsaWVudCByZW5kZXJpbmcuXG4gICAgICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIERpZCBub3QgZmluaXNoIGh5ZHJhdGluZywgZWl0aGVyIGJlY2F1c2UgdGhpcyBpcyB0aGUgaW5pdGlhbFxuICAgICAgICAgICAgICAvLyByZW5kZXIgb3IgYmVjYXVzZSBzb21ldGhpbmcgc3VzcGVuZGVkLlxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IC8vIENvbnRpbnVlIHdpdGggdGhlIG5vcm1hbCBTdXNwZW5zZSBwYXRoLlxuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAvLyBTb21ldGhpbmcgc3VzcGVuZGVkLiBSZS1yZW5kZXIgd2l0aCB0aGUgZmFsbGJhY2sgY2hpbGRyZW4uXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSByZW5kZXJMYW5lczsgLy8gRG8gbm90IHJlc2V0IHRoZSBlZmZlY3QgbGlzdC5cblxuICAgICAgICAgIGlmICggKHdvcmtJblByb2dyZXNzLm1vZGUgJiBQcm9maWxlTW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgICAgdHJhbnNmZXJBY3R1YWxEdXJhdGlvbih3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgfSAvLyBEb24ndCBidWJibGUgcHJvcGVydGllcyBpbiB0aGlzIGNhc2UuXG5cblxuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBuZXh0RGlkVGltZW91dCA9IG5leHRTdGF0ZSAhPT0gbnVsbDtcbiAgICAgICAgdmFyIHByZXZEaWRUaW1lb3V0ID0gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG4gICAgICAgIC8vIGEgcGFzc2l2ZSBlZmZlY3QsIHdoaWNoIGlzIHdoZW4gd2UgcHJvY2VzcyB0aGUgdHJhbnNpdGlvbnNcblxuXG4gICAgICAgIGlmIChuZXh0RGlkVGltZW91dCAhPT0gcHJldkRpZFRpbWVvdXQpIHtcbiAgICAgICAgICAvLyBhbiBlZmZlY3QgdG8gdG9nZ2xlIHRoZSBzdWJ0cmVlJ3MgdmlzaWJpbGl0eS4gV2hlbiB3ZSBzd2l0Y2ggZnJvbVxuICAgICAgICAgIC8vIGZhbGxiYWNrIC0+IHByaW1hcnksIHRoZSBpbm5lciBPZmZzY3JlZW4gZmliZXIgc2NoZWR1bGVzIHRoaXMgZWZmZWN0XG4gICAgICAgICAgLy8gYXMgcGFydCBvZiBpdHMgbm9ybWFsIGNvbXBsZXRlIHBoYXNlLiBCdXQgd2hlbiB3ZSBzd2l0Y2ggZnJvbVxuICAgICAgICAgIC8vIHByaW1hcnkgLT4gZmFsbGJhY2ssIHRoZSBpbm5lciBPZmZzY3JlZW4gZmliZXIgZG9lcyBub3QgaGF2ZSBhIGNvbXBsZXRlXG4gICAgICAgICAgLy8gcGhhc2UuIFNvIHdlIG5lZWQgdG8gc2NoZWR1bGUgaXRzIGVmZmVjdCBoZXJlLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2UgYWxzbyB1c2UgdGhpcyBmbGFnIHRvIGNvbm5lY3QvZGlzY29ubmVjdCB0aGUgZWZmZWN0cywgYnV0IHRoZSBzYW1lXG4gICAgICAgICAgLy8gbG9naWMgYXBwbGllczogd2hlbiByZS1jb25uZWN0aW5nLCB0aGUgT2Zmc2NyZWVuIGZpYmVyJ3MgY29tcGxldGVcbiAgICAgICAgICAvLyBwaGFzZSB3aWxsIGhhbmRsZSBzY2hlZHVsaW5nIHRoZSBlZmZlY3QuIEl0J3Mgb25seSB3aGVuIHRoZSBmYWxsYmFja1xuICAgICAgICAgIC8vIGlzIGFjdGl2ZSB0aGF0IHdlIGhhdmUgdG8gZG8gYW55dGhpbmcgc3BlY2lhbC5cblxuXG4gICAgICAgICAgaWYgKG5leHREaWRUaW1lb3V0KSB7XG4gICAgICAgICAgICB2YXIgX29mZnNjcmVlbkZpYmVyMiA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuICAgICAgICAgICAgX29mZnNjcmVlbkZpYmVyMi5mbGFncyB8PSBWaXNpYmlsaXR5OyAvLyBUT0RPOiBUaGlzIHdpbGwgc3RpbGwgc3VzcGVuZCBhIHN5bmNocm9ub3VzIHRyZWUgaWYgYW55dGhpbmdcbiAgICAgICAgICAgIC8vIGluIHRoZSBjb25jdXJyZW50IHRyZWUgYWxyZWFkeSBzdXNwZW5kZWQgZHVyaW5nIHRoaXMgcmVuZGVyLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGtub3duIGJ1Zy5cblxuICAgICAgICAgICAgaWYgKCh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgICAgLy8gVE9ETzogTW92ZSB0aGlzIGJhY2sgdG8gdGhyb3dFeGNlcHRpb24gYmVjYXVzZSB0aGlzIGlzIHRvbyBsYXRlXG4gICAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBsYXJnZSB0cmVlIHdoaWNoIGlzIGNvbW1vbiBmb3IgaW5pdGlhbCBsb2Fkcy4gV2VcbiAgICAgICAgICAgICAgLy8gZG9uJ3Qga25vdyBpZiB3ZSBzaG91bGQgcmVzdGFydCBhIHJlbmRlciBvciBub3QgdW50aWwgd2UgZ2V0XG4gICAgICAgICAgICAgIC8vIHRoaXMgbWFya2VyLCBhbmQgdGhpcyBpcyB0b28gbGF0ZS5cbiAgICAgICAgICAgICAgLy8gSWYgdGhpcyByZW5kZXIgYWxyZWFkeSBoYWQgYSBwaW5nIG9yIGxvd2VyIHByaSB1cGRhdGVzLFxuICAgICAgICAgICAgICAvLyBhbmQgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSB3ZSBrbm93IHdlJ3JlIGdvaW5nIHRvIHN1c3BlbmQgd2VcbiAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGFibGUgdG8gaW1tZWRpYXRlbHkgcmVzdGFydCBmcm9tIHdpdGhpbiB0aHJvd0V4Y2VwdGlvbi5cbiAgICAgICAgICAgICAgdmFyIGhhc0ludmlzaWJsZUNoaWxkQ29udGV4dCA9IGN1cnJlbnQgPT09IG51bGwgJiYgKHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMudW5zdGFibGVfYXZvaWRUaGlzRmFsbGJhY2sgIT09IHRydWUgfHwgIWVuYWJsZVN1c3BlbnNlQXZvaWRUaGlzRmFsbGJhY2spO1xuXG4gICAgICAgICAgICAgIGlmIChoYXNJbnZpc2libGVDaGlsZENvbnRleHQgfHwgaGFzU3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudCwgSW52aXNpYmxlUGFyZW50U3VzcGVuc2VDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgd2FzIGluIGFuIGludmlzaWJsZSB0cmVlIG9yIGEgbmV3IHJlbmRlciwgdGhlbiBzaG93aW5nXG4gICAgICAgICAgICAgICAgLy8gdGhpcyBib3VuZGFyeSBpcyBvay5cbiAgICAgICAgICAgICAgICByZW5kZXJEaWRTdXNwZW5kKCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSdyZSBnb2luZyB0byBoYXZlIHRvIGhpZGUgY29udGVudCBzbyB3ZSBzaG91bGRcbiAgICAgICAgICAgICAgICAvLyBzdXNwZW5kIGZvciBsb25nZXIgaWYgcG9zc2libGUuXG4gICAgICAgICAgICAgICAgcmVuZGVyRGlkU3VzcGVuZERlbGF5SWZQb3NzaWJsZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHdha2VhYmxlcyA9IHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgIGlmICh3YWtlYWJsZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyBTY2hlZHVsZSBhbiBlZmZlY3QgdG8gYXR0YWNoIGEgcmV0cnkgbGlzdGVuZXIgdG8gdGhlIHByb21pc2UuXG4gICAgICAgICAgLy8gVE9ETzogTW92ZSB0byBwYXNzaXZlIHBoYXNlXG4gICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gVXBkYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmICgod29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICBpZiAobmV4dERpZFRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgLy8gRG9uJ3QgY291bnQgdGltZSBzcGVudCBpbiBhIHRpbWVkIG91dCBTdXNwZW5zZSBzdWJ0cmVlIGFzIHBhcnQgb2YgdGhlIGJhc2UgZHVyYXRpb24uXG4gICAgICAgICAgICAgIHZhciBwcmltYXJ5Q2hpbGRGcmFnbWVudCA9IHdvcmtJblByb2dyZXNzLmNoaWxkO1xuXG4gICAgICAgICAgICAgIGlmIChwcmltYXJ5Q2hpbGRGcmFnbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vICRGbG93Rml4TWUgRmxvdyBkb2Vzbid0IHN1cHBvcnQgdHlwZSBjYXN0aW5nIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlIC09IG9wZXJhdG9yXG4gICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MudHJlZUJhc2VEdXJhdGlvbiAtPSBwcmltYXJ5Q2hpbGRGcmFnbWVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBwb3BIb3N0Q29udGFpbmVyKHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHVwZGF0ZUhvc3RDb250YWluZXIoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MpO1xuXG4gICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICBwcmVwYXJlUG9ydGFsTW91bnQod29ya0luUHJvZ3Jlc3Muc3RhdGVOb2RlLmNvbnRhaW5lckluZm8pO1xuICAgICAgfVxuXG4gICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICAvLyBQb3AgcHJvdmlkZXIgZmliZXJcbiAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgIHBvcFByb3ZpZGVyKGNvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgLy8gU2FtZSBhcyBjbGFzcyBjb21wb25lbnQgY2FzZS4gSSBwdXQgaXQgZG93biBoZXJlIHNvIHRoYXQgdGhlIHRhZ3MgYXJlXG4gICAgICAgIC8vIHNlcXVlbnRpYWwgdG8gZW5zdXJlIHRoaXMgc3dpdGNoIGlzIGNvbXBpbGVkIHRvIGEganVtcCB0YWJsZS5cbiAgICAgICAgdmFyIF9Db21wb25lbnQgPSB3b3JrSW5Qcm9ncmVzcy50eXBlO1xuXG4gICAgICAgIGlmIChpc0NvbnRleHRQcm92aWRlcihfQ29tcG9uZW50KSkge1xuICAgICAgICAgIHBvcENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHBvcFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHZhciByZW5kZXJTdGF0ZSA9IHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgaWYgKHJlbmRlclN0YXRlID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2UncmUgcnVubmluZyBpbiB0aGUgZGVmYXVsdCwgXCJpbmRlcGVuZGVudFwiIG1vZGUuXG4gICAgICAgICAgLy8gV2UgZG9uJ3QgZG8gYW55dGhpbmcgaW4gdGhpcyBtb2RlLlxuICAgICAgICAgIGJ1YmJsZVByb3BlcnRpZXMod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRpZFN1c3BlbmRBbHJlYWR5ID0gKHdvcmtJblByb2dyZXNzLmZsYWdzICYgRGlkQ2FwdHVyZSkgIT09IE5vRmxhZ3M7XG4gICAgICAgIHZhciByZW5kZXJlZFRhaWwgPSByZW5kZXJTdGF0ZS5yZW5kZXJpbmc7XG5cbiAgICAgICAgaWYgKHJlbmRlcmVkVGFpbCA9PT0gbnVsbCkge1xuICAgICAgICAgIC8vIFdlIGp1c3QgcmVuZGVyZWQgdGhlIGhlYWQuXG4gICAgICAgICAgaWYgKCFkaWRTdXNwZW5kQWxyZWFkeSkge1xuICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmlyc3QgcGFzcy4gV2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIGFueXRoaW5nIGlzIHN0aWxsXG4gICAgICAgICAgICAvLyBzdXNwZW5kZWQgaW4gdGhlIHJlbmRlcmVkIHNldC5cbiAgICAgICAgICAgIC8vIElmIG5ldyBjb250ZW50IHVuc3VzcGVuZGVkLCBidXQgdGhlcmUncyBzdGlsbCBzb21lIGNvbnRlbnQgdGhhdFxuICAgICAgICAgICAgLy8gZGlkbid0LiBUaGVuIHdlIG5lZWQgdG8gZG8gYSBzZWNvbmQgcGFzcyB0aGF0IGZvcmNlcyBldmVyeXRoaW5nXG4gICAgICAgICAgICAvLyB0byBrZWVwIHNob3dpbmcgdGhlaXIgZmFsbGJhY2tzLlxuICAgICAgICAgICAgLy8gV2UgbWlnaHQgYmUgc3VzcGVuZGVkIGlmIHNvbWV0aGluZyBpbiB0aGlzIHJlbmRlciBwYXNzIHN1c3BlbmRlZCwgb3JcbiAgICAgICAgICAgIC8vIHNvbWV0aGluZyBpbiB0aGUgcHJldmlvdXMgY29tbWl0dGVkIHBhc3Mgc3VzcGVuZGVkLiBPdGhlcndpc2UsXG4gICAgICAgICAgICAvLyB0aGVyZSdzIG5vIGNoYW5jZSBzbyB3ZSBjYW4gc2tpcCB0aGUgZXhwZW5zaXZlIGNhbGwgdG9cbiAgICAgICAgICAgIC8vIGZpbmRGaXJzdFN1c3BlbmRlZC5cbiAgICAgICAgICAgIHZhciBjYW5ub3RCZVN1c3BlbmRlZCA9IHJlbmRlckhhc05vdFN1c3BlbmRlZFlldCgpICYmIChjdXJyZW50ID09PSBudWxsIHx8IChjdXJyZW50LmZsYWdzICYgRGlkQ2FwdHVyZSkgPT09IE5vRmxhZ3MpO1xuXG4gICAgICAgICAgICBpZiAoIWNhbm5vdEJlU3VzcGVuZGVkKSB7XG4gICAgICAgICAgICAgIHZhciByb3cgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcblxuICAgICAgICAgICAgICB3aGlsZSAocm93ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN1c3BlbmRlZCA9IGZpbmRGaXJzdFN1c3BlbmRlZChyb3cpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN1c3BlbmRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgZGlkU3VzcGVuZEFscmVhZHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgICAgICAgICAgIGN1dE9mZlRhaWxJZk5lZWRlZChyZW5kZXJTdGF0ZSwgZmFsc2UpOyAvLyBJZiB0aGlzIGlzIGEgbmV3bHkgc3VzcGVuZGVkIHRyZWUsIGl0IG1pZ2h0IG5vdCBnZXQgY29tbWl0dGVkIGFzXG4gICAgICAgICAgICAgICAgICAvLyBwYXJ0IG9mIHRoZSBzZWNvbmQgcGFzcy4gSW4gdGhhdCBjYXNlIG5vdGhpbmcgd2lsbCBzdWJzY3JpYmUgdG9cbiAgICAgICAgICAgICAgICAgIC8vIGl0cyB0aGVuYWJsZXMuIEluc3RlYWQsIHdlJ2xsIHRyYW5zZmVyIGl0cyB0aGVuYWJsZXMgdG8gdGhlXG4gICAgICAgICAgICAgICAgICAvLyBTdXNwZW5zZUxpc3Qgc28gdGhhdCBpdCBjYW4gcmV0cnkgaWYgdGhleSByZXNvbHZlLlxuICAgICAgICAgICAgICAgICAgLy8gVGhlcmUgbWlnaHQgYmUgbXVsdGlwbGUgb2YgdGhlc2UgaW4gdGhlIGxpc3QgYnV0IHNpbmNlIHdlJ3JlXG4gICAgICAgICAgICAgICAgICAvLyBnb2luZyB0byB3YWl0IGZvciBhbGwgb2YgdGhlbSBhbnl3YXksIGl0IGRvZXNuJ3QgcmVhbGx5IG1hdHRlclxuICAgICAgICAgICAgICAgICAgLy8gd2hpY2ggb25lcyBnZXRzIHRvIHBpbmcuIEluIHRoZW9yeSB3ZSBjb3VsZCBnZXQgY2xldmVyIGFuZCBrZWVwXG4gICAgICAgICAgICAgICAgICAvLyB0cmFjayBvZiBob3cgbWFueSBkZXBlbmRlbmNpZXMgcmVtYWluIGJ1dCBpdCBnZXRzIHRyaWNreSBiZWNhdXNlXG4gICAgICAgICAgICAgICAgICAvLyBpbiB0aGUgbWVhbnRpbWUsIHdlIGNhbiBhZGQvcmVtb3ZlL2NoYW5nZSBpdGVtcyBhbmQgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgICAgICAgICAgLy8gV2UgbWlnaHQgYmFpbCBvdXQgb2YgdGhlIGxvb3AgYmVmb3JlIGZpbmRpbmcgYW55IGJ1dCB0aGF0XG4gICAgICAgICAgICAgICAgICAvLyBkb2Vzbid0IG1hdHRlciBzaW5jZSB0aGF0IG1lYW5zIHRoYXQgdGhlIG90aGVyIGJvdW5kYXJpZXMgdGhhdFxuICAgICAgICAgICAgICAgICAgLy8gd2UgZGlkIGZpbmQgYWxyZWFkeSBoYXMgdGhlaXIgbGlzdGVuZXJzIGF0dGFjaGVkLlxuXG4gICAgICAgICAgICAgICAgICB2YXIgbmV3VGhlbmFibGVzID0gc3VzcGVuZGVkLnVwZGF0ZVF1ZXVlO1xuXG4gICAgICAgICAgICAgICAgICBpZiAobmV3VGhlbmFibGVzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gbmV3VGhlbmFibGVzO1xuICAgICAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgICAgICAgICAgICAgICB9IC8vIFJlcmVuZGVyIHRoZSB3aG9sZSBsaXN0LCBidXQgdGhpcyB0aW1lLCB3ZSdsbCBmb3JjZSBmYWxsYmFja3NcbiAgICAgICAgICAgICAgICAgIC8vIHRvIHN0YXkgaW4gcGxhY2UuXG4gICAgICAgICAgICAgICAgICAvLyBSZXNldCB0aGUgZWZmZWN0IGZsYWdzIGJlZm9yZSBkb2luZyB0aGUgc2Vjb25kIHBhc3Mgc2luY2UgdGhhdCdzIG5vdyBpbnZhbGlkLlxuICAgICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIGNoaWxkIGZpYmVycyB0byB0aGVpciBvcmlnaW5hbCBzdGF0ZS5cblxuXG4gICAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgICAgICAgICAgICAgICAgcmVzZXRDaGlsZEZpYmVycyh3b3JrSW5Qcm9ncmVzcywgcmVuZGVyTGFuZXMpOyAvLyBTZXQgdXAgdGhlIFN1c3BlbnNlIENvbnRleHQgdG8gZm9yY2Ugc3VzcGVuc2UgYW5kIGltbWVkaWF0ZWx5XG4gICAgICAgICAgICAgICAgICAvLyByZXJlbmRlciB0aGUgY2hpbGRyZW4uXG5cbiAgICAgICAgICAgICAgICAgIHB1c2hTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MsIHNldFNoYWxsb3dTdXNwZW5zZUNvbnRleHQoc3VzcGVuc2VTdGFja0N1cnNvci5jdXJyZW50LCBGb3JjZVN1c3BlbnNlRmFsbGJhY2spKTsgLy8gRG9uJ3QgYnViYmxlIHByb3BlcnRpZXMgaW4gdGhpcyBjYXNlLlxuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3MuY2hpbGQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcm93ID0gcm93LnNpYmxpbmc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlbmRlclN0YXRlLnRhaWwgIT09IG51bGwgJiYgbm93KCkgPiBnZXRSZW5kZXJUYXJnZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgLy8gV2UgaGF2ZSBhbHJlYWR5IHBhc3NlZCBvdXIgQ1BVIGRlYWRsaW5lIGJ1dCB3ZSBzdGlsbCBoYXZlIHJvd3NcbiAgICAgICAgICAgICAgLy8gbGVmdCBpbiB0aGUgdGFpbC4gV2UnbGwganVzdCBnaXZlIHVwIGZ1cnRoZXIgYXR0ZW1wdHMgdG8gcmVuZGVyXG4gICAgICAgICAgICAgIC8vIHRoZSBtYWluIGNvbnRlbnQgYW5kIG9ubHkgcmVuZGVyIGZhbGxiYWNrcy5cbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRGlkQ2FwdHVyZTtcbiAgICAgICAgICAgICAgZGlkU3VzcGVuZEFscmVhZHkgPSB0cnVlO1xuICAgICAgICAgICAgICBjdXRPZmZUYWlsSWZOZWVkZWQocmVuZGVyU3RhdGUsIGZhbHNlKTsgLy8gU2luY2Ugbm90aGluZyBhY3R1YWxseSBzdXNwZW5kZWQsIHRoZXJlIHdpbGwgbm90aGluZyB0byBwaW5nIHRoaXNcbiAgICAgICAgICAgICAgLy8gdG8gZ2V0IGl0IHN0YXJ0ZWQgYmFjayB1cCB0byBhdHRlbXB0IHRoZSBuZXh0IGl0ZW0uIFdoaWxlIGluIHRlcm1zXG4gICAgICAgICAgICAgIC8vIG9mIHByaW9yaXR5IHRoaXMgd29yayBoYXMgdGhlIHNhbWUgcHJpb3JpdHkgYXMgdGhpcyBjdXJyZW50IHJlbmRlcixcbiAgICAgICAgICAgICAgLy8gaXQncyBub3QgcGFydCBvZiB0aGUgc2FtZSB0cmFuc2l0aW9uIG9uY2UgdGhlIHRyYW5zaXRpb24gaGFzXG4gICAgICAgICAgICAgIC8vIGNvbW1pdHRlZC4gSWYgaXQncyBzeW5jLCB3ZSBzdGlsbCB3YW50IHRvIHlpZWxkIHNvIHRoYXQgaXQgY2FuIGJlXG4gICAgICAgICAgICAgIC8vIHBhaW50ZWQuIENvbmNlcHR1YWxseSwgdGhpcyBpcyByZWFsbHkgdGhlIHNhbWUgYXMgcGluZ2luZy5cbiAgICAgICAgICAgICAgLy8gV2UgY2FuIHVzZSBhbnkgUmV0cnlMYW5lIGV2ZW4gaWYgaXQncyB0aGUgb25lIGN1cnJlbnRseSByZW5kZXJpbmdcbiAgICAgICAgICAgICAgLy8gc2luY2Ugd2UncmUgbGVhdmluZyBpdCBiZWhpbmQgb24gdGhpcyBub2RlLlxuXG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gU29tZVJldHJ5TGFuZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3V0T2ZmVGFpbElmTmVlZGVkKHJlbmRlclN0YXRlLCBmYWxzZSk7XG4gICAgICAgICAgfSAvLyBOZXh0IHdlJ3JlIGdvaW5nIHRvIHJlbmRlciB0aGUgdGFpbC5cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEFwcGVuZCB0aGUgcmVuZGVyZWQgcm93IHRvIHRoZSBjaGlsZCBsaXN0LlxuICAgICAgICAgIGlmICghZGlkU3VzcGVuZEFscmVhZHkpIHtcbiAgICAgICAgICAgIHZhciBfc3VzcGVuZGVkID0gZmluZEZpcnN0U3VzcGVuZGVkKHJlbmRlcmVkVGFpbCk7XG5cbiAgICAgICAgICAgIGlmIChfc3VzcGVuZGVkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzIHw9IERpZENhcHR1cmU7XG4gICAgICAgICAgICAgIGRpZFN1c3BlbmRBbHJlYWR5ID0gdHJ1ZTsgLy8gRW5zdXJlIHdlIHRyYW5zZmVyIHRoZSB1cGRhdGUgcXVldWUgdG8gdGhlIHBhcmVudCBzbyB0aGF0IGl0IGRvZXNuJ3RcbiAgICAgICAgICAgICAgLy8gZ2V0IGxvc3QgaWYgdGhpcyByb3cgZW5kcyB1cCBkcm9wcGVkIGR1cmluZyBhIHNlY29uZCBwYXNzLlxuXG4gICAgICAgICAgICAgIHZhciBfbmV3VGhlbmFibGVzID0gX3N1c3BlbmRlZC51cGRhdGVRdWV1ZTtcblxuICAgICAgICAgICAgICBpZiAoX25ld1RoZW5hYmxlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gX25ld1RoZW5hYmxlcztcbiAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBVcGRhdGU7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjdXRPZmZUYWlsSWZOZWVkZWQocmVuZGVyU3RhdGUsIHRydWUpOyAvLyBUaGlzIG1pZ2h0IGhhdmUgYmVlbiBtb2RpZmllZC5cblxuICAgICAgICAgICAgICBpZiAocmVuZGVyU3RhdGUudGFpbCA9PT0gbnVsbCAmJiByZW5kZXJTdGF0ZS50YWlsTW9kZSA9PT0gJ2hpZGRlbicgJiYgIXJlbmRlcmVkVGFpbC5hbHRlcm5hdGUgJiYgIWdldElzSHlkcmF0aW5nKCkgLy8gV2UgZG9uJ3QgY3V0IGl0IGlmIHdlJ3JlIGh5ZHJhdGluZy5cbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAvLyBXZSdyZSBkb25lLlxuICAgICAgICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCAvLyBUaGUgdGltZSBpdCB0b29rIHRvIHJlbmRlciBsYXN0IHJvdyBpcyBncmVhdGVyIHRoYW4gdGhlIHJlbWFpbmluZ1xuICAgICAgICAgICAgLy8gdGltZSB3ZSBoYXZlIHRvIHJlbmRlci4gU28gcmVuZGVyaW5nIG9uZSBtb3JlIHJvdyB3b3VsZCBsaWtlbHlcbiAgICAgICAgICAgIC8vIGV4Y2VlZCBpdC5cbiAgICAgICAgICAgIG5vdygpICogMiAtIHJlbmRlclN0YXRlLnJlbmRlcmluZ1N0YXJ0VGltZSA+IGdldFJlbmRlclRhcmdldFRpbWUoKSAmJiByZW5kZXJMYW5lcyAhPT0gT2Zmc2NyZWVuTGFuZSkge1xuICAgICAgICAgICAgICAvLyBXZSBoYXZlIG5vdyBwYXNzZWQgb3VyIENQVSBkZWFkbGluZSBhbmQgd2UnbGwganVzdCBnaXZlIHVwIGZ1cnRoZXJcbiAgICAgICAgICAgICAgLy8gYXR0ZW1wdHMgdG8gcmVuZGVyIHRoZSBtYWluIGNvbnRlbnQgYW5kIG9ubHkgcmVuZGVyIGZhbGxiYWNrcy5cbiAgICAgICAgICAgICAgLy8gVGhlIGFzc3VtcHRpb24gaXMgdGhhdCB0aGlzIGlzIHVzdWFsbHkgZmFzdGVyLlxuICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBEaWRDYXB0dXJlO1xuICAgICAgICAgICAgICBkaWRTdXNwZW5kQWxyZWFkeSA9IHRydWU7XG4gICAgICAgICAgICAgIGN1dE9mZlRhaWxJZk5lZWRlZChyZW5kZXJTdGF0ZSwgZmFsc2UpOyAvLyBTaW5jZSBub3RoaW5nIGFjdHVhbGx5IHN1c3BlbmRlZCwgdGhlcmUgd2lsbCBub3RoaW5nIHRvIHBpbmcgdGhpc1xuICAgICAgICAgICAgICAvLyB0byBnZXQgaXQgc3RhcnRlZCBiYWNrIHVwIHRvIGF0dGVtcHQgdGhlIG5leHQgaXRlbS4gV2hpbGUgaW4gdGVybXNcbiAgICAgICAgICAgICAgLy8gb2YgcHJpb3JpdHkgdGhpcyB3b3JrIGhhcyB0aGUgc2FtZSBwcmlvcml0eSBhcyB0aGlzIGN1cnJlbnQgcmVuZGVyLFxuICAgICAgICAgICAgICAvLyBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBzYW1lIHRyYW5zaXRpb24gb25jZSB0aGUgdHJhbnNpdGlvbiBoYXNcbiAgICAgICAgICAgICAgLy8gY29tbWl0dGVkLiBJZiBpdCdzIHN5bmMsIHdlIHN0aWxsIHdhbnQgdG8geWllbGQgc28gdGhhdCBpdCBjYW4gYmVcbiAgICAgICAgICAgICAgLy8gcGFpbnRlZC4gQ29uY2VwdHVhbGx5LCB0aGlzIGlzIHJlYWxseSB0aGUgc2FtZSBhcyBwaW5naW5nLlxuICAgICAgICAgICAgICAvLyBXZSBjYW4gdXNlIGFueSBSZXRyeUxhbmUgZXZlbiBpZiBpdCdzIHRoZSBvbmUgY3VycmVudGx5IHJlbmRlcmluZ1xuICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSdyZSBsZWF2aW5nIGl0IGJlaGluZCBvbiB0aGlzIG5vZGUuXG5cbiAgICAgICAgICAgICAgd29ya0luUHJvZ3Jlc3MubGFuZXMgPSBTb21lUmV0cnlMYW5lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZW5kZXJTdGF0ZS5pc0JhY2t3YXJkcykge1xuICAgICAgICAgICAgLy8gVGhlIGVmZmVjdCBsaXN0IG9mIHRoZSBiYWNrd2FyZHMgdGFpbCB3aWxsIGhhdmUgYmVlbiBhZGRlZFxuICAgICAgICAgICAgLy8gdG8gdGhlIGVuZC4gVGhpcyBicmVha3MgdGhlIGd1YXJhbnRlZSB0aGF0IGxpZmUtY3ljbGVzIGZpcmUgaW5cbiAgICAgICAgICAgIC8vIHNpYmxpbmcgb3JkZXIgYnV0IHRoYXQgaXNuJ3QgYSBzdHJvbmcgZ3VhcmFudGVlIHByb21pc2VkIGJ5IFJlYWN0LlxuICAgICAgICAgICAgLy8gRXNwZWNpYWxseSBzaW5jZSB0aGVzZSBtaWdodCBhbHNvIGp1c3QgcG9wIGluIGR1cmluZyBmdXR1cmUgY29tbWl0cy5cbiAgICAgICAgICAgIC8vIEFwcGVuZCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0LlxuICAgICAgICAgICAgcmVuZGVyZWRUYWlsLnNpYmxpbmcgPSB3b3JrSW5Qcm9ncmVzcy5jaGlsZDtcbiAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gcmVuZGVyU3RhdGUubGFzdDtcblxuICAgICAgICAgICAgaWYgKHByZXZpb3VzU2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBwcmV2aW91c1NpYmxpbmcuc2libGluZyA9IHJlbmRlcmVkVGFpbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZW5kZXJTdGF0ZS5sYXN0ID0gcmVuZGVyZWRUYWlsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZW5kZXJTdGF0ZS50YWlsICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gV2Ugc3RpbGwgaGF2ZSB0YWlsIHJvd3MgdG8gcmVuZGVyLlxuICAgICAgICAgIC8vIFBvcCBhIHJvdy5cbiAgICAgICAgICB2YXIgbmV4dCA9IHJlbmRlclN0YXRlLnRhaWw7XG4gICAgICAgICAgcmVuZGVyU3RhdGUucmVuZGVyaW5nID0gbmV4dDtcbiAgICAgICAgICByZW5kZXJTdGF0ZS50YWlsID0gbmV4dC5zaWJsaW5nO1xuICAgICAgICAgIHJlbmRlclN0YXRlLnJlbmRlcmluZ1N0YXJ0VGltZSA9IG5vdygpO1xuICAgICAgICAgIG5leHQuc2libGluZyA9IG51bGw7IC8vIFJlc3RvcmUgdGhlIGNvbnRleHQuXG4gICAgICAgICAgLy8gVE9ETzogV2UgY2FuIHByb2JhYmx5IGp1c3QgYXZvaWQgcG9wcGluZyBpdCBpbnN0ZWFkIGFuZCBvbmx5XG4gICAgICAgICAgLy8gc2V0dGluZyBpdCB0aGUgZmlyc3QgdGltZSB3ZSBnbyBmcm9tIG5vdCBzdXNwZW5kZWQgdG8gc3VzcGVuZGVkLlxuXG4gICAgICAgICAgdmFyIHN1c3BlbnNlQ29udGV4dCA9IHN1c3BlbnNlU3RhY2tDdXJzb3IuY3VycmVudDtcblxuICAgICAgICAgIGlmIChkaWRTdXNwZW5kQWxyZWFkeSkge1xuICAgICAgICAgICAgc3VzcGVuc2VDb250ZXh0ID0gc2V0U2hhbGxvd1N1c3BlbnNlQ29udGV4dChzdXNwZW5zZUNvbnRleHQsIEZvcmNlU3VzcGVuc2VGYWxsYmFjayk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN1c3BlbnNlQ29udGV4dCA9IHNldERlZmF1bHRTaGFsbG93U3VzcGVuc2VDb250ZXh0KHN1c3BlbnNlQ29udGV4dCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcHVzaFN1c3BlbnNlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcywgc3VzcGVuc2VDb250ZXh0KTsgLy8gRG8gYSBwYXNzIG92ZXIgdGhlIG5leHQgcm93LlxuICAgICAgICAgIC8vIERvbid0IGJ1YmJsZSBwcm9wZXJ0aWVzIGluIHRoaXMgY2FzZS5cblxuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTY29wZUNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBwb3BSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHZhciBfbmV4dFN0YXRlID0gd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgdmFyIG5leHRJc0hpZGRlbiA9IF9uZXh0U3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgX3ByZXZTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICAgICAgICB2YXIgcHJldklzSGlkZGVuID0gX3ByZXZTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgIGlmIChwcmV2SXNIaWRkZW4gIT09IG5leHRJc0hpZGRlbiAmJiAoIC8vIExlZ2FjeUhpZGRlbiBkb2Vzbid0IGRvIGFueSBoaWRpbmcg4oCUIGl0IG9ubHkgcHJlLXJlbmRlcnMuXG4gICAgICAgICAgIWVuYWJsZUxlZ2FjeUhpZGRlbiApKSB7XG4gICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBWaXNpYmlsaXR5O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbmV4dElzSGlkZGVuIHx8ICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgQ29uY3VycmVudE1vZGUpID09PSBOb01vZGUpIHtcbiAgICAgICAgICBidWJibGVQcm9wZXJ0aWVzKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBEb24ndCBidWJibGUgcHJvcGVydGllcyBmb3IgaGlkZGVuIGNoaWxkcmVuIHVubGVzcyB3ZSdyZSByZW5kZXJpbmdcbiAgICAgICAgICAvLyBhdCBvZmZzY3JlZW4gcHJpb3JpdHkuXG4gICAgICAgICAgaWYgKGluY2x1ZGVzU29tZUxhbmUoc3VidHJlZVJlbmRlckxhbmVzLCBPZmZzY3JlZW5MYW5lKSkge1xuICAgICAgICAgICAgYnViYmxlUHJvcGVydGllcyh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgd2FzIGFuIGluc2VydGlvbiBvciB1cGRhdGUgaW4gdGhlIGhpZGRlbiBzdWJ0cmVlLlxuICAgICAgICAgICAgICAvLyBJZiBzbywgd2UgbmVlZCB0byBoaWRlIHRob3NlIG5vZGVzIGluIHRoZSBjb21taXQgcGhhc2UsIHNvXG4gICAgICAgICAgICAgIC8vIHNjaGVkdWxlIGEgdmlzaWJpbGl0eSBlZmZlY3QuXG4gICAgICAgICAgICAgIGlmICggd29ya0luUHJvZ3Jlc3Muc3VidHJlZUZsYWdzICYgKFBsYWNlbWVudCB8IFVwZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyB8PSBWaXNpYmlsaXR5O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBDYWNoZUNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgVHJhY2luZ01hcmtlckNvbXBvbmVudDpcbiAgICAgIHtcblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gdW5pdCBvZiB3b3JrIHRhZyAoXCIgKyB3b3JrSW5Qcm9ncmVzcy50YWcgKyBcIikuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBcIiArICdSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG59XG5cbmZ1bmN0aW9uIHVud2luZFdvcmsoY3VycmVudCwgd29ya0luUHJvZ3Jlc3MsIHJlbmRlckxhbmVzKSB7XG4gIC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuICBwb3BUcmVlQ29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG5cbiAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICB2YXIgQ29tcG9uZW50ID0gd29ya0luUHJvZ3Jlc3MudHlwZTtcblxuICAgICAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgICAgIHBvcENvbnRleHQod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZsYWdzID0gd29ya0luUHJvZ3Jlc3MuZmxhZ3M7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgU2hvdWxkQ2FwdHVyZSkge1xuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gZmxhZ3MgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7XG5cbiAgICAgICAgICBpZiAoICh3b3JrSW5Qcm9ncmVzcy5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgICAgIHRyYW5zZmVyQWN0dWFsRHVyYXRpb24od29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgIHtcbiAgICAgICAgdmFyIHJvb3QgPSB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGU7XG4gICAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICBwb3BUb3BMZXZlbENvbnRleHRPYmplY3Qod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgICByZXNldFdvcmtJblByb2dyZXNzVmVyc2lvbnMoKTtcbiAgICAgICAgdmFyIF9mbGFncyA9IHdvcmtJblByb2dyZXNzLmZsYWdzO1xuXG4gICAgICAgIGlmICgoX2ZsYWdzICYgU2hvdWxkQ2FwdHVyZSkgIT09IE5vRmxhZ3MgJiYgKF9mbGFncyAmIERpZENhcHR1cmUpID09PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgLy8gVGhlcmUgd2FzIGFuIGVycm9yIGR1cmluZyByZW5kZXIgdGhhdCB3YXNuJ3QgY2FwdHVyZWQgYnkgYSBzdXNwZW5zZVxuICAgICAgICAgIC8vIGJvdW5kYXJ5LiBEbyBhIHNlY29uZCBwYXNzIG9uIHRoZSByb290IHRvIHVubW91bnQgdGhlIGNoaWxkcmVuLlxuICAgICAgICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gX2ZsYWdzICYgflNob3VsZENhcHR1cmUgfCBEaWRDYXB0dXJlO1xuICAgICAgICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbiAgICAgICAgfSAvLyBXZSB1bndvdW5kIHRvIHRoZSByb290IHdpdGhvdXQgY29tcGxldGluZyBpdC4gRXhpdC5cblxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICAvLyBUT0RPOiBwb3BIeWRyYXRpb25TdGF0ZVxuICAgICAgICBwb3BIb3N0Q29udGV4dCh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wU3VzcGVuc2VDb250ZXh0KHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgdmFyIHN1c3BlbnNlU3RhdGUgPSB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsICYmIHN1c3BlbnNlU3RhdGUuZGVoeWRyYXRlZCAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhyZXcgaW4gbmV3bHkgbW91bnRlZCBkZWh5ZHJhdGVkIGNvbXBvbmVudC4gVGhpcyBpcyBsaWtlbHkgYSBidWcgaW4gJyArICdSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmVzZXRIeWRyYXRpb25TdGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9mbGFnczIgPSB3b3JrSW5Qcm9ncmVzcy5mbGFncztcblxuICAgICAgICBpZiAoX2ZsYWdzMiAmIFNob3VsZENhcHR1cmUpIHtcbiAgICAgICAgICB3b3JrSW5Qcm9ncmVzcy5mbGFncyA9IF9mbGFnczIgJiB+U2hvdWxkQ2FwdHVyZSB8IERpZENhcHR1cmU7IC8vIENhcHR1cmVkIGEgc3VzcGVuc2UgZWZmZWN0LiBSZS1yZW5kZXIgdGhlIGJvdW5kYXJ5LlxuXG4gICAgICAgICAgaWYgKCAod29ya0luUHJvZ3Jlc3MubW9kZSAmIFByb2ZpbGVNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgICB0cmFuc2ZlckFjdHVhbER1cmF0aW9uKHdvcmtJblByb2dyZXNzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gd29ya0luUHJvZ3Jlc3M7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgU3VzcGVuc2VMaXN0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBwb3BTdXNwZW5zZUNvbnRleHQod29ya0luUHJvZ3Jlc3MpOyAvLyBTdXNwZW5zZUxpc3QgZG9lc24ndCBhY3R1YWxseSBjYXRjaCBhbnl0aGluZy4gSXQgc2hvdWxkJ3ZlIGJlZW5cbiAgICAgICAgLy8gY2F1Z2h0IGJ5IGEgbmVzdGVkIGJvdW5kYXJ5LiBJZiBub3QsIGl0IHNob3VsZCBidWJibGUgdGhyb3VnaC5cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHBvcEhvc3RDb250YWluZXIod29ya0luUHJvZ3Jlc3MpO1xuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICBjYXNlIENvbnRleHRQcm92aWRlcjpcbiAgICAgIHZhciBjb250ZXh0ID0gd29ya0luUHJvZ3Jlc3MudHlwZS5fY29udGV4dDtcbiAgICAgIHBvcFByb3ZpZGVyKGNvbnRleHQsIHdvcmtJblByb2dyZXNzKTtcbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICBwb3BSZW5kZXJMYW5lcyh3b3JrSW5Qcm9ncmVzcyk7XG4gICAgICByZXR1cm4gbnVsbDtcblxuICAgIGNhc2UgQ2FjaGVDb21wb25lbnQ6XG5cbiAgICAgIHJldHVybiBudWxsO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVud2luZEludGVycnVwdGVkV29yayhjdXJyZW50LCBpbnRlcnJ1cHRlZFdvcmssIHJlbmRlckxhbmVzKSB7XG4gIC8vIE5vdGU6IFRoaXMgaW50ZW50aW9uYWxseSBkb2Vzbid0IGNoZWNrIGlmIHdlJ3JlIGh5ZHJhdGluZyBiZWNhdXNlIGNvbXBhcmluZ1xuICAvLyB0byB0aGUgY3VycmVudCB0cmVlIHByb3ZpZGVyIGZpYmVyIGlzIGp1c3QgYXMgZmFzdCBhbmQgbGVzcyBlcnJvci1wcm9uZS5cbiAgLy8gSWRlYWxseSB3ZSB3b3VsZCBoYXZlIGEgc3BlY2lhbCB2ZXJzaW9uIG9mIHRoZSB3b3JrIGxvb3Agb25seVxuICAvLyBmb3IgaHlkcmF0aW9uLlxuICBwb3BUcmVlQ29udGV4dChpbnRlcnJ1cHRlZFdvcmspO1xuXG4gIHN3aXRjaCAoaW50ZXJydXB0ZWRXb3JrLnRhZykge1xuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBjaGlsZENvbnRleHRUeXBlcyA9IGludGVycnVwdGVkV29yay50eXBlLmNoaWxkQ29udGV4dFR5cGVzO1xuXG4gICAgICAgIGlmIChjaGlsZENvbnRleHRUeXBlcyAhPT0gbnVsbCAmJiBjaGlsZENvbnRleHRUeXBlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcG9wQ29udGV4dChpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RSb290OlxuICAgICAge1xuICAgICAgICB2YXIgcm9vdCA9IGludGVycnVwdGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgIHBvcEhvc3RDb250YWluZXIoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgICAgcG9wVG9wTGV2ZWxDb250ZXh0T2JqZWN0KGludGVycnVwdGVkV29yayk7XG4gICAgICAgIHJlc2V0V29ya0luUHJvZ3Jlc3NWZXJzaW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcG9wSG9zdENvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBwb3BIb3N0Q29udGFpbmVyKGludGVycnVwdGVkV29yayk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICBwb3BTdXNwZW5zZUNvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICBwb3BTdXNwZW5zZUNvbnRleHQoaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBDb250ZXh0UHJvdmlkZXI6XG4gICAgICB2YXIgY29udGV4dCA9IGludGVycnVwdGVkV29yay50eXBlLl9jb250ZXh0O1xuICAgICAgcG9wUHJvdmlkZXIoY29udGV4dCwgaW50ZXJydXB0ZWRXb3JrKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgY2FzZSBMZWdhY3lIaWRkZW5Db21wb25lbnQ6XG4gICAgICBwb3BSZW5kZXJMYW5lcyhpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgYnJlYWs7XG4gIH1cbn1cblxudmFyIGRpZFdhcm5BYm91dFVuZGVmaW5lZFNuYXBzaG90QmVmb3JlVXBkYXRlID0gbnVsbDtcblxue1xuICBkaWRXYXJuQWJvdXRVbmRlZmluZWRTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9IG5ldyBTZXQoKTtcbn0gLy8gVXNlZCBkdXJpbmcgdGhlIGNvbW1pdCBwaGFzZSB0byB0cmFjayB0aGUgc3RhdGUgb2YgdGhlIE9mZnNjcmVlbiBjb21wb25lbnQgc3RhY2suXG4vLyBBbGxvd3MgdXMgdG8gYXZvaWQgdHJhdmVyc2luZyB0aGUgcmV0dXJuIHBhdGggdG8gZmluZCB0aGUgbmVhcmVzdCBPZmZzY3JlZW4gYW5jZXN0b3IuXG4vLyBPbmx5IHVzZWQgd2hlbiBlbmFibGVTdXNwZW5zZUxheW91dEVmZmVjdFNlbWFudGljcyBpcyBlbmFibGVkLlxuXG5cbnZhciBvZmZzY3JlZW5TdWJ0cmVlSXNIaWRkZW4gPSBmYWxzZTtcbnZhciBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gZmFsc2U7XG52YXIgUG9zc2libHlXZWFrU2V0ID0gdHlwZW9mIFdlYWtTZXQgPT09ICdmdW5jdGlvbicgPyBXZWFrU2V0IDogU2V0O1xudmFyIG5leHRFZmZlY3QgPSBudWxsOyAvLyBVc2VkIGZvciBQcm9maWxpbmcgYnVpbGRzIHRvIHRyYWNrIHVwZGF0ZXJzLlxuXG52YXIgaW5Qcm9ncmVzc0xhbmVzID0gbnVsbDtcbnZhciBpblByb2dyZXNzUm9vdCA9IG51bGw7XG5mdW5jdGlvbiByZXBvcnRVbmNhdWdodEVycm9ySW5ERVYoZXJyb3IpIHtcbiAgLy8gV3JhcHBpbmcgZWFjaCBzbWFsbCBwYXJ0IG9mIHRoZSBjb21taXQgcGhhc2UgaW50byBhIGd1YXJkZWRcbiAgLy8gY2FsbGJhY2sgaXMgYSBiaXQgdG9vIHNsb3cgKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9wdWxsLzIxNjY2KS5cbiAgLy8gQnV0IHdlIHJlbHkgb24gaXQgdG8gc3VyZmFjZSBlcnJvcnMgdG8gREVWIHRvb2xzIGxpa2Ugb3ZlcmxheXNcbiAgLy8gKGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMjE3MTIpLlxuICAvLyBBcyBhIGNvbXByb21pc2UsIHJldGhyb3cgb25seSBjYXVnaHQgZXJyb3JzIGluIGEgZ3VhcmQuXG4gIHtcbiAgICBpbnZva2VHdWFyZGVkQ2FsbGJhY2sobnVsbCwgZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG4gICAgY2xlYXJDYXVnaHRFcnJvcigpO1xuICB9XG59XG5cbnZhciBjYWxsQ29tcG9uZW50V2lsbFVubW91bnRXaXRoVGltZXIgPSBmdW5jdGlvbiAoY3VycmVudCwgaW5zdGFuY2UpIHtcbiAgaW5zdGFuY2UucHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gIGluc3RhbmNlLnN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuXG4gIGlmICggY3VycmVudC5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICB0cnkge1xuICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgaW5zdGFuY2UuY29tcG9uZW50V2lsbFVubW91bnQoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oY3VycmVudCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50KCk7XG4gIH1cbn07IC8vIENhcHR1cmUgZXJyb3JzIHNvIHRoZXkgZG9uJ3QgaW50ZXJydXB0IG1vdW50aW5nLlxuXG5cbmZ1bmN0aW9uIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpIHtcbiAgdHJ5IHtcbiAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCwgY3VycmVudCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IpO1xuICB9XG59IC8vIENhcHR1cmUgZXJyb3JzIHNvIHRoZXkgZG9uJ3QgaW50ZXJydXB0IHVubW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbENvbXBvbmVudFdpbGxVbm1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGluc3RhbmNlKSB7XG4gIHRyeSB7XG4gICAgY2FsbENvbXBvbmVudFdpbGxVbm1vdW50V2l0aFRpbWVyKGN1cnJlbnQsIGluc3RhbmNlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn0gLy8gQ2FwdHVyZSBlcnJvcnMgc28gdGhleSBkb24ndCBpbnRlcnJ1cHQgbW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbENvbXBvbmVudERpZE1vdW50KGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGluc3RhbmNlKSB7XG4gIHRyeSB7XG4gICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn0gLy8gQ2FwdHVyZSBlcnJvcnMgc28gdGhleSBkb24ndCBpbnRlcnJ1cHQgbW91bnRpbmcuXG5cblxuZnVuY3Rpb24gc2FmZWx5QXR0YWNoUmVmKGN1cnJlbnQsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpIHtcbiAgdHJ5IHtcbiAgICBjb21taXRBdHRhY2hSZWYoY3VycmVudCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZXJyb3IpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNhZmVseURldGFjaFJlZihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yKSB7XG4gIHZhciByZWYgPSBjdXJyZW50LnJlZjtcblxuICBpZiAocmVmICE9PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiByZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciByZXRWYWw7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyICYmIGVuYWJsZVByb2ZpbGVyQ29tbWl0SG9va3MgJiYgY3VycmVudC5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgICAgICAgcmV0VmFsID0gcmVmKG51bGwpO1xuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihjdXJyZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0VmFsID0gcmVmKG51bGwpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXRWYWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBlcnJvcignVW5leHBlY3RlZCByZXR1cm4gdmFsdWUgZnJvbSBhIGNhbGxiYWNrIHJlZiBpbiAlcy4gJyArICdBIGNhbGxiYWNrIHJlZiBzaG91bGQgbm90IHJldHVybiBhIGZ1bmN0aW9uLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoY3VycmVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZWx5Q2FsbERlc3Ryb3koY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVzdHJveSkge1xuICB0cnkge1xuICAgIGRlc3Ryb3koKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvcik7XG4gIH1cbn1cblxudmFyIGZvY3VzZWRJbnN0YW5jZUhhbmRsZSA9IG51bGw7XG52YXIgc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyID0gZmFsc2U7XG5mdW5jdGlvbiBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmlyc3RDaGlsZCkge1xuICBmb2N1c2VkSW5zdGFuY2VIYW5kbGUgPSBwcmVwYXJlRm9yQ29tbWl0KHJvb3QuY29udGFpbmVySW5mbyk7XG4gIG5leHRFZmZlY3QgPSBmaXJzdENoaWxkO1xuICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNfYmVnaW4oKTsgLy8gV2Ugbm8gbG9uZ2VyIG5lZWQgdG8gdHJhY2sgdGhlIGFjdGl2ZSBpbnN0YW5jZSBmaWJlclxuXG4gIHZhciBzaG91bGRGaXJlID0gc2hvdWxkRmlyZUFmdGVyQWN0aXZlSW5zdGFuY2VCbHVyO1xuICBzaG91bGRGaXJlQWZ0ZXJBY3RpdmVJbnN0YW5jZUJsdXIgPSBmYWxzZTtcbiAgZm9jdXNlZEluc3RhbmNlSGFuZGxlID0gbnVsbDtcbiAgcmV0dXJuIHNob3VsZEZpcmU7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdEJlZm9yZU11dGF0aW9uRWZmZWN0c19iZWdpbigpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0OyAvLyBUaGlzIHBoYXNlIGlzIG9ubHkgdXNlZCBmb3IgYmVmb3JlQWN0aXZlSW5zdGFuY2VCbHVyLlxuXG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoKGZpYmVyLnN1YnRyZWVGbGFncyAmIEJlZm9yZU11dGF0aW9uTWFzaykgIT09IE5vRmxhZ3MgJiYgY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGNoaWxkLnJldHVybiA9IGZpYmVyO1xuICAgICAgbmV4dEVmZmVjdCA9IGNoaWxkO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNfY29tcGxldGUoKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0QmVmb3JlTXV0YXRpb25FZmZlY3RzX2NvbXBsZXRlKCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgIHRyeSB7XG4gICAgICBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNPbkZpYmVyKGZpYmVyKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgIH1cblxuICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRCZWZvcmVNdXRhdGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkV29yaykge1xuICB2YXIgY3VycmVudCA9IGZpbmlzaGVkV29yay5hbHRlcm5hdGU7XG4gIHZhciBmbGFncyA9IGZpbmlzaGVkV29yay5mbGFncztcblxuICBpZiAoKGZsYWdzICYgU25hcHNob3QpICE9PSBOb0ZsYWdzKSB7XG4gICAgc2V0Q3VycmVudEZpYmVyKGZpbmlzaGVkV29yayk7XG5cbiAgICBzd2l0Y2ggKGZpbmlzaGVkV29yay50YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBwcmV2UHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgICB2YXIgcHJldlN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZTsgLy8gV2UgY291bGQgdXBkYXRlIGluc3RhbmNlIHByb3BzIGFuZCBzdGF0ZSBoZXJlLFxuICAgICAgICAgICAgLy8gYnV0IGluc3RlYWQgd2UgcmVseSBvbiB0aGVtIGJlaW5nIHNldCBkdXJpbmcgbGFzdCByZW5kZXIuXG4gICAgICAgICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgd2hlbiB3ZSBpbXBsZW1lbnQgcmVzdW1pbmcuXG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgcHJvcHMgdG8gbWF0Y2ggbWVtb2l6ZWQgcHJvcHMgYmVmb3JlICcgKyAnZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnByb3BzYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnN0YXRlICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRTdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgZXJyb3IoJ0V4cGVjdGVkICVzIHN0YXRlIHRvIG1hdGNoIG1lbW9pemVkIHN0YXRlIGJlZm9yZSAnICsgJ2dldFNuYXBzaG90QmVmb3JlVXBkYXRlLiAnICsgJ1RoaXMgbWlnaHQgZWl0aGVyIGJlIGJlY2F1c2Ugb2YgYSBidWcgaW4gUmVhY3QsIG9yIGJlY2F1c2UgJyArICdhIGNvbXBvbmVudCByZWFzc2lnbnMgaXRzIG93biBgdGhpcy5zdGF0ZWAuICcgKyAnUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspIHx8ICdpbnN0YW5jZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc25hcHNob3QgPSBpbnN0YW5jZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZShmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgPT09IGZpbmlzaGVkV29yay50eXBlID8gcHJldlByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhmaW5pc2hlZFdvcmsudHlwZSwgcHJldlByb3BzKSwgcHJldlN0YXRlKTtcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YXIgZGlkV2FyblNldCA9IGRpZFdhcm5BYm91dFVuZGVmaW5lZFNuYXBzaG90QmVmb3JlVXBkYXRlO1xuXG4gICAgICAgICAgICAgIGlmIChzbmFwc2hvdCA9PT0gdW5kZWZpbmVkICYmICFkaWRXYXJuU2V0LmhhcyhmaW5pc2hlZFdvcmsudHlwZSkpIHtcbiAgICAgICAgICAgICAgICBkaWRXYXJuU2V0LmFkZChmaW5pc2hlZFdvcmsudHlwZSk7XG5cbiAgICAgICAgICAgICAgICBlcnJvcignJXMuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUoKTogQSBzbmFwc2hvdCB2YWx1ZSAob3IgbnVsbCkgJyArICdtdXN0IGJlIHJldHVybmVkLiBZb3UgaGF2ZSByZXR1cm5lZCB1bmRlZmluZWQuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpbnN0YW5jZS5fX3JlYWN0SW50ZXJuYWxTbmFwc2hvdEJlZm9yZVVwZGF0ZSA9IHNuYXBzaG90O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgIHtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB2YXIgcm9vdCA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgICAgICBjbGVhckNvbnRhaW5lcihyb290LmNvbnRhaW5lckluZm8pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgLy8gTm90aGluZyB0byBkbyBmb3IgdGhlc2UgY29tcG9uZW50IHR5cGVzXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHVuaXQgb2Ygd29yayB0YWcgc2hvdWxkIG5vdCBoYXZlIHNpZGUtZWZmZWN0cy4gVGhpcyBlcnJvciBpcyAnICsgJ2xpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoZmxhZ3MsIGZpbmlzaGVkV29yaywgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICB2YXIgdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG4gIHZhciBsYXN0RWZmZWN0ID0gdXBkYXRlUXVldWUgIT09IG51bGwgPyB1cGRhdGVRdWV1ZS5sYXN0RWZmZWN0IDogbnVsbDtcblxuICBpZiAobGFzdEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaXJzdEVmZmVjdCA9IGxhc3RFZmZlY3QubmV4dDtcbiAgICB2YXIgZWZmZWN0ID0gZmlyc3RFZmZlY3Q7XG5cbiAgICBkbyB7XG4gICAgICBpZiAoKGVmZmVjdC50YWcgJiBmbGFncykgPT09IGZsYWdzKSB7XG4gICAgICAgIC8vIFVubW91bnRcbiAgICAgICAgdmFyIGRlc3Ryb3kgPSBlZmZlY3QuZGVzdHJveTtcbiAgICAgICAgZWZmZWN0LmRlc3Ryb3kgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKGRlc3Ryb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBQYXNzaXZlJDEpICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RVbm1vdW50U3RhcnRlZChmaW5pc2hlZFdvcmspO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBMYXlvdXQpICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKChmbGFncyAmIEluc2VydGlvbikgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgICBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZmluaXNoZWRXb3JrLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcblxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoKGZsYWdzICYgUGFzc2l2ZSQxKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICAgIG1hcmtDb21wb25lbnRQYXNzaXZlRWZmZWN0VW5tb3VudFN0b3BwZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgTGF5b3V0KSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICAgIG1hcmtDb21wb25lbnRMYXlvdXRFZmZlY3RVbm1vdW50U3RvcHBlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBlZmZlY3QgPSBlZmZlY3QubmV4dDtcbiAgICB9IHdoaWxlIChlZmZlY3QgIT09IGZpcnN0RWZmZWN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KGZsYWdzLCBmaW5pc2hlZFdvcmspIHtcbiAgdmFyIHVwZGF0ZVF1ZXVlID0gZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlO1xuICB2YXIgbGFzdEVmZmVjdCA9IHVwZGF0ZVF1ZXVlICE9PSBudWxsID8gdXBkYXRlUXVldWUubGFzdEVmZmVjdCA6IG51bGw7XG5cbiAgaWYgKGxhc3RFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmlyc3RFZmZlY3QgPSBsYXN0RWZmZWN0Lm5leHQ7XG4gICAgdmFyIGVmZmVjdCA9IGZpcnN0RWZmZWN0O1xuXG4gICAgZG8ge1xuICAgICAgaWYgKChlZmZlY3QudGFnICYgZmxhZ3MpID09PSBmbGFncykge1xuICAgICAgICB7XG4gICAgICAgICAgaWYgKChmbGFncyAmIFBhc3NpdmUkMSkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgbWFya0NvbXBvbmVudFBhc3NpdmVFZmZlY3RNb3VudFN0YXJ0ZWQoZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKChmbGFncyAmIExheW91dCkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdE1vdW50U3RhcnRlZChmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH1cbiAgICAgICAgfSAvLyBNb3VudFxuXG5cbiAgICAgICAgdmFyIGNyZWF0ZSA9IGVmZmVjdC5jcmVhdGU7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmICgoZmxhZ3MgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgIHNldElzUnVubmluZ0luc2VydGlvbkVmZmVjdCh0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBlZmZlY3QuZGVzdHJveSA9IGNyZWF0ZSgpO1xuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoKGZsYWdzICYgSW5zZXJ0aW9uKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBzZXRJc1J1bm5pbmdJbnNlcnRpb25FZmZlY3QoZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoKGZsYWdzICYgUGFzc2l2ZSQxKSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBtYXJrQ29tcG9uZW50UGFzc2l2ZUVmZmVjdE1vdW50U3RvcHBlZCgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgTGF5b3V0KSAhPT0gTm9GbGFncyQxKSB7XG4gICAgICAgICAgICBtYXJrQ29tcG9uZW50TGF5b3V0RWZmZWN0TW91bnRTdG9wcGVkKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIHZhciBkZXN0cm95ID0gZWZmZWN0LmRlc3Ryb3k7XG5cbiAgICAgICAgICBpZiAoZGVzdHJveSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBkZXN0cm95ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB2YXIgaG9va05hbWUgPSB2b2lkIDA7XG5cbiAgICAgICAgICAgIGlmICgoZWZmZWN0LnRhZyAmIExheW91dCkgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICAgICAgaG9va05hbWUgPSAndXNlTGF5b3V0RWZmZWN0JztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGVmZmVjdC50YWcgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgICAgICAgIGhvb2tOYW1lID0gJ3VzZUluc2VydGlvbkVmZmVjdCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBob29rTmFtZSA9ICd1c2VFZmZlY3QnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgYWRkZW5kdW0gPSB2b2lkIDA7XG5cbiAgICAgICAgICAgIGlmIChkZXN0cm95ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJyBZb3UgcmV0dXJuZWQgbnVsbC4gSWYgeW91ciBlZmZlY3QgZG9lcyBub3QgcmVxdWlyZSBjbGVhbiAnICsgJ3VwLCByZXR1cm4gdW5kZWZpbmVkIChvciBub3RoaW5nKS4nO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGVzdHJveS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJ1xcblxcbkl0IGxvb2tzIGxpa2UgeW91IHdyb3RlICcgKyBob29rTmFtZSArICcoYXN5bmMgKCkgPT4gLi4uKSBvciByZXR1cm5lZCBhIFByb21pc2UuICcgKyAnSW5zdGVhZCwgd3JpdGUgdGhlIGFzeW5jIGZ1bmN0aW9uIGluc2lkZSB5b3VyIGVmZmVjdCAnICsgJ2FuZCBjYWxsIGl0IGltbWVkaWF0ZWx5OlxcblxcbicgKyBob29rTmFtZSArICcoKCkgPT4ge1xcbicgKyAnICBhc3luYyBmdW5jdGlvbiBmZXRjaERhdGEoKSB7XFxuJyArICcgICAgLy8gWW91IGNhbiBhd2FpdCBoZXJlXFxuJyArICcgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBNeUFQSS5nZXREYXRhKHNvbWVJZCk7XFxuJyArICcgICAgLy8gLi4uXFxuJyArICcgIH1cXG4nICsgJyAgZmV0Y2hEYXRhKCk7XFxuJyArIFwifSwgW3NvbWVJZF0pOyAvLyBPciBbXSBpZiBlZmZlY3QgZG9lc24ndCBuZWVkIHByb3BzIG9yIHN0YXRlXFxuXFxuXCIgKyAnTGVhcm4gbW9yZSBhYm91dCBkYXRhIGZldGNoaW5nIHdpdGggSG9va3M6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9ob29rcy1kYXRhLWZldGNoaW5nJztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGFkZGVuZHVtID0gJyBZb3UgcmV0dXJuZWQ6ICcgKyBkZXN0cm95O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlcnJvcignJXMgbXVzdCBub3QgcmV0dXJuIGFueXRoaW5nIGJlc2lkZXMgYSBmdW5jdGlvbiwgJyArICd3aGljaCBpcyB1c2VkIGZvciBjbGVhbi11cC4lcycsIGhvb2tOYW1lLCBhZGRlbmR1bSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGVmZmVjdCA9IGVmZmVjdC5uZXh0O1xuICAgIH0gd2hpbGUgKGVmZmVjdCAhPT0gZmlyc3RFZmZlY3QpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVFZmZlY3REdXJhdGlvbnMoZmluaXNoZWRSb290LCBmaW5pc2hlZFdvcmspIHtcbiAge1xuICAgIC8vIE9ubHkgUHJvZmlsZXJzIHdpdGggd29yayBpbiB0aGVpciBzdWJ0cmVlIHdpbGwgaGF2ZSBhbiBVcGRhdGUgZWZmZWN0IHNjaGVkdWxlZC5cbiAgICBpZiAoKGZpbmlzaGVkV29yay5mbGFncyAmIFVwZGF0ZSkgIT09IE5vRmxhZ3MpIHtcbiAgICAgIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgICAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciBwYXNzaXZlRWZmZWN0RHVyYXRpb24gPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlLnBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgIHZhciBfZmluaXNoZWRXb3JrJG1lbW9pemUgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcyxcbiAgICAgICAgICAgICAgICBpZCA9IF9maW5pc2hlZFdvcmskbWVtb2l6ZS5pZCxcbiAgICAgICAgICAgICAgICBvblBvc3RDb21taXQgPSBfZmluaXNoZWRXb3JrJG1lbW9pemUub25Qb3N0Q29tbWl0OyAvLyBUaGlzIHZhbHVlIHdpbGwgc3RpbGwgcmVmbGVjdCB0aGUgcHJldmlvdXMgY29tbWl0IHBoYXNlLlxuICAgICAgICAgICAgLy8gSXQgZG9lcyBub3QgZ2V0IHJlc2V0IHVudGlsIHRoZSBzdGFydCBvZiB0aGUgbmV4dCBjb21taXQgcGhhc2UuXG5cbiAgICAgICAgICAgIHZhciBjb21taXRUaW1lID0gZ2V0Q29tbWl0VGltZSgpO1xuICAgICAgICAgICAgdmFyIHBoYXNlID0gZmluaXNoZWRXb3JrLmFsdGVybmF0ZSA9PT0gbnVsbCA/ICdtb3VudCcgOiAndXBkYXRlJztcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZiAoaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBwaGFzZSA9ICduZXN0ZWQtdXBkYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uUG9zdENvbW1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBvblBvc3RDb21taXQoaWQsIHBoYXNlLCBwYXNzaXZlRWZmZWN0RHVyYXRpb24sIGNvbW1pdFRpbWUpO1xuICAgICAgICAgICAgfSAvLyBCdWJibGUgdGltZXMgdG8gdGhlIG5leHQgbmVhcmVzdCBhbmNlc3RvciBQcm9maWxlci5cbiAgICAgICAgICAgIC8vIEFmdGVyIHdlIHByb2Nlc3MgdGhhdCBQcm9maWxlciwgd2UnbGwgYnViYmxlIGZ1cnRoZXIgdXAuXG5cblxuICAgICAgICAgICAgdmFyIHBhcmVudEZpYmVyID0gZmluaXNoZWRXb3JrLnJldHVybjtcblxuICAgICAgICAgICAgb3V0ZXI6IHdoaWxlIChwYXJlbnRGaWJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgICAgICAgICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgICAgICAgICB2YXIgcm9vdCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICAgICAgICAgIHJvb3QucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IHBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuXG4gICAgICAgICAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRTdGF0ZU5vZGUgPSBwYXJlbnRGaWJlci5zdGF0ZU5vZGU7XG4gICAgICAgICAgICAgICAgICBwYXJlbnRTdGF0ZU5vZGUucGFzc2l2ZUVmZmVjdER1cmF0aW9uICs9IHBhc3NpdmVFZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcGFyZW50RmliZXIgPSBwYXJlbnRGaWJlci5yZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0TGF5b3V0RWZmZWN0T25GaWJlcihmaW5pc2hlZFJvb3QsIGN1cnJlbnQsIGZpbmlzaGVkV29yaywgY29tbWl0dGVkTGFuZXMpIHtcbiAgaWYgKChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncykge1xuICAgIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICggIW9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4pIHtcbiAgICAgICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgbGF5b3V0IGVmZmVjdHMgaGF2ZSBhbHJlYWR5IGJlZW4gZGVzdHJveWVkIChkdXJpbmcgbXV0YXRpb24gcGhhc2UpLlxuICAgICAgICAgICAgLy8gVGhpcyBpcyBkb25lIHRvIHByZXZlbnQgc2libGluZyBjb21wb25lbnQgZWZmZWN0cyBmcm9tIGludGVyZmVyaW5nIHdpdGggZWFjaCBvdGhlcixcbiAgICAgICAgICAgIC8vIGUuZy4gYSBkZXN0cm95IGZ1bmN0aW9uIGluIG9uZSBjb21wb25lbnQgc2hvdWxkIG5ldmVyIG92ZXJyaWRlIGEgcmVmIHNldFxuICAgICAgICAgICAgLy8gYnkgYSBjcmVhdGUgZnVuY3Rpb24gaW4gYW5vdGhlciBjb21wb25lbnQgZHVyaW5nIHRoZSBzYW1lIGNvbW1pdC5cbiAgICAgICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZTtcblxuICAgICAgICAgIGlmIChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgICAgICBpZiAoY3VycmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGNvdWxkIHVwZGF0ZSBpbnN0YW5jZSBwcm9wcyBhbmQgc3RhdGUgaGVyZSxcbiAgICAgICAgICAgICAgICAvLyBidXQgaW5zdGVhZCB3ZSByZWx5IG9uIHRoZW0gYmVpbmcgc2V0IGR1cmluZyBsYXN0IHJlbmRlci5cbiAgICAgICAgICAgICAgICAvLyBUT0RPOiByZXZpc2l0IHRoaXMgd2hlbiB3ZSBpbXBsZW1lbnQgcmVzdW1pbmcuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcykge1xuICAgICAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBwcm9wcyB0byBtYXRjaCBtZW1vaXplZCBwcm9wcyBiZWZvcmUgJyArICdjb21wb25lbnREaWRNb3VudC4gJyArICdUaGlzIG1pZ2h0IGVpdGhlciBiZSBiZWNhdXNlIG9mIGEgYnVnIGluIFJlYWN0LCBvciBiZWNhdXNlICcgKyAnYSBjb21wb25lbnQgcmVhc3NpZ25zIGl0cyBvd24gYHRoaXMucHJvcHNgLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmluaXNoZWRXb3JrKSB8fCAnaW5zdGFuY2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSAhPT0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgc3RhdGUgdG8gbWF0Y2ggbWVtb2l6ZWQgc3RhdGUgYmVmb3JlICcgKyAnY29tcG9uZW50RGlkTW91bnQuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnN0YXRlYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIGZpbmlzaGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbXBvbmVudERpZE1vdW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBwcmV2UHJvcHMgPSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgPT09IGZpbmlzaGVkV29yay50eXBlID8gY3VycmVudC5tZW1vaXplZFByb3BzIDogcmVzb2x2ZURlZmF1bHRQcm9wcyhmaW5pc2hlZFdvcmsudHlwZSwgY3VycmVudC5tZW1vaXplZFByb3BzKTtcbiAgICAgICAgICAgICAgICB2YXIgcHJldlN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlOyAvLyBXZSBjb3VsZCB1cGRhdGUgaW5zdGFuY2UgcHJvcHMgYW5kIHN0YXRlIGhlcmUsXG4gICAgICAgICAgICAgICAgLy8gYnV0IGluc3RlYWQgd2UgcmVseSBvbiB0aGVtIGJlaW5nIHNldCBkdXJpbmcgbGFzdCByZW5kZXIuXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGlzIHdoZW4gd2UgaW1wbGVtZW50IHJlc3VtaW5nLlxuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLnByb3BzICE9PSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcykge1xuICAgICAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBwcm9wcyB0byBtYXRjaCBtZW1vaXplZCBwcm9wcyBiZWZvcmUgJyArICdjb21wb25lbnREaWRVcGRhdGUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnByb3BzYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2Uuc3RhdGUgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZXJyb3IoJ0V4cGVjdGVkICVzIHN0YXRlIHRvIG1hdGNoIG1lbW9pemVkIHN0YXRlIGJlZm9yZSAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZS4gJyArICdUaGlzIG1pZ2h0IGVpdGhlciBiZSBiZWNhdXNlIG9mIGEgYnVnIGluIFJlYWN0LCBvciBiZWNhdXNlICcgKyAnYSBjb21wb25lbnQgcmVhc3NpZ25zIGl0cyBvd24gYHRoaXMuc3RhdGVgLiAnICsgJ1BsZWFzZSBmaWxlIGFuIGlzc3VlLicsIGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmluaXNoZWRXb3JrKSB8fCAnaW5zdGFuY2UnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRMYXlvdXRFZmZlY3RUaW1lcigpO1xuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5jb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUsIGluc3RhbmNlLl9fcmVhY3RJbnRlcm5hbFNuYXBzaG90QmVmb3JlVXBkYXRlKTtcbiAgICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGluc3RhbmNlLmNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMsIHByZXZTdGF0ZSwgaW5zdGFuY2UuX19yZWFjdEludGVybmFsU25hcHNob3RCZWZvcmVVcGRhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gLy8gVE9ETzogSSB0aGluayB0aGlzIGlzIG5vdyBhbHdheXMgbm9uLW51bGwgYnkgdGhlIHRpbWUgaXQgcmVhY2hlcyB0aGVcbiAgICAgICAgICAvLyBjb21taXQgcGhhc2UuIENvbnNpZGVyIHJlbW92aW5nIHRoZSB0eXBlIGNoZWNrLlxuXG5cbiAgICAgICAgICB2YXIgdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICBpZiAodXBkYXRlUXVldWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay50eXBlID09PSBmaW5pc2hlZFdvcmsuZWxlbWVudFR5cGUgJiYgIWRpZFdhcm5BYm91dFJlYXNzaWduaW5nUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucHJvcHMgIT09IGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBlcnJvcignRXhwZWN0ZWQgJXMgcHJvcHMgdG8gbWF0Y2ggbWVtb2l6ZWQgcHJvcHMgYmVmb3JlICcgKyAncHJvY2Vzc2luZyB0aGUgdXBkYXRlIHF1ZXVlLiAnICsgJ1RoaXMgbWlnaHQgZWl0aGVyIGJlIGJlY2F1c2Ugb2YgYSBidWcgaW4gUmVhY3QsIG9yIGJlY2F1c2UgJyArICdhIGNvbXBvbmVudCByZWFzc2lnbnMgaXRzIG93biBgdGhpcy5wcm9wc2AuICcgKyAnUGxlYXNlIGZpbGUgYW4gaXNzdWUuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspIHx8ICdpbnN0YW5jZScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5zdGF0ZSAhPT0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgIGVycm9yKCdFeHBlY3RlZCAlcyBzdGF0ZSB0byBtYXRjaCBtZW1vaXplZCBzdGF0ZSBiZWZvcmUgJyArICdwcm9jZXNzaW5nIHRoZSB1cGRhdGUgcXVldWUuICcgKyAnVGhpcyBtaWdodCBlaXRoZXIgYmUgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBSZWFjdCwgb3IgYmVjYXVzZSAnICsgJ2EgY29tcG9uZW50IHJlYXNzaWducyBpdHMgb3duIGB0aGlzLnN0YXRlYC4gJyArICdQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykgfHwgJ2luc3RhbmNlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IC8vIFdlIGNvdWxkIHVwZGF0ZSBpbnN0YW5jZSBwcm9wcyBhbmQgc3RhdGUgaGVyZSxcbiAgICAgICAgICAgIC8vIGJ1dCBpbnN0ZWFkIHdlIHJlbHkgb24gdGhlbSBiZWluZyBzZXQgZHVyaW5nIGxhc3QgcmVuZGVyLlxuICAgICAgICAgICAgLy8gVE9ETzogcmV2aXNpdCB0aGlzIHdoZW4gd2UgaW1wbGVtZW50IHJlc3VtaW5nLlxuXG5cbiAgICAgICAgICAgIGNvbW1pdFVwZGF0ZVF1ZXVlKGZpbmlzaGVkV29yaywgdXBkYXRlUXVldWUsIGluc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RSb290OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVE9ETzogSSB0aGluayB0aGlzIGlzIG5vdyBhbHdheXMgbm9uLW51bGwgYnkgdGhlIHRpbWUgaXQgcmVhY2hlcyB0aGVcbiAgICAgICAgICAvLyBjb21taXQgcGhhc2UuIENvbnNpZGVyIHJlbW92aW5nIHRoZSB0eXBlIGNoZWNrLlxuICAgICAgICAgIHZhciBfdXBkYXRlUXVldWUgPSBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWU7XG5cbiAgICAgICAgICBpZiAoX3VwZGF0ZVF1ZXVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgX2luc3RhbmNlID0gbnVsbDtcblxuICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICBzd2l0Y2ggKGZpbmlzaGVkV29yay5jaGlsZC50YWcpIHtcbiAgICAgICAgICAgICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgICAgICAgICAgICBfaW5zdGFuY2UgPSBnZXRQdWJsaWNJbnN0YW5jZShmaW5pc2hlZFdvcmsuY2hpbGQuc3RhdGVOb2RlKTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgICAgICAgICAgIF9pbnN0YW5jZSA9IGZpbmlzaGVkV29yay5jaGlsZC5zdGF0ZU5vZGU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb21taXRVcGRhdGVRdWV1ZShmaW5pc2hlZFdvcmssIF91cGRhdGVRdWV1ZSwgX2luc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgX2luc3RhbmNlMiA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7IC8vIFJlbmRlcmVycyBtYXkgc2NoZWR1bGUgd29yayB0byBiZSBkb25lIGFmdGVyIGhvc3QgY29tcG9uZW50cyBhcmUgbW91bnRlZFxuICAgICAgICAgIC8vIChlZyBET00gcmVuZGVyZXIgbWF5IHNjaGVkdWxlIGF1dG8tZm9jdXMgZm9yIGlucHV0cyBhbmQgZm9ybSBjb250cm9scykuXG4gICAgICAgICAgLy8gVGhlc2UgZWZmZWN0cyBzaG91bGQgb25seSBiZSBjb21taXR0ZWQgd2hlbiBjb21wb25lbnRzIGFyZSBmaXJzdCBtb3VudGVkLFxuICAgICAgICAgIC8vIGFrYSB3aGVuIHRoZXJlIGlzIG5vIGN1cnJlbnQvYWx0ZXJuYXRlLlxuXG4gICAgICAgICAgaWYgKGN1cnJlbnQgPT09IG51bGwgJiYgZmluaXNoZWRXb3JrLmZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGZpbmlzaGVkV29yay50eXBlO1xuICAgICAgICAgICAgdmFyIHByb3BzID0gZmluaXNoZWRXb3JrLm1lbW9pemVkUHJvcHM7XG4gICAgICAgICAgICBjb21taXRNb3VudChfaW5zdGFuY2UyLCB0eXBlLCBwcm9wcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgICAge1xuICAgICAgICAgIC8vIFdlIGhhdmUgbm8gbGlmZS1jeWNsZXMgYXNzb2NpYXRlZCB3aXRoIHRleHQuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBIb3N0UG9ydGFsOlxuICAgICAgICB7XG4gICAgICAgICAgLy8gV2UgaGF2ZSBubyBsaWZlLWN5Y2xlcyBhc3NvY2lhdGVkIHdpdGggcG9ydGFscy5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIFByb2ZpbGVyOlxuICAgICAgICB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFyIF9maW5pc2hlZFdvcmskbWVtb2l6ZTIgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wcyxcbiAgICAgICAgICAgICAgICBvbkNvbW1pdCA9IF9maW5pc2hlZFdvcmskbWVtb2l6ZTIub25Db21taXQsXG4gICAgICAgICAgICAgICAgb25SZW5kZXIgPSBfZmluaXNoZWRXb3JrJG1lbW9pemUyLm9uUmVuZGVyO1xuICAgICAgICAgICAgdmFyIGVmZmVjdER1cmF0aW9uID0gZmluaXNoZWRXb3JrLnN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbjtcbiAgICAgICAgICAgIHZhciBjb21taXRUaW1lID0gZ2V0Q29tbWl0VGltZSgpO1xuICAgICAgICAgICAgdmFyIHBoYXNlID0gY3VycmVudCA9PT0gbnVsbCA/ICdtb3VudCcgOiAndXBkYXRlJztcblxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZiAoaXNDdXJyZW50VXBkYXRlTmVzdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBwaGFzZSA9ICduZXN0ZWQtdXBkYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9uUmVuZGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIG9uUmVuZGVyKGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzLmlkLCBwaGFzZSwgZmluaXNoZWRXb3JrLmFjdHVhbER1cmF0aW9uLCBmaW5pc2hlZFdvcmsudHJlZUJhc2VEdXJhdGlvbiwgZmluaXNoZWRXb3JrLmFjdHVhbFN0YXJ0VGltZSwgY29tbWl0VGltZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbkNvbW1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIG9uQ29tbWl0KGZpbmlzaGVkV29yay5tZW1vaXplZFByb3BzLmlkLCBwaGFzZSwgZWZmZWN0RHVyYXRpb24sIGNvbW1pdFRpbWUpO1xuICAgICAgICAgICAgICB9IC8vIFNjaGVkdWxlIGEgcGFzc2l2ZSBlZmZlY3QgZm9yIHRoaXMgUHJvZmlsZXIgdG8gY2FsbCBvblBvc3RDb21taXQgaG9va3MuXG4gICAgICAgICAgICAgIC8vIFRoaXMgZWZmZWN0IHNob3VsZCBiZSBzY2hlZHVsZWQgZXZlbiBpZiB0aGVyZSBpcyBubyBvblBvc3RDb21taXQgY2FsbGJhY2sgZm9yIHRoaXMgUHJvZmlsZXIsXG4gICAgICAgICAgICAgIC8vIGJlY2F1c2UgdGhlIGVmZmVjdCBpcyBhbHNvIHdoZXJlIHRpbWVzIGJ1YmJsZSB0byBwYXJlbnQgUHJvZmlsZXJzLlxuXG5cbiAgICAgICAgICAgICAgZW5xdWV1ZVBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3QoZmluaXNoZWRXb3JrKTsgLy8gUHJvcGFnYXRlIGxheW91dCBlZmZlY3QgZHVyYXRpb25zIHRvIHRoZSBuZXh0IG5lYXJlc3QgUHJvZmlsZXIgYW5jZXN0b3IuXG4gICAgICAgICAgICAgIC8vIERvIG5vdCByZXNldCB0aGVzZSB2YWx1ZXMgdW50aWwgdGhlIG5leHQgcmVuZGVyIHNvIERldlRvb2xzIGhhcyBhIGNoYW5jZSB0byByZWFkIHRoZW0gZmlyc3QuXG5cbiAgICAgICAgICAgICAgdmFyIHBhcmVudEZpYmVyID0gZmluaXNoZWRXb3JrLnJldHVybjtcblxuICAgICAgICAgICAgICBvdXRlcjogd2hpbGUgKHBhcmVudEZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChwYXJlbnRGaWJlci50YWcpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICAgICAgICAgICAgICAgIHZhciByb290ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlO1xuICAgICAgICAgICAgICAgICAgICByb290LmVmZmVjdER1cmF0aW9uICs9IGVmZmVjdER1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcblxuICAgICAgICAgICAgICAgICAgY2FzZSBQcm9maWxlcjpcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudFN0YXRlTm9kZSA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgcGFyZW50U3RhdGVOb2RlLmVmZmVjdER1cmF0aW9uICs9IGVmZmVjdER1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXJlbnRGaWJlciA9IHBhcmVudEZpYmVyLnJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgU3VzcGVuc2VDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBjb21taXRTdXNwZW5zZUh5ZHJhdGlvbkNhbGxiYWNrcyhmaW5pc2hlZFJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBTdXNwZW5zZUxpc3RDb21wb25lbnQ6XG4gICAgICBjYXNlIEluY29tcGxldGVDbGFzc0NvbXBvbmVudDpcbiAgICAgIGNhc2UgU2NvcGVDb21wb25lbnQ6XG4gICAgICBjYXNlIE9mZnNjcmVlbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgTGVnYWN5SGlkZGVuQ29tcG9uZW50OlxuICAgICAgY2FzZSBUcmFjaW5nTWFya2VyQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHVuaXQgb2Ygd29yayB0YWcgc2hvdWxkIG5vdCBoYXZlIHNpZGUtZWZmZWN0cy4gVGhpcyBlcnJvciBpcyAnICsgJ2xpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmICggIW9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4pIHtcbiAgICB7XG4gICAgICBpZiAoZmluaXNoZWRXb3JrLmZsYWdzICYgUmVmKSB7XG4gICAgICAgIGNvbW1pdEF0dGFjaFJlZihmaW5pc2hlZFdvcmspO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiByZWFwcGVhckxheW91dEVmZmVjdHNPbkZpYmVyKG5vZGUpIHtcbiAgLy8gVHVybiBvbiBsYXlvdXQgZWZmZWN0cyBpbiBhIHRyZWUgdGhhdCBwcmV2aW91c2x5IGRpc2FwcGVhcmVkLlxuICAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBmbGFncyAmIExheW91dFN0YXRpY1xuICBzd2l0Y2ggKG5vZGUudGFnKSB7XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIG5vZGUubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHN0YXJ0TGF5b3V0RWZmZWN0VGltZXIoKTtcbiAgICAgICAgICAgIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24obm9kZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNhZmVseUNhbGxDb21taXRIb29rTGF5b3V0RWZmZWN0TGlzdE1vdW50KG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gbm9kZS5zdGF0ZU5vZGU7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRNb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHNhZmVseUNhbGxDb21wb25lbnREaWRNb3VudChub2RlLCBub2RlLnJldHVybiwgaW5zdGFuY2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2FmZWx5QXR0YWNoUmVmKG5vZGUsIG5vZGUucmV0dXJuKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHNhZmVseUF0dGFjaFJlZihub2RlLCBub2RlLnJldHVybik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGhpZGVPclVuaGlkZUFsbENoaWxkcmVuKGZpbmlzaGVkV29yaywgaXNIaWRkZW4pIHtcbiAgLy8gT25seSBoaWRlIG9yIHVuaGlkZSB0aGUgdG9wLW1vc3QgaG9zdCBub2Rlcy5cbiAgdmFyIGhvc3RTdWJ0cmVlUm9vdCA9IG51bGw7XG5cbiAge1xuICAgIC8vIFdlIG9ubHkgaGF2ZSB0aGUgdG9wIEZpYmVyIHRoYXQgd2FzIGluc2VydGVkIGJ1dCB3ZSBuZWVkIHRvIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgdmFyIG5vZGUgPSBmaW5pc2hlZFdvcms7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKG5vZGUudGFnID09PSBIb3N0Q29tcG9uZW50KSB7XG4gICAgICAgIGlmIChob3N0U3VidHJlZVJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICBob3N0U3VidHJlZVJvb3QgPSBub2RlO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IG5vZGUuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICBpZiAoaXNIaWRkZW4pIHtcbiAgICAgICAgICAgICAgaGlkZUluc3RhbmNlKGluc3RhbmNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHVuaGlkZUluc3RhbmNlKG5vZGUuc3RhdGVOb2RlLCBub2RlLm1lbW9pemVkUHJvcHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS50YWcgPT09IEhvc3RUZXh0KSB7XG4gICAgICAgIGlmIChob3N0U3VidHJlZVJvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIF9pbnN0YW5jZTMgPSBub2RlLnN0YXRlTm9kZTtcblxuICAgICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICAgIGhpZGVUZXh0SW5zdGFuY2UoX2luc3RhbmNlMyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB1bmhpZGVUZXh0SW5zdGFuY2UoX2luc3RhbmNlMywgbm9kZS5tZW1vaXplZFByb3BzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKChub2RlLnRhZyA9PT0gT2Zmc2NyZWVuQ29tcG9uZW50IHx8IG5vZGUudGFnID09PSBMZWdhY3lIaWRkZW5Db21wb25lbnQpICYmIG5vZGUubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbCAmJiBub2RlICE9PSBmaW5pc2hlZFdvcmspIDsgZWxzZSBpZiAobm9kZS5jaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICBub2RlLmNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICAgIG5vZGUgPSBub2RlLmNoaWxkO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5vZGUgPT09IGZpbmlzaGVkV29yaykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgICAgaWYgKG5vZGUucmV0dXJuID09PSBudWxsIHx8IG5vZGUucmV0dXJuID09PSBmaW5pc2hlZFdvcmspIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaG9zdFN1YnRyZWVSb290ID09PSBub2RlKSB7XG4gICAgICAgICAgaG9zdFN1YnRyZWVSb290ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGhvc3RTdWJ0cmVlUm9vdCA9PT0gbm9kZSkge1xuICAgICAgICBob3N0U3VidHJlZVJvb3QgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBub2RlLnNpYmxpbmcucmV0dXJuID0gbm9kZS5yZXR1cm47XG4gICAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRBdHRhY2hSZWYoZmluaXNoZWRXb3JrKSB7XG4gIHZhciByZWYgPSBmaW5pc2hlZFdvcmsucmVmO1xuXG4gIGlmIChyZWYgIT09IG51bGwpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuICAgIHZhciBpbnN0YW5jZVRvVXNlO1xuXG4gICAgc3dpdGNoIChmaW5pc2hlZFdvcmsudGFnKSB7XG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIGluc3RhbmNlVG9Vc2UgPSBnZXRQdWJsaWNJbnN0YW5jZShpbnN0YW5jZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpbnN0YW5jZVRvVXNlID0gaW5zdGFuY2U7XG4gICAgfSAvLyBNb3ZlZCBvdXRzaWRlIHRvIGVuc3VyZSBEQ0Ugd29ya3Mgd2l0aCB0aGlzIGZsYWdcblxuICAgIGlmICh0eXBlb2YgcmVmID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgcmV0VmFsO1xuXG4gICAgICBpZiAoIGZpbmlzaGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgcmV0VmFsID0gcmVmKGluc3RhbmNlVG9Vc2UpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHJlY29yZExheW91dEVmZmVjdER1cmF0aW9uKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldFZhbCA9IHJlZihpbnN0YW5jZVRvVXNlKTtcbiAgICAgIH1cblxuICAgICAge1xuICAgICAgICBpZiAodHlwZW9mIHJldFZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGVycm9yKCdVbmV4cGVjdGVkIHJldHVybiB2YWx1ZSBmcm9tIGEgY2FsbGJhY2sgcmVmIGluICVzLiAnICsgJ0EgY2FsbGJhY2sgcmVmIHNob3VsZCBub3QgcmV0dXJuIGEgZnVuY3Rpb24uJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaW5pc2hlZFdvcmspKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIGlmICghcmVmLmhhc093blByb3BlcnR5KCdjdXJyZW50JykpIHtcbiAgICAgICAgICBlcnJvcignVW5leHBlY3RlZCByZWYgb2JqZWN0IHByb3ZpZGVkIGZvciAlcy4gJyArICdVc2UgZWl0aGVyIGEgcmVmLXNldHRlciBmdW5jdGlvbiBvciBSZWFjdC5jcmVhdGVSZWYoKS4nLCBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKGZpbmlzaGVkV29yaykpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlZi5jdXJyZW50ID0gaW5zdGFuY2VUb1VzZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZGV0YWNoRmliZXJNdXRhdGlvbihmaWJlcikge1xuICAvLyBDdXQgb2ZmIHRoZSByZXR1cm4gcG9pbnRlciB0byBkaXNjb25uZWN0IGl0IGZyb20gdGhlIHRyZWUuXG4gIC8vIFRoaXMgZW5hYmxlcyB1cyB0byBkZXRlY3QgYW5kIHdhcm4gYWdhaW5zdCBzdGF0ZSB1cGRhdGVzIG9uIGFuIHVubW91bnRlZCBjb21wb25lbnQuXG4gIC8vIEl0IGFsc28gcHJldmVudHMgZXZlbnRzIGZyb20gYnViYmxpbmcgZnJvbSB3aXRoaW4gZGlzY29ubmVjdGVkIGNvbXBvbmVudHMuXG4gIC8vXG4gIC8vIElkZWFsbHksIHdlIHNob3VsZCBhbHNvIGNsZWFyIHRoZSBjaGlsZCBwb2ludGVyIG9mIHRoZSBwYXJlbnQgYWx0ZXJuYXRlIHRvIGxldCB0aGlzXG4gIC8vIGdldCBHQzplZCBidXQgd2UgZG9uJ3Qga25vdyB3aGljaCBmb3Igc3VyZSB3aGljaCBwYXJlbnQgaXMgdGhlIGN1cnJlbnRcbiAgLy8gb25lIHNvIHdlJ2xsIHNldHRsZSBmb3IgR0M6aW5nIHRoZSBzdWJ0cmVlIG9mIHRoaXMgY2hpbGQuXG4gIC8vIFRoaXMgY2hpbGQgaXRzZWxmIHdpbGwgYmUgR0M6ZWQgd2hlbiB0aGUgcGFyZW50IHVwZGF0ZXMgdGhlIG5leHQgdGltZS5cbiAgLy9cbiAgLy8gTm90ZSB0aGF0IHdlIGNhbid0IGNsZWFyIGNoaWxkIG9yIHNpYmxpbmcgcG9pbnRlcnMgeWV0LlxuICAvLyBUaGV5J3JlIG5lZWRlZCBmb3IgcGFzc2l2ZSBlZmZlY3RzIGFuZCBmb3IgZmluZERPTU5vZGUuXG4gIC8vIFdlIGRlZmVyIHRob3NlIGZpZWxkcywgYW5kIGFsbCBvdGhlciBjbGVhbnVwLCB0byB0aGUgcGFzc2l2ZSBwaGFzZSAoc2VlIGRldGFjaEZpYmVyQWZ0ZXJFZmZlY3RzKS5cbiAgLy9cbiAgLy8gRG9uJ3QgcmVzZXQgdGhlIGFsdGVybmF0ZSB5ZXQsIGVpdGhlci4gV2UgbmVlZCB0aGF0IHNvIHdlIGNhbiBkZXRhY2ggdGhlXG4gIC8vIGFsdGVybmF0ZSdzIGZpZWxkcyBpbiB0aGUgcGFzc2l2ZSBwaGFzZS4gQ2xlYXJpbmcgdGhlIHJldHVybiBwb2ludGVyIGlzXG4gIC8vIHN1ZmZpY2llbnQgZm9yIGZpbmRET01Ob2RlIHNlbWFudGljcy5cbiAgdmFyIGFsdGVybmF0ZSA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICBpZiAoYWx0ZXJuYXRlICE9PSBudWxsKSB7XG4gICAgYWx0ZXJuYXRlLnJldHVybiA9IG51bGw7XG4gIH1cblxuICBmaWJlci5yZXR1cm4gPSBudWxsO1xufVxuXG5mdW5jdGlvbiBkZXRhY2hGaWJlckFmdGVyRWZmZWN0cyhmaWJlcikge1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmIChhbHRlcm5hdGUgIT09IG51bGwpIHtcbiAgICBmaWJlci5hbHRlcm5hdGUgPSBudWxsO1xuICAgIGRldGFjaEZpYmVyQWZ0ZXJFZmZlY3RzKGFsdGVybmF0ZSk7XG4gIH0gLy8gTm90ZTogRGVmZW5zaXZlbHkgdXNpbmcgbmVnYXRpb24gaW5zdGVhZCBvZiA8IGluIGNhc2VcbiAgLy8gYGRlbGV0ZWRUcmVlQ2xlYW5VcExldmVsYCBpcyB1bmRlZmluZWQuXG5cblxuICB7XG4gICAgLy8gQ2xlYXIgY3ljbGljYWwgRmliZXIgZmllbGRzLiBUaGlzIGxldmVsIGFsb25lIGlzIGRlc2lnbmVkIHRvIHJvdWdobHlcbiAgICAvLyBhcHByb3hpbWF0ZSB0aGUgcGxhbm5lZCBGaWJlciByZWZhY3Rvci4gSW4gdGhhdCB3b3JsZCwgYHNldFN0YXRlYCB3aWxsIGJlXG4gICAgLy8gYm91bmQgdG8gYSBzcGVjaWFsIFwiaW5zdGFuY2VcIiBvYmplY3QgaW5zdGVhZCBvZiBhIEZpYmVyLiBUaGUgSW5zdGFuY2VcbiAgICAvLyBvYmplY3Qgd2lsbCBub3QgaGF2ZSBhbnkgb2YgdGhlc2UgZmllbGRzLiBJdCB3aWxsIG9ubHkgYmUgY29ubmVjdGVkIHRvXG4gICAgLy8gdGhlIGZpYmVyIHRyZWUgdmlhIGEgc2luZ2xlIGxpbmsgYXQgdGhlIHJvb3QuIFNvIGlmIHRoaXMgbGV2ZWwgYWxvbmUgaXNcbiAgICAvLyBzdWZmaWNpZW50IHRvIGZpeCBtZW1vcnkgaXNzdWVzLCB0aGF0IGJvZGVzIHdlbGwgZm9yIG91ciBwbGFucy5cbiAgICBmaWJlci5jaGlsZCA9IG51bGw7XG4gICAgZmliZXIuZGVsZXRpb25zID0gbnVsbDtcbiAgICBmaWJlci5zaWJsaW5nID0gbnVsbDsgLy8gVGhlIGBzdGF0ZU5vZGVgIGlzIGN5Y2xpY2FsIGJlY2F1c2Ugb24gaG9zdCBub2RlcyBpdCBwb2ludHMgdG8gdGhlIGhvc3RcbiAgICAvLyB0cmVlLCB3aGljaCBoYXMgaXRzIG93biBwb2ludGVycyB0byBjaGlsZHJlbiwgcGFyZW50cywgYW5kIHNpYmxpbmdzLlxuICAgIC8vIFRoZSBvdGhlciBob3N0IG5vZGVzIGFsc28gcG9pbnQgYmFjayB0byBmaWJlcnMsIHNvIHdlIHNob3VsZCBkZXRhY2ggdGhhdFxuICAgIC8vIG9uZSwgdG9vLlxuXG4gICAgaWYgKGZpYmVyLnRhZyA9PT0gSG9zdENvbXBvbmVudCkge1xuICAgICAgdmFyIGhvc3RJbnN0YW5jZSA9IGZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgaWYgKGhvc3RJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICBkZXRhY2hEZWxldGVkSW5zdGFuY2UoaG9zdEluc3RhbmNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmaWJlci5zdGF0ZU5vZGUgPSBudWxsOyAvLyBJJ20gaW50ZW50aW9uYWxseSBub3QgY2xlYXJpbmcgdGhlIGByZXR1cm5gIGZpZWxkIGluIHRoaXMgbGV2ZWwuIFdlXG4gICAgLy8gYWxyZWFkeSBkaXNjb25uZWN0IHRoZSBgcmV0dXJuYCBwb2ludGVyIGF0IHRoZSByb290IG9mIHRoZSBkZWxldGVkXG4gICAgLy8gc3VidHJlZSAoaW4gYGRldGFjaEZpYmVyTXV0YXRpb25gKS4gQmVzaWRlcywgYHJldHVybmAgYnkgaXRzZWxmIGlzIG5vdFxuICAgIC8vIGN5Y2xpY2FsIOKAlCBpdCdzIG9ubHkgY3ljbGljYWwgd2hlbiBjb21iaW5lZCB3aXRoIGBjaGlsZGAsIGBzaWJsaW5nYCwgYW5kXG4gICAgLy8gYGFsdGVybmF0ZWAuIEJ1dCB3ZSdsbCBjbGVhciBpdCBpbiB0aGUgbmV4dCBsZXZlbCBhbnl3YXksIGp1c3QgaW4gY2FzZS5cblxuICAgIHtcbiAgICAgIGZpYmVyLl9kZWJ1Z093bmVyID0gbnVsbDtcbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBUaGVvcmV0aWNhbGx5LCBub3RoaW5nIGluIGhlcmUgc2hvdWxkIGJlIG5lY2Vzc2FyeSwgYmVjYXVzZSB3ZSBhbHJlYWR5XG4gICAgICAvLyBkaXNjb25uZWN0ZWQgdGhlIGZpYmVyIGZyb20gdGhlIHRyZWUuIFNvIGV2ZW4gaWYgc29tZXRoaW5nIGxlYWtzIHRoaXNcbiAgICAgIC8vIHBhcnRpY3VsYXIgZmliZXIsIGl0IHdvbid0IGxlYWsgYW55dGhpbmcgZWxzZVxuICAgICAgLy9cbiAgICAgIC8vIFRoZSBwdXJwb3NlIG9mIHRoaXMgYnJhbmNoIGlzIHRvIGJlIHN1cGVyIGFnZ3Jlc3NpdmUgc28gd2UgY2FuIG1lYXN1cmVcbiAgICAgIC8vIGlmIHRoZXJlJ3MgYW55IGRpZmZlcmVuY2UgaW4gbWVtb3J5IGltcGFjdC4gSWYgdGhlcmUgaXMsIHRoYXQgY291bGRcbiAgICAgIC8vIGluZGljYXRlIGEgUmVhY3QgbGVhayB3ZSBkb24ndCBrbm93IGFib3V0LlxuICAgICAgZmliZXIucmV0dXJuID0gbnVsbDtcbiAgICAgIGZpYmVyLmRlcGVuZGVuY2llcyA9IG51bGw7XG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gbnVsbDtcbiAgICAgIGZpYmVyLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgICAgZmliZXIucGVuZGluZ1Byb3BzID0gbnVsbDtcbiAgICAgIGZpYmVyLnN0YXRlTm9kZSA9IG51bGw7IC8vIFRPRE86IE1vdmUgdG8gYGNvbW1pdFBhc3NpdmVVbm1vdW50SW5zaWRlRGVsZXRlZFRyZWVPbkZpYmVyYCBpbnN0ZWFkLlxuXG4gICAgICBmaWJlci51cGRhdGVRdWV1ZSA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldEhvc3RQYXJlbnRGaWJlcihmaWJlcikge1xuICB2YXIgcGFyZW50ID0gZmliZXIucmV0dXJuO1xuXG4gIHdoaWxlIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICBpZiAoaXNIb3N0UGFyZW50KHBhcmVudCkpIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuXG4gICAgcGFyZW50ID0gcGFyZW50LnJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgdG8gZmluZCBhIGhvc3QgcGFyZW50LiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgJyArICdpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG59XG5cbmZ1bmN0aW9uIGlzSG9zdFBhcmVudChmaWJlcikge1xuICByZXR1cm4gZmliZXIudGFnID09PSBIb3N0Q29tcG9uZW50IHx8IGZpYmVyLnRhZyA9PT0gSG9zdFJvb3QgfHwgZmliZXIudGFnID09PSBIb3N0UG9ydGFsO1xufVxuXG5mdW5jdGlvbiBnZXRIb3N0U2libGluZyhmaWJlcikge1xuICAvLyBXZSdyZSBnb2luZyB0byBzZWFyY2ggZm9yd2FyZCBpbnRvIHRoZSB0cmVlIHVudGlsIHdlIGZpbmQgYSBzaWJsaW5nIGhvc3RcbiAgLy8gbm9kZS4gVW5mb3J0dW5hdGVseSwgaWYgbXVsdGlwbGUgaW5zZXJ0aW9ucyBhcmUgZG9uZSBpbiBhIHJvdyB3ZSBoYXZlIHRvXG4gIC8vIHNlYXJjaCBwYXN0IHRoZW0uIFRoaXMgbGVhZHMgdG8gZXhwb25lbnRpYWwgc2VhcmNoIGZvciB0aGUgbmV4dCBzaWJsaW5nLlxuICAvLyBUT0RPOiBGaW5kIGEgbW9yZSBlZmZpY2llbnQgd2F5IHRvIGRvIHRoaXMuXG4gIHZhciBub2RlID0gZmliZXI7XG5cbiAgc2libGluZ3M6IHdoaWxlICh0cnVlKSB7XG4gICAgLy8gSWYgd2UgZGlkbid0IGZpbmQgYW55dGhpbmcsIGxldCdzIHRyeSB0aGUgbmV4dCBzaWJsaW5nLlxuICAgIHdoaWxlIChub2RlLnNpYmxpbmcgPT09IG51bGwpIHtcbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCB8fCBpc0hvc3RQYXJlbnQobm9kZS5yZXR1cm4pKSB7XG4gICAgICAgIC8vIElmIHdlIHBvcCBvdXQgb2YgdGhlIHJvb3Qgb3IgaGl0IHRoZSBwYXJlbnQgdGhlIGZpYmVyIHdlIGFyZSB0aGVcbiAgICAgICAgLy8gbGFzdCBzaWJsaW5nLlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuXG4gICAgd2hpbGUgKG5vZGUudGFnICE9PSBIb3N0Q29tcG9uZW50ICYmIG5vZGUudGFnICE9PSBIb3N0VGV4dCAmJiBub2RlLnRhZyAhPT0gRGVoeWRyYXRlZEZyYWdtZW50KSB7XG4gICAgICAvLyBJZiBpdCBpcyBub3QgaG9zdCBub2RlIGFuZCwgd2UgbWlnaHQgaGF2ZSBhIGhvc3Qgbm9kZSBpbnNpZGUgaXQuXG4gICAgICAvLyBUcnkgdG8gc2VhcmNoIGRvd24gdW50aWwgd2UgZmluZCBvbmUuXG4gICAgICBpZiAobm9kZS5mbGFncyAmIFBsYWNlbWVudCkge1xuICAgICAgICAvLyBJZiB3ZSBkb24ndCBoYXZlIGEgY2hpbGQsIHRyeSB0aGUgc2libGluZ3MgaW5zdGVhZC5cbiAgICAgICAgY29udGludWUgc2libGluZ3M7XG4gICAgICB9IC8vIElmIHdlIGRvbid0IGhhdmUgYSBjaGlsZCwgdHJ5IHRoZSBzaWJsaW5ncyBpbnN0ZWFkLlxuICAgICAgLy8gV2UgYWxzbyBza2lwIHBvcnRhbHMgYmVjYXVzZSB0aGV5IGFyZSBub3QgcGFydCBvZiB0aGlzIGhvc3QgdHJlZS5cblxuXG4gICAgICBpZiAobm9kZS5jaGlsZCA9PT0gbnVsbCB8fCBub2RlLnRhZyA9PT0gSG9zdFBvcnRhbCkge1xuICAgICAgICBjb250aW51ZSBzaWJsaW5ncztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICB9XG4gICAgfSAvLyBDaGVjayBpZiB0aGlzIGhvc3Qgbm9kZSBpcyBzdGFibGUgb3IgYWJvdXQgdG8gYmUgcGxhY2VkLlxuXG5cbiAgICBpZiAoIShub2RlLmZsYWdzICYgUGxhY2VtZW50KSkge1xuICAgICAgLy8gRm91bmQgaXQhXG4gICAgICByZXR1cm4gbm9kZS5zdGF0ZU5vZGU7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBsYWNlbWVudChmaW5pc2hlZFdvcmspIHtcblxuXG4gIHZhciBwYXJlbnRGaWJlciA9IGdldEhvc3RQYXJlbnRGaWJlcihmaW5pc2hlZFdvcmspOyAvLyBOb3RlOiB0aGVzZSB0d28gdmFyaWFibGVzICptdXN0KiBhbHdheXMgYmUgdXBkYXRlZCB0b2dldGhlci5cblxuICBzd2l0Y2ggKHBhcmVudEZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IHBhcmVudEZpYmVyLnN0YXRlTm9kZTtcblxuICAgICAgICBpZiAocGFyZW50RmliZXIuZmxhZ3MgJiBDb250ZW50UmVzZXQpIHtcbiAgICAgICAgICAvLyBSZXNldCB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBwYXJlbnQgYmVmb3JlIGRvaW5nIGFueSBpbnNlcnRpb25zXG4gICAgICAgICAgcmVzZXRUZXh0Q29udGVudChwYXJlbnQpOyAvLyBDbGVhciBDb250ZW50UmVzZXQgZnJvbSB0aGUgZWZmZWN0IHRhZ1xuXG4gICAgICAgICAgcGFyZW50RmliZXIuZmxhZ3MgJj0gfkNvbnRlbnRSZXNldDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBiZWZvcmUgPSBnZXRIb3N0U2libGluZyhmaW5pc2hlZFdvcmspOyAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBpbnNlcnRlZCBidXQgd2UgbmVlZCB0byByZWN1cnNlIGRvd24gaXRzXG4gICAgICAgIC8vIGNoaWxkcmVuIHRvIGZpbmQgYWxsIHRoZSB0ZXJtaW5hbCBub2Rlcy5cblxuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGUoZmluaXNoZWRXb3JrLCBiZWZvcmUsIHBhcmVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Um9vdDpcbiAgICBjYXNlIEhvc3RQb3J0YWw6XG4gICAgICB7XG4gICAgICAgIHZhciBfcGFyZW50ID0gcGFyZW50RmliZXIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87XG5cbiAgICAgICAgdmFyIF9iZWZvcmUgPSBnZXRIb3N0U2libGluZyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGluc2VydE9yQXBwZW5kUGxhY2VtZW50Tm9kZUludG9Db250YWluZXIoZmluaXNoZWRXb3JrLCBfYmVmb3JlLCBfcGFyZW50KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lLW5vLWZhbGx0aHJvdWdoXG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhvc3QgcGFyZW50IGZpYmVyLiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgJyArICdpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlSW50b0NvbnRhaW5lcihub2RlLCBiZWZvcmUsIHBhcmVudCkge1xuICB2YXIgdGFnID0gbm9kZS50YWc7XG4gIHZhciBpc0hvc3QgPSB0YWcgPT09IEhvc3RDb21wb25lbnQgfHwgdGFnID09PSBIb3N0VGV4dDtcblxuICBpZiAoaXNIb3N0KSB7XG4gICAgdmFyIHN0YXRlTm9kZSA9IG5vZGUuc3RhdGVOb2RlO1xuXG4gICAgaWYgKGJlZm9yZSkge1xuICAgICAgaW5zZXJ0SW5Db250YWluZXJCZWZvcmUocGFyZW50LCBzdGF0ZU5vZGUsIGJlZm9yZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZENoaWxkVG9Db250YWluZXIocGFyZW50LCBzdGF0ZU5vZGUpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0YWcgPT09IEhvc3RQb3J0YWwpIDsgZWxzZSB7XG4gICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICAgIGlmIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlSW50b0NvbnRhaW5lcihjaGlsZCwgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgdmFyIHNpYmxpbmcgPSBjaGlsZC5zaWJsaW5nO1xuXG4gICAgICB3aGlsZSAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGVJbnRvQ29udGFpbmVyKHNpYmxpbmcsIGJlZm9yZSwgcGFyZW50KTtcbiAgICAgICAgc2libGluZyA9IHNpYmxpbmcuc2libGluZztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5zZXJ0T3JBcHBlbmRQbGFjZW1lbnROb2RlKG5vZGUsIGJlZm9yZSwgcGFyZW50KSB7XG4gIHZhciB0YWcgPSBub2RlLnRhZztcbiAgdmFyIGlzSG9zdCA9IHRhZyA9PT0gSG9zdENvbXBvbmVudCB8fCB0YWcgPT09IEhvc3RUZXh0O1xuXG4gIGlmIChpc0hvc3QpIHtcbiAgICB2YXIgc3RhdGVOb2RlID0gbm9kZS5zdGF0ZU5vZGU7XG5cbiAgICBpZiAoYmVmb3JlKSB7XG4gICAgICBpbnNlcnRCZWZvcmUocGFyZW50LCBzdGF0ZU5vZGUsIGJlZm9yZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwcGVuZENoaWxkKHBhcmVudCwgc3RhdGVOb2RlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGFnID09PSBIb3N0UG9ydGFsKSA7IGVsc2Uge1xuICAgIHZhciBjaGlsZCA9IG5vZGUuY2hpbGQ7XG5cbiAgICBpZiAoY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGluc2VydE9yQXBwZW5kUGxhY2VtZW50Tm9kZShjaGlsZCwgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgdmFyIHNpYmxpbmcgPSBjaGlsZC5zaWJsaW5nO1xuXG4gICAgICB3aGlsZSAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgICBpbnNlcnRPckFwcGVuZFBsYWNlbWVudE5vZGUoc2libGluZywgYmVmb3JlLCBwYXJlbnQpO1xuICAgICAgICBzaWJsaW5nID0gc2libGluZy5zaWJsaW5nO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSAvLyBUaGVzZSBhcmUgdHJhY2tlZCBvbiB0aGUgc3RhY2sgYXMgd2UgcmVjdXJzaXZlbHkgdHJhdmVyc2UgYVxuLy8gZGVsZXRlZCBzdWJ0cmVlLlxuLy8gVE9ETzogVXBkYXRlIHRoZXNlIGR1cmluZyB0aGUgd2hvbGUgbXV0YXRpb24gcGhhc2UsIG5vdCBqdXN0IGR1cmluZ1xuLy8gYSBkZWxldGlvbi5cblxuXG52YXIgaG9zdFBhcmVudCA9IG51bGw7XG52YXIgaG9zdFBhcmVudElzQ29udGFpbmVyID0gZmFsc2U7XG5cbmZ1bmN0aW9uIGNvbW1pdERlbGV0aW9uRWZmZWN0cyhyb290LCByZXR1cm5GaWJlciwgZGVsZXRlZEZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBvbmx5IGhhdmUgdGhlIHRvcCBGaWJlciB0aGF0IHdhcyBkZWxldGVkIGJ1dCB3ZSBuZWVkIHRvIHJlY3Vyc2UgZG93biBpdHNcbiAgICAvLyBjaGlsZHJlbiB0byBmaW5kIGFsbCB0aGUgdGVybWluYWwgbm9kZXMuXG4gICAgLy8gUmVjdXJzaXZlbHkgZGVsZXRlIGFsbCBob3N0IG5vZGVzIGZyb20gdGhlIHBhcmVudCwgZGV0YWNoIHJlZnMsIGNsZWFuXG4gICAgLy8gdXAgbW91bnRlZCBsYXlvdXQgZWZmZWN0cywgYW5kIGNhbGwgY29tcG9uZW50V2lsbFVubW91bnQuXG4gICAgLy8gV2Ugb25seSBuZWVkIHRvIHJlbW92ZSB0aGUgdG9wbW9zdCBob3N0IGNoaWxkIGluIGVhY2ggYnJhbmNoLiBCdXQgdGhlbiB3ZVxuICAgIC8vIHN0aWxsIG5lZWQgdG8ga2VlcCB0cmF2ZXJzaW5nIHRvIHVubW91bnQgZWZmZWN0cywgcmVmcywgYW5kIGNXVS4gVE9ETzogV2VcbiAgICAvLyBjb3VsZCBzcGxpdCB0aGlzIGludG8gdHdvIHNlcGFyYXRlIHRyYXZlcnNhbHMgZnVuY3Rpb25zLCB3aGVyZSB0aGUgc2Vjb25kXG4gICAgLy8gb25lIGRvZXNuJ3QgaW5jbHVkZSBhbnkgcmVtb3ZlQ2hpbGQgbG9naWMuIFRoaXMgaXMgbWF5YmUgdGhlIHNhbWVcbiAgICAvLyBmdW5jdGlvbiBhcyBcImRpc2FwcGVhckxheW91dEVmZmVjdHNcIiAob3Igd2hhdGV2ZXIgdGhhdCB0dXJucyBpbnRvIGFmdGVyXG4gICAgLy8gdGhlIGxheW91dCBwaGFzZSBpcyByZWZhY3RvcmVkIHRvIHVzZSByZWN1cnNpb24pLlxuICAgIC8vIEJlZm9yZSBzdGFydGluZywgZmluZCB0aGUgbmVhcmVzdCBob3N0IHBhcmVudCBvbiB0aGUgc3RhY2sgc28gd2Uga25vd1xuICAgIC8vIHdoaWNoIGluc3RhbmNlL2NvbnRhaW5lciB0byByZW1vdmUgdGhlIGNoaWxkcmVuIGZyb20uXG4gICAgLy8gVE9ETzogSW5zdGVhZCBvZiBzZWFyY2hpbmcgdXAgdGhlIGZpYmVyIHJldHVybiBwYXRoIG9uIGV2ZXJ5IGRlbGV0aW9uLCB3ZVxuICAgIC8vIGNhbiB0cmFjayB0aGUgbmVhcmVzdCBob3N0IGNvbXBvbmVudCBvbiB0aGUgSlMgc3RhY2sgYXMgd2UgdHJhdmVyc2UgdGhlXG4gICAgLy8gdHJlZSBkdXJpbmcgdGhlIGNvbW1pdCBwaGFzZS4gVGhpcyB3b3VsZCBtYWtlIGluc2VydGlvbnMgZmFzdGVyLCB0b28uXG4gICAgdmFyIHBhcmVudCA9IHJldHVybkZpYmVyO1xuXG4gICAgZmluZFBhcmVudDogd2hpbGUgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChwYXJlbnQudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZTtcbiAgICAgICAgICAgIGhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWsgZmluZFBhcmVudDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrIGZpbmRQYXJlbnQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBob3N0UGFyZW50ID0gcGFyZW50LnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrIGZpbmRQYXJlbnQ7XG4gICAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwYXJlbnQgPSBwYXJlbnQucmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChob3N0UGFyZW50ID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgYSBob3N0IHBhcmVudC4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5ICcgKyAnYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgIH1cblxuICAgIGNvbW1pdERlbGV0aW9uRWZmZWN0c09uRmliZXIocm9vdCwgcmV0dXJuRmliZXIsIGRlbGV0ZWRGaWJlcik7XG4gICAgaG9zdFBhcmVudCA9IG51bGw7XG4gICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gZmFsc2U7XG4gIH1cblxuICBkZXRhY2hGaWJlck11dGF0aW9uKGRlbGV0ZWRGaWJlcik7XG59XG5cbmZ1bmN0aW9uIHJlY3Vyc2l2ZWx5VHJhdmVyc2VEZWxldGlvbkVmZmVjdHMoZmluaXNoZWRSb290LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBwYXJlbnQpIHtcbiAgLy8gVE9ETzogVXNlIGEgc3RhdGljIGZsYWcgdG8gc2tpcCB0cmVlcyB0aGF0IGRvbid0IGhhdmUgdW5tb3VudCBlZmZlY3RzXG4gIHZhciBjaGlsZCA9IHBhcmVudC5jaGlsZDtcblxuICB3aGlsZSAoY2hpbGQgIT09IG51bGwpIHtcbiAgICBjb21taXREZWxldGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgY2hpbGQpO1xuICAgIGNoaWxkID0gY2hpbGQuc2libGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXREZWxldGlvbkVmZmVjdHNPbkZpYmVyKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKSB7XG4gIG9uQ29tbWl0VW5tb3VudChkZWxldGVkRmliZXIpOyAvLyBUaGUgY2FzZXMgaW4gdGhpcyBvdXRlciBzd2l0Y2ggbW9kaWZ5IHRoZSBzdGFjayBiZWZvcmUgdGhleSB0cmF2ZXJzZVxuICAvLyBpbnRvIHRoZWlyIHN1YnRyZWUuIFRoZXJlIGFyZSBzaW1wbGVyIGNhc2VzIGluIHRoZSBpbm5lciBzd2l0Y2hcbiAgLy8gdGhhdCBkb24ndCBtb2RpZnkgdGhlIHN0YWNrLlxuXG4gIHN3aXRjaCAoZGVsZXRlZEZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgaWYgKCFvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuKSB7XG4gICAgICAgICAgc2FmZWx5RGV0YWNoUmVmKGRlbGV0ZWRGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcik7XG4gICAgICAgIH0gLy8gSW50ZW50aW9uYWwgZmFsbHRocm91Z2ggdG8gbmV4dCBicmFuY2hcblxuICAgICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZS1uby1mYWxsdGhyb3VnaFxuXG4gICAgY2FzZSBIb3N0VGV4dDpcbiAgICAgIHtcbiAgICAgICAgLy8gV2Ugb25seSBuZWVkIHRvIHJlbW92ZSB0aGUgbmVhcmVzdCBob3N0IGNoaWxkLiBTZXQgdGhlIGhvc3QgcGFyZW50XG4gICAgICAgIC8vIHRvIGBudWxsYCBvbiB0aGUgc3RhY2sgdG8gaW5kaWNhdGUgdGhhdCBuZXN0ZWQgY2hpbGRyZW4gZG9uJ3RcbiAgICAgICAgLy8gbmVlZCB0byBiZSByZW1vdmVkLlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHByZXZIb3N0UGFyZW50ID0gaG9zdFBhcmVudDtcbiAgICAgICAgICB2YXIgcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgICBob3N0UGFyZW50ID0gbnVsbDtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlRGVsZXRpb25FZmZlY3RzKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKTtcbiAgICAgICAgICBob3N0UGFyZW50ID0gcHJldkhvc3RQYXJlbnQ7XG4gICAgICAgICAgaG9zdFBhcmVudElzQ29udGFpbmVyID0gcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcblxuICAgICAgICAgIGlmIChob3N0UGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBOb3cgdGhhdCBhbGwgdGhlIGNoaWxkIGVmZmVjdHMgaGF2ZSB1bm1vdW50ZWQsIHdlIGNhbiByZW1vdmUgdGhlXG4gICAgICAgICAgICAvLyBub2RlIGZyb20gdGhlIHRyZWUuXG4gICAgICAgICAgICBpZiAoaG9zdFBhcmVudElzQ29udGFpbmVyKSB7XG4gICAgICAgICAgICAgIHJlbW92ZUNoaWxkRnJvbUNvbnRhaW5lcihob3N0UGFyZW50LCBkZWxldGVkRmliZXIuc3RhdGVOb2RlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJlbW92ZUNoaWxkKGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgRGVoeWRyYXRlZEZyYWdtZW50OlxuICAgICAge1xuICAgICAgICAvLyBEZWxldGUgdGhlIGRlaHlkcmF0ZWQgc3VzcGVuc2UgYm91bmRhcnkgYW5kIGFsbCBvZiBpdHMgY29udGVudC5cblxuXG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoaG9zdFBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGhvc3RQYXJlbnRJc0NvbnRhaW5lcikge1xuICAgICAgICAgICAgICBjbGVhclN1c3BlbnNlQm91bmRhcnlGcm9tQ29udGFpbmVyKGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY2xlYXJTdXNwZW5zZUJvdW5kYXJ5KGhvc3RQYXJlbnQsIGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHtcbiAgICAgICAge1xuICAgICAgICAgIC8vIFdoZW4gd2UgZ28gaW50byBhIHBvcnRhbCwgaXQgYmVjb21lcyB0aGUgcGFyZW50IHRvIHJlbW92ZSBmcm9tLlxuICAgICAgICAgIHZhciBfcHJldkhvc3RQYXJlbnQgPSBob3N0UGFyZW50O1xuICAgICAgICAgIHZhciBfcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IGhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgICBob3N0UGFyZW50ID0gZGVsZXRlZEZpYmVyLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1xuICAgICAgICAgIGhvc3RQYXJlbnRJc0NvbnRhaW5lciA9IHRydWU7XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgICAgaG9zdFBhcmVudCA9IF9wcmV2SG9zdFBhcmVudDtcbiAgICAgICAgICBob3N0UGFyZW50SXNDb250YWluZXIgPSBfcHJldkhvc3RQYXJlbnRJc0NvbnRhaW5lcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IGRlbGV0ZWRGaWJlci51cGRhdGVRdWV1ZTtcblxuICAgICAgICAgIGlmICh1cGRhdGVRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGxhc3RFZmZlY3QgPSB1cGRhdGVRdWV1ZS5sYXN0RWZmZWN0O1xuXG4gICAgICAgICAgICBpZiAobGFzdEVmZmVjdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICB2YXIgZmlyc3RFZmZlY3QgPSBsYXN0RWZmZWN0Lm5leHQ7XG4gICAgICAgICAgICAgIHZhciBlZmZlY3QgPSBmaXJzdEVmZmVjdDtcblxuICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgdmFyIF9lZmZlY3QgPSBlZmZlY3QsXG4gICAgICAgICAgICAgICAgICAgIGRlc3Ryb3kgPSBfZWZmZWN0LmRlc3Ryb3ksXG4gICAgICAgICAgICAgICAgICAgIHRhZyA9IF9lZmZlY3QudGFnO1xuXG4gICAgICAgICAgICAgICAgaWYgKGRlc3Ryb3kgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiBJbnNlcnRpb24pICE9PSBOb0ZsYWdzJDEpIHtcbiAgICAgICAgICAgICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoKHRhZyAmIExheW91dCkgIT09IE5vRmxhZ3MkMSkge1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdGFydGVkKGRlbGV0ZWRGaWJlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoIGRlbGV0ZWRGaWJlci5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgc2FmZWx5Q2FsbERlc3Ryb3koZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZXN0cm95KTtcbiAgICAgICAgICAgICAgICAgICAgICByZWNvcmRMYXlvdXRFZmZlY3REdXJhdGlvbihkZWxldGVkRmliZXIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHNhZmVseUNhbGxEZXN0cm95KGRlbGV0ZWRGaWJlciwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVzdHJveSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgbWFya0NvbXBvbmVudExheW91dEVmZmVjdFVubW91bnRTdG9wcGVkKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBlZmZlY3QgPSBlZmZlY3QubmV4dDtcbiAgICAgICAgICAgICAgfSB3aGlsZSAoZWZmZWN0ICE9PSBmaXJzdEVmZmVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICghb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbikge1xuICAgICAgICAgIHNhZmVseURldGFjaFJlZihkZWxldGVkRmliZXIsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpO1xuICAgICAgICAgIHZhciBpbnN0YW5jZSA9IGRlbGV0ZWRGaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzYWZlbHlDYWxsQ29tcG9uZW50V2lsbFVubW91bnQoZGVsZXRlZEZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBpbnN0YW5jZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgU2NvcGVDb21wb25lbnQ6XG4gICAgICB7XG5cbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgT2Zmc2NyZWVuQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIC8vIFRPRE86IFJlbW92ZSB0aGlzIGRlYWQgZmxhZ1xuICAgICAgICAgZGVsZXRlZEZpYmVyLm1vZGUgJiBDb25jdXJyZW50TW9kZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgb2Zmc2NyZWVuIGNvbXBvbmVudCBpcyBoaWRkZW4sIHdlIGFscmVhZHkgdW5tb3VudGVkIGl0LiBCZWZvcmVcbiAgICAgICAgICAvLyBkZWxldGluZyB0aGUgY2hpbGRyZW4sIHRyYWNrIHRoYXQgaXQncyBhbHJlYWR5IHVubW91bnRlZCBzbyB0aGF0IHdlXG4gICAgICAgICAgLy8gZG9uJ3QgYXR0ZW1wdCB0byB1bm1vdW50IHRoZSBlZmZlY3RzIGFnYWluLlxuICAgICAgICAgIC8vIFRPRE86IElmIHRoZSB0cmVlIGlzIGhpZGRlbiwgaW4gbW9zdCBjYXNlcyB3ZSBzaG91bGQgYmUgYWJsZSB0byBza2lwXG4gICAgICAgICAgLy8gb3ZlciB0aGUgbmVzdGVkIGNoaWxkcmVuIGVudGlyZWx5LiBBbiBleGNlcHRpb24gaXMgd2UgaGF2ZW4ndCB5ZXQgZm91bmRcbiAgICAgICAgICAvLyB0aGUgdG9wbW9zdCBob3N0IG5vZGUgdG8gZGVsZXRlLCB3aGljaCB3ZSBhbHJlYWR5IHRyYWNrIG9uIHRoZSBzdGFjay5cbiAgICAgICAgICAvLyBCdXQgdGhlIG90aGVyIGNhc2UgaXMgcG9ydGFscywgd2hpY2ggbmVlZCB0byBiZSBkZXRhY2hlZCBubyBtYXR0ZXIgaG93XG4gICAgICAgICAgLy8gZGVlcGx5IHRoZXkgYXJlIG5lc3RlZC4gV2Ugc2hvdWxkIHVzZSBhIHN1YnRyZWUgZmxhZyB0byB0cmFjayB3aGV0aGVyIGFcbiAgICAgICAgICAvLyBzdWJ0cmVlIGluY2x1ZGVzIGEgbmVzdGVkIHBvcnRhbC5cbiAgICAgICAgICB2YXIgcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICAgIG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiB8fCBkZWxldGVkRmliZXIubWVtb2l6ZWRTdGF0ZSAhPT0gbnVsbDtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlRGVsZXRpb25FZmZlY3RzKGZpbmlzaGVkUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3RvciwgZGVsZXRlZEZpYmVyKTtcbiAgICAgICAgICBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZURlbGV0aW9uRWZmZWN0cyhmaW5pc2hlZFJvb3QsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IsIGRlbGV0ZWRGaWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VEZWxldGlvbkVmZmVjdHMoZmluaXNoZWRSb290LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBkZWxldGVkRmliZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0U3VzcGVuc2VDYWxsYmFjayhmaW5pc2hlZFdvcmspIHtcbiAgLy8gVE9ETzogTW92ZSB0aGlzIHRvIHBhc3NpdmUgcGhhc2VcbiAgdmFyIG5ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFN1c3BlbnNlSHlkcmF0aW9uQ2FsbGJhY2tzKGZpbmlzaGVkUm9vdCwgZmluaXNoZWRXb3JrKSB7XG5cbiAgdmFyIG5ld1N0YXRlID0gZmluaXNoZWRXb3JrLm1lbW9pemVkU3RhdGU7XG5cbiAgaWYgKG5ld1N0YXRlID09PSBudWxsKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBmaW5pc2hlZFdvcmsuYWx0ZXJuYXRlO1xuXG4gICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgIHZhciBwcmV2U3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG5cbiAgICAgIGlmIChwcmV2U3RhdGUgIT09IG51bGwpIHtcbiAgICAgICAgdmFyIHN1c3BlbnNlSW5zdGFuY2UgPSBwcmV2U3RhdGUuZGVoeWRyYXRlZDtcblxuICAgICAgICBpZiAoc3VzcGVuc2VJbnN0YW5jZSAhPT0gbnVsbCkge1xuICAgICAgICAgIGNvbW1pdEh5ZHJhdGVkU3VzcGVuc2VJbnN0YW5jZShzdXNwZW5zZUluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yaykge1xuICAvLyBJZiB0aGlzIGJvdW5kYXJ5IGp1c3QgdGltZWQgb3V0LCB0aGVuIGl0IHdpbGwgaGF2ZSBhIHNldCBvZiB3YWtlYWJsZXMuXG4gIC8vIEZvciBlYWNoIHdha2VhYmxlLCBhdHRhY2ggYSBsaXN0ZW5lciBzbyB0aGF0IHdoZW4gaXQgcmVzb2x2ZXMsIFJlYWN0XG4gIC8vIGF0dGVtcHRzIHRvIHJlLXJlbmRlciB0aGUgYm91bmRhcnkgaW4gdGhlIHByaW1hcnkgKHByZS10aW1lb3V0KSBzdGF0ZS5cbiAgdmFyIHdha2VhYmxlcyA9IGZpbmlzaGVkV29yay51cGRhdGVRdWV1ZTtcblxuICBpZiAod2FrZWFibGVzICE9PSBudWxsKSB7XG4gICAgZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB2YXIgcmV0cnlDYWNoZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG5cbiAgICBpZiAocmV0cnlDYWNoZSA9PT0gbnVsbCkge1xuICAgICAgcmV0cnlDYWNoZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGUgPSBuZXcgUG9zc2libHlXZWFrU2V0KCk7XG4gICAgfVxuXG4gICAgd2FrZWFibGVzLmZvckVhY2goZnVuY3Rpb24gKHdha2VhYmxlKSB7XG4gICAgICAvLyBNZW1vaXplIHVzaW5nIHRoZSBib3VuZGFyeSBmaWJlciB0byBwcmV2ZW50IHJlZHVuZGFudCBsaXN0ZW5lcnMuXG4gICAgICB2YXIgcmV0cnkgPSByZXNvbHZlUmV0cnlXYWtlYWJsZS5iaW5kKG51bGwsIGZpbmlzaGVkV29yaywgd2FrZWFibGUpO1xuXG4gICAgICBpZiAoIXJldHJ5Q2FjaGUuaGFzKHdha2VhYmxlKSkge1xuICAgICAgICByZXRyeUNhY2hlLmFkZCh3YWtlYWJsZSk7XG5cbiAgICAgICAge1xuICAgICAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICAgICAgaWYgKGluUHJvZ3Jlc3NMYW5lcyAhPT0gbnVsbCAmJiBpblByb2dyZXNzUm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIHBlbmRpbmcgd29yayBzdGlsbCwgYXNzb2NpYXRlIHRoZSBvcmlnaW5hbCB1cGRhdGVycyB3aXRoIGl0LlxuICAgICAgICAgICAgICByZXN0b3JlUGVuZGluZ1VwZGF0ZXJzKGluUHJvZ3Jlc3NSb290LCBpblByb2dyZXNzTGFuZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0V4cGVjdGVkIGZpbmlzaGVkIHJvb3QgYW5kIGxhbmVzIHRvIGJlIHNldC4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB3YWtlYWJsZS50aGVuKHJldHJ5LCByZXRyeSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0gLy8gVGhpcyBmdW5jdGlvbiBkZXRlY3RzIHdoZW4gYSBTdXNwZW5zZSBib3VuZGFyeSBnb2VzIGZyb20gdmlzaWJsZSB0byBoaWRkZW4uXG5mdW5jdGlvbiBjb21taXRNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrLCBjb21taXR0ZWRMYW5lcykge1xuICBpblByb2dyZXNzTGFuZXMgPSBjb21taXR0ZWRMYW5lcztcbiAgaW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICBzZXRDdXJyZW50RmliZXIoZmluaXNoZWRXb3JrKTtcbiAgY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihmaW5pc2hlZFdvcmssIHJvb3QpO1xuICBzZXRDdXJyZW50RmliZXIoZmluaXNoZWRXb3JrKTtcbiAgaW5Qcm9ncmVzc0xhbmVzID0gbnVsbDtcbiAgaW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xufVxuXG5mdW5jdGlvbiByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIHBhcmVudEZpYmVyLCBsYW5lcykge1xuICAvLyBEZWxldGlvbnMgZWZmZWN0cyBjYW4gYmUgc2NoZWR1bGVkIG9uIGFueSBmaWJlciB0eXBlLiBUaGV5IG5lZWQgdG8gaGFwcGVuXG4gIC8vIGJlZm9yZSB0aGUgY2hpbGRyZW4gZWZmZWN0cyBoYWUgZmlyZWQuXG4gIHZhciBkZWxldGlvbnMgPSBwYXJlbnRGaWJlci5kZWxldGlvbnM7XG5cbiAgaWYgKGRlbGV0aW9ucyAhPT0gbnVsbCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGVsZXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hpbGRUb0RlbGV0ZSA9IGRlbGV0aW9uc1tpXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbWl0RGVsZXRpb25FZmZlY3RzKHJvb3QsIHBhcmVudEZpYmVyLCBjaGlsZFRvRGVsZXRlKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGNoaWxkVG9EZWxldGUsIHBhcmVudEZpYmVyLCBlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHByZXZEZWJ1Z0ZpYmVyID0gZ2V0Q3VycmVudEZpYmVyKCk7XG5cbiAgaWYgKHBhcmVudEZpYmVyLnN1YnRyZWVGbGFncyAmIE11dGF0aW9uTWFzaykge1xuICAgIHZhciBjaGlsZCA9IHBhcmVudEZpYmVyLmNoaWxkO1xuXG4gICAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoY2hpbGQpO1xuICAgICAgY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihjaGlsZCwgcm9vdCk7XG4gICAgICBjaGlsZCA9IGNoaWxkLnNpYmxpbmc7XG4gICAgfVxuICB9XG5cbiAgc2V0Q3VycmVudEZpYmVyKHByZXZEZWJ1Z0ZpYmVyKTtcbn1cblxuZnVuY3Rpb24gY29tbWl0TXV0YXRpb25FZmZlY3RzT25GaWJlcihmaW5pc2hlZFdvcmssIHJvb3QsIGxhbmVzKSB7XG4gIHZhciBjdXJyZW50ID0gZmluaXNoZWRXb3JrLmFsdGVybmF0ZTtcbiAgdmFyIGZsYWdzID0gZmluaXNoZWRXb3JrLmZsYWdzOyAvLyBUaGUgZWZmZWN0IGZsYWcgc2hvdWxkIGJlIGNoZWNrZWQgKmFmdGVyKiB3ZSByZWZpbmUgdGhlIHR5cGUgb2YgZmliZXIsXG4gIC8vIGJlY2F1c2UgdGhlIGZpYmVyIHRhZyBpcyBtb3JlIHNwZWNpZmljLiBBbiBleGNlcHRpb24gaXMgYW55IGZsYWcgcmVsYXRlZFxuICAvLyB0byByZWNvbmNpbGF0aW9uLCBiZWNhdXNlIHRob3NlIGNhbiBiZSBzZXQgb24gYWxsIGZpYmVyIHR5cGVzLlxuXG4gIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChJbnNlcnRpb24gfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KEluc2VydGlvbiB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfSAvLyBMYXlvdXQgZWZmZWN0cyBhcmUgZGVzdHJveWVkIGR1cmluZyB0aGUgbXV0YXRpb24gcGhhc2Ugc28gdGhhdCBhbGxcbiAgICAgICAgICAvLyBkZXN0cm95IGZ1bmN0aW9ucyBmb3IgYWxsIGZpYmVycyBhcmUgY2FsbGVkIGJlZm9yZSBhbnkgY3JlYXRlIGZ1bmN0aW9ucy5cbiAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIHNpYmxpbmcgY29tcG9uZW50IGVmZmVjdHMgZnJvbSBpbnRlcmZlcmluZyB3aXRoIGVhY2ggb3RoZXIsXG4gICAgICAgICAgLy8gZS5nLiBhIGRlc3Ryb3kgZnVuY3Rpb24gaW4gb25lIGNvbXBvbmVudCBzaG91bGQgbmV2ZXIgb3ZlcnJpZGUgYSByZWYgc2V0XG4gICAgICAgICAgLy8gYnkgYSBjcmVhdGUgZnVuY3Rpb24gaW4gYW5vdGhlciBjb21wb25lbnQgZHVyaW5nIHRoZSBzYW1lIGNvbW1pdC5cblxuXG4gICAgICAgICAgaWYgKCBmaW5pc2hlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChMYXlvdXQgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4sIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RVbm1vdW50KExheW91dCB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgUmVmKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHNhZmVseURldGFjaFJlZihjdXJyZW50LCBjdXJyZW50LnJldHVybik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgY2FzZSBIb3N0Q29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuXG4gICAgICAgIGlmIChmbGFncyAmIFJlZikge1xuICAgICAgICAgIGlmIChjdXJyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoY3VycmVudCwgY3VycmVudC5yZXR1cm4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHtcbiAgICAgICAgICAvLyBUT0RPOiBDb250ZW50UmVzZXQgZ2V0cyBjbGVhcmVkIGJ5IHRoZSBjaGlsZHJlbiBkdXJpbmcgdGhlIGNvbW1pdFxuICAgICAgICAgIC8vIHBoYXNlLiBUaGlzIGlzIGEgcmVmYWN0b3IgaGF6YXJkIGJlY2F1c2UgaXQgbWVhbnMgd2UgbXVzdCByZWFkXG4gICAgICAgICAgLy8gZmxhZ3MgdGhlIGZsYWdzIGFmdGVyIGBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHNgIGhhcyBhbHJlYWR5IHJ1bjtcbiAgICAgICAgICAvLyB0aGUgb3JkZXIgbWF0dGVycy4gV2Ugc2hvdWxkIHJlZmFjdG9yIHNvIHRoYXQgQ29udGVudFJlc2V0IGRvZXMgbm90XG4gICAgICAgICAgLy8gcmVseSBvbiBtdXRhdGluZyB0aGUgZmxhZyBkdXJpbmcgY29tbWl0LiBMaWtlIGJ5IHNldHRpbmcgYSBmbGFnXG4gICAgICAgICAgLy8gZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UgaW5zdGVhZC5cbiAgICAgICAgICBpZiAoZmluaXNoZWRXb3JrLmZsYWdzICYgQ29udGVudFJlc2V0KSB7XG4gICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICByZXNldFRleHRDb250ZW50KGluc3RhbmNlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmbGFncyAmIFVwZGF0ZSkge1xuICAgICAgICAgICAgdmFyIF9pbnN0YW5jZTQgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgICBpZiAoX2luc3RhbmNlNCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIC8vIENvbW1pdCB0aGUgd29yayBwcmVwYXJlZCBlYXJsaWVyLlxuICAgICAgICAgICAgICB2YXIgbmV3UHJvcHMgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wczsgLy8gRm9yIGh5ZHJhdGlvbiB3ZSByZXVzZSB0aGUgdXBkYXRlIHBhdGggYnV0IHdlIHRyZWF0IHRoZSBvbGRQcm9wc1xuICAgICAgICAgICAgICAvLyBhcyB0aGUgbmV3UHJvcHMuIFRoZSB1cGRhdGVQYXlsb2FkIHdpbGwgY29udGFpbiB0aGUgcmVhbCBjaGFuZ2UgaW5cbiAgICAgICAgICAgICAgLy8gdGhpcyBjYXNlLlxuXG4gICAgICAgICAgICAgIHZhciBvbGRQcm9wcyA9IGN1cnJlbnQgIT09IG51bGwgPyBjdXJyZW50Lm1lbW9pemVkUHJvcHMgOiBuZXdQcm9wcztcbiAgICAgICAgICAgICAgdmFyIHR5cGUgPSBmaW5pc2hlZFdvcmsudHlwZTsgLy8gVE9ETzogVHlwZSB0aGUgdXBkYXRlUXVldWUgdG8gYmUgc3BlY2lmaWMgdG8gaG9zdCBjb21wb25lbnRzLlxuXG4gICAgICAgICAgICAgIHZhciB1cGRhdGVQYXlsb2FkID0gZmluaXNoZWRXb3JrLnVwZGF0ZVF1ZXVlO1xuICAgICAgICAgICAgICBmaW5pc2hlZFdvcmsudXBkYXRlUXVldWUgPSBudWxsO1xuXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVQYXlsb2FkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbW1pdFVwZGF0ZShfaW5zdGFuY2U0LCB1cGRhdGVQYXlsb2FkLCB0eXBlLCBvbGRQcm9wcywgbmV3UHJvcHMsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFRleHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKGZpbmlzaGVkV29yay5zdGF0ZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIHNob3VsZCBoYXZlIGEgdGV4dCBub2RlIGluaXRpYWxpemVkLiBUaGlzIGVycm9yIGlzIGxpa2VseSAnICsgJ2NhdXNlZCBieSBhIGJ1ZyBpbiBSZWFjdC4gUGxlYXNlIGZpbGUgYW4gaXNzdWUuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB0ZXh0SW5zdGFuY2UgPSBmaW5pc2hlZFdvcmsuc3RhdGVOb2RlO1xuICAgICAgICAgICAgdmFyIG5ld1RleHQgPSBmaW5pc2hlZFdvcmsubWVtb2l6ZWRQcm9wczsgLy8gRm9yIGh5ZHJhdGlvbiB3ZSByZXVzZSB0aGUgdXBkYXRlIHBhdGggYnV0IHdlIHRyZWF0IHRoZSBvbGRQcm9wc1xuICAgICAgICAgICAgLy8gYXMgdGhlIG5ld1Byb3BzLiBUaGUgdXBkYXRlUGF5bG9hZCB3aWxsIGNvbnRhaW4gdGhlIHJlYWwgY2hhbmdlIGluXG4gICAgICAgICAgICAvLyB0aGlzIGNhc2UuXG5cbiAgICAgICAgICAgIHZhciBvbGRUZXh0ID0gY3VycmVudCAhPT0gbnVsbCA/IGN1cnJlbnQubWVtb2l6ZWRQcm9wcyA6IG5ld1RleHQ7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbW1pdFRleHRVcGRhdGUodGV4dEluc3RhbmNlLCBvbGRUZXh0LCBuZXdUZXh0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdmFyIHByZXZSb290U3RhdGUgPSBjdXJyZW50Lm1lbW9pemVkU3RhdGU7XG5cbiAgICAgICAgICAgICAgaWYgKHByZXZSb290U3RhdGUuaXNEZWh5ZHJhdGVkKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGNvbW1pdEh5ZHJhdGVkQ29udGFpbmVyKHJvb3QuY29udGFpbmVySW5mbyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgIHtcbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIGNvbW1pdFJlY29uY2lsaWF0aW9uRWZmZWN0cyhmaW5pc2hlZFdvcmspO1xuICAgICAgICB2YXIgb2Zmc2NyZWVuRmliZXIgPSBmaW5pc2hlZFdvcmsuY2hpbGQ7XG5cbiAgICAgICAgaWYgKG9mZnNjcmVlbkZpYmVyLmZsYWdzICYgVmlzaWJpbGl0eSkge1xuICAgICAgICAgIHZhciBvZmZzY3JlZW5JbnN0YW5jZSA9IG9mZnNjcmVlbkZpYmVyLnN0YXRlTm9kZTtcbiAgICAgICAgICB2YXIgbmV3U3RhdGUgPSBvZmZzY3JlZW5GaWJlci5tZW1vaXplZFN0YXRlO1xuICAgICAgICAgIHZhciBpc0hpZGRlbiA9IG5ld1N0YXRlICE9PSBudWxsOyAvLyBUcmFjayB0aGUgY3VycmVudCBzdGF0ZSBvbiB0aGUgT2Zmc2NyZWVuIGluc3RhbmNlIHNvIHdlIGNhblxuICAgICAgICAgIC8vIHJlYWQgaXQgZHVyaW5nIGFuIGV2ZW50XG5cbiAgICAgICAgICBvZmZzY3JlZW5JbnN0YW5jZS5pc0hpZGRlbiA9IGlzSGlkZGVuO1xuXG4gICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICB2YXIgd2FzSGlkZGVuID0gb2Zmc2NyZWVuRmliZXIuYWx0ZXJuYXRlICE9PSBudWxsICYmIG9mZnNjcmVlbkZpYmVyLmFsdGVybmF0ZS5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgICBpZiAoIXdhc0hpZGRlbikge1xuICAgICAgICAgICAgICAvLyBUT0RPOiBNb3ZlIHRvIHBhc3NpdmUgcGhhc2VcbiAgICAgICAgICAgICAgbWFya0NvbW1pdFRpbWVPZkZhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZsYWdzICYgVXBkYXRlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdFN1c3BlbnNlQ2FsbGJhY2soZmluaXNoZWRXb3JrKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmluaXNoZWRXb3JrLCBmaW5pc2hlZFdvcmsucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXR0YWNoU3VzcGVuc2VSZXRyeUxpc3RlbmVycyhmaW5pc2hlZFdvcmspO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIHZhciBfd2FzSGlkZGVuID0gY3VycmVudCAhPT0gbnVsbCAmJiBjdXJyZW50Lm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG5cbiAgICAgICAgaWYgKCAvLyBUT0RPOiBSZW1vdmUgdGhpcyBkZWFkIGZsYWdcbiAgICAgICAgIGZpbmlzaGVkV29yay5tb2RlICYgQ29uY3VycmVudE1vZGUpIHtcbiAgICAgICAgICAvLyBCZWZvcmUgY29tbWl0dGluZyB0aGUgY2hpbGRyZW4sIHRyYWNrIG9uIHRoZSBzdGFjayB3aGV0aGVyIHRoaXNcbiAgICAgICAgICAvLyBvZmZzY3JlZW4gc3VidHJlZSB3YXMgYWxyZWFkeSBoaWRkZW4sIHNvIHRoYXQgd2UgZG9uJ3QgdW5tb3VudCB0aGVcbiAgICAgICAgICAvLyBlZmZlY3RzIGFnYWluLlxuICAgICAgICAgIHZhciBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG4gICAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuIHx8IF93YXNIaWRkZW47XG4gICAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gPSBwcmV2T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZWN1cnNpdmVseVRyYXZlcnNlTXV0YXRpb25FZmZlY3RzKHJvb3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cblxuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICBpZiAoZmxhZ3MgJiBWaXNpYmlsaXR5KSB7XG4gICAgICAgICAgdmFyIF9vZmZzY3JlZW5JbnN0YW5jZSA9IGZpbmlzaGVkV29yay5zdGF0ZU5vZGU7XG4gICAgICAgICAgdmFyIF9uZXdTdGF0ZSA9IGZpbmlzaGVkV29yay5tZW1vaXplZFN0YXRlO1xuXG4gICAgICAgICAgdmFyIF9pc0hpZGRlbiA9IF9uZXdTdGF0ZSAhPT0gbnVsbDtcblxuICAgICAgICAgIHZhciBvZmZzY3JlZW5Cb3VuZGFyeSA9IGZpbmlzaGVkV29yazsgLy8gVHJhY2sgdGhlIGN1cnJlbnQgc3RhdGUgb24gdGhlIE9mZnNjcmVlbiBpbnN0YW5jZSBzbyB3ZSBjYW5cbiAgICAgICAgICAvLyByZWFkIGl0IGR1cmluZyBhbiBldmVudFxuXG4gICAgICAgICAgX29mZnNjcmVlbkluc3RhbmNlLmlzSGlkZGVuID0gX2lzSGlkZGVuO1xuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKF9pc0hpZGRlbikge1xuICAgICAgICAgICAgICBpZiAoIV93YXNIaWRkZW4pIHtcbiAgICAgICAgICAgICAgICBpZiAoKG9mZnNjcmVlbkJvdW5kYXJ5Lm1vZGUgJiBDb25jdXJyZW50TW9kZSkgIT09IE5vTW9kZSkge1xuICAgICAgICAgICAgICAgICAgbmV4dEVmZmVjdCA9IG9mZnNjcmVlbkJvdW5kYXJ5O1xuICAgICAgICAgICAgICAgICAgdmFyIG9mZnNjcmVlbkNoaWxkID0gb2Zmc2NyZWVuQm91bmRhcnkuY2hpbGQ7XG5cbiAgICAgICAgICAgICAgICAgIHdoaWxlIChvZmZzY3JlZW5DaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuZXh0RWZmZWN0ID0gb2Zmc2NyZWVuQ2hpbGQ7XG4gICAgICAgICAgICAgICAgICAgIGRpc2FwcGVhckxheW91dEVmZmVjdHNfYmVnaW4ob2Zmc2NyZWVuQ2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICBvZmZzY3JlZW5DaGlsZCA9IG9mZnNjcmVlbkNoaWxkLnNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAge1xuICAgICAgICAgICAgLy8gVE9ETzogVGhpcyBuZWVkcyB0byBydW4gd2hlbmV2ZXIgdGhlcmUncyBhbiBpbnNlcnRpb24gb3IgdXBkYXRlXG4gICAgICAgICAgICAvLyBpbnNpZGUgYSBoaWRkZW4gT2Zmc2NyZWVuIHRyZWUuXG4gICAgICAgICAgICBoaWRlT3JVbmhpZGVBbGxDaGlsZHJlbihvZmZzY3JlZW5Cb3VuZGFyeSwgX2lzSGlkZGVuKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgcmVjdXJzaXZlbHlUcmF2ZXJzZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuICAgICAgICBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKTtcblxuICAgICAgICBpZiAoZmxhZ3MgJiBVcGRhdGUpIHtcbiAgICAgICAgICBhdHRhY2hTdXNwZW5zZVJldHJ5TGlzdGVuZXJzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICBjYXNlIFNjb3BlQ29tcG9uZW50OlxuICAgICAge1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHJlY3Vyc2l2ZWx5VHJhdmVyc2VNdXRhdGlvbkVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgY29tbWl0UmVjb25jaWxpYXRpb25FZmZlY3RzKGZpbmlzaGVkV29yayk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRSZWNvbmNpbGlhdGlvbkVmZmVjdHMoZmluaXNoZWRXb3JrKSB7XG4gIC8vIFBsYWNlbWVudCBlZmZlY3RzIChpbnNlcnRpb25zLCByZW9yZGVycykgY2FuIGJlIHNjaGVkdWxlZCBvbiBhbnkgZmliZXJcbiAgLy8gdHlwZS4gVGhleSBuZWVkcyB0byBoYXBwZW4gYWZ0ZXIgdGhlIGNoaWxkcmVuIGVmZmVjdHMgaGF2ZSBmaXJlZCwgYnV0XG4gIC8vIGJlZm9yZSB0aGUgZWZmZWN0cyBvbiB0aGlzIGZpYmVyIGhhdmUgZmlyZWQuXG4gIHZhciBmbGFncyA9IGZpbmlzaGVkV29yay5mbGFncztcblxuICBpZiAoZmxhZ3MgJiBQbGFjZW1lbnQpIHtcbiAgICB0cnkge1xuICAgICAgY29tbWl0UGxhY2VtZW50KGZpbmlzaGVkV29yayk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybiwgZXJyb3IpO1xuICAgIH0gLy8gQ2xlYXIgdGhlIFwicGxhY2VtZW50XCIgZnJvbSBlZmZlY3QgdGFnIHNvIHRoYXQgd2Uga25vdyB0aGF0IHRoaXMgaXNcbiAgICAvLyBpbnNlcnRlZCwgYmVmb3JlIGFueSBsaWZlLWN5Y2xlcyBsaWtlIGNvbXBvbmVudERpZE1vdW50IGdldHMgY2FsbGVkLlxuICAgIC8vIFRPRE86IGZpbmRET01Ob2RlIGRvZXNuJ3QgcmVseSBvbiB0aGlzIGFueSBtb3JlIGJ1dCBpc01vdW50ZWQgZG9lc1xuICAgIC8vIGFuZCBpc01vdW50ZWQgaXMgZGVwcmVjYXRlZCBhbnl3YXkgc28gd2Ugc2hvdWxkIGJlIGFibGUgdG8ga2lsbCB0aGlzLlxuXG5cbiAgICBmaW5pc2hlZFdvcmsuZmxhZ3MgJj0gflBsYWNlbWVudDtcbiAgfVxuXG4gIGlmIChmbGFncyAmIEh5ZHJhdGluZykge1xuICAgIGZpbmlzaGVkV29yay5mbGFncyAmPSB+SHlkcmF0aW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdExheW91dEVmZmVjdHMoZmluaXNoZWRXb3JrLCByb290LCBjb21taXR0ZWRMYW5lcykge1xuICBpblByb2dyZXNzTGFuZXMgPSBjb21taXR0ZWRMYW5lcztcbiAgaW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICBuZXh0RWZmZWN0ID0gZmluaXNoZWRXb3JrO1xuICBjb21taXRMYXlvdXRFZmZlY3RzX2JlZ2luKGZpbmlzaGVkV29yaywgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICBpblByb2dyZXNzTGFuZXMgPSBudWxsO1xuICBpblByb2dyZXNzUm9vdCA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdExheW91dEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKSB7XG4gIC8vIFN1c3BlbnNlIGxheW91dCBlZmZlY3RzIHNlbWFudGljcyBkb24ndCBjaGFuZ2UgZm9yIGxlZ2FjeSByb290cy5cbiAgdmFyIGlzTW9kZXJuUm9vdCA9IChzdWJ0cmVlUm9vdC5tb2RlICYgQ29uY3VycmVudE1vZGUpICE9PSBOb01vZGU7XG5cbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuICAgIHZhciBmaXJzdENoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoIGZpYmVyLnRhZyA9PT0gT2Zmc2NyZWVuQ29tcG9uZW50ICYmIGlzTW9kZXJuUm9vdCkge1xuICAgICAgLy8gS2VlcCB0cmFjayBvZiB0aGUgY3VycmVudCBPZmZzY3JlZW4gc3RhY2sncyBzdGF0ZS5cbiAgICAgIHZhciBpc0hpZGRlbiA9IGZpYmVyLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG4gICAgICB2YXIgbmV3T2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuID0gaXNIaWRkZW4gfHwgb2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuO1xuXG4gICAgICBpZiAobmV3T2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuKSB7XG4gICAgICAgIC8vIFRoZSBPZmZzY3JlZW4gdHJlZSBpcyBoaWRkZW4uIFNraXAgb3ZlciBpdHMgbGF5b3V0IGVmZmVjdHMuXG4gICAgICAgIGNvbW1pdExheW91dE1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRPRE8gKE9mZnNjcmVlbikgQWxzbyBjaGVjazogc3VidHJlZUZsYWdzICYgTGF5b3V0TWFza1xuICAgICAgICB2YXIgY3VycmVudCA9IGZpYmVyLmFsdGVybmF0ZTtcbiAgICAgICAgdmFyIHdhc0hpZGRlbiA9IGN1cnJlbnQgIT09IG51bGwgJiYgY3VycmVudC5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuICAgICAgICB2YXIgbmV3T2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHdhc0hpZGRlbiB8fCBvZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICB2YXIgcHJldk9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbiA9IG9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgdmFyIHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuID0gb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbjsgLy8gVHJhdmVyc2UgdGhlIE9mZnNjcmVlbiBzdWJ0cmVlIHdpdGggdGhlIGN1cnJlbnQgT2Zmc2NyZWVuIGFzIHRoZSByb290LlxuXG4gICAgICAgIG9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbiA9IG5ld09mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IG5ld09mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW47XG5cbiAgICAgICAgaWYgKG9mZnNjcmVlblN1YnRyZWVXYXNIaWRkZW4gJiYgIXByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyB0aGUgcm9vdCBvZiBhIHJlYXBwZWFyaW5nIGJvdW5kYXJ5LiBUdXJuIGl0cyBsYXlvdXQgZWZmZWN0c1xuICAgICAgICAgIC8vIGJhY2sgb24uXG4gICAgICAgICAgbmV4dEVmZmVjdCA9IGZpYmVyO1xuICAgICAgICAgIHJlYXBwZWFyTGF5b3V0RWZmZWN0c19iZWdpbihmaWJlcik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGQgPSBmaXJzdENoaWxkO1xuXG4gICAgICAgIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICAgICAgICBjb21taXRMYXlvdXRFZmZlY3RzX2JlZ2luKGNoaWxkLCAvLyBOZXcgcm9vdDsgYnViYmxlIGJhY2sgdXAgdG8gaGVyZSBhbmQgc3RvcC5cbiAgICAgICAgICByb290LCBjb21taXR0ZWRMYW5lcyk7XG4gICAgICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgICAgICB9IC8vIFJlc3RvcmUgT2Zmc2NyZWVuIHN0YXRlIGFuZCByZXN1bWUgaW4gb3VyLXByb2dyZXNzIHRyYXZlcnNhbC5cblxuXG4gICAgICAgIG5leHRFZmZlY3QgPSBmaWJlcjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZUlzSGlkZGVuID0gcHJldk9mZnNjcmVlblN1YnRyZWVJc0hpZGRlbjtcbiAgICAgICAgb2Zmc2NyZWVuU3VidHJlZVdhc0hpZGRlbiA9IHByZXZPZmZzY3JlZW5TdWJ0cmVlV2FzSGlkZGVuO1xuICAgICAgICBjb21taXRMYXlvdXRNb3VudEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKChmaWJlci5zdWJ0cmVlRmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncyAmJiBmaXJzdENoaWxkICE9PSBudWxsKSB7XG4gICAgICBmaXJzdENoaWxkLnJldHVybiA9IGZpYmVyO1xuICAgICAgbmV4dEVmZmVjdCA9IGZpcnN0Q2hpbGQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1pdExheW91dE1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRMYXlvdXRNb3VudEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzKSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcblxuICAgIGlmICgoZmliZXIuZmxhZ3MgJiBMYXlvdXRNYXNrKSAhPT0gTm9GbGFncykge1xuICAgICAgdmFyIGN1cnJlbnQgPSBmaWJlci5hbHRlcm5hdGU7XG4gICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb21taXRMYXlvdXRFZmZlY3RPbkZpYmVyKHJvb3QsIGN1cnJlbnQsIGZpYmVyLCBjb21taXR0ZWRMYW5lcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgfVxuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkaXNhcHBlYXJMYXlvdXRFZmZlY3RzX2JlZ2luKHN1YnRyZWVSb290KSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcbiAgICB2YXIgZmlyc3RDaGlsZCA9IGZpYmVyLmNoaWxkOyAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBmbGFncyAmIChSZWZTdGF0aWMgfCBMYXlvdXRTdGF0aWMpXG5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgTWVtb0NvbXBvbmVudDpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICggZmliZXIubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGFydExheW91dEVmZmVjdFRpbWVyKCk7XG4gICAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChMYXlvdXQsIGZpYmVyLCBmaWJlci5yZXR1cm4pO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgcmVjb3JkTGF5b3V0RWZmZWN0RHVyYXRpb24oZmliZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoTGF5b3V0LCBmaWJlciwgZmliZXIucmV0dXJuKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIENsYXNzQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogZmxhZ3MgJiBSZWZTdGF0aWNcbiAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoZmliZXIsIGZpYmVyLnJldHVybik7XG4gICAgICAgICAgdmFyIGluc3RhbmNlID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnRXaWxsVW5tb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgc2FmZWx5Q2FsbENvbXBvbmVudFdpbGxVbm1vdW50KGZpYmVyLCBmaWJlci5yZXR1cm4sIGluc3RhbmNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBzYWZlbHlEZXRhY2hSZWYoZmliZXIsIGZpYmVyLnJldHVybik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBPZmZzY3JlZW5Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFcbiAgICAgICAgICB2YXIgaXNIaWRkZW4gPSBmaWJlci5tZW1vaXplZFN0YXRlICE9PSBudWxsO1xuXG4gICAgICAgICAgaWYgKGlzSGlkZGVuKSB7XG4gICAgICAgICAgICAvLyBOZXN0ZWQgT2Zmc2NyZWVuIHRyZWUgaXMgYWxyZWFkeSBoaWRkZW4uIERvbid0IGRpc2FwcGVhclxuICAgICAgICAgICAgLy8gaXRzIGVmZmVjdHMuXG4gICAgICAgICAgICBkaXNhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfSAvLyBUT0RPIChPZmZzY3JlZW4pIENoZWNrOiBzdWJ0cmVlRmxhZ3MgJiBMYXlvdXRTdGF0aWNcblxuXG4gICAgaWYgKGZpcnN0Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlzYXBwZWFyTGF5b3V0RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGRpc2FwcGVhckxheW91dEVmZmVjdHNfY29tcGxldGUoc3VidHJlZVJvb3QpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWFwcGVhckxheW91dEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuICAgIHZhciBmaXJzdENoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoZmliZXIudGFnID09PSBPZmZzY3JlZW5Db21wb25lbnQpIHtcbiAgICAgIHZhciBpc0hpZGRlbiA9IGZpYmVyLm1lbW9pemVkU3RhdGUgIT09IG51bGw7XG5cbiAgICAgIGlmIChpc0hpZGRlbikge1xuICAgICAgICAvLyBOZXN0ZWQgT2Zmc2NyZWVuIHRyZWUgaXMgc3RpbGwgaGlkZGVuLiBEb24ndCByZS1hcHBlYXIgaXRzIGVmZmVjdHMuXG4gICAgICAgIHJlYXBwZWFyTGF5b3V0RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH0gLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogc3VidHJlZUZsYWdzICYgTGF5b3V0U3RhdGljXG5cblxuICAgIGlmIChmaXJzdENoaWxkICE9PSBudWxsKSB7XG4gICAgICAvLyBUaGlzIG5vZGUgbWF5IGhhdmUgYmVlbiByZXVzZWQgZnJvbSBhIHByZXZpb3VzIHJlbmRlciwgc28gd2UgY2FuJ3RcbiAgICAgIC8vIGFzc3VtZSBpdHMgcmV0dXJuIHBvaW50ZXIgaXMgY29ycmVjdC5cbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVhcHBlYXJMYXlvdXRFZmZlY3RzX2NvbXBsZXRlKHN1YnRyZWVSb290KSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDsgLy8gVE9ETyAoT2Zmc2NyZWVuKSBDaGVjazogZmxhZ3MgJiBMYXlvdXRTdGF0aWNcblxuICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG5cbiAgICB0cnkge1xuICAgICAgcmVhcHBlYXJMYXlvdXRFZmZlY3RzT25GaWJlcihmaWJlcik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpYmVyLCBmaWJlci5yZXR1cm4sIGVycm9yKTtcbiAgICB9XG5cbiAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuXG4gICAgaWYgKGZpYmVyID09PSBzdWJ0cmVlUm9vdCkge1xuICAgICAgbmV4dEVmZmVjdCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgbm9kZSBtYXkgaGF2ZSBiZWVuIHJldXNlZCBmcm9tIGEgcHJldmlvdXMgcmVuZGVyLCBzbyB3ZSBjYW4ndFxuICAgICAgLy8gYXNzdW1lIGl0cyByZXR1cm4gcG9pbnRlciBpcyBjb3JyZWN0LlxuICAgICAgc2libGluZy5yZXR1cm4gPSBmaWJlci5yZXR1cm47XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gZmliZXIucmV0dXJuO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHMocm9vdCwgZmluaXNoZWRXb3JrLCBjb21taXR0ZWRMYW5lcywgY29tbWl0dGVkVHJhbnNpdGlvbnMpIHtcbiAgbmV4dEVmZmVjdCA9IGZpbmlzaGVkV29yaztcbiAgY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19iZWdpbihmaW5pc2hlZFdvcmssIHJvb3QsIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHNfYmVnaW4oc3VidHJlZVJvb3QsIHJvb3QsIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucykge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIGZpcnN0Q2hpbGQgPSBmaWJlci5jaGlsZDtcblxuICAgIGlmICgoZmliZXIuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzICYmIGZpcnN0Q2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGZpcnN0Q2hpbGQucmV0dXJuID0gZmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gZmlyc3RDaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZU1vdW50RWZmZWN0c19jb21wbGV0ZShzdWJ0cmVlUm9vdCwgcm9vdCwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKSB7XG4gIHdoaWxlIChuZXh0RWZmZWN0ICE9PSBudWxsKSB7XG4gICAgdmFyIGZpYmVyID0gbmV4dEVmZmVjdDtcblxuICAgIGlmICgoZmliZXIuZmxhZ3MgJiBQYXNzaXZlKSAhPT0gTm9GbGFncykge1xuICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29tbWl0UGFzc2l2ZU1vdW50T25GaWJlcihyb290LCBmaWJlciwgY29tbWl0dGVkTGFuZXMsIGNvbW1pdHRlZFRyYW5zaXRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKGZpYmVyLCBmaWJlci5yZXR1cm4sIGVycm9yKTtcbiAgICAgIH1cblxuICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICB9XG5cbiAgICBpZiAoZmliZXIgPT09IHN1YnRyZWVSb290KSB7XG4gICAgICBuZXh0RWZmZWN0ID0gbnVsbDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc2libGluZyA9IGZpYmVyLnNpYmxpbmc7XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgc2libGluZy5yZXR1cm4gPSBmaWJlci5yZXR1cm47XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gZmliZXIucmV0dXJuO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVNb3VudE9uRmliZXIoZmluaXNoZWRSb290LCBmaW5pc2hlZFdvcmssIGNvbW1pdHRlZExhbmVzLCBjb21taXR0ZWRUcmFuc2l0aW9ucykge1xuICBzd2l0Y2ggKGZpbmlzaGVkV29yay50YWcpIHtcbiAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICB7XG4gICAgICAgIGlmICggZmluaXNoZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAgIHN0YXJ0UGFzc2l2ZUVmZmVjdFRpbWVyKCk7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RNb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yayk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHJlY29yZFBhc3NpdmVFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KFBhc3NpdmUkMSB8IEhhc0VmZmVjdCwgZmluaXNoZWRXb3JrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0cyhmaXJzdENoaWxkKSB7XG4gIG5leHRFZmZlY3QgPSBmaXJzdENoaWxkO1xuICBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNfYmVnaW4oKTtcbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzX2JlZ2luKCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7XG5cbiAgICBpZiAoKG5leHRFZmZlY3QuZmxhZ3MgJiBDaGlsZERlbGV0aW9uKSAhPT0gTm9GbGFncykge1xuICAgICAgdmFyIGRlbGV0aW9ucyA9IGZpYmVyLmRlbGV0aW9ucztcblxuICAgICAgaWYgKGRlbGV0aW9ucyAhPT0gbnVsbCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGV0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBmaWJlclRvRGVsZXRlID0gZGVsZXRpb25zW2ldO1xuICAgICAgICAgIG5leHRFZmZlY3QgPSBmaWJlclRvRGVsZXRlO1xuICAgICAgICAgIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0c0luc2lkZU9mRGVsZXRlZFRyZWVfYmVnaW4oZmliZXJUb0RlbGV0ZSwgZmliZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAge1xuICAgICAgICAgIC8vIEEgZmliZXIgd2FzIGRlbGV0ZWQgZnJvbSB0aGlzIHBhcmVudCBmaWJlciwgYnV0IGl0J3Mgc3RpbGwgcGFydCBvZlxuICAgICAgICAgIC8vIHRoZSBwcmV2aW91cyAoYWx0ZXJuYXRlKSBwYXJlbnQgZmliZXIncyBsaXN0IG9mIGNoaWxkcmVuLiBCZWNhdXNlXG4gICAgICAgICAgLy8gY2hpbGRyZW4gYXJlIGEgbGlua2VkIGxpc3QsIGFuIGVhcmxpZXIgc2libGluZyB0aGF0J3Mgc3RpbGwgYWxpdmVcbiAgICAgICAgICAvLyB3aWxsIGJlIGNvbm5lY3RlZCB0byB0aGUgZGVsZXRlZCBmaWJlciB2aWEgaXRzIGBhbHRlcm5hdGVgOlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gICBsaXZlIGZpYmVyXG4gICAgICAgICAgLy8gICAtLWFsdGVybmF0ZS0tPiBwcmV2aW91cyBsaXZlIGZpYmVyXG4gICAgICAgICAgLy8gICAtLXNpYmxpbmctLT4gZGVsZXRlZCBmaWJlclxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2UgY2FuJ3QgZGlzY29ubmVjdCBgYWx0ZXJuYXRlYCBvbiBub2RlcyB0aGF0IGhhdmVuJ3QgYmVlbiBkZWxldGVkXG4gICAgICAgICAgLy8geWV0LCBidXQgd2UgY2FuIGRpc2Nvbm5lY3QgdGhlIGBzaWJsaW5nYCBhbmQgYGNoaWxkYCBwb2ludGVycy5cbiAgICAgICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGZpYmVyLmFsdGVybmF0ZTtcblxuICAgICAgICAgIGlmIChwcmV2aW91c0ZpYmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgZGV0YWNoZWRDaGlsZCA9IHByZXZpb3VzRmliZXIuY2hpbGQ7XG5cbiAgICAgICAgICAgIGlmIChkZXRhY2hlZENoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIHByZXZpb3VzRmliZXIuY2hpbGQgPSBudWxsO1xuXG4gICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICB2YXIgZGV0YWNoZWRTaWJsaW5nID0gZGV0YWNoZWRDaGlsZC5zaWJsaW5nO1xuICAgICAgICAgICAgICAgIGRldGFjaGVkQ2hpbGQuc2libGluZyA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGV0YWNoZWRDaGlsZCA9IGRldGFjaGVkU2libGluZztcbiAgICAgICAgICAgICAgfSB3aGlsZSAoZGV0YWNoZWRDaGlsZCAhPT0gbnVsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbmV4dEVmZmVjdCA9IGZpYmVyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICgoZmliZXIuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzICYmIGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBjaGlsZC5yZXR1cm4gPSBmaWJlcjtcbiAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzX2NvbXBsZXRlKCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0c19jb21wbGV0ZSgpIHtcbiAgd2hpbGUgKG5leHRFZmZlY3QgIT09IG51bGwpIHtcbiAgICB2YXIgZmliZXIgPSBuZXh0RWZmZWN0O1xuXG4gICAgaWYgKChmaWJlci5mbGFncyAmIFBhc3NpdmUpICE9PSBOb0ZsYWdzKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRPbkZpYmVyKGZpYmVyKTtcbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gZmliZXIucmV0dXJuO1xuICAgICAgbmV4dEVmZmVjdCA9IHNpYmxpbmc7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dEVmZmVjdCA9IGZpYmVyLnJldHVybjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudE9uRmliZXIoZmluaXNoZWRXb3JrKSB7XG4gIHN3aXRjaCAoZmluaXNoZWRXb3JrLnRhZykge1xuICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgIHtcbiAgICAgICAgaWYgKCBmaW5pc2hlZFdvcmsubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKTtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoUGFzc2l2ZSQxIHwgSGFzRWZmZWN0LCBmaW5pc2hlZFdvcmssIGZpbmlzaGVkV29yay5yZXR1cm4pO1xuICAgICAgICAgIHJlY29yZFBhc3NpdmVFZmZlY3REdXJhdGlvbihmaW5pc2hlZFdvcmspO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpbmlzaGVkV29yaywgZmluaXNoZWRXb3JrLnJldHVybik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNJbnNpZGVPZkRlbGV0ZWRUcmVlX2JlZ2luKGRlbGV0ZWRTdWJ0cmVlUm9vdCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7IC8vIERlbGV0aW9uIGVmZmVjdHMgZmlyZSBpbiBwYXJlbnQgLT4gY2hpbGQgb3JkZXJcbiAgICAvLyBUT0RPOiBDaGVjayBpZiBmaWJlciBoYXMgYSBQYXNzaXZlU3RhdGljIGZsYWdcblxuICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG4gICAgY29tbWl0UGFzc2l2ZVVubW91bnRJbnNpZGVEZWxldGVkVHJlZU9uRmliZXIoZmliZXIsIG5lYXJlc3RNb3VudGVkQW5jZXN0b3IpO1xuICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQ7IC8vIFRPRE86IE9ubHkgdHJhdmVyc2Ugc3VidHJlZSBpZiBpdCBoYXMgYSBQYXNzaXZlU3RhdGljIGZsYWcuIChCdXQsIGlmIHdlXG4gICAgLy8gZG8gdGhpcywgc3RpbGwgbmVlZCB0byBoYW5kbGUgYGRlbGV0ZWRUcmVlQ2xlYW5VcExldmVsYCBjb3JyZWN0bHkuKVxuXG4gICAgaWYgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICBjaGlsZC5yZXR1cm4gPSBmaWJlcjtcbiAgICAgIG5leHRFZmZlY3QgPSBjaGlsZDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tbWl0UGFzc2l2ZVVubW91bnRFZmZlY3RzSW5zaWRlT2ZEZWxldGVkVHJlZV9jb21wbGV0ZShkZWxldGVkU3VidHJlZVJvb3QpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXRQYXNzaXZlVW5tb3VudEVmZmVjdHNJbnNpZGVPZkRlbGV0ZWRUcmVlX2NvbXBsZXRlKGRlbGV0ZWRTdWJ0cmVlUm9vdCkge1xuICB3aGlsZSAobmV4dEVmZmVjdCAhPT0gbnVsbCkge1xuICAgIHZhciBmaWJlciA9IG5leHRFZmZlY3Q7XG4gICAgdmFyIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nO1xuICAgIHZhciByZXR1cm5GaWJlciA9IGZpYmVyLnJldHVybjtcblxuICAgIHtcbiAgICAgIC8vIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIHRoZSBlbnRpcmUgZGVsZXRlZCB0cmVlIGFuZCBjbGVhbiB1cCBmaWJlciBmaWVsZHMuXG4gICAgICAvLyBUaGlzIGlzIG1vcmUgYWdncmVzc2l2ZSB0aGFuIGlkZWFsLCBhbmQgdGhlIGxvbmcgdGVybSBnb2FsIGlzIHRvIG9ubHlcbiAgICAgIC8vIGhhdmUgdG8gZGV0YWNoIHRoZSBkZWxldGVkIHRyZWUgYXQgdGhlIHJvb3QuXG4gICAgICBkZXRhY2hGaWJlckFmdGVyRWZmZWN0cyhmaWJlcik7XG5cbiAgICAgIGlmIChmaWJlciA9PT0gZGVsZXRlZFN1YnRyZWVSb290KSB7XG4gICAgICAgIG5leHRFZmZlY3QgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgIHNpYmxpbmcucmV0dXJuID0gcmV0dXJuRmliZXI7XG4gICAgICBuZXh0RWZmZWN0ID0gc2libGluZztcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0RWZmZWN0ID0gcmV0dXJuRmliZXI7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0UGFzc2l2ZVVubW91bnRJbnNpZGVEZWxldGVkVHJlZU9uRmliZXIoY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcikge1xuICBzd2l0Y2ggKGN1cnJlbnQudGFnKSB7XG4gICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBpZiAoIGN1cnJlbnQubW9kZSAmIFByb2ZpbGVNb2RlKSB7XG4gICAgICAgICAgc3RhcnRQYXNzaXZlRWZmZWN0VGltZXIoKTtcbiAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoUGFzc2l2ZSQxLCBjdXJyZW50LCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yKTtcbiAgICAgICAgICByZWNvcmRQYXNzaXZlRWZmZWN0RHVyYXRpb24oY3VycmVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RVbm1vdW50KFBhc3NpdmUkMSwgY3VycmVudCwgbmVhcmVzdE1vdW50ZWRBbmNlc3Rvcik7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufSAvLyBUT0RPOiBSZXVzZSByZWFwcGVhckxheW91dEVmZmVjdHMgdHJhdmVyc2FsIGhlcmU/XG5cblxuZnVuY3Rpb24gaW52b2tlTGF5b3V0RWZmZWN0TW91bnRJbkRFVihmaWJlcikge1xuICB7XG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZS1jaGVjayBTdHJpY3RFZmZlY3RzTW9kZSBoZXJlLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgaWYgdGhhdCBjaGVjayBoYXMgYWxyZWFkeSBwYXNzZWQuXG4gICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29tbWl0SG9va0VmZmVjdExpc3RNb3VudChMYXlvdXQgfCBIYXNFZmZlY3QsIGZpYmVyKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaW5zdGFuY2UuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZVBhc3NpdmVFZmZlY3RNb3VudEluREVWKGZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlLWNoZWNrIFN0cmljdEVmZmVjdHNNb2RlIGhlcmUuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBpZiB0aGF0IGNoZWNrIGhhcyBhbHJlYWR5IHBhc3NlZC5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdE1vdW50KFBhc3NpdmUkMSB8IEhhc0VmZmVjdCwgZmliZXIpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaW52b2tlTGF5b3V0RWZmZWN0VW5tb3VudEluREVWKGZpYmVyKSB7XG4gIHtcbiAgICAvLyBXZSBkb24ndCBuZWVkIHRvIHJlLWNoZWNrIFN0cmljdEVmZmVjdHNNb2RlIGhlcmUuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBvbmx5IGNhbGxlZCBpZiB0aGF0IGNoZWNrIGhhcyBhbHJlYWR5IHBhc3NlZC5cbiAgICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgIGNhc2UgU2ltcGxlTWVtb0NvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb21taXRIb29rRWZmZWN0TGlzdFVubW91bnQoTGF5b3V0IHwgSGFzRWZmZWN0LCBmaWJlciwgZmliZXIucmV0dXJuKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY2FwdHVyZUNvbW1pdFBoYXNlRXJyb3IoZmliZXIsIGZpYmVyLnJldHVybiwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICB2YXIgaW5zdGFuY2UgPSBmaWJlci5zdGF0ZU5vZGU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmNvbXBvbmVudFdpbGxVbm1vdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzYWZlbHlDYWxsQ29tcG9uZW50V2lsbFVubW91bnQoZmliZXIsIGZpYmVyLnJldHVybiwgaW5zdGFuY2UpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZVBhc3NpdmVFZmZlY3RVbm1vdW50SW5ERVYoZmliZXIpIHtcbiAge1xuICAgIC8vIFdlIGRvbid0IG5lZWQgdG8gcmUtY2hlY2sgU3RyaWN0RWZmZWN0c01vZGUgaGVyZS5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG9ubHkgY2FsbGVkIGlmIHRoYXQgY2hlY2sgaGFzIGFscmVhZHkgcGFzc2VkLlxuICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBGb3J3YXJkUmVmOlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbW1pdEhvb2tFZmZlY3RMaXN0VW5tb3VudChQYXNzaXZlJDEgfCBIYXNFZmZlY3QsIGZpYmVyLCBmaWJlci5yZXR1cm4pO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvcihmaWJlciwgZmliZXIucmV0dXJuLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBDT01QT05FTlRfVFlQRSA9IDA7XG52YXIgSEFTX1BTRVVET19DTEFTU19UWVBFID0gMTtcbnZhciBST0xFX1RZUEUgPSAyO1xudmFyIFRFU1RfTkFNRV9UWVBFID0gMztcbnZhciBURVhUX1RZUEUgPSA0O1xuXG5pZiAodHlwZW9mIFN5bWJvbCA9PT0gJ2Z1bmN0aW9uJyAmJiBTeW1ib2wuZm9yKSB7XG4gIHZhciBzeW1ib2xGb3IgPSBTeW1ib2wuZm9yO1xuICBDT01QT05FTlRfVFlQRSA9IHN5bWJvbEZvcignc2VsZWN0b3IuY29tcG9uZW50Jyk7XG4gIEhBU19QU0VVRE9fQ0xBU1NfVFlQRSA9IHN5bWJvbEZvcignc2VsZWN0b3IuaGFzX3BzZXVkb19jbGFzcycpO1xuICBST0xFX1RZUEUgPSBzeW1ib2xGb3IoJ3NlbGVjdG9yLnJvbGUnKTtcbiAgVEVTVF9OQU1FX1RZUEUgPSBzeW1ib2xGb3IoJ3NlbGVjdG9yLnRlc3RfaWQnKTtcbiAgVEVYVF9UWVBFID0gc3ltYm9sRm9yKCdzZWxlY3Rvci50ZXh0Jyk7XG59XG52YXIgY29tbWl0SG9va3MgPSBbXTtcbmZ1bmN0aW9uIG9uQ29tbWl0Um9vdCQxKCkge1xuICB7XG4gICAgY29tbWl0SG9va3MuZm9yRWFjaChmdW5jdGlvbiAoY29tbWl0SG9vaykge1xuICAgICAgcmV0dXJuIGNvbW1pdEhvb2soKTtcbiAgICB9KTtcbiAgfVxufVxuXG52YXIgUmVhY3RDdXJyZW50QWN0UXVldWUgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZTtcbmZ1bmN0aW9uIGlzTGVnYWN5QWN0RW52aXJvbm1lbnQoZmliZXIpIHtcbiAge1xuICAgIC8vIExlZ2FjeSBtb2RlLiBXZSBwcmVzZXJ2ZSB0aGUgYmVoYXZpb3Igb2YgUmVhY3QgMTcncyBhY3QuIEl0IGFzc3VtZXMgYW5cbiAgICAvLyBhY3QgZW52aXJvbm1lbnQgd2hlbmV2ZXIgYGplc3RgIGlzIGRlZmluZWQsIGJ1dCB5b3UgY2FuIHN0aWxsIHR1cm4gb2ZmXG4gICAgLy8gc3B1cmlvdXMgd2FybmluZ3MgYnkgc2V0dGluZyBJU19SRUFDVF9BQ1RfRU5WSVJPTk1FTlQgZXhwbGljaXRseVxuICAgIC8vIHRvIGZhbHNlLlxuICAgIHZhciBpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWwgPSAvLyAkRmxvd0V4cGVjdGVkRXJyb3Ig4oCTIEZsb3cgZG9lc24ndCBrbm93IGFib3V0IElTX1JFQUNUX0FDVF9FTlZJUk9OTUVOVCBnbG9iYWxcbiAgICB0eXBlb2YgSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UICE9PSAndW5kZWZpbmVkJyA/IElTX1JFQUNUX0FDVF9FTlZJUk9OTUVOVCA6IHVuZGVmaW5lZDsgLy8gJEZsb3dFeHBlY3RlZEVycm9yIC0gRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgamVzdFxuXG4gICAgdmFyIGplc3RJc0RlZmluZWQgPSB0eXBlb2YgamVzdCAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgcmV0dXJuICBqZXN0SXNEZWZpbmVkICYmIGlzUmVhY3RBY3RFbnZpcm9ubWVudEdsb2JhbCAhPT0gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkge1xuICB7XG4gICAgdmFyIGlzUmVhY3RBY3RFbnZpcm9ubWVudEdsb2JhbCA9IC8vICRGbG93RXhwZWN0ZWRFcnJvciDigJMgRmxvdyBkb2Vzbid0IGtub3cgYWJvdXQgSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UIGdsb2JhbFxuICAgIHR5cGVvZiBJU19SRUFDVF9BQ1RfRU5WSVJPTk1FTlQgIT09ICd1bmRlZmluZWQnID8gSVNfUkVBQ1RfQUNUX0VOVklST05NRU5UIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWwgJiYgUmVhY3RDdXJyZW50QWN0UXVldWUuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogSW5jbHVkZSBsaW5rIHRvIHJlbGV2YW50IGRvY3VtZW50YXRpb24gcGFnZS5cbiAgICAgIGVycm9yKCdUaGUgY3VycmVudCB0ZXN0aW5nIGVudmlyb25tZW50IGlzIG5vdCBjb25maWd1cmVkIHRvIHN1cHBvcnQgJyArICdhY3QoLi4uKScpO1xuICAgIH1cblxuICAgIHJldHVybiBpc1JlYWN0QWN0RW52aXJvbm1lbnRHbG9iYWw7XG4gIH1cbn1cblxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixcbiAgICBSZWFjdEN1cnJlbnRPd25lciQyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50T3duZXIsXG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMyA9IFJlYWN0U2hhcmVkSW50ZXJuYWxzLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFxuICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRBY3RRdWV1ZTtcbnZhciBOb0NvbnRleHQgPVxuLyogICAgICAgICAgICAgKi9cbjA7XG52YXIgQmF0Y2hlZENvbnRleHQgPVxuLyogICAgICAgICAgICAgICAqL1xuMTtcbnZhciBSZW5kZXJDb250ZXh0ID1cbi8qICAgICAgICAgICAgICAgICovXG4yO1xudmFyIENvbW1pdENvbnRleHQgPVxuLyogICAgICAgICAgICAgICAgKi9cbjQ7XG52YXIgUm9vdEluUHJvZ3Jlc3MgPSAwO1xudmFyIFJvb3RGYXRhbEVycm9yZWQgPSAxO1xudmFyIFJvb3RFcnJvcmVkID0gMjtcbnZhciBSb290U3VzcGVuZGVkID0gMztcbnZhciBSb290U3VzcGVuZGVkV2l0aERlbGF5ID0gNDtcbnZhciBSb290Q29tcGxldGVkID0gNTtcbnZhciBSb290RGlkTm90Q29tcGxldGUgPSA2OyAvLyBEZXNjcmliZXMgd2hlcmUgd2UgYXJlIGluIHRoZSBSZWFjdCBleGVjdXRpb24gc3RhY2tcblxudmFyIGV4ZWN1dGlvbkNvbnRleHQgPSBOb0NvbnRleHQ7IC8vIFRoZSByb290IHdlJ3JlIHdvcmtpbmcgb25cblxudmFyIHdvcmtJblByb2dyZXNzUm9vdCA9IG51bGw7IC8vIFRoZSBmaWJlciB3ZSdyZSB3b3JraW5nIG9uXG5cbnZhciB3b3JrSW5Qcm9ncmVzcyA9IG51bGw7IC8vIFRoZSBsYW5lcyB3ZSdyZSByZW5kZXJpbmdcblxudmFyIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lczsgLy8gU3RhY2sgdGhhdCBhbGxvd3MgY29tcG9uZW50cyB0byBjaGFuZ2UgdGhlIHJlbmRlciBsYW5lcyBmb3IgaXRzIHN1YnRyZWVcbi8vIFRoaXMgaXMgYSBzdXBlcnNldCBvZiB0aGUgbGFuZXMgd2Ugc3RhcnRlZCB3b3JraW5nIG9uIGF0IHRoZSByb290LiBUaGUgb25seVxuLy8gY2FzZSB3aGVyZSBpdCdzIGRpZmZlcmVudCBmcm9tIGB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lc2AgaXMgd2hlbiB3ZVxuLy8gZW50ZXIgYSBzdWJ0cmVlIHRoYXQgaXMgaGlkZGVuIGFuZCBuZWVkcyB0byBiZSB1bmhpZGRlbjogU3VzcGVuc2UgYW5kXG4vLyBPZmZzY3JlZW4gY29tcG9uZW50LlxuLy9cbi8vIE1vc3QgdGhpbmdzIGluIHRoZSB3b3JrIGxvb3Agc2hvdWxkIGRlYWwgd2l0aCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcy5cbi8vIE1vc3QgdGhpbmdzIGluIGJlZ2luL2NvbXBsZXRlIHBoYXNlcyBzaG91bGQgZGVhbCB3aXRoIHN1YnRyZWVSZW5kZXJMYW5lcy5cblxudmFyIHN1YnRyZWVSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG52YXIgc3VidHJlZVJlbmRlckxhbmVzQ3Vyc29yID0gY3JlYXRlQ3Vyc29yKE5vTGFuZXMpOyAvLyBXaGV0aGVyIHRvIHJvb3QgY29tcGxldGVkLCBlcnJvcmVkLCBzdXNwZW5kZWQsIGV0Yy5cblxudmFyIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290SW5Qcm9ncmVzczsgLy8gQSBmYXRhbCBlcnJvciwgaWYgb25lIGlzIHRocm93blxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvciA9IG51bGw7IC8vIFwiSW5jbHVkZWRcIiBsYW5lcyByZWZlciB0byBsYW5lcyB0aGF0IHdlcmUgd29ya2VkIG9uIGR1cmluZyB0aGlzIHJlbmRlci4gSXQnc1xuLy8gc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gYHJlbmRlckxhbmVzYCBiZWNhdXNlIGByZW5kZXJMYW5lc2AgY2FuIGNoYW5nZSBhcyB5b3Vcbi8vIGVudGVyIGFuZCBleGl0IGFuIE9mZnNjcmVlbiB0cmVlLiBUaGlzIHZhbHVlIGlzIHRoZSBjb21iaW5hdGlvbiBvZiBhbGwgcmVuZGVyXG4vLyBsYW5lcyBmb3IgdGhlIGVudGlyZSByZW5kZXIgcGhhc2UuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzID0gTm9MYW5lczsgLy8gVGhlIHdvcmsgbGVmdCBvdmVyIGJ5IGNvbXBvbmVudHMgdGhhdCB3ZXJlIHZpc2l0ZWQgZHVyaW5nIHRoaXMgcmVuZGVyLiBPbmx5XG4vLyBpbmNsdWRlcyB1bnByb2Nlc3NlZCB1cGRhdGVzLCBub3Qgd29yayBpbiBiYWlsZWQgb3V0IGNoaWxkcmVuLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzID0gTm9MYW5lczsgLy8gTGFuZXMgdGhhdCB3ZXJlIHVwZGF0ZWQgKGluIGFuIGludGVybGVhdmVkIGV2ZW50KSBkdXJpbmcgdGhpcyByZW5kZXIuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IE5vTGFuZXM7IC8vIExhbmVzIHRoYXQgd2VyZSB1cGRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlICgqbm90KiBhbiBpbnRlcmxlYXZlZCBldmVudCkuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcyA9IE5vTGFuZXM7IC8vIEVycm9ycyB0aGF0IGFyZSB0aHJvd24gZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzID0gbnVsbDsgLy8gVGhlc2UgYXJlIGVycm9ycyB0aGF0IHdlIHJlY292ZXJlZCBmcm9tIHdpdGhvdXQgc3VyZmFjaW5nIHRoZW0gdG8gdGhlIFVJLlxuLy8gV2Ugd2lsbCBsb2cgdGhlbSBvbmNlIHRoZSB0cmVlIGNvbW1pdHMuXG5cbnZhciB3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycyA9IG51bGw7IC8vIFRoZSBtb3N0IHJlY2VudCB0aW1lIHdlIGNvbW1pdHRlZCBhIGZhbGxiYWNrLiBUaGlzIGxldHMgdXMgZW5zdXJlIGEgdHJhaW5cbi8vIG1vZGVsIHdoZXJlIHdlIGRvbid0IGNvbW1pdCBuZXcgbG9hZGluZyBzdGF0ZXMgaW4gdG9vIHF1aWNrIHN1Y2Nlc3Npb24uXG5cbnZhciBnbG9iYWxNb3N0UmVjZW50RmFsbGJhY2tUaW1lID0gMDtcbnZhciBGQUxMQkFDS19USFJPVFRMRV9NUyA9IDUwMDsgLy8gVGhlIGFic29sdXRlIHRpbWUgZm9yIHdoZW4gd2Ugc2hvdWxkIHN0YXJ0IGdpdmluZyB1cCBvbiByZW5kZXJpbmdcbi8vIG1vcmUgYW5kIHByZWZlciBDUFUgc3VzcGVuc2UgaGV1cmlzdGljcyBpbnN0ZWFkLlxuXG52YXIgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyVGFyZ2V0VGltZSA9IEluZmluaXR5OyAvLyBIb3cgbG9uZyBhIHJlbmRlciBpcyBzdXBwb3NlZCB0byB0YWtlIGJlZm9yZSB3ZSBzdGFydCBmb2xsb3dpbmcgQ1BVXG4vLyBzdXNwZW5zZSBoZXVyaXN0aWNzIGFuZCBvcHQgb3V0IG9mIHJlbmRlcmluZyBtb3JlIGNvbnRlbnQuXG5cbnZhciBSRU5ERVJfVElNRU9VVF9NUyA9IDUwMDtcbnZhciB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zID0gbnVsbDtcblxuZnVuY3Rpb24gcmVzZXRSZW5kZXJUaW1lcigpIHtcbiAgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyVGFyZ2V0VGltZSA9IG5vdygpICsgUkVOREVSX1RJTUVPVVRfTVM7XG59XG5cbmZ1bmN0aW9uIGdldFJlbmRlclRhcmdldFRpbWUoKSB7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJUYXJnZXRUaW1lO1xufVxudmFyIGhhc1VuY2F1Z2h0RXJyb3IgPSBmYWxzZTtcbnZhciBmaXJzdFVuY2F1Z2h0RXJyb3IgPSBudWxsO1xudmFyIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID0gbnVsbDsgLy8gT25seSB1c2VkIHdoZW4gZW5hYmxlUHJvZmlsZXJOZXN0ZWRVcGRhdGVTY2hlZHVsZWRIb29rIGlzIHRydWU7XG52YXIgcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbnZhciByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyA9IG51bGw7XG52YXIgcGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMgPSBOb0xhbmVzO1xudmFyIHBlbmRpbmdQYXNzaXZlUHJvZmlsZXJFZmZlY3RzID0gW107XG52YXIgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IG51bGw7IC8vIFVzZSB0aGVzZSB0byBwcmV2ZW50IGFuIGluZmluaXRlIGxvb3Agb2YgbmVzdGVkIHVwZGF0ZXNcblxudmFyIE5FU1RFRF9VUERBVEVfTElNSVQgPSA1MDtcbnZhciBuZXN0ZWRVcGRhdGVDb3VudCA9IDA7XG52YXIgcm9vdFdpdGhOZXN0ZWRVcGRhdGVzID0gbnVsbDtcbnZhciBpc0ZsdXNoaW5nUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbnZhciBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG52YXIgTkVTVEVEX1BBU1NJVkVfVVBEQVRFX0xJTUlUID0gNTA7XG52YXIgbmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID0gMDtcbnZhciByb290V2l0aFBhc3NpdmVOZXN0ZWRVcGRhdGVzID0gbnVsbDsgLy8gSWYgdHdvIHVwZGF0ZXMgYXJlIHNjaGVkdWxlZCB3aXRoaW4gdGhlIHNhbWUgZXZlbnQsIHdlIHNob3VsZCB0cmVhdCB0aGVpclxuLy8gZXZlbnQgdGltZXMgYXMgc2ltdWx0YW5lb3VzLCBldmVuIGlmIHRoZSBhY3R1YWwgY2xvY2sgdGltZSBoYXMgYWR2YW5jZWRcbi8vIGJldHdlZW4gdGhlIGZpcnN0IGFuZCBzZWNvbmQgY2FsbC5cblxudmFyIGN1cnJlbnRFdmVudFRpbWUgPSBOb1RpbWVzdGFtcDtcbnZhciBjdXJyZW50RXZlbnRUcmFuc2l0aW9uTGFuZSA9IE5vTGFuZXM7XG52YXIgaXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0ID0gZmFsc2U7XG5mdW5jdGlvbiBnZXRXb3JrSW5Qcm9ncmVzc1Jvb3QoKSB7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3Q7XG59XG5mdW5jdGlvbiByZXF1ZXN0RXZlbnRUaW1lKCkge1xuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgLy8gV2UncmUgaW5zaWRlIFJlYWN0LCBzbyBpdCdzIGZpbmUgdG8gcmVhZCB0aGUgYWN0dWFsIHRpbWUuXG4gICAgcmV0dXJuIG5vdygpO1xuICB9IC8vIFdlJ3JlIG5vdCBpbnNpZGUgUmVhY3QsIHNvIHdlIG1heSBiZSBpbiB0aGUgbWlkZGxlIG9mIGEgYnJvd3NlciBldmVudC5cblxuXG4gIGlmIChjdXJyZW50RXZlbnRUaW1lICE9PSBOb1RpbWVzdGFtcCkge1xuICAgIC8vIFVzZSB0aGUgc2FtZSBzdGFydCB0aW1lIGZvciBhbGwgdXBkYXRlcyB1bnRpbCB3ZSBlbnRlciBSZWFjdCBhZ2Fpbi5cbiAgICByZXR1cm4gY3VycmVudEV2ZW50VGltZTtcbiAgfSAvLyBUaGlzIGlzIHRoZSBmaXJzdCB1cGRhdGUgc2luY2UgUmVhY3QgeWllbGRlZC4gQ29tcHV0ZSBhIG5ldyBzdGFydCB0aW1lLlxuXG5cbiAgY3VycmVudEV2ZW50VGltZSA9IG5vdygpO1xuICByZXR1cm4gY3VycmVudEV2ZW50VGltZTtcbn1cbmZ1bmN0aW9uIHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKSB7XG4gIC8vIFNwZWNpYWwgY2FzZXNcbiAgdmFyIG1vZGUgPSBmaWJlci5tb2RlO1xuXG4gIGlmICgobW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIFN5bmNMYW5lO1xuICB9IGVsc2UgaWYgKCAoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHQgJiYgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICAvLyBUaGlzIGlzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gVGhlc2UgYXJlIG5vdCBvZmZpY2lhbGx5IHN1cHBvcnRlZC4gVGhlXG4gICAgLy8gb2xkIGJlaGF2aW9yIGlzIHRvIGdpdmUgdGhpcyB0aGUgc2FtZSBcInRocmVhZFwiIChsYW5lcykgYXNcbiAgICAvLyB3aGF0ZXZlciBpcyBjdXJyZW50bHkgcmVuZGVyaW5nLiBTbyBpZiB5b3UgY2FsbCBgc2V0U3RhdGVgIG9uIGEgY29tcG9uZW50XG4gICAgLy8gdGhhdCBoYXBwZW5zIGxhdGVyIGluIHRoZSBzYW1lIHJlbmRlciwgaXQgd2lsbCBmbHVzaC4gSWRlYWxseSwgd2Ugd2FudCB0b1xuICAgIC8vIHJlbW92ZSB0aGUgc3BlY2lhbCBjYXNlIGFuZCB0cmVhdCB0aGVtIGFzIGlmIHRoZXkgY2FtZSBmcm9tIGFuXG4gICAgLy8gaW50ZXJsZWF2ZWQgZXZlbnQuIFJlZ2FyZGxlc3MsIHRoaXMgcGF0dGVybiBpcyBub3Qgb2ZmaWNpYWxseSBzdXBwb3J0ZWQuXG4gICAgLy8gVGhpcyBiZWhhdmlvciBpcyBvbmx5IGEgZmFsbGJhY2suIFRoZSBmbGFnIG9ubHkgZXhpc3RzIHVudGlsIHdlIGNhbiByb2xsXG4gICAgLy8gb3V0IHRoZSBzZXRTdGF0ZSB3YXJuaW5nLCBzaW5jZSBleGlzdGluZyBjb2RlIG1pZ2h0IGFjY2lkZW50YWxseSByZWx5IG9uXG4gICAgLy8gdGhlIGN1cnJlbnQgYmVoYXZpb3IuXG4gICAgcmV0dXJuIHBpY2tBcmJpdHJhcnlMYW5lKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHZhciBpc1RyYW5zaXRpb24gPSByZXF1ZXN0Q3VycmVudFRyYW5zaXRpb24oKSAhPT0gTm9UcmFuc2l0aW9uO1xuXG4gIGlmIChpc1RyYW5zaXRpb24pIHtcbiAgICBpZiAoIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiAhPT0gbnVsbCkge1xuICAgICAgdmFyIHRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb247XG5cbiAgICAgIGlmICghdHJhbnNpdGlvbi5fdXBkYXRlZEZpYmVycykge1xuICAgICAgICB0cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzID0gbmV3IFNldCgpO1xuICAgICAgfVxuXG4gICAgICB0cmFuc2l0aW9uLl91cGRhdGVkRmliZXJzLmFkZChmaWJlcik7XG4gICAgfSAvLyBUaGUgYWxnb3JpdGhtIGZvciBhc3NpZ25pbmcgYW4gdXBkYXRlIHRvIGEgbGFuZSBzaG91bGQgYmUgc3RhYmxlIGZvciBhbGxcbiAgICAvLyB1cGRhdGVzIGF0IHRoZSBzYW1lIHByaW9yaXR5IHdpdGhpbiB0aGUgc2FtZSBldmVudC4gVG8gZG8gdGhpcywgdGhlXG4gICAgLy8gaW5wdXRzIHRvIHRoZSBhbGdvcml0aG0gbXVzdCBiZSB0aGUgc2FtZS5cbiAgICAvL1xuICAgIC8vIFRoZSB0cmljayB3ZSB1c2UgaXMgdG8gY2FjaGUgdGhlIGZpcnN0IG9mIGVhY2ggb2YgdGhlc2UgaW5wdXRzIHdpdGhpbiBhblxuICAgIC8vIGV2ZW50LiBUaGVuIHJlc2V0IHRoZSBjYWNoZWQgdmFsdWVzIG9uY2Ugd2UgY2FuIGJlIHN1cmUgdGhlIGV2ZW50IGlzXG4gICAgLy8gb3Zlci4gT3VyIGhldXJpc3RpYyBmb3IgdGhhdCBpcyB3aGVuZXZlciB3ZSBlbnRlciBhIGNvbmN1cnJlbnQgd29yayBsb29wLlxuXG5cbiAgICBpZiAoY3VycmVudEV2ZW50VHJhbnNpdGlvbkxhbmUgPT09IE5vTGFuZSkge1xuICAgICAgLy8gQWxsIHRyYW5zaXRpb25zIHdpdGhpbiB0aGUgc2FtZSBldmVudCBhcmUgYXNzaWduZWQgdGhlIHNhbWUgbGFuZS5cbiAgICAgIGN1cnJlbnRFdmVudFRyYW5zaXRpb25MYW5lID0gY2xhaW1OZXh0VHJhbnNpdGlvbkxhbmUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudEV2ZW50VHJhbnNpdGlvbkxhbmU7XG4gIH0gLy8gVXBkYXRlcyBvcmlnaW5hdGluZyBpbnNpZGUgY2VydGFpbiBSZWFjdCBtZXRob2RzLCBsaWtlIGZsdXNoU3luYywgaGF2ZVxuICAvLyB0aGVpciBwcmlvcml0eSBzZXQgYnkgdHJhY2tpbmcgaXQgd2l0aCBhIGNvbnRleHQgdmFyaWFibGUuXG4gIC8vXG4gIC8vIFRoZSBvcGFxdWUgdHlwZSByZXR1cm5lZCBieSB0aGUgaG9zdCBjb25maWcgaXMgaW50ZXJuYWxseSBhIGxhbmUsIHNvIHdlIGNhblxuICAvLyB1c2UgdGhhdCBkaXJlY3RseS5cbiAgLy8gVE9ETzogTW92ZSB0aGlzIHR5cGUgY29udmVyc2lvbiB0byB0aGUgZXZlbnQgcHJpb3JpdHkgbW9kdWxlLlxuXG5cbiAgdmFyIHVwZGF0ZUxhbmUgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcblxuICBpZiAodXBkYXRlTGFuZSAhPT0gTm9MYW5lKSB7XG4gICAgcmV0dXJuIHVwZGF0ZUxhbmU7XG4gIH0gLy8gVGhpcyB1cGRhdGUgb3JpZ2luYXRlZCBvdXRzaWRlIFJlYWN0LiBBc2sgdGhlIGhvc3QgZW52aXJvbm1lbnQgZm9yIGFuXG4gIC8vIGFwcHJvcHJpYXRlIHByaW9yaXR5LCBiYXNlZCBvbiB0aGUgdHlwZSBvZiBldmVudC5cbiAgLy9cbiAgLy8gVGhlIG9wYXF1ZSB0eXBlIHJldHVybmVkIGJ5IHRoZSBob3N0IGNvbmZpZyBpcyBpbnRlcm5hbGx5IGEgbGFuZSwgc28gd2UgY2FuXG4gIC8vIHVzZSB0aGF0IGRpcmVjdGx5LlxuICAvLyBUT0RPOiBNb3ZlIHRoaXMgdHlwZSBjb252ZXJzaW9uIHRvIHRoZSBldmVudCBwcmlvcml0eSBtb2R1bGUuXG5cblxuICB2YXIgZXZlbnRMYW5lID0gZ2V0Q3VycmVudEV2ZW50UHJpb3JpdHkoKTtcbiAgcmV0dXJuIGV2ZW50TGFuZTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFJldHJ5TGFuZShmaWJlcikge1xuICAvLyBUaGlzIGlzIGEgZm9yayBvZiBgcmVxdWVzdFVwZGF0ZUxhbmVgIGRlc2lnbmVkIHNwZWNpZmljYWxseSBmb3IgU3VzcGVuc2VcbiAgLy8gXCJyZXRyaWVzXCIg4oCUIGEgc3BlY2lhbCB1cGRhdGUgdGhhdCBhdHRlbXB0cyB0byBmbGlwIGEgU3VzcGVuc2UgYm91bmRhcnlcbiAgLy8gZnJvbSBpdHMgcGxhY2Vob2xkZXIgc3RhdGUgdG8gaXRzIHByaW1hcnkvcmVzb2x2ZWQgc3RhdGUuXG4gIC8vIFNwZWNpYWwgY2FzZXNcbiAgdmFyIG1vZGUgPSBmaWJlci5tb2RlO1xuXG4gIGlmICgobW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlKSB7XG4gICAgcmV0dXJuIFN5bmNMYW5lO1xuICB9XG5cbiAgcmV0dXJuIGNsYWltTmV4dFJldHJ5TGFuZSgpO1xufVxuXG5mdW5jdGlvbiBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSkge1xuICBjaGVja0Zvck5lc3RlZFVwZGF0ZXMoKTtcblxuICB7XG4gICAgaWYgKGlzUnVubmluZ0luc2VydGlvbkVmZmVjdCkge1xuICAgICAgZXJyb3IoJ3VzZUluc2VydGlvbkVmZmVjdCBtdXN0IG5vdCBzY2hlZHVsZSB1cGRhdGVzLicpO1xuICAgIH1cbiAgfVxuXG4gIHtcbiAgICBpZiAoaXNGbHVzaGluZ1Bhc3NpdmVFZmZlY3RzKSB7XG4gICAgICBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gdHJ1ZTtcbiAgICB9XG4gIH0gLy8gTWFyayB0aGF0IHRoZSByb290IGhhcyBhIHBlbmRpbmcgdXBkYXRlLlxuXG5cbiAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIGxhbmUsIGV2ZW50VGltZSk7XG5cbiAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgUmVuZGVyQ29udGV4dCkgIT09IE5vTGFuZXMgJiYgcm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290KSB7XG4gICAgLy8gVGhpcyB1cGRhdGUgd2FzIGRpc3BhdGNoZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuIFRoaXMgaXMgYSBtaXN0YWtlXG4gICAgLy8gaWYgdGhlIHVwZGF0ZSBvcmlnaW5hdGVzIGZyb20gdXNlciBzcGFjZSAod2l0aCB0aGUgZXhjZXB0aW9uIG9mIGxvY2FsXG4gICAgLy8gaG9vayB1cGRhdGVzLCB3aGljaCBhcmUgaGFuZGxlZCBkaWZmZXJlbnRseSBhbmQgZG9uJ3QgcmVhY2ggdGhpc1xuICAgIC8vIGZ1bmN0aW9uKSwgYnV0IHRoZXJlIGFyZSBzb21lIGludGVybmFsIFJlYWN0IGZlYXR1cmVzIHRoYXQgdXNlIHRoaXMgYXNcbiAgICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwsIGxpa2Ugc2VsZWN0aXZlIGh5ZHJhdGlvbi5cbiAgICB3YXJuQWJvdXRSZW5kZXJQaGFzZVVwZGF0ZXNJbkRFVihmaWJlcik7IC8vIFRyYWNrIGxhbmVzIHRoYXQgd2VyZSB1cGRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlXG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBhIG5vcm1hbCB1cGRhdGUsIHNjaGVkdWxlZCBmcm9tIG91dHNpZGUgdGhlIHJlbmRlciBwaGFzZS4gRm9yXG4gICAgLy8gZXhhbXBsZSwgZHVyaW5nIGFuIGlucHV0IGV2ZW50LlxuICAgIHtcbiAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICBhZGRGaWJlclRvTGFuZXNNYXAocm9vdCwgZmliZXIsIGxhbmUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdhcm5JZlVwZGF0ZXNOb3RXcmFwcGVkV2l0aEFjdERFVihmaWJlcik7XG5cbiAgICBpZiAocm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290KSB7XG4gICAgICAvLyBSZWNlaXZlZCBhbiB1cGRhdGUgdG8gYSB0cmVlIHRoYXQncyBpbiB0aGUgbWlkZGxlIG9mIHJlbmRlcmluZy4gTWFya1xuICAgICAgLy8gdGhhdCB0aGVyZSB3YXMgYW4gaW50ZXJsZWF2ZWQgdXBkYXRlIHdvcmsgb24gdGhpcyByb290LiBVbmxlc3MgdGhlXG4gICAgICAvLyBgZGVmZXJSZW5kZXJQaGFzZVVwZGF0ZVRvTmV4dEJhdGNoYCBmbGFnIGlzIG9mZiBhbmQgdGhpcyBpcyBhIHJlbmRlclxuICAgICAgLy8gcGhhc2UgdXBkYXRlLiBJbiB0aGF0IGNhc2UsIHdlIGRvbid0IHRyZWF0IHJlbmRlciBwaGFzZSB1cGRhdGVzIGFzIGlmXG4gICAgICAvLyB0aGV5IHdlcmUgaW50ZXJsZWF2ZWQsIGZvciBiYWNrd2FyZHMgY29tcGF0IHJlYXNvbnMuXG4gICAgICBpZiAoIChleGVjdXRpb25Db250ZXh0ICYgUmVuZGVyQ29udGV4dCkgPT09IE5vQ29udGV4dCkge1xuICAgICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3NSb290SW50ZXJsZWF2ZWRVcGRhdGVkTGFuZXMsIGxhbmUpO1xuICAgICAgfVxuXG4gICAgICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZFdpdGhEZWxheSkge1xuICAgICAgICAvLyBUaGUgcm9vdCBhbHJlYWR5IHN1c3BlbmRlZCB3aXRoIGEgZGVsYXksIHdoaWNoIG1lYW5zIHRoaXMgcmVuZGVyXG4gICAgICAgIC8vIGRlZmluaXRlbHkgd29uJ3QgZmluaXNoLiBTaW5jZSB3ZSBoYXZlIGEgbmV3IHVwZGF0ZSwgbGV0J3MgbWFyayBpdCBhc1xuICAgICAgICAvLyBzdXNwZW5kZWQgbm93LCByaWdodCBiZWZvcmUgbWFya2luZyB0aGUgaW5jb21pbmcgdXBkYXRlLiBUaGlzIGhhcyB0aGVcbiAgICAgICAgLy8gZWZmZWN0IG9mIGludGVycnVwdGluZyB0aGUgY3VycmVudCByZW5kZXIgYW5kIHN3aXRjaGluZyB0byB0aGUgdXBkYXRlLlxuICAgICAgICAvLyBUT0RPOiBNYWtlIHN1cmUgdGhpcyBkb2Vzbid0IG92ZXJyaWRlIHBpbmdzIHRoYXQgaGFwcGVuIHdoaWxlIHdlJ3ZlXG4gICAgICAgIC8vIGFscmVhZHkgc3RhcnRlZCByZW5kZXJpbmcuXG4gICAgICAgIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuXG4gICAgaWYgKGxhbmUgPT09IFN5bmNMYW5lICYmIGV4ZWN1dGlvbkNvbnRleHQgPT09IE5vQ29udGV4dCAmJiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSA9PT0gTm9Nb2RlICYmIC8vIFRyZWF0IGBhY3RgIGFzIGlmIGl0J3MgaW5zaWRlIGBiYXRjaGVkVXBkYXRlc2AsIGV2ZW4gaW4gbGVnYWN5IG1vZGUuXG4gICAgISggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5pc0JhdGNoaW5nTGVnYWN5KSkge1xuICAgICAgLy8gRmx1c2ggdGhlIHN5bmNocm9ub3VzIHdvcmsgbm93LCB1bmxlc3Mgd2UncmUgYWxyZWFkeSB3b3JraW5nIG9yIGluc2lkZVxuICAgICAgLy8gYSBiYXRjaC4gVGhpcyBpcyBpbnRlbnRpb25hbGx5IGluc2lkZSBzY2hlZHVsZVVwZGF0ZU9uRmliZXIgaW5zdGVhZCBvZlxuICAgICAgLy8gc2NoZWR1bGVDYWxsYmFja0ZvckZpYmVyIHRvIHByZXNlcnZlIHRoZSBhYmlsaXR5IHRvIHNjaGVkdWxlIGEgY2FsbGJhY2tcbiAgICAgIC8vIHdpdGhvdXQgaW1tZWRpYXRlbHkgZmx1c2hpbmcgaXQuIFdlIG9ubHkgZG8gdGhpcyBmb3IgdXNlci1pbml0aWF0ZWRcbiAgICAgIC8vIHVwZGF0ZXMsIHRvIHByZXNlcnZlIGhpc3RvcmljYWwgYmVoYXZpb3Igb2YgbGVnYWN5IG1vZGUuXG4gICAgICByZXNldFJlbmRlclRpbWVyKCk7XG4gICAgICBmbHVzaFN5bmNDYWxsYmFja3NPbmx5SW5MZWdhY3lNb2RlKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBzY2hlZHVsZUluaXRpYWxIeWRyYXRpb25PblJvb3Qocm9vdCwgbGFuZSwgZXZlbnRUaW1lKSB7XG4gIC8vIFRoaXMgaXMgYSBzcGVjaWFsIGZvcmsgb2Ygc2NoZWR1bGVVcGRhdGVPbkZpYmVyIHRoYXQgaXMgb25seSB1c2VkIHRvXG4gIC8vIHNjaGVkdWxlIHRoZSBpbml0aWFsIGh5ZHJhdGlvbiBvZiBhIHJvb3QgdGhhdCBoYXMganVzdCBiZWVuIGNyZWF0ZWQuIE1vc3RcbiAgLy8gb2YgdGhlIHN0dWZmIGluIHNjaGVkdWxlVXBkYXRlT25GaWJlciBjYW4gYmUgc2tpcHBlZC5cbiAgLy9cbiAgLy8gVGhlIG1haW4gcmVhc29uIGZvciB0aGlzIHNlcGFyYXRlIHBhdGgsIHRob3VnaCwgaXMgdG8gZGlzdGluZ3Vpc2ggdGhlXG4gIC8vIGluaXRpYWwgY2hpbGRyZW4gZnJvbSBzdWJzZXF1ZW50IHVwZGF0ZXMuIEluIGZ1bGx5IGNsaWVudC1yZW5kZXJlZCByb290c1xuICAvLyAoY3JlYXRlUm9vdCBpbnN0ZWFkIG9mIGh5ZHJhdGVSb290KSwgYWxsIHRvcC1sZXZlbCByZW5kZXJzIGFyZSBtb2RlbGVkIGFzXG4gIC8vIHVwZGF0ZXMsIGJ1dCBoeWRyYXRpb24gcm9vdHMgYXJlIHNwZWNpYWwgYmVjYXVzZSB0aGUgaW5pdGlhbCByZW5kZXIgbXVzdFxuICAvLyBtYXRjaCB3aGF0IHdhcyByZW5kZXJlZCBvbiB0aGUgc2VydmVyLlxuICB2YXIgY3VycmVudCA9IHJvb3QuY3VycmVudDtcbiAgY3VycmVudC5sYW5lcyA9IGxhbmU7XG4gIG1hcmtSb290VXBkYXRlZChyb290LCBsYW5lLCBldmVudFRpbWUpO1xuICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgZXZlbnRUaW1lKTtcbn1cbmZ1bmN0aW9uIGlzVW5zYWZlQ2xhc3NSZW5kZXJQaGFzZVVwZGF0ZShmaWJlcikge1xuICAvLyBDaGVjayBpZiB0aGlzIGlzIGEgcmVuZGVyIHBoYXNlIHVwZGF0ZS4gT25seSBjYWxsZWQgYnkgY2xhc3MgY29tcG9uZW50cyxcbiAgLy8gd2hpY2ggc3BlY2lhbCAoZGVwcmVjYXRlZCkgYmVoYXZpb3IgZm9yIFVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZSBwcm9wcy5cbiAgcmV0dXJuICgvLyBUT0RPOiBSZW1vdmUgb3V0ZGF0ZWQgZGVmZXJSZW5kZXJQaGFzZVVwZGF0ZVRvTmV4dEJhdGNoIGV4cGVyaW1lbnQuIFdlXG4gICAgLy8gZGVjaWRlZCBub3QgdG8gZW5hYmxlIGl0LlxuICAgICAoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHRcbiAgKTtcbn0gLy8gVXNlIHRoaXMgZnVuY3Rpb24gdG8gc2NoZWR1bGUgYSB0YXNrIGZvciBhIHJvb3QuIFRoZXJlJ3Mgb25seSBvbmUgdGFzayBwZXJcbi8vIHJvb3Q7IGlmIGEgdGFzayB3YXMgYWxyZWFkeSBzY2hlZHVsZWQsIHdlJ2xsIGNoZWNrIHRvIG1ha2Ugc3VyZSB0aGUgcHJpb3JpdHlcbi8vIG9mIHRoZSBleGlzdGluZyB0YXNrIGlzIHRoZSBzYW1lIGFzIHRoZSBwcmlvcml0eSBvZiB0aGUgbmV4dCBsZXZlbCB0aGF0IHRoZVxuLy8gcm9vdCBoYXMgd29yayBvbi4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb24gZXZlcnkgdXBkYXRlLCBhbmQgcmlnaHQgYmVmb3JlXG4vLyBleGl0aW5nIGEgdGFzay5cblxuZnVuY3Rpb24gZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIGN1cnJlbnRUaW1lKSB7XG4gIHZhciBleGlzdGluZ0NhbGxiYWNrTm9kZSA9IHJvb3QuY2FsbGJhY2tOb2RlOyAvLyBDaGVjayBpZiBhbnkgbGFuZXMgYXJlIGJlaW5nIHN0YXJ2ZWQgYnkgb3RoZXIgd29yay4gSWYgc28sIG1hcmsgdGhlbSBhc1xuICAvLyBleHBpcmVkIHNvIHdlIGtub3cgdG8gd29yayBvbiB0aG9zZSBuZXh0LlxuXG4gIG1hcmtTdGFydmVkTGFuZXNBc0V4cGlyZWQocm9vdCwgY3VycmVudFRpbWUpOyAvLyBEZXRlcm1pbmUgdGhlIG5leHQgbGFuZXMgdG8gd29yayBvbiwgYW5kIHRoZWlyIHByaW9yaXR5LlxuXG4gIHZhciBuZXh0TGFuZXMgPSBnZXROZXh0TGFuZXMocm9vdCwgcm9vdCA9PT0gd29ya0luUHJvZ3Jlc3NSb290ID8gd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgOiBOb0xhbmVzKTtcblxuICBpZiAobmV4dExhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlOiBUaGVyZSdzIG5vdGhpbmcgdG8gd29yayBvbi5cbiAgICBpZiAoZXhpc3RpbmdDYWxsYmFja05vZGUgIT09IG51bGwpIHtcbiAgICAgIGNhbmNlbENhbGxiYWNrJDEoZXhpc3RpbmdDYWxsYmFja05vZGUpO1xuICAgIH1cblxuICAgIHJvb3QuY2FsbGJhY2tOb2RlID0gbnVsbDtcbiAgICByb290LmNhbGxiYWNrUHJpb3JpdHkgPSBOb0xhbmU7XG4gICAgcmV0dXJuO1xuICB9IC8vIFdlIHVzZSB0aGUgaGlnaGVzdCBwcmlvcml0eSBsYW5lIHRvIHJlcHJlc2VudCB0aGUgcHJpb3JpdHkgb2YgdGhlIGNhbGxiYWNrLlxuXG5cbiAgdmFyIG5ld0NhbGxiYWNrUHJpb3JpdHkgPSBnZXRIaWdoZXN0UHJpb3JpdHlMYW5lKG5leHRMYW5lcyk7IC8vIENoZWNrIGlmIHRoZXJlJ3MgYW4gZXhpc3RpbmcgdGFzay4gV2UgbWF5IGJlIGFibGUgdG8gcmV1c2UgaXQuXG5cbiAgdmFyIGV4aXN0aW5nQ2FsbGJhY2tQcmlvcml0eSA9IHJvb3QuY2FsbGJhY2tQcmlvcml0eTtcblxuICBpZiAoZXhpc3RpbmdDYWxsYmFja1ByaW9yaXR5ID09PSBuZXdDYWxsYmFja1ByaW9yaXR5ICYmIC8vIFNwZWNpYWwgY2FzZSByZWxhdGVkIHRvIGBhY3RgLiBJZiB0aGUgY3VycmVudGx5IHNjaGVkdWxlZCB0YXNrIGlzIGFcbiAgLy8gU2NoZWR1bGVyIHRhc2ssIHJhdGhlciB0aGFuIGFuIGBhY3RgIHRhc2ssIGNhbmNlbCBpdCBhbmQgcmUtc2NoZWR1bGVkXG4gIC8vIG9uIHRoZSBgYWN0YCBxdWV1ZS5cbiAgISggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ICE9PSBudWxsICYmIGV4aXN0aW5nQ2FsbGJhY2tOb2RlICE9PSBmYWtlQWN0Q2FsbGJhY2tOb2RlKSkge1xuICAgIHtcbiAgICAgIC8vIElmIHdlJ3JlIGdvaW5nIHRvIHJlLXVzZSBhbiBleGlzdGluZyB0YXNrLCBpdCBuZWVkcyB0byBleGlzdC5cbiAgICAgIC8vIEFzc3VtZSB0aGF0IGRpc2NyZXRlIHVwZGF0ZSBtaWNyb3Rhc2tzIGFyZSBub24tY2FuY2VsbGFibGUgYW5kIG51bGwuXG4gICAgICAvLyBUT0RPOiBUZW1wb3JhcnkgdW50aWwgd2UgY29uZmlybSB0aGlzIHdhcm5pbmcgaXMgbm90IGZpcmVkLlxuICAgICAgaWYgKGV4aXN0aW5nQ2FsbGJhY2tOb2RlID09IG51bGwgJiYgZXhpc3RpbmdDYWxsYmFja1ByaW9yaXR5ICE9PSBTeW5jTGFuZSkge1xuICAgICAgICBlcnJvcignRXhwZWN0ZWQgc2NoZWR1bGVkIGNhbGxiYWNrIHRvIGV4aXN0LiBUaGlzIGVycm9yIGlzIGxpa2VseSBjYXVzZWQgYnkgYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICAgICAgfVxuICAgIH0gLy8gVGhlIHByaW9yaXR5IGhhc24ndCBjaGFuZ2VkLiBXZSBjYW4gcmV1c2UgdGhlIGV4aXN0aW5nIHRhc2suIEV4aXQuXG5cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChleGlzdGluZ0NhbGxiYWNrTm9kZSAhPSBudWxsKSB7XG4gICAgLy8gQ2FuY2VsIHRoZSBleGlzdGluZyBjYWxsYmFjay4gV2UnbGwgc2NoZWR1bGUgYSBuZXcgb25lIGJlbG93LlxuICAgIGNhbmNlbENhbGxiYWNrJDEoZXhpc3RpbmdDYWxsYmFja05vZGUpO1xuICB9IC8vIFNjaGVkdWxlIGEgbmV3IGNhbGxiYWNrLlxuXG5cbiAgdmFyIG5ld0NhbGxiYWNrTm9kZTtcblxuICBpZiAobmV3Q2FsbGJhY2tQcmlvcml0eSA9PT0gU3luY0xhbmUpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IFN5bmMgUmVhY3QgY2FsbGJhY2tzIGFyZSBzY2hlZHVsZWQgb24gYSBzcGVjaWFsXG4gICAgLy8gaW50ZXJuYWwgcXVldWVcbiAgICBpZiAocm9vdC50YWcgPT09IExlZ2FjeVJvb3QpIHtcbiAgICAgIGlmICggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5pc0JhdGNoaW5nTGVnYWN5ICE9PSBudWxsKSB7XG4gICAgICAgIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuZGlkU2NoZWR1bGVMZWdhY3lVcGRhdGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBzY2hlZHVsZUxlZ2FjeVN5bmNDYWxsYmFjayhwZXJmb3JtU3luY1dvcmtPblJvb3QuYmluZChudWxsLCByb290KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjaGVkdWxlU3luY0NhbGxiYWNrKHBlcmZvcm1TeW5jV29ya09uUm9vdC5iaW5kKG51bGwsIHJvb3QpKTtcbiAgICB9XG5cbiAgICB7XG4gICAgICAvLyBGbHVzaCB0aGUgcXVldWUgaW4gYSBtaWNyb3Rhc2suXG4gICAgICBpZiAoIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBJbnNpZGUgYGFjdGAsIHVzZSBvdXIgaW50ZXJuYWwgYGFjdGAgcXVldWUgc28gdGhhdCB0aGVzZSBnZXQgZmx1c2hlZFxuICAgICAgICAvLyBhdCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IHNjb3BlIGV2ZW4gd2hlbiB1c2luZyB0aGUgc3luYyB2ZXJzaW9uXG4gICAgICAgIC8vIG9mIGBhY3RgLlxuICAgICAgICBSZWFjdEN1cnJlbnRBY3RRdWV1ZSQxLmN1cnJlbnQucHVzaChmbHVzaFN5bmNDYWxsYmFja3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2NoZWR1bGVNaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgIC8vIEluIFNhZmFyaSwgYXBwZW5kaW5nIGFuIGlmcmFtZSBmb3JjZXMgbWljcm90YXNrcyB0byBydW4uXG4gICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8yMjQ1OVxuICAgICAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgcnVubmluZyBjYWxsYmFja3MgaW4gdGhlIG1pZGRsZSBvZiByZW5kZXJcbiAgICAgICAgICAvLyBvciBjb21taXQgc28gd2UgbmVlZCB0byBjaGVjayBhZ2FpbnN0IHRoYXQuXG4gICAgICAgICAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgPT09IE5vQ29udGV4dCkge1xuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgd291bGQgc3RpbGwgcHJlbWF0dXJlbHkgZmx1c2ggdGhlIGNhbGxiYWNrc1xuICAgICAgICAgICAgLy8gaWYgdGhpcyBoYXBwZW5zIG91dHNpZGUgcmVuZGVyIG9yIGNvbW1pdCBwaGFzZSAoZS5nLiBpbiBhbiBldmVudCkuXG4gICAgICAgICAgICBmbHVzaFN5bmNDYWxsYmFja3MoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIG5ld0NhbGxiYWNrTm9kZSA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHNjaGVkdWxlclByaW9yaXR5TGV2ZWw7XG5cbiAgICBzd2l0Y2ggKGxhbmVzVG9FdmVudFByaW9yaXR5KG5leHRMYW5lcykpIHtcbiAgICAgIGNhc2UgRGlzY3JldGVFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gSW1tZWRpYXRlUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIENvbnRpbnVvdXNFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gVXNlckJsb2NraW5nUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIERlZmF1bHRFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIElkbGVFdmVudFByaW9yaXR5OlxuICAgICAgICBzY2hlZHVsZXJQcmlvcml0eUxldmVsID0gSWRsZVByaW9yaXR5O1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgc2NoZWR1bGVyUHJpb3JpdHlMZXZlbCA9IE5vcm1hbFByaW9yaXR5O1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBuZXdDYWxsYmFja05vZGUgPSBzY2hlZHVsZUNhbGxiYWNrJDEoc2NoZWR1bGVyUHJpb3JpdHlMZXZlbCwgcGVyZm9ybUNvbmN1cnJlbnRXb3JrT25Sb290LmJpbmQobnVsbCwgcm9vdCkpO1xuICB9XG5cbiAgcm9vdC5jYWxsYmFja1ByaW9yaXR5ID0gbmV3Q2FsbGJhY2tQcmlvcml0eTtcbiAgcm9vdC5jYWxsYmFja05vZGUgPSBuZXdDYWxsYmFja05vZGU7XG59IC8vIFRoaXMgaXMgdGhlIGVudHJ5IHBvaW50IGZvciBldmVyeSBjb25jdXJyZW50IHRhc2ssIGkuZS4gYW55dGhpbmcgdGhhdFxuLy8gZ29lcyB0aHJvdWdoIFNjaGVkdWxlci5cblxuXG5mdW5jdGlvbiBwZXJmb3JtQ29uY3VycmVudFdvcmtPblJvb3Qocm9vdCwgZGlkVGltZW91dCkge1xuICB7XG4gICAgcmVzZXROZXN0ZWRVcGRhdGVGbGFnKCk7XG4gIH0gLy8gU2luY2Ugd2Uga25vdyB3ZSdyZSBpbiBhIFJlYWN0IGV2ZW50LCB3ZSBjYW4gY2xlYXIgdGhlIGN1cnJlbnRcbiAgLy8gZXZlbnQgdGltZS4gVGhlIG5leHQgdXBkYXRlIHdpbGwgY29tcHV0ZSBhIG5ldyBldmVudCB0aW1lLlxuXG5cbiAgY3VycmVudEV2ZW50VGltZSA9IE5vVGltZXN0YW1wO1xuICBjdXJyZW50RXZlbnRUcmFuc2l0aW9uTGFuZSA9IE5vTGFuZXM7XG5cbiAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgIT09IE5vQ29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hvdWxkIG5vdCBhbHJlYWR5IGJlIHdvcmtpbmcuJyk7XG4gIH0gLy8gRmx1c2ggYW55IHBlbmRpbmcgcGFzc2l2ZSBlZmZlY3RzIGJlZm9yZSBkZWNpZGluZyB3aGljaCBsYW5lcyB0byB3b3JrIG9uLFxuICAvLyBpbiBjYXNlIHRoZXkgc2NoZWR1bGUgYWRkaXRpb25hbCB3b3JrLlxuXG5cbiAgdmFyIG9yaWdpbmFsQ2FsbGJhY2tOb2RlID0gcm9vdC5jYWxsYmFja05vZGU7XG4gIHZhciBkaWRGbHVzaFBhc3NpdmVFZmZlY3RzID0gZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuXG4gIGlmIChkaWRGbHVzaFBhc3NpdmVFZmZlY3RzKSB7XG4gICAgLy8gU29tZXRoaW5nIGluIHRoZSBwYXNzaXZlIGVmZmVjdCBwaGFzZSBtYXkgaGF2ZSBjYW5jZWxlZCB0aGUgY3VycmVudCB0YXNrLlxuICAgIC8vIENoZWNrIGlmIHRoZSB0YXNrIG5vZGUgZm9yIHRoaXMgcm9vdCB3YXMgY2hhbmdlZC5cbiAgICBpZiAocm9vdC5jYWxsYmFja05vZGUgIT09IG9yaWdpbmFsQ2FsbGJhY2tOb2RlKSB7XG4gICAgICAvLyBUaGUgY3VycmVudCB0YXNrIHdhcyBjYW5jZWxlZC4gRXhpdC4gV2UgZG9uJ3QgbmVlZCB0byBjYWxsXG4gICAgICAvLyBgZW5zdXJlUm9vdElzU2NoZWR1bGVkYCBiZWNhdXNlIHRoZSBjaGVjayBhYm92ZSBpbXBsaWVzIGVpdGhlciB0aGF0XG4gICAgICAvLyB0aGVyZSdzIGEgbmV3IHRhc2ssIG9yIHRoYXQgdGhlcmUncyBubyByZW1haW5pbmcgd29yayBvbiB0aGlzIHJvb3QuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH0gLy8gRGV0ZXJtaW5lIHRoZSBuZXh0IGxhbmVzIHRvIHdvcmsgb24sIHVzaW5nIHRoZSBmaWVsZHMgc3RvcmVkXG4gIC8vIG9uIHRoZSByb290LlxuXG5cbiAgdmFyIGxhbmVzID0gZ2V0TmV4dExhbmVzKHJvb3QsIHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCA/IHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzIDogTm9MYW5lcyk7XG5cbiAgaWYgKGxhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gRGVmZW5zaXZlIGNvZGluZy4gVGhpcyBpcyBuZXZlciBleHBlY3RlZCB0byBoYXBwZW4uXG4gICAgcmV0dXJuIG51bGw7XG4gIH0gLy8gV2UgZGlzYWJsZSB0aW1lLXNsaWNpbmcgaW4gc29tZSBjYXNlczogaWYgdGhlIHdvcmsgaGFzIGJlZW4gQ1BVLWJvdW5kXG4gIC8vIGZvciB0b28gbG9uZyAoXCJleHBpcmVkXCIgd29yaywgdG8gcHJldmVudCBzdGFydmF0aW9uKSwgb3Igd2UncmUgaW5cbiAgLy8gc3luYy11cGRhdGVzLWJ5LWRlZmF1bHQgbW9kZS5cbiAgLy8gVE9ETzogV2Ugb25seSBjaGVjayBgZGlkVGltZW91dGAgZGVmZW5zaXZlbHksIHRvIGFjY291bnQgZm9yIGEgU2NoZWR1bGVyXG4gIC8vIGJ1ZyB3ZSdyZSBzdGlsbCBpbnZlc3RpZ2F0aW5nLiBPbmNlIHRoZSBidWcgaW4gU2NoZWR1bGVyIGlzIGZpeGVkLFxuICAvLyB3ZSBjYW4gcmVtb3ZlIHRoaXMsIHNpbmNlIHdlIHRyYWNrIGV4cGlyYXRpb24gb3Vyc2VsdmVzLlxuXG5cbiAgdmFyIHNob3VsZFRpbWVTbGljZSA9ICFpbmNsdWRlc0Jsb2NraW5nTGFuZShyb290LCBsYW5lcykgJiYgIWluY2x1ZGVzRXhwaXJlZExhbmUocm9vdCwgbGFuZXMpICYmICggIWRpZFRpbWVvdXQpO1xuICB2YXIgZXhpdFN0YXR1cyA9IHNob3VsZFRpbWVTbGljZSA/IHJlbmRlclJvb3RDb25jdXJyZW50KHJvb3QsIGxhbmVzKSA6IHJlbmRlclJvb3RTeW5jKHJvb3QsIGxhbmVzKTtcblxuICBpZiAoZXhpdFN0YXR1cyAhPT0gUm9vdEluUHJvZ3Jlc3MpIHtcbiAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdEVycm9yZWQpIHtcbiAgICAgIC8vIElmIHNvbWV0aGluZyB0aHJldyBhbiBlcnJvciwgdHJ5IHJlbmRlcmluZyBvbmUgbW9yZSB0aW1lLiBXZSdsbFxuICAgICAgLy8gcmVuZGVyIHN5bmNocm9ub3VzbHkgdG8gYmxvY2sgY29uY3VycmVudCBkYXRhIG11dGF0aW9ucywgYW5kIHdlJ2xsXG4gICAgICAvLyBpbmNsdWRlcyBhbGwgcGVuZGluZyB1cGRhdGVzIGFyZSBpbmNsdWRlZC4gSWYgaXQgc3RpbGwgZmFpbHMgYWZ0ZXJcbiAgICAgIC8vIHRoZSBzZWNvbmQgYXR0ZW1wdCwgd2UnbGwgZ2l2ZSB1cCBhbmQgY29tbWl0IHRoZSByZXN1bHRpbmcgdHJlZS5cbiAgICAgIHZhciBlcnJvclJldHJ5TGFuZXMgPSBnZXRMYW5lc1RvUmV0cnlTeW5jaHJvbm91c2x5T25FcnJvcihyb290KTtcblxuICAgICAgaWYgKGVycm9yUmV0cnlMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICBsYW5lcyA9IGVycm9yUmV0cnlMYW5lcztcbiAgICAgICAgZXhpdFN0YXR1cyA9IHJlY292ZXJGcm9tQ29uY3VycmVudEVycm9yKHJvb3QsIGVycm9yUmV0cnlMYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV4aXRTdGF0dXMgPT09IFJvb3RGYXRhbEVycm9yZWQpIHtcbiAgICAgIHZhciBmYXRhbEVycm9yID0gd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvcjtcbiAgICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIE5vTGFuZXMpO1xuICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgbm93KCkpO1xuICAgICAgdGhyb3cgZmF0YWxFcnJvcjtcbiAgICB9XG5cbiAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdERpZE5vdENvbXBsZXRlKSB7XG4gICAgICAvLyBUaGUgcmVuZGVyIHVud291bmQgd2l0aG91dCBjb21wbGV0aW5nIHRoZSB0cmVlLiBUaGlzIGhhcHBlbnMgaW4gc3BlY2lhbFxuICAgICAgLy8gY2FzZXMgd2hlcmUgbmVlZCB0byBleGl0IHRoZSBjdXJyZW50IHJlbmRlciB3aXRob3V0IHByb2R1Y2luZyBhXG4gICAgICAvLyBjb25zaXN0ZW50IHRyZWUgb3IgY29tbWl0dGluZy5cbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIHNob3VsZCBvbmx5IGhhcHBlbiBkdXJpbmcgYSBjb25jdXJyZW50IHJlbmRlciwgbm90IGEgZGlzY3JldGUgb3JcbiAgICAgIC8vIHN5bmNocm9ub3VzIHVwZGF0ZS4gV2Ugc2hvdWxkIGhhdmUgYWxyZWFkeSBjaGVja2VkIGZvciB0aGlzIHdoZW4gd2VcbiAgICAgIC8vIHVud291bmQgdGhlIHN0YWNrLlxuICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRoZSByZW5kZXIgY29tcGxldGVkLlxuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyByZW5kZXIgbWF5IGhhdmUgeWllbGRlZCB0byBhIGNvbmN1cnJlbnQgZXZlbnQsIGFuZCBpZiBzbyxcbiAgICAgIC8vIGNvbmZpcm0gdGhhdCBhbnkgbmV3bHkgcmVuZGVyZWQgc3RvcmVzIGFyZSBjb25zaXN0ZW50LlxuICAgICAgLy8gVE9ETzogSXQncyBwb3NzaWJsZSB0aGF0IGV2ZW4gYSBjb25jdXJyZW50IHJlbmRlciBtYXkgbmV2ZXIgaGF2ZSB5aWVsZGVkXG4gICAgICAvLyB0byB0aGUgbWFpbiB0aHJlYWQsIGlmIGl0IHdhcyBmYXN0IGVub3VnaCwgb3IgaWYgaXQgZXhwaXJlZC4gV2UgY291bGRcbiAgICAgIC8vIHNraXAgdGhlIGNvbnNpc3RlbmN5IGNoZWNrIGluIHRoYXQgY2FzZSwgdG9vLlxuICAgICAgdmFyIHJlbmRlcldhc0NvbmN1cnJlbnQgPSAhaW5jbHVkZXNCbG9ja2luZ0xhbmUocm9vdCwgbGFuZXMpO1xuICAgICAgdmFyIGZpbmlzaGVkV29yayA9IHJvb3QuY3VycmVudC5hbHRlcm5hdGU7XG5cbiAgICAgIGlmIChyZW5kZXJXYXNDb25jdXJyZW50ICYmICFpc1JlbmRlckNvbnNpc3RlbnRXaXRoRXh0ZXJuYWxTdG9yZXMoZmluaXNoZWRXb3JrKSkge1xuICAgICAgICAvLyBBIHN0b3JlIHdhcyBtdXRhdGVkIGluIGFuIGludGVybGVhdmVkIGV2ZW50LiBSZW5kZXIgYWdhaW4sXG4gICAgICAgIC8vIHN5bmNocm9ub3VzbHksIHRvIGJsb2NrIGZ1cnRoZXIgbXV0YXRpb25zLlxuICAgICAgICBleGl0U3RhdHVzID0gcmVuZGVyUm9vdFN5bmMocm9vdCwgbGFuZXMpOyAvLyBXZSBuZWVkIHRvIGNoZWNrIGFnYWluIGlmIHNvbWV0aGluZyB0aHJld1xuXG4gICAgICAgIGlmIChleGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgICAgICAgIHZhciBfZXJyb3JSZXRyeUxhbmVzID0gZ2V0TGFuZXNUb1JldHJ5U3luY2hyb25vdXNseU9uRXJyb3Iocm9vdCk7XG5cbiAgICAgICAgICBpZiAoX2Vycm9yUmV0cnlMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICAgICAgbGFuZXMgPSBfZXJyb3JSZXRyeUxhbmVzO1xuICAgICAgICAgICAgZXhpdFN0YXR1cyA9IHJlY292ZXJGcm9tQ29uY3VycmVudEVycm9yKHJvb3QsIF9lcnJvclJldHJ5TGFuZXMpOyAvLyBXZSBhc3N1bWUgdGhlIHRyZWUgaXMgbm93IGNvbnNpc3RlbnQgYmVjYXVzZSB3ZSBkaWRuJ3QgeWllbGQgdG8gYW55XG4gICAgICAgICAgICAvLyBjb25jdXJyZW50IGV2ZW50cy5cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXhpdFN0YXR1cyA9PT0gUm9vdEZhdGFsRXJyb3JlZCkge1xuICAgICAgICAgIHZhciBfZmF0YWxFcnJvciA9IHdvcmtJblByb2dyZXNzUm9vdEZhdGFsRXJyb3I7XG4gICAgICAgICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgTm9MYW5lcyk7XG4gICAgICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG4gICAgICAgICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgICAgICAgICB0aHJvdyBfZmF0YWxFcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSAvLyBXZSBub3cgaGF2ZSBhIGNvbnNpc3RlbnQgdHJlZS4gVGhlIG5leHQgc3RlcCBpcyBlaXRoZXIgdG8gY29tbWl0IGl0LFxuICAgICAgLy8gb3IsIGlmIHNvbWV0aGluZyBzdXNwZW5kZWQsIHdhaXQgdG8gY29tbWl0IGl0IGFmdGVyIGEgdGltZW91dC5cblxuXG4gICAgICByb290LmZpbmlzaGVkV29yayA9IGZpbmlzaGVkV29yaztcbiAgICAgIHJvb3QuZmluaXNoZWRMYW5lcyA9IGxhbmVzO1xuICAgICAgZmluaXNoQ29uY3VycmVudFJlbmRlcihyb290LCBleGl0U3RhdHVzLCBsYW5lcyk7XG4gICAgfVxuICB9XG5cbiAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcblxuICBpZiAocm9vdC5jYWxsYmFja05vZGUgPT09IG9yaWdpbmFsQ2FsbGJhY2tOb2RlKSB7XG4gICAgLy8gVGhlIHRhc2sgbm9kZSBzY2hlZHVsZWQgZm9yIHRoaXMgcm9vdCBpcyB0aGUgc2FtZSBvbmUgdGhhdCdzXG4gICAgLy8gY3VycmVudGx5IGV4ZWN1dGVkLiBOZWVkIHRvIHJldHVybiBhIGNvbnRpbnVhdGlvbi5cbiAgICByZXR1cm4gcGVyZm9ybUNvbmN1cnJlbnRXb3JrT25Sb290LmJpbmQobnVsbCwgcm9vdCk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmVjb3ZlckZyb21Db25jdXJyZW50RXJyb3Iocm9vdCwgZXJyb3JSZXRyeUxhbmVzKSB7XG4gIC8vIElmIGFuIGVycm9yIG9jY3VycmVkIGR1cmluZyBoeWRyYXRpb24sIGRpc2NhcmQgc2VydmVyIHJlc3BvbnNlIGFuZCBmYWxsXG4gIC8vIGJhY2sgdG8gY2xpZW50IHNpZGUgcmVuZGVyLlxuICAvLyBCZWZvcmUgcmVuZGVyaW5nIGFnYWluLCBzYXZlIHRoZSBlcnJvcnMgZnJvbSB0aGUgcHJldmlvdXMgYXR0ZW1wdC5cbiAgdmFyIGVycm9yc0Zyb21GaXJzdEF0dGVtcHQgPSB3b3JrSW5Qcm9ncmVzc1Jvb3RDb25jdXJyZW50RXJyb3JzO1xuXG4gIGlmIChpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpKSB7XG4gICAgLy8gVGhlIHNoZWxsIGZhaWxlZCB0byBoeWRyYXRlLiBTZXQgYSBmbGFnIHRvIGZvcmNlIGEgY2xpZW50IHJlbmRlcmluZ1xuICAgIC8vIGR1cmluZyB0aGUgbmV4dCBhdHRlbXB0LiBUbyBkbyB0aGlzLCB3ZSBjYWxsIHByZXBhcmVGcmVzaFN0YWNrIG5vd1xuICAgIC8vIHRvIGNyZWF0ZSB0aGUgcm9vdCB3b3JrLWluLXByb2dyZXNzIGZpYmVyLiBUaGlzIGlzIGEgYml0IHdlaXJkIGluIHRlcm1zXG4gICAgLy8gb2YgZmFjdG9yaW5nLCBiZWNhdXNlIGl0IHJlbGllcyBvbiByZW5kZXJSb290U3luYyBub3QgY2FsbGluZ1xuICAgIC8vIHByZXBhcmVGcmVzaFN0YWNrIGFnYWluIGluIHRoZSBjYWxsIGJlbG93LCB3aGljaCBoYXBwZW5zIGJlY2F1c2UgdGhlXG4gICAgLy8gcm9vdCBhbmQgbGFuZXMgaGF2ZW4ndCBjaGFuZ2VkLlxuICAgIC8vXG4gICAgLy8gVE9ETzogSSB0aGluayB3aGF0IHdlIHNob3VsZCBkbyBpcyBzZXQgRm9yY2VDbGllbnRSZW5kZXIgaW5zaWRlXG4gICAgLy8gdGhyb3dFeGNlcHRpb24sIGxpa2Ugd2UgZG8gZm9yIG5lc3RlZCBTdXNwZW5zZSBib3VuZGFyaWVzLiBUaGUgcmVhc29uXG4gICAgLy8gaXQncyBoZXJlIGluc3RlYWQgaXMgc28gd2UgY2FuIHN3aXRjaCB0byB0aGUgc3luY2hyb25vdXMgd29yayBsb29wLCB0b28uXG4gICAgLy8gU29tZXRoaW5nIHRvIGNvbnNpZGVyIGZvciBhIGZ1dHVyZSByZWZhY3Rvci5cbiAgICB2YXIgcm9vdFdvcmtJblByb2dyZXNzID0gcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgZXJyb3JSZXRyeUxhbmVzKTtcbiAgICByb290V29ya0luUHJvZ3Jlc3MuZmxhZ3MgfD0gRm9yY2VDbGllbnRSZW5kZXI7XG5cbiAgICB7XG4gICAgICBlcnJvckh5ZHJhdGluZ0NvbnRhaW5lcihyb290LmNvbnRhaW5lckluZm8pO1xuICAgIH1cbiAgfVxuXG4gIHZhciBleGl0U3RhdHVzID0gcmVuZGVyUm9vdFN5bmMocm9vdCwgZXJyb3JSZXRyeUxhbmVzKTtcblxuICBpZiAoZXhpdFN0YXR1cyAhPT0gUm9vdEVycm9yZWQpIHtcbiAgICAvLyBTdWNjZXNzZnVsbHkgZmluaXNoZWQgcmVuZGVyaW5nIG9uIHJldHJ5XG4gICAgLy8gVGhlIGVycm9ycyBmcm9tIHRoZSBmYWlsZWQgZmlyc3QgYXR0ZW1wdCBoYXZlIGJlZW4gcmVjb3ZlcmVkLiBBZGRcbiAgICAvLyB0aGVtIHRvIHRoZSBjb2xsZWN0aW9uIG9mIHJlY292ZXJhYmxlIGVycm9ycy4gV2UnbGwgbG9nIHRoZW0gaW4gdGhlXG4gICAgLy8gY29tbWl0IHBoYXNlLlxuICAgIHZhciBlcnJvcnNGcm9tU2Vjb25kQXR0ZW1wdCA9IHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzO1xuICAgIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzID0gZXJyb3JzRnJvbUZpcnN0QXR0ZW1wdDsgLy8gVGhlIGVycm9ycyBmcm9tIHRoZSBzZWNvbmQgYXR0ZW1wdCBzaG91bGQgYmUgcXVldWVkIGFmdGVyIHRoZSBlcnJvcnNcbiAgICAvLyBmcm9tIHRoZSBmaXJzdCBhdHRlbXB0LCB0byBwcmVzZXJ2ZSB0aGUgY2F1c2FsIHNlcXVlbmNlLlxuXG4gICAgaWYgKGVycm9yc0Zyb21TZWNvbmRBdHRlbXB0ICE9PSBudWxsKSB7XG4gICAgICBxdWV1ZVJlY292ZXJhYmxlRXJyb3JzKGVycm9yc0Zyb21TZWNvbmRBdHRlbXB0KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhpdFN0YXR1cztcbn1cblxuZnVuY3Rpb24gcXVldWVSZWNvdmVyYWJsZUVycm9ycyhlcnJvcnMpIHtcbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzID09PSBudWxsKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMgPSBlcnJvcnM7XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMucHVzaC5hcHBseSh3b3JrSW5Qcm9ncmVzc1Jvb3RSZWNvdmVyYWJsZUVycm9ycywgZXJyb3JzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5pc2hDb25jdXJyZW50UmVuZGVyKHJvb3QsIGV4aXRTdGF0dXMsIGxhbmVzKSB7XG4gIHN3aXRjaCAoZXhpdFN0YXR1cykge1xuICAgIGNhc2UgUm9vdEluUHJvZ3Jlc3M6XG4gICAgY2FzZSBSb290RmF0YWxFcnJvcmVkOlxuICAgICAge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jvb3QgZGlkIG5vdCBjb21wbGV0ZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgICAgIH1cbiAgICAvLyBGbG93IGtub3dzIGFib3V0IGludmFyaWFudCwgc28gaXQgY29tcGxhaW5zIGlmIEkgYWRkIGEgYnJlYWtcbiAgICAvLyBzdGF0ZW1lbnQsIGJ1dCBlc2xpbnQgZG9lc24ndCBrbm93IGFib3V0IGludmFyaWFudCwgc28gaXQgY29tcGxhaW5zXG4gICAgLy8gaWYgSSBkby4gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWZhbGx0aHJvdWdoXG5cbiAgICBjYXNlIFJvb3RFcnJvcmVkOlxuICAgICAge1xuICAgICAgICAvLyBXZSBzaG91bGQgaGF2ZSBhbHJlYWR5IGF0dGVtcHRlZCB0byByZXRyeSB0aGlzIHRyZWUuIElmIHdlIHJlYWNoZWRcbiAgICAgICAgLy8gdGhpcyBwb2ludCwgaXQgZXJyb3JlZCBhZ2Fpbi4gQ29tbWl0IGl0LlxuICAgICAgICBjb21taXRSb290KHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFJvb3RTdXNwZW5kZWQ6XG4gICAgICB7XG4gICAgICAgIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgbGFuZXMpOyAvLyBXZSBoYXZlIGFuIGFjY2VwdGFibGUgbG9hZGluZyBzdGF0ZS4gV2UgbmVlZCB0byBmaWd1cmUgb3V0IGlmIHdlXG4gICAgICAgIC8vIHNob3VsZCBpbW1lZGlhdGVseSBjb21taXQgaXQgb3Igd2FpdCBhIGJpdC5cblxuICAgICAgICBpZiAoaW5jbHVkZXNPbmx5UmV0cmllcyhsYW5lcykgJiYgLy8gZG8gbm90IGRlbGF5IGlmIHdlJ3JlIGluc2lkZSBhbiBhY3QoKSBzY29wZVxuICAgICAgICAhc2hvdWxkRm9yY2VGbHVzaEZhbGxiYWNrc0luREVWKCkpIHtcbiAgICAgICAgICAvLyBUaGlzIHJlbmRlciBvbmx5IGluY2x1ZGVkIHJldHJpZXMsIG5vIHVwZGF0ZXMuIFRocm90dGxlIGNvbW1pdHRpbmdcbiAgICAgICAgICAvLyByZXRyaWVzIHNvIHRoYXQgd2UgZG9uJ3Qgc2hvdyB0b28gbWFueSBsb2FkaW5nIHN0YXRlcyB0b28gcXVpY2tseS5cbiAgICAgICAgICB2YXIgbXNVbnRpbFRpbWVvdXQgPSBnbG9iYWxNb3N0UmVjZW50RmFsbGJhY2tUaW1lICsgRkFMTEJBQ0tfVEhST1RUTEVfTVMgLSBub3coKTsgLy8gRG9uJ3QgYm90aGVyIHdpdGggYSB2ZXJ5IHNob3J0IHN1c3BlbnNlIHRpbWUuXG5cbiAgICAgICAgICBpZiAobXNVbnRpbFRpbWVvdXQgPiAxMCkge1xuICAgICAgICAgICAgdmFyIG5leHRMYW5lcyA9IGdldE5leHRMYW5lcyhyb290LCBOb0xhbmVzKTtcblxuICAgICAgICAgICAgaWYgKG5leHRMYW5lcyAhPT0gTm9MYW5lcykge1xuICAgICAgICAgICAgICAvLyBUaGVyZSdzIGFkZGl0aW9uYWwgd29yayBvbiB0aGlzIHJvb3QuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc3VzcGVuZGVkTGFuZXMgPSByb290LnN1c3BlbmRlZExhbmVzO1xuXG4gICAgICAgICAgICBpZiAoIWlzU3Vic2V0T2ZMYW5lcyhzdXNwZW5kZWRMYW5lcywgbGFuZXMpKSB7XG4gICAgICAgICAgICAgIC8vIFdlIHNob3VsZCBwcmVmZXIgdG8gcmVuZGVyIHRoZSBmYWxsYmFjayBvZiBhdCB0aGUgbGFzdFxuICAgICAgICAgICAgICAvLyBzdXNwZW5kZWQgbGV2ZWwuIFBpbmcgdGhlIGxhc3Qgc3VzcGVuZGVkIGxldmVsIHRvIHRyeVxuICAgICAgICAgICAgICAvLyByZW5kZXJpbmcgaXQgYWdhaW4uXG4gICAgICAgICAgICAgIC8vIEZJWE1FOiBXaGF0IGlmIHRoZSBzdXNwZW5kZWQgbGFuZXMgYXJlIElkbGU/IFNob3VsZCBub3QgcmVzdGFydC5cbiAgICAgICAgICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgICAgICAgICAgbWFya1Jvb3RQaW5nZWQocm9vdCwgc3VzcGVuZGVkTGFuZXMpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH0gLy8gVGhlIHJlbmRlciBpcyBzdXNwZW5kZWQsIGl0IGhhc24ndCB0aW1lZCBvdXQsIGFuZCB0aGVyZSdzIG5vXG4gICAgICAgICAgICAvLyBsb3dlciBwcmlvcml0eSB3b3JrIHRvIGRvLiBJbnN0ZWFkIG9mIGNvbW1pdHRpbmcgdGhlIGZhbGxiYWNrXG4gICAgICAgICAgICAvLyBpbW1lZGlhdGVseSwgd2FpdCBmb3IgbW9yZSBkYXRhIHRvIGFycml2ZS5cblxuXG4gICAgICAgICAgICByb290LnRpbWVvdXRIYW5kbGUgPSBzY2hlZHVsZVRpbWVvdXQoY29tbWl0Um9vdC5iaW5kKG51bGwsIHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKSwgbXNVbnRpbFRpbWVvdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIFRoZSB3b3JrIGV4cGlyZWQuIENvbW1pdCBpbW1lZGlhdGVseS5cblxuXG4gICAgICAgIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgUm9vdFN1c3BlbmRlZFdpdGhEZWxheTpcbiAgICAgIHtcbiAgICAgICAgbWFya1Jvb3RTdXNwZW5kZWQkMShyb290LCBsYW5lcyk7XG5cbiAgICAgICAgaWYgKGluY2x1ZGVzT25seVRyYW5zaXRpb25zKGxhbmVzKSkge1xuICAgICAgICAgIC8vIFRoaXMgaXMgYSB0cmFuc2l0aW9uLCBzbyB3ZSBzaG91bGQgZXhpdCB3aXRob3V0IGNvbW1pdHRpbmcgYVxuICAgICAgICAgIC8vIHBsYWNlaG9sZGVyIGFuZCB3aXRob3V0IHNjaGVkdWxpbmcgYSB0aW1lb3V0LiBEZWxheSBpbmRlZmluaXRlbHlcbiAgICAgICAgICAvLyB1bnRpbCB3ZSByZWNlaXZlIG1vcmUgZGF0YS5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghc2hvdWxkRm9yY2VGbHVzaEZhbGxiYWNrc0luREVWKCkpIHtcbiAgICAgICAgICAvLyBUaGlzIGlzIG5vdCBhIHRyYW5zaXRpb24sIGJ1dCB3ZSBkaWQgdHJpZ2dlciBhbiBhdm9pZGVkIHN0YXRlLlxuICAgICAgICAgIC8vIFNjaGVkdWxlIGEgcGxhY2Vob2xkZXIgdG8gZGlzcGxheSBhZnRlciBhIHNob3J0IGRlbGF5LCB1c2luZyB0aGUgSnVzdFxuICAgICAgICAgIC8vIE5vdGljZWFibGUgRGlmZmVyZW5jZS5cbiAgICAgICAgICAvLyBUT0RPOiBJcyB0aGUgSk5EIG9wdGltaXphdGlvbiB3b3J0aCB0aGUgYWRkZWQgY29tcGxleGl0eT8gSWYgdGhpcyBpc1xuICAgICAgICAgIC8vIHRoZSBvbmx5IHJlYXNvbiB3ZSB0cmFjayB0aGUgZXZlbnQgdGltZSwgdGhlbiBwcm9iYWJseSBub3QuXG4gICAgICAgICAgLy8gQ29uc2lkZXIgcmVtb3ZpbmcuXG4gICAgICAgICAgdmFyIG1vc3RSZWNlbnRFdmVudFRpbWUgPSBnZXRNb3N0UmVjZW50RXZlbnRUaW1lKHJvb3QsIGxhbmVzKTtcbiAgICAgICAgICB2YXIgZXZlbnRUaW1lTXMgPSBtb3N0UmVjZW50RXZlbnRUaW1lO1xuICAgICAgICAgIHZhciB0aW1lRWxhcHNlZE1zID0gbm93KCkgLSBldmVudFRpbWVNcztcblxuICAgICAgICAgIHZhciBfbXNVbnRpbFRpbWVvdXQgPSBqbmQodGltZUVsYXBzZWRNcykgLSB0aW1lRWxhcHNlZE1zOyAvLyBEb24ndCBib3RoZXIgd2l0aCBhIHZlcnkgc2hvcnQgc3VzcGVuc2UgdGltZS5cblxuXG4gICAgICAgICAgaWYgKF9tc1VudGlsVGltZW91dCA+IDEwKSB7XG4gICAgICAgICAgICAvLyBJbnN0ZWFkIG9mIGNvbW1pdHRpbmcgdGhlIGZhbGxiYWNrIGltbWVkaWF0ZWx5LCB3YWl0IGZvciBtb3JlIGRhdGFcbiAgICAgICAgICAgIC8vIHRvIGFycml2ZS5cbiAgICAgICAgICAgIHJvb3QudGltZW91dEhhbmRsZSA9IHNjaGVkdWxlVGltZW91dChjb21taXRSb290LmJpbmQobnVsbCwgcm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpLCBfbXNVbnRpbFRpbWVvdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIENvbW1pdCB0aGUgcGxhY2Vob2xkZXIuXG5cblxuICAgICAgICBjb21taXRSb290KHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFJvb3RDb21wbGV0ZWQ6XG4gICAgICB7XG4gICAgICAgIC8vIFRoZSB3b3JrIGNvbXBsZXRlZC4gUmVhZHkgdG8gY29tbWl0LlxuICAgICAgICBjb21taXRSb290KHJvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzLCB3b3JrSW5Qcm9ncmVzc1RyYW5zaXRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gcm9vdCBleGl0IHN0YXR1cy4nKTtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpc1JlbmRlckNvbnNpc3RlbnRXaXRoRXh0ZXJuYWxTdG9yZXMoZmluaXNoZWRXb3JrKSB7XG4gIC8vIFNlYXJjaCB0aGUgcmVuZGVyZWQgdHJlZSBmb3IgZXh0ZXJuYWwgc3RvcmUgcmVhZHMsIGFuZCBjaGVjayB3aGV0aGVyIHRoZVxuICAvLyBzdG9yZXMgd2VyZSBtdXRhdGVkIGluIGEgY29uY3VycmVudCBldmVudC4gSW50ZW50aW9uYWxseSB1c2luZyBhbiBpdGVyYXRpdmVcbiAgLy8gbG9vcCBpbnN0ZWFkIG9mIHJlY3Vyc2lvbiBzbyB3ZSBjYW4gZXhpdCBlYXJseS5cbiAgdmFyIG5vZGUgPSBmaW5pc2hlZFdvcms7XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAobm9kZS5mbGFncyAmIFN0b3JlQ29uc2lzdGVuY3kpIHtcbiAgICAgIHZhciB1cGRhdGVRdWV1ZSA9IG5vZGUudXBkYXRlUXVldWU7XG5cbiAgICAgIGlmICh1cGRhdGVRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgY2hlY2tzID0gdXBkYXRlUXVldWUuc3RvcmVzO1xuXG4gICAgICAgIGlmIChjaGVja3MgIT09IG51bGwpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoZWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGNoZWNrID0gY2hlY2tzW2ldO1xuICAgICAgICAgICAgdmFyIGdldFNuYXBzaG90ID0gY2hlY2suZ2V0U25hcHNob3Q7XG4gICAgICAgICAgICB2YXIgcmVuZGVyZWRWYWx1ZSA9IGNoZWNrLnZhbHVlO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoIW9iamVjdElzKGdldFNuYXBzaG90KCksIHJlbmRlcmVkVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gRm91bmQgYW4gaW5jb25zaXN0ZW50IHN0b3JlLlxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgLy8gSWYgYGdldFNuYXBzaG90YCB0aHJvd3MsIHJldHVybiBgZmFsc2VgLiBUaGlzIHdpbGwgc2NoZWR1bGVcbiAgICAgICAgICAgICAgLy8gYSByZS1yZW5kZXIsIGFuZCB0aGUgZXJyb3Igd2lsbCBiZSByZXRocm93biBkdXJpbmcgcmVuZGVyLlxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZDtcblxuICAgIGlmIChub2RlLnN1YnRyZWVGbGFncyAmIFN0b3JlQ29uc2lzdGVuY3kgJiYgY2hpbGQgIT09IG51bGwpIHtcbiAgICAgIGNoaWxkLnJldHVybiA9IG5vZGU7XG4gICAgICBub2RlID0gY2hpbGQ7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAobm9kZSA9PT0gZmluaXNoZWRXb3JrKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB3aGlsZSAobm9kZS5zaWJsaW5nID09PSBudWxsKSB7XG4gICAgICBpZiAobm9kZS5yZXR1cm4gPT09IG51bGwgfHwgbm9kZS5yZXR1cm4gPT09IGZpbmlzaGVkV29yaykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgbm9kZSA9IG5vZGUucmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc2libGluZy5yZXR1cm4gPSBub2RlLnJldHVybjtcbiAgICBub2RlID0gbm9kZS5zaWJsaW5nO1xuICB9IC8vIEZsb3cgZG9lc24ndCBrbm93IHRoaXMgaXMgdW5yZWFjaGFibGUsIGJ1dCBlc2xpbnQgZG9lc1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5yZWFjaGFibGVcblxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtYXJrUm9vdFN1c3BlbmRlZCQxKHJvb3QsIHN1c3BlbmRlZExhbmVzKSB7XG4gIC8vIFdoZW4gc3VzcGVuZGluZywgd2Ugc2hvdWxkIGFsd2F5cyBleGNsdWRlIGxhbmVzIHRoYXQgd2VyZSBwaW5nZWQgb3IgKG1vcmVcbiAgLy8gcmFyZWx5LCBzaW5jZSB3ZSB0cnkgdG8gYXZvaWQgaXQpIHVwZGF0ZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UuXG4gIC8vIFRPRE86IExvbCBtYXliZSB0aGVyZSdzIGEgYmV0dGVyIHdheSB0byBmYWN0b3IgdGhpcyBiZXNpZGVzIHRoaXNcbiAgLy8gb2Jub3hpb3VzbHkgbmFtZWQgZnVuY3Rpb24gOilcbiAgc3VzcGVuZGVkTGFuZXMgPSByZW1vdmVMYW5lcyhzdXNwZW5kZWRMYW5lcywgd29ya0luUHJvZ3Jlc3NSb290UGluZ2VkTGFuZXMpO1xuICBzdXNwZW5kZWRMYW5lcyA9IHJlbW92ZUxhbmVzKHN1c3BlbmRlZExhbmVzLCB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyk7XG4gIG1hcmtSb290U3VzcGVuZGVkKHJvb3QsIHN1c3BlbmRlZExhbmVzKTtcbn0gLy8gVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIHN5bmNocm9ub3VzIHRhc2tzIHRoYXQgZG9uJ3QgZ29cbi8vIHRocm91Z2ggU2NoZWR1bGVyXG5cblxuZnVuY3Rpb24gcGVyZm9ybVN5bmNXb3JrT25Sb290KHJvb3QpIHtcbiAge1xuICAgIHN5bmNOZXN0ZWRVcGRhdGVGbGFnKCk7XG4gIH1cblxuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgbm90IGFscmVhZHkgYmUgd29ya2luZy4nKTtcbiAgfVxuXG4gIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgdmFyIGxhbmVzID0gZ2V0TmV4dExhbmVzKHJvb3QsIE5vTGFuZXMpO1xuXG4gIGlmICghaW5jbHVkZXNTb21lTGFuZShsYW5lcywgU3luY0xhbmUpKSB7XG4gICAgLy8gVGhlcmUncyBubyByZW1haW5pbmcgc3luYyB3b3JrIGxlZnQuXG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBleGl0U3RhdHVzID0gcmVuZGVyUm9vdFN5bmMocm9vdCwgbGFuZXMpO1xuXG4gIGlmIChyb290LnRhZyAhPT0gTGVnYWN5Um9vdCAmJiBleGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgIC8vIElmIHNvbWV0aGluZyB0aHJldyBhbiBlcnJvciwgdHJ5IHJlbmRlcmluZyBvbmUgbW9yZSB0aW1lLiBXZSdsbCByZW5kZXJcbiAgICAvLyBzeW5jaHJvbm91c2x5IHRvIGJsb2NrIGNvbmN1cnJlbnQgZGF0YSBtdXRhdGlvbnMsIGFuZCB3ZSdsbCBpbmNsdWRlc1xuICAgIC8vIGFsbCBwZW5kaW5nIHVwZGF0ZXMgYXJlIGluY2x1ZGVkLiBJZiBpdCBzdGlsbCBmYWlscyBhZnRlciB0aGUgc2Vjb25kXG4gICAgLy8gYXR0ZW1wdCwgd2UnbGwgZ2l2ZSB1cCBhbmQgY29tbWl0IHRoZSByZXN1bHRpbmcgdHJlZS5cbiAgICB2YXIgZXJyb3JSZXRyeUxhbmVzID0gZ2V0TGFuZXNUb1JldHJ5U3luY2hyb25vdXNseU9uRXJyb3Iocm9vdCk7XG5cbiAgICBpZiAoZXJyb3JSZXRyeUxhbmVzICE9PSBOb0xhbmVzKSB7XG4gICAgICBsYW5lcyA9IGVycm9yUmV0cnlMYW5lcztcbiAgICAgIGV4aXRTdGF0dXMgPSByZWNvdmVyRnJvbUNvbmN1cnJlbnRFcnJvcihyb290LCBlcnJvclJldHJ5TGFuZXMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChleGl0U3RhdHVzID09PSBSb290RmF0YWxFcnJvcmVkKSB7XG4gICAgdmFyIGZhdGFsRXJyb3IgPSB3b3JrSW5Qcm9ncmVzc1Jvb3RGYXRhbEVycm9yO1xuICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIE5vTGFuZXMpO1xuICAgIG1hcmtSb290U3VzcGVuZGVkJDEocm9vdCwgbGFuZXMpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG4gICAgdGhyb3cgZmF0YWxFcnJvcjtcbiAgfVxuXG4gIGlmIChleGl0U3RhdHVzID09PSBSb290RGlkTm90Q29tcGxldGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jvb3QgZGlkIG5vdCBjb21wbGV0ZS4gVGhpcyBpcyBhIGJ1ZyBpbiBSZWFjdC4nKTtcbiAgfSAvLyBXZSBub3cgaGF2ZSBhIGNvbnNpc3RlbnQgdHJlZS4gQmVjYXVzZSB0aGlzIGlzIGEgc3luYyByZW5kZXIsIHdlXG4gIC8vIHdpbGwgY29tbWl0IGl0IGV2ZW4gaWYgc29tZXRoaW5nIHN1c3BlbmRlZC5cblxuXG4gIHZhciBmaW5pc2hlZFdvcmsgPSByb290LmN1cnJlbnQuYWx0ZXJuYXRlO1xuICByb290LmZpbmlzaGVkV29yayA9IGZpbmlzaGVkV29yaztcbiAgcm9vdC5maW5pc2hlZExhbmVzID0gbGFuZXM7XG4gIGNvbW1pdFJvb3Qocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVjb3ZlcmFibGVFcnJvcnMsIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMpOyAvLyBCZWZvcmUgZXhpdGluZywgbWFrZSBzdXJlIHRoZXJlJ3MgYSBjYWxsYmFjayBzY2hlZHVsZWQgZm9yIHRoZSBuZXh0XG4gIC8vIHBlbmRpbmcgbGV2ZWwuXG5cbiAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIG5vdygpKTtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZsdXNoUm9vdChyb290LCBsYW5lcykge1xuICBpZiAobGFuZXMgIT09IE5vTGFuZXMpIHtcbiAgICBtYXJrUm9vdEVudGFuZ2xlZChyb290LCBtZXJnZUxhbmVzKGxhbmVzLCBTeW5jTGFuZSkpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG5cbiAgICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSA9PT0gTm9Db250ZXh0KSB7XG4gICAgICByZXNldFJlbmRlclRpbWVyKCk7XG4gICAgICBmbHVzaFN5bmNDYWxsYmFja3MoKTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIGJhdGNoZWRVcGRhdGVzJDEoZm4sIGEpIHtcbiAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgZXhlY3V0aW9uQ29udGV4dCB8PSBCYXRjaGVkQ29udGV4dDtcblxuICB0cnkge1xuICAgIHJldHVybiBmbihhKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBleGVjdXRpb25Db250ZXh0ID0gcHJldkV4ZWN1dGlvbkNvbnRleHQ7IC8vIElmIHRoZXJlIHdlcmUgbGVnYWN5IHN5bmMgdXBkYXRlcywgZmx1c2ggdGhlbSBhdCB0aGUgZW5kIG9mIHRoZSBvdXRlclxuICAgIC8vIG1vc3QgYmF0Y2hlZFVwZGF0ZXMtbGlrZSBtZXRob2QuXG5cbiAgICBpZiAoZXhlY3V0aW9uQ29udGV4dCA9PT0gTm9Db250ZXh0ICYmIC8vIFRyZWF0IGBhY3RgIGFzIGlmIGl0J3MgaW5zaWRlIGBiYXRjaGVkVXBkYXRlc2AsIGV2ZW4gaW4gbGVnYWN5IG1vZGUuXG4gICAgISggUmVhY3RDdXJyZW50QWN0UXVldWUkMS5pc0JhdGNoaW5nTGVnYWN5KSkge1xuICAgICAgcmVzZXRSZW5kZXJUaW1lcigpO1xuICAgICAgZmx1c2hTeW5jQ2FsbGJhY2tzT25seUluTGVnYWN5TW9kZSgpO1xuICAgIH1cbiAgfVxufVxuZnVuY3Rpb24gZGlzY3JldGVVcGRhdGVzKGZuLCBhLCBiLCBjLCBkKSB7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcblxuICB0cnkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IG51bGw7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgcmV0dXJuIGZuKGEsIGIsIGMsIGQpO1xuICB9IGZpbmFsbHkge1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcblxuICAgIGlmIChleGVjdXRpb25Db250ZXh0ID09PSBOb0NvbnRleHQpIHtcbiAgICAgIHJlc2V0UmVuZGVyVGltZXIoKTtcbiAgICB9XG4gIH1cbn0gLy8gT3ZlcmxvYWQgdGhlIGRlZmluaXRpb24gdG8gdGhlIHR3byB2YWxpZCBzaWduYXR1cmVzLlxuLy8gV2FybmluZywgdGhpcyBvcHRzLW91dCBvZiBjaGVja2luZyB0aGUgZnVuY3Rpb24gYm9keS5cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuZnVuY3Rpb24gZmx1c2hTeW5jKGZuKSB7XG4gIC8vIEluIGxlZ2FjeSBtb2RlLCB3ZSBmbHVzaCBwZW5kaW5nIHBhc3NpdmUgZWZmZWN0cyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZVxuICAvLyBuZXh0IGV2ZW50LCBub3QgYXQgdGhlIGVuZCBvZiB0aGUgcHJldmlvdXMgb25lLlxuICBpZiAocm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgIT09IG51bGwgJiYgcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMudGFnID09PSBMZWdhY3lSb290ICYmIChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgPT09IE5vQ29udGV4dCkge1xuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgfVxuXG4gIHZhciBwcmV2RXhlY3V0aW9uQ29udGV4dCA9IGV4ZWN1dGlvbkNvbnRleHQ7XG4gIGV4ZWN1dGlvbkNvbnRleHQgfD0gQmF0Y2hlZENvbnRleHQ7XG4gIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcbiAgdmFyIHByZXZpb3VzUHJpb3JpdHkgPSBnZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoKTtcblxuICB0cnkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IG51bGw7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG5cbiAgICBpZiAoZm4pIHtcbiAgICAgIHJldHVybiBmbigpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBzZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkocHJldmlvdXNQcmlvcml0eSk7XG4gICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247XG4gICAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0OyAvLyBGbHVzaCB0aGUgaW1tZWRpYXRlIGNhbGxiYWNrcyB0aGF0IHdlcmUgc2NoZWR1bGVkIGR1cmluZyB0aGlzIGJhdGNoLlxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIHdpbGwgaGFwcGVuIGV2ZW4gaWYgYmF0Y2hlZFVwZGF0ZXMgaXMgaGlnaGVyIHVwXG4gICAgLy8gdGhlIHN0YWNrLlxuXG4gICAgaWYgKChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgPT09IE5vQ29udGV4dCkge1xuICAgICAgZmx1c2hTeW5jQ2FsbGJhY2tzKCk7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBpc0FscmVhZHlSZW5kZXJpbmcoKSB7XG4gIC8vIFVzZWQgYnkgdGhlIHJlbmRlcmVyIHRvIHByaW50IGEgd2FybmluZyBpZiBjZXJ0YWluIEFQSXMgYXJlIGNhbGxlZCBmcm9tXG4gIC8vIHRoZSB3cm9uZyBjb250ZXh0LlxuICByZXR1cm4gIChleGVjdXRpb25Db250ZXh0ICYgKFJlbmRlckNvbnRleHQgfCBDb21taXRDb250ZXh0KSkgIT09IE5vQ29udGV4dDtcbn1cbmZ1bmN0aW9uIHB1c2hSZW5kZXJMYW5lcyhmaWJlciwgbGFuZXMpIHtcbiAgcHVzaChzdWJ0cmVlUmVuZGVyTGFuZXNDdXJzb3IsIHN1YnRyZWVSZW5kZXJMYW5lcywgZmliZXIpO1xuICBzdWJ0cmVlUmVuZGVyTGFuZXMgPSBtZXJnZUxhbmVzKHN1YnRyZWVSZW5kZXJMYW5lcywgbGFuZXMpO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzID0gbWVyZ2VMYW5lcyh3b3JrSW5Qcm9ncmVzc1Jvb3RJbmNsdWRlZExhbmVzLCBsYW5lcyk7XG59XG5mdW5jdGlvbiBwb3BSZW5kZXJMYW5lcyhmaWJlcikge1xuICBzdWJ0cmVlUmVuZGVyTGFuZXMgPSBzdWJ0cmVlUmVuZGVyTGFuZXNDdXJzb3IuY3VycmVudDtcbiAgcG9wKHN1YnRyZWVSZW5kZXJMYW5lc0N1cnNvciwgZmliZXIpO1xufVxuXG5mdW5jdGlvbiBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBsYW5lcykge1xuICByb290LmZpbmlzaGVkV29yayA9IG51bGw7XG4gIHJvb3QuZmluaXNoZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHZhciB0aW1lb3V0SGFuZGxlID0gcm9vdC50aW1lb3V0SGFuZGxlO1xuXG4gIGlmICh0aW1lb3V0SGFuZGxlICE9PSBub1RpbWVvdXQpIHtcbiAgICAvLyBUaGUgcm9vdCBwcmV2aW91cyBzdXNwZW5kZWQgYW5kIHNjaGVkdWxlZCBhIHRpbWVvdXQgdG8gY29tbWl0IGEgZmFsbGJhY2tcbiAgICAvLyBzdGF0ZS4gTm93IHRoYXQgd2UgaGF2ZSBhZGRpdGlvbmFsIHdvcmssIGNhbmNlbCB0aGUgdGltZW91dC5cbiAgICByb290LnRpbWVvdXRIYW5kbGUgPSBub1RpbWVvdXQ7IC8vICRGbG93Rml4TWUgQ29tcGxhaW5zIG5vVGltZW91dCBpcyBub3QgYSBUaW1lb3V0SUQsIGRlc3BpdGUgdGhlIGNoZWNrIGFib3ZlXG5cbiAgICBjYW5jZWxUaW1lb3V0KHRpbWVvdXRIYW5kbGUpO1xuICB9XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzICE9PSBudWxsKSB7XG4gICAgdmFyIGludGVycnVwdGVkV29yayA9IHdvcmtJblByb2dyZXNzLnJldHVybjtcblxuICAgIHdoaWxlIChpbnRlcnJ1cHRlZFdvcmsgIT09IG51bGwpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gaW50ZXJydXB0ZWRXb3JrLmFsdGVybmF0ZTtcbiAgICAgIHVud2luZEludGVycnVwdGVkV29yayhjdXJyZW50LCBpbnRlcnJ1cHRlZFdvcmspO1xuICAgICAgaW50ZXJydXB0ZWRXb3JrID0gaW50ZXJydXB0ZWRXb3JrLnJldHVybjtcbiAgICB9XG4gIH1cblxuICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSByb290O1xuICB2YXIgcm9vdFdvcmtJblByb2dyZXNzID0gY3JlYXRlV29ya0luUHJvZ3Jlc3Mocm9vdC5jdXJyZW50LCBudWxsKTtcbiAgd29ya0luUHJvZ3Jlc3MgPSByb290V29ya0luUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gc3VidHJlZVJlbmRlckxhbmVzID0gd29ya0luUHJvZ3Jlc3NSb290SW5jbHVkZWRMYW5lcyA9IGxhbmVzO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdEluUHJvZ3Jlc3M7XG4gIHdvcmtJblByb2dyZXNzUm9vdEZhdGFsRXJyb3IgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RTa2lwcGVkTGFuZXMgPSBOb0xhbmVzO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHdvcmtJblByb2dyZXNzUm9vdFBpbmdlZExhbmVzID0gTm9MYW5lcztcbiAgd29ya0luUHJvZ3Jlc3NSb290Q29uY3VycmVudEVycm9ycyA9IG51bGw7XG4gIHdvcmtJblByb2dyZXNzUm9vdFJlY292ZXJhYmxlRXJyb3JzID0gbnVsbDtcbiAgZmluaXNoUXVldWVpbmdDb25jdXJyZW50VXBkYXRlcygpO1xuXG4gIHtcbiAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5kaXNjYXJkUGVuZGluZ1dhcm5pbmdzKCk7XG4gIH1cblxuICByZXR1cm4gcm9vdFdvcmtJblByb2dyZXNzO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVFcnJvcihyb290LCB0aHJvd25WYWx1ZSkge1xuICBkbyB7XG4gICAgdmFyIGVycm9yZWRXb3JrID0gd29ya0luUHJvZ3Jlc3M7XG5cbiAgICB0cnkge1xuICAgICAgLy8gUmVzZXQgbW9kdWxlLWxldmVsIHN0YXRlIHRoYXQgd2FzIHNldCBkdXJpbmcgdGhlIHJlbmRlciBwaGFzZS5cbiAgICAgIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICAgICAgcmVzZXRIb29rc0FmdGVyVGhyb3coKTtcbiAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7IC8vIFRPRE86IEkgZm91bmQgYW5kIGFkZGVkIHRoaXMgbWlzc2luZyBsaW5lIHdoaWxlIGludmVzdGlnYXRpbmcgYVxuICAgICAgLy8gc2VwYXJhdGUgaXNzdWUuIFdyaXRlIGEgcmVncmVzc2lvbiB0ZXN0IHVzaW5nIHN0cmluZyByZWZzLlxuXG4gICAgICBSZWFjdEN1cnJlbnRPd25lciQyLmN1cnJlbnQgPSBudWxsO1xuXG4gICAgICBpZiAoZXJyb3JlZFdvcmsgPT09IG51bGwgfHwgZXJyb3JlZFdvcmsucmV0dXJuID09PSBudWxsKSB7XG4gICAgICAgIC8vIEV4cGVjdGVkIHRvIGJlIHdvcmtpbmcgb24gYSBub24tcm9vdCBmaWJlci4gVGhpcyBpcyBhIGZhdGFsIGVycm9yXG4gICAgICAgIC8vIGJlY2F1c2UgdGhlcmUncyBubyBhbmNlc3RvciB0aGF0IGNhbiBoYW5kbGUgaXQ7IHRoZSByb290IGlzXG4gICAgICAgIC8vIHN1cHBvc2VkIHRvIGNhcHR1cmUgYWxsIGVycm9ycyB0aGF0IHdlcmVuJ3QgY2F1Z2h0IGJ5IGFuIGVycm9yXG4gICAgICAgIC8vIGJvdW5kYXJ5LlxuICAgICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdEZhdGFsRXJyb3JlZDtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3NSb290RmF0YWxFcnJvciA9IHRocm93blZhbHVlOyAvLyBTZXQgYHdvcmtJblByb2dyZXNzYCB0byBudWxsLiBUaGlzIHJlcHJlc2VudHMgYWR2YW5jaW5nIHRvIHRoZSBuZXh0XG4gICAgICAgIC8vIHNpYmxpbmcsIG9yIHRoZSBwYXJlbnQgaWYgdGhlcmUgYXJlIG5vIHNpYmxpbmdzLiBCdXQgc2luY2UgdGhlIHJvb3RcbiAgICAgICAgLy8gaGFzIG5vIHNpYmxpbmdzIG5vciBhIHBhcmVudCwgd2Ugc2V0IGl0IHRvIG51bGwuIFVzdWFsbHkgdGhpcyBpc1xuICAgICAgICAvLyBoYW5kbGVkIGJ5IGBjb21wbGV0ZVVuaXRPZldvcmtgIG9yIGB1bndpbmRXb3JrYCwgYnV0IHNpbmNlIHdlJ3JlXG4gICAgICAgIC8vIGludGVudGlvbmFsbHkgbm90IGNhbGxpbmcgdGhvc2UsIHdlIG5lZWQgc2V0IGl0IGhlcmUuXG4gICAgICAgIC8vIFRPRE86IENvbnNpZGVyIGNhbGxpbmcgYHVud2luZFdvcmtgIHRvIHBvcCB0aGUgY29udGV4dHMuXG5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3MgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChlbmFibGVQcm9maWxlclRpbWVyICYmIGVycm9yZWRXb3JrLm1vZGUgJiBQcm9maWxlTW9kZSkge1xuICAgICAgICAvLyBSZWNvcmQgdGhlIHRpbWUgc3BlbnQgcmVuZGVyaW5nIGJlZm9yZSBhbiBlcnJvciB3YXMgdGhyb3duLiBUaGlzXG4gICAgICAgIC8vIGF2b2lkcyBpbmFjY3VyYXRlIFByb2ZpbGVyIGR1cmF0aW9ucyBpbiB0aGUgY2FzZSBvZiBhXG4gICAgICAgIC8vIHN1c3BlbmRlZCByZW5kZXIuXG4gICAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoZXJyb3JlZFdvcmssIHRydWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW5hYmxlU2NoZWR1bGluZ1Byb2ZpbGVyKSB7XG4gICAgICAgIG1hcmtDb21wb25lbnRSZW5kZXJTdG9wcGVkKCk7XG5cbiAgICAgICAgaWYgKHRocm93blZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB0aHJvd25WYWx1ZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHRocm93blZhbHVlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB2YXIgd2FrZWFibGUgPSB0aHJvd25WYWx1ZTtcbiAgICAgICAgICBtYXJrQ29tcG9uZW50U3VzcGVuZGVkKGVycm9yZWRXb3JrLCB3YWtlYWJsZSwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1hcmtDb21wb25lbnRFcnJvcmVkKGVycm9yZWRXb3JrLCB0aHJvd25WYWx1ZSwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRocm93RXhjZXB0aW9uKHJvb3QsIGVycm9yZWRXb3JrLnJldHVybiwgZXJyb3JlZFdvcmssIHRocm93blZhbHVlLCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICBjb21wbGV0ZVVuaXRPZldvcmsoZXJyb3JlZFdvcmspO1xuICAgIH0gY2F0Y2ggKHlldEFub3RoZXJUaHJvd25WYWx1ZSkge1xuICAgICAgLy8gU29tZXRoaW5nIGluIHRoZSByZXR1cm4gcGF0aCBhbHNvIHRocmV3LlxuICAgICAgdGhyb3duVmFsdWUgPSB5ZXRBbm90aGVyVGhyb3duVmFsdWU7XG5cbiAgICAgIGlmICh3b3JrSW5Qcm9ncmVzcyA9PT0gZXJyb3JlZFdvcmsgJiYgZXJyb3JlZFdvcmsgIT09IG51bGwpIHtcbiAgICAgICAgLy8gSWYgdGhpcyBib3VuZGFyeSBoYXMgYWxyZWFkeSBlcnJvcmVkLCB0aGVuIHdlIGhhZCB0cm91YmxlIHByb2Nlc3NpbmdcbiAgICAgICAgLy8gdGhlIGVycm9yLiBCdWJibGUgaXQgdG8gdGhlIG5leHQgYm91bmRhcnkuXG4gICAgICAgIGVycm9yZWRXb3JrID0gZXJyb3JlZFdvcmsucmV0dXJuO1xuICAgICAgICB3b3JrSW5Qcm9ncmVzcyA9IGVycm9yZWRXb3JrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3JlZFdvcmsgPSB3b3JrSW5Qcm9ncmVzcztcbiAgICAgIH1cblxuICAgICAgY29udGludWU7XG4gICAgfSAvLyBSZXR1cm4gdG8gdGhlIG5vcm1hbCB3b3JrIGxvb3AuXG5cblxuICAgIHJldHVybjtcbiAgfSB3aGlsZSAodHJ1ZSk7XG59XG5cbmZ1bmN0aW9uIHB1c2hEaXNwYXRjaGVyKCkge1xuICB2YXIgcHJldkRpc3BhdGNoZXIgPSBSZWFjdEN1cnJlbnREaXNwYXRjaGVyJDIuY3VycmVudDtcbiAgUmVhY3RDdXJyZW50RGlzcGF0Y2hlciQyLmN1cnJlbnQgPSBDb250ZXh0T25seURpc3BhdGNoZXI7XG5cbiAgaWYgKHByZXZEaXNwYXRjaGVyID09PSBudWxsKSB7XG4gICAgLy8gVGhlIFJlYWN0IGlzb21vcnBoaWMgcGFja2FnZSBkb2VzIG5vdCBpbmNsdWRlIGEgZGVmYXVsdCBkaXNwYXRjaGVyLlxuICAgIC8vIEluc3RlYWQgdGhlIGZpcnN0IHJlbmRlcmVyIHdpbGwgbGF6aWx5IGF0dGFjaCBvbmUsIGluIG9yZGVyIHRvIGdpdmVcbiAgICAvLyBuaWNlciBlcnJvciBtZXNzYWdlcy5cbiAgICByZXR1cm4gQ29udGV4dE9ubHlEaXNwYXRjaGVyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBwcmV2RGlzcGF0Y2hlcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBwb3BEaXNwYXRjaGVyKHByZXZEaXNwYXRjaGVyKSB7XG4gIFJlYWN0Q3VycmVudERpc3BhdGNoZXIkMi5jdXJyZW50ID0gcHJldkRpc3BhdGNoZXI7XG59XG5cbmZ1bmN0aW9uIG1hcmtDb21taXRUaW1lT2ZGYWxsYmFjaygpIHtcbiAgZ2xvYmFsTW9zdFJlY2VudEZhbGxiYWNrVGltZSA9IG5vdygpO1xufVxuZnVuY3Rpb24gbWFya1NraXBwZWRVcGRhdGVMYW5lcyhsYW5lKSB7XG4gIHdvcmtJblByb2dyZXNzUm9vdFNraXBwZWRMYW5lcyA9IG1lcmdlTGFuZXMobGFuZSwgd29ya0luUHJvZ3Jlc3NSb290U2tpcHBlZExhbmVzKTtcbn1cbmZ1bmN0aW9uIHJlbmRlckRpZFN1c3BlbmQoKSB7XG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290SW5Qcm9ncmVzcykge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290U3VzcGVuZGVkO1xuICB9XG59XG5mdW5jdGlvbiByZW5kZXJEaWRTdXNwZW5kRGVsYXlJZlBvc3NpYmxlKCkge1xuICBpZiAod29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdEluUHJvZ3Jlc3MgfHwgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZCB8fCB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID09PSBSb290RXJyb3JlZCkge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPSBSb290U3VzcGVuZGVkV2l0aERlbGF5O1xuICB9IC8vIENoZWNrIGlmIHRoZXJlIGFyZSB1cGRhdGVzIHRoYXQgd2Ugc2tpcHBlZCB0cmVlIHRoYXQgbWlnaHQgaGF2ZSB1bmJsb2NrZWRcbiAgLy8gdGhpcyByZW5kZXIuXG5cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290ICE9PSBudWxsICYmIChpbmNsdWRlc05vbklkbGVXb3JrKHdvcmtJblByb2dyZXNzUm9vdFNraXBwZWRMYW5lcykgfHwgaW5jbHVkZXNOb25JZGxlV29yayh3b3JrSW5Qcm9ncmVzc1Jvb3RJbnRlcmxlYXZlZFVwZGF0ZWRMYW5lcykpKSB7XG4gICAgLy8gTWFyayB0aGUgY3VycmVudCByZW5kZXIgYXMgc3VzcGVuZGVkIHNvIHRoYXQgd2Ugc3dpdGNoIHRvIHdvcmtpbmcgb25cbiAgICAvLyB0aGUgdXBkYXRlcyB0aGF0IHdlcmUgc2tpcHBlZC4gVXN1YWxseSB3ZSBvbmx5IHN1c3BlbmQgYXQgdGhlIGVuZCBvZlxuICAgIC8vIHRoZSByZW5kZXIgcGhhc2UuXG4gICAgLy8gVE9ETzogV2Ugc2hvdWxkIHByb2JhYmx5IGFsd2F5cyBtYXJrIHRoZSByb290IGFzIHN1c3BlbmRlZCBpbW1lZGlhdGVseVxuICAgIC8vIChpbnNpZGUgdGhpcyBmdW5jdGlvbiksIHNpbmNlIGJ5IHN1c3BlbmRpbmcgYXQgdGhlIGVuZCBvZiB0aGUgcmVuZGVyXG4gICAgLy8gcGhhc2UgaW50cm9kdWNlcyBhIHBvdGVudGlhbCBtaXN0YWtlIHdoZXJlIHdlIHN1c3BlbmQgbGFuZXMgdGhhdCB3ZXJlXG4gICAgLy8gcGluZ2VkIG9yIHVwZGF0ZWQgd2hpbGUgd2Ugd2VyZSByZW5kZXJpbmcuXG4gICAgbWFya1Jvb3RTdXNwZW5kZWQkMSh3b3JrSW5Qcm9ncmVzc1Jvb3QsIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKTtcbiAgfVxufVxuZnVuY3Rpb24gcmVuZGVyRGlkRXJyb3IoZXJyb3IpIHtcbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgIT09IFJvb3RTdXNwZW5kZWRXaXRoRGVsYXkpIHtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzID0gUm9vdEVycm9yZWQ7XG4gIH1cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290Q29uY3VycmVudEVycm9ycyA9PT0gbnVsbCkge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdENvbmN1cnJlbnRFcnJvcnMgPSBbZXJyb3JdO1xuICB9IGVsc2Uge1xuICAgIHdvcmtJblByb2dyZXNzUm9vdENvbmN1cnJlbnRFcnJvcnMucHVzaChlcnJvcik7XG4gIH1cbn0gLy8gQ2FsbGVkIGR1cmluZyByZW5kZXIgdG8gZGV0ZXJtaW5lIGlmIGFueXRoaW5nIGhhcyBzdXNwZW5kZWQuXG4vLyBSZXR1cm5zIGZhbHNlIGlmIHdlJ3JlIG5vdCBzdXJlLlxuXG5mdW5jdGlvbiByZW5kZXJIYXNOb3RTdXNwZW5kZWRZZXQoKSB7XG4gIC8vIElmIHNvbWV0aGluZyBlcnJvcmVkIG9yIGNvbXBsZXRlZCwgd2UgY2FuJ3QgcmVhbGx5IGJlIHN1cmUsXG4gIC8vIHNvIHRob3NlIGFyZSBmYWxzZS5cbiAgcmV0dXJuIHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RJblByb2dyZXNzO1xufVxuXG5mdW5jdGlvbiByZW5kZXJSb290U3luYyhyb290LCBsYW5lcykge1xuICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICBleGVjdXRpb25Db250ZXh0IHw9IFJlbmRlckNvbnRleHQ7XG4gIHZhciBwcmV2RGlzcGF0Y2hlciA9IHB1c2hEaXNwYXRjaGVyKCk7IC8vIElmIHRoZSByb290IG9yIGxhbmVzIGhhdmUgY2hhbmdlZCwgdGhyb3cgb3V0IHRoZSBleGlzdGluZyBzdGFja1xuICAvLyBhbmQgcHJlcGFyZSBhIGZyZXNoIG9uZS4gT3RoZXJ3aXNlIHdlJ2xsIGNvbnRpbnVlIHdoZXJlIHdlIGxlZnQgb2ZmLlxuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3QgIT09IHJvb3QgfHwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMgIT09IGxhbmVzKSB7XG4gICAge1xuICAgICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICAgIHZhciBtZW1vaXplZFVwZGF0ZXJzID0gcm9vdC5tZW1vaXplZFVwZGF0ZXJzO1xuXG4gICAgICAgIGlmIChtZW1vaXplZFVwZGF0ZXJzLnNpemUgPiAwKSB7XG4gICAgICAgICAgcmVzdG9yZVBlbmRpbmdVcGRhdGVycyhyb290LCB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyk7XG4gICAgICAgICAgbWVtb2l6ZWRVcGRhdGVycy5jbGVhcigpO1xuICAgICAgICB9IC8vIEF0IHRoaXMgcG9pbnQsIG1vdmUgRmliZXJzIHRoYXQgc2NoZWR1bGVkIHRoZSB1cGNvbWluZyB3b3JrIGZyb20gdGhlIE1hcCB0byB0aGUgU2V0LlxuICAgICAgICAvLyBJZiB3ZSBiYWlsb3V0IG9uIHRoaXMgd29yaywgd2UnbGwgbW92ZSB0aGVtIGJhY2sgKGxpa2UgYWJvdmUpLlxuICAgICAgICAvLyBJdCdzIGltcG9ydGFudCB0byBtb3ZlIHRoZW0gbm93IGluIGNhc2UgdGhlIHdvcmsgc3Bhd25zIG1vcmUgd29yayBhdCB0aGUgc2FtZSBwcmlvcml0eSB3aXRoIGRpZmZlcmVudCB1cGRhdGVycy5cbiAgICAgICAgLy8gVGhhdCB3YXkgd2UgY2FuIGtlZXAgdGhlIGN1cnJlbnQgdXBkYXRlIGFuZCBmdXR1cmUgdXBkYXRlcyBzZXBhcmF0ZS5cblxuXG4gICAgICAgIG1vdmVQZW5kaW5nRmliZXJzVG9NZW1vaXplZChyb290LCBsYW5lcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgd29ya0luUHJvZ3Jlc3NUcmFuc2l0aW9ucyA9IGdldFRyYW5zaXRpb25zRm9yTGFuZXMoKTtcbiAgICBwcmVwYXJlRnJlc2hTdGFjayhyb290LCBsYW5lcyk7XG4gIH1cblxuICB7XG4gICAgbWFya1JlbmRlclN0YXJ0ZWQobGFuZXMpO1xuICB9XG5cbiAgZG8ge1xuICAgIHRyeSB7XG4gICAgICB3b3JrTG9vcFN5bmMoKTtcbiAgICAgIGJyZWFrO1xuICAgIH0gY2F0Y2ggKHRocm93blZhbHVlKSB7XG4gICAgICBoYW5kbGVFcnJvcihyb290LCB0aHJvd25WYWx1ZSk7XG4gICAgfVxuICB9IHdoaWxlICh0cnVlKTtcblxuICByZXNldENvbnRleHREZXBlbmRlbmNpZXMoKTtcbiAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0O1xuICBwb3BEaXNwYXRjaGVyKHByZXZEaXNwYXRjaGVyKTtcblxuICBpZiAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpIHtcbiAgICAvLyBUaGlzIGlzIGEgc3luYyByZW5kZXIsIHNvIHdlIHNob3VsZCBoYXZlIGZpbmlzaGVkIHRoZSB3aG9sZSB0cmVlLlxuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbW1pdCBhbiBpbmNvbXBsZXRlIHJvb3QuIFRoaXMgZXJyb3IgaXMgbGlrZWx5IGNhdXNlZCBieSBhICcgKyAnYnVnIGluIFJlYWN0LiBQbGVhc2UgZmlsZSBhbiBpc3N1ZS4nKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrUmVuZGVyU3RvcHBlZCgpO1xuICB9IC8vIFNldCB0aGlzIHRvIG51bGwgdG8gaW5kaWNhdGUgdGhlcmUncyBubyBpbi1wcm9ncmVzcyByZW5kZXIuXG5cblxuICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xuICB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzO1xufSAvLyBUaGUgd29yayBsb29wIGlzIGFuIGV4dHJlbWVseSBob3QgcGF0aC4gVGVsbCBDbG9zdXJlIG5vdCB0byBpbmxpbmUgaXQuXG5cbi8qKiBAbm9pbmxpbmUgKi9cblxuXG5mdW5jdGlvbiB3b3JrTG9vcFN5bmMoKSB7XG4gIC8vIEFscmVhZHkgdGltZWQgb3V0LCBzbyBwZXJmb3JtIHdvcmsgd2l0aG91dCBjaGVja2luZyBpZiB3ZSBuZWVkIHRvIHlpZWxkLlxuICB3aGlsZSAod29ya0luUHJvZ3Jlc3MgIT09IG51bGwpIHtcbiAgICBwZXJmb3JtVW5pdE9mV29yayh3b3JrSW5Qcm9ncmVzcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyUm9vdENvbmN1cnJlbnQocm9vdCwgbGFuZXMpIHtcbiAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgZXhlY3V0aW9uQ29udGV4dCB8PSBSZW5kZXJDb250ZXh0O1xuICB2YXIgcHJldkRpc3BhdGNoZXIgPSBwdXNoRGlzcGF0Y2hlcigpOyAvLyBJZiB0aGUgcm9vdCBvciBsYW5lcyBoYXZlIGNoYW5nZWQsIHRocm93IG91dCB0aGUgZXhpc3Rpbmcgc3RhY2tcbiAgLy8gYW5kIHByZXBhcmUgYSBmcmVzaCBvbmUuIE90aGVyd2lzZSB3ZSdsbCBjb250aW51ZSB3aGVyZSB3ZSBsZWZ0IG9mZi5cblxuICBpZiAod29ya0luUHJvZ3Jlc3NSb290ICE9PSByb290IHx8IHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzICE9PSBsYW5lcykge1xuICAgIHtcbiAgICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgICB2YXIgbWVtb2l6ZWRVcGRhdGVycyA9IHJvb3QubWVtb2l6ZWRVcGRhdGVycztcblxuICAgICAgICBpZiAobWVtb2l6ZWRVcGRhdGVycy5zaXplID4gMCkge1xuICAgICAgICAgIHJlc3RvcmVQZW5kaW5nVXBkYXRlcnMocm9vdCwgd29ya0luUHJvZ3Jlc3NSb290UmVuZGVyTGFuZXMpO1xuICAgICAgICAgIG1lbW9pemVkVXBkYXRlcnMuY2xlYXIoKTtcbiAgICAgICAgfSAvLyBBdCB0aGlzIHBvaW50LCBtb3ZlIEZpYmVycyB0aGF0IHNjaGVkdWxlZCB0aGUgdXBjb21pbmcgd29yayBmcm9tIHRoZSBNYXAgdG8gdGhlIFNldC5cbiAgICAgICAgLy8gSWYgd2UgYmFpbG91dCBvbiB0aGlzIHdvcmssIHdlJ2xsIG1vdmUgdGhlbSBiYWNrIChsaWtlIGFib3ZlKS5cbiAgICAgICAgLy8gSXQncyBpbXBvcnRhbnQgdG8gbW92ZSB0aGVtIG5vdyBpbiBjYXNlIHRoZSB3b3JrIHNwYXducyBtb3JlIHdvcmsgYXQgdGhlIHNhbWUgcHJpb3JpdHkgd2l0aCBkaWZmZXJlbnQgdXBkYXRlcnMuXG4gICAgICAgIC8vIFRoYXQgd2F5IHdlIGNhbiBrZWVwIHRoZSBjdXJyZW50IHVwZGF0ZSBhbmQgZnV0dXJlIHVwZGF0ZXMgc2VwYXJhdGUuXG5cblxuICAgICAgICBtb3ZlUGVuZGluZ0ZpYmVyc1RvTWVtb2l6ZWQocm9vdCwgbGFuZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMgPSBnZXRUcmFuc2l0aW9uc0ZvckxhbmVzKCk7XG4gICAgcmVzZXRSZW5kZXJUaW1lcigpO1xuICAgIHByZXBhcmVGcmVzaFN0YWNrKHJvb3QsIGxhbmVzKTtcbiAgfVxuXG4gIHtcbiAgICBtYXJrUmVuZGVyU3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICBkbyB7XG4gICAgdHJ5IHtcbiAgICAgIHdvcmtMb29wQ29uY3VycmVudCgpO1xuICAgICAgYnJlYWs7XG4gICAgfSBjYXRjaCAodGhyb3duVmFsdWUpIHtcbiAgICAgIGhhbmRsZUVycm9yKHJvb3QsIHRocm93blZhbHVlKTtcbiAgICB9XG4gIH0gd2hpbGUgKHRydWUpO1xuXG4gIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICBwb3BEaXNwYXRjaGVyKHByZXZEaXNwYXRjaGVyKTtcbiAgZXhlY3V0aW9uQ29udGV4dCA9IHByZXZFeGVjdXRpb25Db250ZXh0O1xuXG5cbiAgaWYgKHdvcmtJblByb2dyZXNzICE9PSBudWxsKSB7XG4gICAgLy8gU3RpbGwgd29yayByZW1haW5pbmcuXG4gICAge1xuICAgICAgbWFya1JlbmRlcllpZWxkZWQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUm9vdEluUHJvZ3Jlc3M7XG4gIH0gZWxzZSB7XG4gICAgLy8gQ29tcGxldGVkIHRoZSB0cmVlLlxuICAgIHtcbiAgICAgIG1hcmtSZW5kZXJTdG9wcGVkKCk7XG4gICAgfSAvLyBTZXQgdGhpcyB0byBudWxsIHRvIGluZGljYXRlIHRoZXJlJ3Mgbm8gaW4tcHJvZ3Jlc3MgcmVuZGVyLlxuXG5cbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzID0gTm9MYW5lczsgLy8gUmV0dXJuIHRoZSBmaW5hbCBleGl0IHN0YXR1cy5cblxuICAgIHJldHVybiB3b3JrSW5Qcm9ncmVzc1Jvb3RFeGl0U3RhdHVzO1xuICB9XG59XG4vKiogQG5vaW5saW5lICovXG5cblxuZnVuY3Rpb24gd29ya0xvb3BDb25jdXJyZW50KCkge1xuICAvLyBQZXJmb3JtIHdvcmsgdW50aWwgU2NoZWR1bGVyIGFza3MgdXMgdG8geWllbGRcbiAgd2hpbGUgKHdvcmtJblByb2dyZXNzICE9PSBudWxsICYmICFzaG91bGRZaWVsZCgpKSB7XG4gICAgcGVyZm9ybVVuaXRPZldvcmsod29ya0luUHJvZ3Jlc3MpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBlcmZvcm1Vbml0T2ZXb3JrKHVuaXRPZldvcmspIHtcbiAgLy8gVGhlIGN1cnJlbnQsIGZsdXNoZWQsIHN0YXRlIG9mIHRoaXMgZmliZXIgaXMgdGhlIGFsdGVybmF0ZS4gSWRlYWxseVxuICAvLyBub3RoaW5nIHNob3VsZCByZWx5IG9uIHRoaXMsIGJ1dCByZWx5aW5nIG9uIGl0IGhlcmUgbWVhbnMgdGhhdCB3ZSBkb24ndFxuICAvLyBuZWVkIGFuIGFkZGl0aW9uYWwgZmllbGQgb24gdGhlIHdvcmsgaW4gcHJvZ3Jlc3MuXG4gIHZhciBjdXJyZW50ID0gdW5pdE9mV29yay5hbHRlcm5hdGU7XG4gIHNldEN1cnJlbnRGaWJlcih1bml0T2ZXb3JrKTtcbiAgdmFyIG5leHQ7XG5cbiAgaWYgKCAodW5pdE9mV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICBzdGFydFByb2ZpbGVyVGltZXIodW5pdE9mV29yayk7XG4gICAgbmV4dCA9IGJlZ2luV29yayQxKGN1cnJlbnQsIHVuaXRPZldvcmssIHN1YnRyZWVSZW5kZXJMYW5lcyk7XG4gICAgc3RvcFByb2ZpbGVyVGltZXJJZlJ1bm5pbmdBbmRSZWNvcmREZWx0YSh1bml0T2ZXb3JrLCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBuZXh0ID0gYmVnaW5Xb3JrJDEoY3VycmVudCwgdW5pdE9mV29yaywgc3VidHJlZVJlbmRlckxhbmVzKTtcbiAgfVxuXG4gIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gIHVuaXRPZldvcmsubWVtb2l6ZWRQcm9wcyA9IHVuaXRPZldvcmsucGVuZGluZ1Byb3BzO1xuXG4gIGlmIChuZXh0ID09PSBudWxsKSB7XG4gICAgLy8gSWYgdGhpcyBkb2Vzbid0IHNwYXduIG5ldyB3b3JrLCBjb21wbGV0ZSB0aGUgY3VycmVudCB3b3JrLlxuICAgIGNvbXBsZXRlVW5pdE9mV29yayh1bml0T2ZXb3JrKTtcbiAgfSBlbHNlIHtcbiAgICB3b3JrSW5Qcm9ncmVzcyA9IG5leHQ7XG4gIH1cblxuICBSZWFjdEN1cnJlbnRPd25lciQyLmN1cnJlbnQgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBjb21wbGV0ZVVuaXRPZldvcmsodW5pdE9mV29yaykge1xuICAvLyBBdHRlbXB0IHRvIGNvbXBsZXRlIHRoZSBjdXJyZW50IHVuaXQgb2Ygd29yaywgdGhlbiBtb3ZlIHRvIHRoZSBuZXh0XG4gIC8vIHNpYmxpbmcuIElmIHRoZXJlIGFyZSBubyBtb3JlIHNpYmxpbmdzLCByZXR1cm4gdG8gdGhlIHBhcmVudCBmaWJlci5cbiAgdmFyIGNvbXBsZXRlZFdvcmsgPSB1bml0T2ZXb3JrO1xuXG4gIGRvIHtcbiAgICAvLyBUaGUgY3VycmVudCwgZmx1c2hlZCwgc3RhdGUgb2YgdGhpcyBmaWJlciBpcyB0aGUgYWx0ZXJuYXRlLiBJZGVhbGx5XG4gICAgLy8gbm90aGluZyBzaG91bGQgcmVseSBvbiB0aGlzLCBidXQgcmVseWluZyBvbiBpdCBoZXJlIG1lYW5zIHRoYXQgd2UgZG9uJ3RcbiAgICAvLyBuZWVkIGFuIGFkZGl0aW9uYWwgZmllbGQgb24gdGhlIHdvcmsgaW4gcHJvZ3Jlc3MuXG4gICAgdmFyIGN1cnJlbnQgPSBjb21wbGV0ZWRXb3JrLmFsdGVybmF0ZTtcbiAgICB2YXIgcmV0dXJuRmliZXIgPSBjb21wbGV0ZWRXb3JrLnJldHVybjsgLy8gQ2hlY2sgaWYgdGhlIHdvcmsgY29tcGxldGVkIG9yIGlmIHNvbWV0aGluZyB0aHJldy5cblxuICAgIGlmICgoY29tcGxldGVkV29yay5mbGFncyAmIEluY29tcGxldGUpID09PSBOb0ZsYWdzKSB7XG4gICAgICBzZXRDdXJyZW50RmliZXIoY29tcGxldGVkV29yayk7XG4gICAgICB2YXIgbmV4dCA9IHZvaWQgMDtcblxuICAgICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpID09PSBOb01vZGUpIHtcbiAgICAgICAgbmV4dCA9IGNvbXBsZXRlV29yayhjdXJyZW50LCBjb21wbGV0ZWRXb3JrLCBzdWJ0cmVlUmVuZGVyTGFuZXMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnRQcm9maWxlclRpbWVyKGNvbXBsZXRlZFdvcmspO1xuICAgICAgICBuZXh0ID0gY29tcGxldGVXb3JrKGN1cnJlbnQsIGNvbXBsZXRlZFdvcmssIHN1YnRyZWVSZW5kZXJMYW5lcyk7IC8vIFVwZGF0ZSByZW5kZXIgZHVyYXRpb24gYXNzdW1pbmcgd2UgZGlkbid0IGVycm9yLlxuXG4gICAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoY29tcGxldGVkV29yaywgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuXG4gICAgICBpZiAobmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBDb21wbGV0aW5nIHRoaXMgZmliZXIgc3Bhd25lZCBuZXcgd29yay4gV29yayBvbiB0aGF0IG5leHQuXG4gICAgICAgIHdvcmtJblByb2dyZXNzID0gbmV4dDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGZpYmVyIGRpZCBub3QgY29tcGxldGUgYmVjYXVzZSBzb21ldGhpbmcgdGhyZXcuIFBvcCB2YWx1ZXMgb2ZmXG4gICAgICAvLyB0aGUgc3RhY2sgd2l0aG91dCBlbnRlcmluZyB0aGUgY29tcGxldGUgcGhhc2UuIElmIHRoaXMgaXMgYSBib3VuZGFyeSxcbiAgICAgIC8vIGNhcHR1cmUgdmFsdWVzIGlmIHBvc3NpYmxlLlxuICAgICAgdmFyIF9uZXh0ID0gdW53aW5kV29yayhjdXJyZW50LCBjb21wbGV0ZWRXb3JrKTsgLy8gQmVjYXVzZSB0aGlzIGZpYmVyIGRpZCBub3QgY29tcGxldGUsIGRvbid0IHJlc2V0IGl0cyBsYW5lcy5cblxuXG4gICAgICBpZiAoX25leHQgIT09IG51bGwpIHtcbiAgICAgICAgLy8gSWYgY29tcGxldGluZyB0aGlzIHdvcmsgc3Bhd25lZCBuZXcgd29yaywgZG8gdGhhdCBuZXh0LiBXZSdsbCBjb21lXG4gICAgICAgIC8vIGJhY2sgaGVyZSBhZ2Fpbi5cbiAgICAgICAgLy8gU2luY2Ugd2UncmUgcmVzdGFydGluZywgcmVtb3ZlIGFueXRoaW5nIHRoYXQgaXMgbm90IGEgaG9zdCBlZmZlY3RcbiAgICAgICAgLy8gZnJvbSB0aGUgZWZmZWN0IHRhZy5cbiAgICAgICAgX25leHQuZmxhZ3MgJj0gSG9zdEVmZmVjdE1hc2s7XG4gICAgICAgIHdvcmtJblByb2dyZXNzID0gX25leHQ7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCAoY29tcGxldGVkV29yay5tb2RlICYgUHJvZmlsZU1vZGUpICE9PSBOb01vZGUpIHtcbiAgICAgICAgLy8gUmVjb3JkIHRoZSByZW5kZXIgZHVyYXRpb24gZm9yIHRoZSBmaWJlciB0aGF0IGVycm9yZWQuXG4gICAgICAgIHN0b3BQcm9maWxlclRpbWVySWZSdW5uaW5nQW5kUmVjb3JkRGVsdGEoY29tcGxldGVkV29yaywgZmFsc2UpOyAvLyBJbmNsdWRlIHRoZSB0aW1lIHNwZW50IHdvcmtpbmcgb24gZmFpbGVkIGNoaWxkcmVuIGJlZm9yZSBjb250aW51aW5nLlxuXG4gICAgICAgIHZhciBhY3R1YWxEdXJhdGlvbiA9IGNvbXBsZXRlZFdvcmsuYWN0dWFsRHVyYXRpb247XG4gICAgICAgIHZhciBjaGlsZCA9IGNvbXBsZXRlZFdvcmsuY2hpbGQ7XG5cbiAgICAgICAgd2hpbGUgKGNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgICAgYWN0dWFsRHVyYXRpb24gKz0gY2hpbGQuYWN0dWFsRHVyYXRpb247XG4gICAgICAgICAgY2hpbGQgPSBjaGlsZC5zaWJsaW5nO1xuICAgICAgICB9XG5cbiAgICAgICAgY29tcGxldGVkV29yay5hY3R1YWxEdXJhdGlvbiA9IGFjdHVhbER1cmF0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAocmV0dXJuRmliZXIgIT09IG51bGwpIHtcbiAgICAgICAgLy8gTWFyayB0aGUgcGFyZW50IGZpYmVyIGFzIGluY29tcGxldGUgYW5kIGNsZWFyIGl0cyBzdWJ0cmVlIGZsYWdzLlxuICAgICAgICByZXR1cm5GaWJlci5mbGFncyB8PSBJbmNvbXBsZXRlO1xuICAgICAgICByZXR1cm5GaWJlci5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgICAgICByZXR1cm5GaWJlci5kZWxldGlvbnMgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gV2UndmUgdW53b3VuZCBhbGwgdGhlIHdheSB0byB0aGUgcm9vdC5cbiAgICAgICAgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9IFJvb3REaWROb3RDb21wbGV0ZTtcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNpYmxpbmdGaWJlciA9IGNvbXBsZXRlZFdvcmsuc2libGluZztcblxuICAgIGlmIChzaWJsaW5nRmliZXIgIT09IG51bGwpIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIG1vcmUgd29yayB0byBkbyBpbiB0aGlzIHJldHVybkZpYmVyLCBkbyB0aGF0IG5leHQuXG4gICAgICB3b3JrSW5Qcm9ncmVzcyA9IHNpYmxpbmdGaWJlcjtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIE90aGVyd2lzZSwgcmV0dXJuIHRvIHRoZSBwYXJlbnRcblxuXG4gICAgY29tcGxldGVkV29yayA9IHJldHVybkZpYmVyOyAvLyBVcGRhdGUgdGhlIG5leHQgdGhpbmcgd2UncmUgd29ya2luZyBvbiBpbiBjYXNlIHNvbWV0aGluZyB0aHJvd3MuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcyA9IGNvbXBsZXRlZFdvcms7XG4gIH0gd2hpbGUgKGNvbXBsZXRlZFdvcmsgIT09IG51bGwpOyAvLyBXZSd2ZSByZWFjaGVkIHRoZSByb290LlxuXG5cbiAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RJblByb2dyZXNzKSB7XG4gICAgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9IFJvb3RDb21wbGV0ZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWl0Um9vdChyb290LCByZWNvdmVyYWJsZUVycm9ycywgdHJhbnNpdGlvbnMpIHtcbiAgLy8gVE9ETzogVGhpcyBubyBsb25nZXIgbWFrZXMgYW55IHNlbnNlLiBXZSBhbHJlYWR5IHdyYXAgdGhlIG11dGF0aW9uIGFuZFxuICAvLyBsYXlvdXQgcGhhc2VzLiBTaG91bGQgYmUgYWJsZSB0byByZW1vdmUuXG4gIHZhciBwcmV2aW91c1VwZGF0ZUxhbmVQcmlvcml0eSA9IGdldEN1cnJlbnRVcGRhdGVQcmlvcml0eSgpO1xuICB2YXIgcHJldlRyYW5zaXRpb24gPSBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb247XG5cbiAgdHJ5IHtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBudWxsO1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShEaXNjcmV0ZUV2ZW50UHJpb3JpdHkpO1xuICAgIGNvbW1pdFJvb3RJbXBsKHJvb3QsIHJlY292ZXJhYmxlRXJyb3JzLCB0cmFuc2l0aW9ucywgcHJldmlvdXNVcGRhdGVMYW5lUHJpb3JpdHkpO1xuICB9IGZpbmFsbHkge1xuICAgIFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbiA9IHByZXZUcmFuc2l0aW9uO1xuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1VwZGF0ZUxhbmVQcmlvcml0eSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gY29tbWl0Um9vdEltcGwocm9vdCwgcmVjb3ZlcmFibGVFcnJvcnMsIHRyYW5zaXRpb25zLCByZW5kZXJQcmlvcml0eUxldmVsKSB7XG4gIGRvIHtcbiAgICAvLyBgZmx1c2hQYXNzaXZlRWZmZWN0c2Agd2lsbCBjYWxsIGBmbHVzaFN5bmNVcGRhdGVRdWV1ZWAgYXQgdGhlIGVuZCwgd2hpY2hcbiAgICAvLyBtZWFucyBgZmx1c2hQYXNzaXZlRWZmZWN0c2Agd2lsbCBzb21ldGltZXMgcmVzdWx0IGluIGFkZGl0aW9uYWxcbiAgICAvLyBwYXNzaXZlIGVmZmVjdHMuIFNvIHdlIG5lZWQgdG8ga2VlcCBmbHVzaGluZyBpbiBhIGxvb3AgdW50aWwgdGhlcmUgYXJlXG4gICAgLy8gbm8gbW9yZSBwZW5kaW5nIGVmZmVjdHMuXG4gICAgLy8gVE9ETzogTWlnaHQgYmUgYmV0dGVyIGlmIGBmbHVzaFBhc3NpdmVFZmZlY3RzYCBkaWQgbm90IGF1dG9tYXRpY2FsbHlcbiAgICAvLyBmbHVzaCBzeW5jaHJvbm91cyB3b3JrIGF0IHRoZSBlbmQsIHRvIGF2b2lkIGZhY3RvcmluZyBoYXphcmRzIGxpa2UgdGhpcy5cbiAgICBmbHVzaFBhc3NpdmVFZmZlY3RzKCk7XG4gIH0gd2hpbGUgKHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzICE9PSBudWxsKTtcblxuICBmbHVzaFJlbmRlclBoYXNlU3RyaWN0TW9kZVdhcm5pbmdzSW5ERVYoKTtcblxuICBpZiAoKGV4ZWN1dGlvbkNvbnRleHQgJiAoUmVuZGVyQ29udGV4dCB8IENvbW1pdENvbnRleHQpKSAhPT0gTm9Db250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTaG91bGQgbm90IGFscmVhZHkgYmUgd29ya2luZy4nKTtcbiAgfVxuXG4gIHZhciBmaW5pc2hlZFdvcmsgPSByb290LmZpbmlzaGVkV29yaztcbiAgdmFyIGxhbmVzID0gcm9vdC5maW5pc2hlZExhbmVzO1xuXG4gIHtcbiAgICBtYXJrQ29tbWl0U3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICBpZiAoZmluaXNoZWRXb3JrID09PSBudWxsKSB7XG5cbiAgICB7XG4gICAgICBtYXJrQ29tbWl0U3RvcHBlZCgpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9IGVsc2Uge1xuICAgIHtcbiAgICAgIGlmIChsYW5lcyA9PT0gTm9MYW5lcykge1xuICAgICAgICBlcnJvcigncm9vdC5maW5pc2hlZExhbmVzIHNob3VsZCBub3QgYmUgZW1wdHkgZHVyaW5nIGEgY29tbWl0LiBUaGlzIGlzIGEgJyArICdidWcgaW4gUmVhY3QuJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcm9vdC5maW5pc2hlZFdvcmsgPSBudWxsO1xuICByb290LmZpbmlzaGVkTGFuZXMgPSBOb0xhbmVzO1xuXG4gIGlmIChmaW5pc2hlZFdvcmsgPT09IHJvb3QuY3VycmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbW1pdCB0aGUgc2FtZSB0cmVlIGFzIGJlZm9yZS4gVGhpcyBlcnJvciBpcyBsaWtlbHkgY2F1c2VkIGJ5ICcgKyAnYSBidWcgaW4gUmVhY3QuIFBsZWFzZSBmaWxlIGFuIGlzc3VlLicpO1xuICB9IC8vIGNvbW1pdFJvb3QgbmV2ZXIgcmV0dXJucyBhIGNvbnRpbnVhdGlvbjsgaXQgYWx3YXlzIGZpbmlzaGVzIHN5bmNocm9ub3VzbHkuXG4gIC8vIFNvIHdlIGNhbiBjbGVhciB0aGVzZSBub3cgdG8gYWxsb3cgYSBuZXcgY2FsbGJhY2sgdG8gYmUgc2NoZWR1bGVkLlxuXG5cbiAgcm9vdC5jYWxsYmFja05vZGUgPSBudWxsO1xuICByb290LmNhbGxiYWNrUHJpb3JpdHkgPSBOb0xhbmU7IC8vIFVwZGF0ZSB0aGUgZmlyc3QgYW5kIGxhc3QgcGVuZGluZyB0aW1lcyBvbiB0aGlzIHJvb3QuIFRoZSBuZXcgZmlyc3RcbiAgLy8gcGVuZGluZyB0aW1lIGlzIHdoYXRldmVyIGlzIGxlZnQgb24gdGhlIHJvb3QgZmliZXIuXG5cbiAgdmFyIHJlbWFpbmluZ0xhbmVzID0gbWVyZ2VMYW5lcyhmaW5pc2hlZFdvcmsubGFuZXMsIGZpbmlzaGVkV29yay5jaGlsZExhbmVzKTtcbiAgbWFya1Jvb3RGaW5pc2hlZChyb290LCByZW1haW5pbmdMYW5lcyk7XG5cbiAgaWYgKHJvb3QgPT09IHdvcmtJblByb2dyZXNzUm9vdCkge1xuICAgIC8vIFdlIGNhbiByZXNldCB0aGVzZSBub3cgdGhhdCB0aGV5IGFyZSBmaW5pc2hlZC5cbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3QgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RSZW5kZXJMYW5lcyA9IE5vTGFuZXM7XG4gIH0gLy8gSWYgdGhlcmUgYXJlIHBlbmRpbmcgcGFzc2l2ZSBlZmZlY3RzLCBzY2hlZHVsZSBhIGNhbGxiYWNrIHRvIHByb2Nlc3MgdGhlbS5cbiAgLy8gRG8gdGhpcyBhcyBlYXJseSBhcyBwb3NzaWJsZSwgc28gaXQgaXMgcXVldWVkIGJlZm9yZSBhbnl0aGluZyBlbHNlIHRoYXRcbiAgLy8gbWlnaHQgZ2V0IHNjaGVkdWxlZCBpbiB0aGUgY29tbWl0IHBoYXNlLiAoU2VlICMxNjcxNC4pXG4gIC8vIFRPRE86IERlbGV0ZSBhbGwgb3RoZXIgcGxhY2VzIHRoYXQgc2NoZWR1bGUgdGhlIHBhc3NpdmUgZWZmZWN0IGNhbGxiYWNrXG4gIC8vIFRoZXkncmUgcmVkdW5kYW50LlxuXG5cbiAgaWYgKChmaW5pc2hlZFdvcmsuc3VidHJlZUZsYWdzICYgUGFzc2l2ZU1hc2spICE9PSBOb0ZsYWdzIHx8IChmaW5pc2hlZFdvcmsuZmxhZ3MgJiBQYXNzaXZlTWFzaykgIT09IE5vRmxhZ3MpIHtcbiAgICBpZiAoIXJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzKSB7XG4gICAgICByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cyA9IHRydWU7XG4gICAgICAvLyB0byBzdG9yZSBpdCBpbiBwZW5kaW5nUGFzc2l2ZVRyYW5zaXRpb25zIHVudGlsIHRoZXkgZ2V0IHByb2Nlc3NlZFxuICAgICAgLy8gV2UgbmVlZCB0byBwYXNzIHRoaXMgdGhyb3VnaCBhcyBhbiBhcmd1bWVudCB0byBjb21taXRSb290XG4gICAgICAvLyBiZWNhdXNlIHdvcmtJblByb2dyZXNzVHJhbnNpdGlvbnMgbWlnaHQgaGF2ZSBjaGFuZ2VkIGJldHdlZW5cbiAgICAgIC8vIHRoZSBwcmV2aW91cyByZW5kZXIgYW5kIGNvbW1pdCBpZiB3ZSB0aHJvdHRsZSB0aGUgY29tbWl0XG4gICAgICAvLyB3aXRoIHNldFRpbWVvdXRcblxuICAgICAgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IHRyYW5zaXRpb25zO1xuICAgICAgc2NoZWR1bGVDYWxsYmFjayQxKE5vcm1hbFByaW9yaXR5LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTsgLy8gVGhpcyByZW5kZXIgdHJpZ2dlcmVkIHBhc3NpdmUgZWZmZWN0czogcmVsZWFzZSB0aGUgcm9vdCBjYWNoZSBwb29sXG4gICAgICAgIC8vICphZnRlciogcGFzc2l2ZSBlZmZlY3RzIGZpcmUgdG8gYXZvaWQgZnJlZWluZyBhIGNhY2hlIHBvb2wgdGhhdCBtYXlcbiAgICAgICAgLy8gYmUgcmVmZXJlbmNlZCBieSBhIG5vZGUgaW4gdGhlIHRyZWUgKEhvc3RSb290LCBDYWNoZSBib3VuZGFyeSBldGMpXG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIGFueSBlZmZlY3RzIGluIHRoZSB3aG9sZSB0cmVlLlxuICAvLyBUT0RPOiBUaGlzIGlzIGxlZnQgb3ZlciBmcm9tIHRoZSBlZmZlY3QgbGlzdCBpbXBsZW1lbnRhdGlvbiwgd2hlcmUgd2UgaGFkXG4gIC8vIHRvIGNoZWNrIGZvciB0aGUgZXhpc3RlbmNlIG9mIGBmaXJzdEVmZmVjdGAgdG8gc2F0aXNmeSBGbG93LiBJIHRoaW5rIHRoZVxuICAvLyBvbmx5IG90aGVyIHJlYXNvbiB0aGlzIG9wdGltaXphdGlvbiBleGlzdHMgaXMgYmVjYXVzZSBpdCBhZmZlY3RzIHByb2ZpbGluZy5cbiAgLy8gUmVjb25zaWRlciB3aGV0aGVyIHRoaXMgaXMgbmVjZXNzYXJ5LlxuXG5cbiAgdmFyIHN1YnRyZWVIYXNFZmZlY3RzID0gKGZpbmlzaGVkV29yay5zdWJ0cmVlRmxhZ3MgJiAoQmVmb3JlTXV0YXRpb25NYXNrIHwgTXV0YXRpb25NYXNrIHwgTGF5b3V0TWFzayB8IFBhc3NpdmVNYXNrKSkgIT09IE5vRmxhZ3M7XG4gIHZhciByb290SGFzRWZmZWN0ID0gKGZpbmlzaGVkV29yay5mbGFncyAmIChCZWZvcmVNdXRhdGlvbk1hc2sgfCBNdXRhdGlvbk1hc2sgfCBMYXlvdXRNYXNrIHwgUGFzc2l2ZU1hc2spKSAhPT0gTm9GbGFncztcblxuICBpZiAoc3VidHJlZUhhc0VmZmVjdHMgfHwgcm9vdEhhc0VmZmVjdCkge1xuICAgIHZhciBwcmV2VHJhbnNpdGlvbiA9IFJlYWN0Q3VycmVudEJhdGNoQ29uZmlnJDMudHJhbnNpdGlvbjtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBudWxsO1xuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG4gICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KERpc2NyZXRlRXZlbnRQcmlvcml0eSk7XG4gICAgdmFyIHByZXZFeGVjdXRpb25Db250ZXh0ID0gZXhlY3V0aW9uQ29udGV4dDtcbiAgICBleGVjdXRpb25Db250ZXh0IHw9IENvbW1pdENvbnRleHQ7IC8vIFJlc2V0IHRoaXMgdG8gbnVsbCBiZWZvcmUgY2FsbGluZyBsaWZlY3ljbGVzXG5cbiAgICBSZWFjdEN1cnJlbnRPd25lciQyLmN1cnJlbnQgPSBudWxsOyAvLyBUaGUgY29tbWl0IHBoYXNlIGlzIGJyb2tlbiBpbnRvIHNldmVyYWwgc3ViLXBoYXNlcy4gV2UgZG8gYSBzZXBhcmF0ZSBwYXNzXG4gICAgLy8gb2YgdGhlIGVmZmVjdCBsaXN0IGZvciBlYWNoIHBoYXNlOiBhbGwgbXV0YXRpb24gZWZmZWN0cyBjb21lIGJlZm9yZSBhbGxcbiAgICAvLyBsYXlvdXQgZWZmZWN0cywgYW5kIHNvIG9uLlxuICAgIC8vIFRoZSBmaXJzdCBwaGFzZSBhIFwiYmVmb3JlIG11dGF0aW9uXCIgcGhhc2UuIFdlIHVzZSB0aGlzIHBoYXNlIHRvIHJlYWQgdGhlXG4gICAgLy8gc3RhdGUgb2YgdGhlIGhvc3QgdHJlZSByaWdodCBiZWZvcmUgd2UgbXV0YXRlIGl0LiBUaGlzIGlzIHdoZXJlXG4gICAgLy8gZ2V0U25hcHNob3RCZWZvcmVVcGRhdGUgaXMgY2FsbGVkLlxuXG4gICAgdmFyIHNob3VsZEZpcmVBZnRlckFjdGl2ZUluc3RhbmNlQmx1ciA9IGNvbW1pdEJlZm9yZU11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmspO1xuXG4gICAge1xuICAgICAgLy8gTWFyayB0aGUgY3VycmVudCBjb21taXQgdGltZSB0byBiZSBzaGFyZWQgYnkgYWxsIFByb2ZpbGVycyBpbiB0aGlzXG4gICAgICAvLyBiYXRjaC4gVGhpcyBlbmFibGVzIHRoZW0gdG8gYmUgZ3JvdXBlZCBsYXRlci5cbiAgICAgIHJlY29yZENvbW1pdFRpbWUoKTtcbiAgICB9XG5cblxuICAgIGNvbW1pdE11dGF0aW9uRWZmZWN0cyhyb290LCBmaW5pc2hlZFdvcmssIGxhbmVzKTtcblxuICAgIHJlc2V0QWZ0ZXJDb21taXQocm9vdC5jb250YWluZXJJbmZvKTsgLy8gVGhlIHdvcmstaW4tcHJvZ3Jlc3MgdHJlZSBpcyBub3cgdGhlIGN1cnJlbnQgdHJlZS4gVGhpcyBtdXN0IGNvbWUgYWZ0ZXJcbiAgICAvLyB0aGUgbXV0YXRpb24gcGhhc2UsIHNvIHRoYXQgdGhlIHByZXZpb3VzIHRyZWUgaXMgc3RpbGwgY3VycmVudCBkdXJpbmdcbiAgICAvLyBjb21wb25lbnRXaWxsVW5tb3VudCwgYnV0IGJlZm9yZSB0aGUgbGF5b3V0IHBoYXNlLCBzbyB0aGF0IHRoZSBmaW5pc2hlZFxuICAgIC8vIHdvcmsgaXMgY3VycmVudCBkdXJpbmcgY29tcG9uZW50RGlkTW91bnQvVXBkYXRlLlxuXG4gICAgcm9vdC5jdXJyZW50ID0gZmluaXNoZWRXb3JrOyAvLyBUaGUgbmV4dCBwaGFzZSBpcyB0aGUgbGF5b3V0IHBoYXNlLCB3aGVyZSB3ZSBjYWxsIGVmZmVjdHMgdGhhdCByZWFkXG5cbiAgICB7XG4gICAgICBtYXJrTGF5b3V0RWZmZWN0c1N0YXJ0ZWQobGFuZXMpO1xuICAgIH1cblxuICAgIGNvbW1pdExheW91dEVmZmVjdHMoZmluaXNoZWRXb3JrLCByb290LCBsYW5lcyk7XG5cbiAgICB7XG4gICAgICBtYXJrTGF5b3V0RWZmZWN0c1N0b3BwZWQoKTtcbiAgICB9XG4gICAgLy8gb3Bwb3J0dW5pdHkgdG8gcGFpbnQuXG5cblxuICAgIHJlcXVlc3RQYWludCgpO1xuICAgIGV4ZWN1dGlvbkNvbnRleHQgPSBwcmV2RXhlY3V0aW9uQ29udGV4dDsgLy8gUmVzZXQgdGhlIHByaW9yaXR5IHRvIHRoZSBwcmV2aW91cyBub24tc3luYyB2YWx1ZS5cblxuICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmV2aW91c1ByaW9yaXR5KTtcbiAgICBSZWFjdEN1cnJlbnRCYXRjaENvbmZpZyQzLnRyYW5zaXRpb24gPSBwcmV2VHJhbnNpdGlvbjtcbiAgfSBlbHNlIHtcbiAgICAvLyBObyBlZmZlY3RzLlxuICAgIHJvb3QuY3VycmVudCA9IGZpbmlzaGVkV29yazsgLy8gTWVhc3VyZSB0aGVzZSBhbnl3YXkgc28gdGhlIGZsYW1lZ3JhcGggZXhwbGljaXRseSBzaG93cyB0aGF0IHRoZXJlIHdlcmVcbiAgICAvLyBubyBlZmZlY3RzLlxuICAgIC8vIFRPRE86IE1heWJlIHRoZXJlJ3MgYSBiZXR0ZXIgd2F5IHRvIHJlcG9ydCB0aGlzLlxuXG4gICAge1xuICAgICAgcmVjb3JkQ29tbWl0VGltZSgpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290RGlkSGF2ZVBhc3NpdmVFZmZlY3RzID0gcm9vdERvZXNIYXZlUGFzc2l2ZUVmZmVjdHM7XG5cbiAgaWYgKHJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzKSB7XG4gICAgLy8gVGhpcyBjb21taXQgaGFzIHBhc3NpdmUgZWZmZWN0cy4gU3Rhc2ggYSByZWZlcmVuY2UgdG8gdGhlbS4gQnV0IGRvbid0XG4gICAgLy8gc2NoZWR1bGUgYSBjYWxsYmFjayB1bnRpbCBhZnRlciBmbHVzaGluZyBsYXlvdXQgd29yay5cbiAgICByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cyA9IGZhbHNlO1xuICAgIHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzID0gcm9vdDtcbiAgICBwZW5kaW5nUGFzc2l2ZUVmZmVjdHNMYW5lcyA9IGxhbmVzO1xuICB9IGVsc2Uge1xuXG4gICAge1xuICAgICAgbmVzdGVkUGFzc2l2ZVVwZGF0ZUNvdW50ID0gMDtcbiAgICAgIHJvb3RXaXRoUGFzc2l2ZU5lc3RlZFVwZGF0ZXMgPSBudWxsO1xuICAgIH1cbiAgfSAvLyBSZWFkIHRoaXMgYWdhaW4sIHNpbmNlIGFuIGVmZmVjdCBtaWdodCBoYXZlIHVwZGF0ZWQgaXRcblxuXG4gIHJlbWFpbmluZ0xhbmVzID0gcm9vdC5wZW5kaW5nTGFuZXM7IC8vIENoZWNrIGlmIHRoZXJlJ3MgcmVtYWluaW5nIHdvcmsgb24gdGhpcyByb290XG4gIC8vIFRPRE86IFRoaXMgaXMgcGFydCBvZiB0aGUgYGNvbXBvbmVudERpZENhdGNoYCBpbXBsZW1lbnRhdGlvbi4gSXRzIHB1cnBvc2VcbiAgLy8gaXMgdG8gZGV0ZWN0IHdoZXRoZXIgc29tZXRoaW5nIG1pZ2h0IGhhdmUgY2FsbGVkIHNldFN0YXRlIGluc2lkZVxuICAvLyBgY29tcG9uZW50RGlkQ2F0Y2hgLiBUaGUgbWVjaGFuaXNtIGlzIGtub3duIHRvIGJlIGZsYXdlZCBiZWNhdXNlIGBzZXRTdGF0ZWBcbiAgLy8gaW5zaWRlIGBjb21wb25lbnREaWRDYXRjaGAgaXMgaXRzZWxmIGZsYXdlZCDigJQgdGhhdCdzIHdoeSB3ZSByZWNvbW1lbmRcbiAgLy8gYGdldERlcml2ZWRTdGF0ZUZyb21FcnJvcmAgaW5zdGVhZC4gSG93ZXZlciwgaXQgY291bGQgYmUgaW1wcm92ZWQgYnlcbiAgLy8gY2hlY2tpbmcgaWYgcmVtYWluaW5nTGFuZXMgaW5jbHVkZXMgU3luYyB3b3JrLCBpbnN0ZWFkIG9mIHdoZXRoZXIgdGhlcmUnc1xuICAvLyBhbnkgd29yayByZW1haW5pbmcgYXQgYWxsICh3aGljaCB3b3VsZCBhbHNvIGluY2x1ZGUgc3R1ZmYgbGlrZSBTdXNwZW5zZVxuICAvLyByZXRyaWVzIG9yIHRyYW5zaXRpb25zKS4gSXQncyBiZWVuIGxpa2UgdGhpcyBmb3IgYSB3aGlsZSwgdGhvdWdoLCBzbyBmaXhpbmdcbiAgLy8gaXQgcHJvYmFibHkgaXNuJ3QgdGhhdCB1cmdlbnQuXG5cbiAgaWYgKHJlbWFpbmluZ0xhbmVzID09PSBOb0xhbmVzKSB7XG4gICAgLy8gSWYgdGhlcmUncyBubyByZW1haW5pbmcgd29yaywgd2UgY2FuIGNsZWFyIHRoZSBzZXQgb2YgYWxyZWFkeSBmYWlsZWRcbiAgICAvLyBlcnJvciBib3VuZGFyaWVzLlxuICAgIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID0gbnVsbDtcbiAgfVxuXG4gIHtcbiAgICBpZiAoIXJvb3REaWRIYXZlUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIGNvbW1pdERvdWJsZUludm9rZUVmZmVjdHNJbkRFVihyb290LmN1cnJlbnQsIGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBvbkNvbW1pdFJvb3QoZmluaXNoZWRXb3JrLnN0YXRlTm9kZSwgcmVuZGVyUHJpb3JpdHlMZXZlbCk7XG5cbiAge1xuICAgIGlmIChpc0RldlRvb2xzUHJlc2VudCkge1xuICAgICAgcm9vdC5tZW1vaXplZFVwZGF0ZXJzLmNsZWFyKCk7XG4gICAgfVxuICB9XG5cbiAge1xuICAgIG9uQ29tbWl0Um9vdCQxKCk7XG4gIH0gLy8gQWx3YXlzIGNhbGwgdGhpcyBiZWZvcmUgZXhpdGluZyBgY29tbWl0Um9vdGAsIHRvIGVuc3VyZSB0aGF0IGFueVxuICAvLyBhZGRpdGlvbmFsIHdvcmsgb24gdGhpcyByb290IGlzIHNjaGVkdWxlZC5cblxuXG4gIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBub3coKSk7XG5cbiAgaWYgKHJlY292ZXJhYmxlRXJyb3JzICE9PSBudWxsKSB7XG4gICAgLy8gVGhlcmUgd2VyZSBlcnJvcnMgZHVyaW5nIHRoaXMgcmVuZGVyLCBidXQgcmVjb3ZlcmVkIGZyb20gdGhlbSB3aXRob3V0XG4gICAgLy8gbmVlZGluZyB0byBzdXJmYWNlIGl0IHRvIHRoZSBVSS4gV2UgbG9nIHRoZW0gaGVyZS5cbiAgICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gcm9vdC5vblJlY292ZXJhYmxlRXJyb3I7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlY292ZXJhYmxlRXJyb3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcmVjb3ZlcmFibGVFcnJvciA9IHJlY292ZXJhYmxlRXJyb3JzW2ldO1xuICAgICAgdmFyIGNvbXBvbmVudFN0YWNrID0gcmVjb3ZlcmFibGVFcnJvci5zdGFjaztcbiAgICAgIHZhciBkaWdlc3QgPSByZWNvdmVyYWJsZUVycm9yLmRpZ2VzdDtcbiAgICAgIG9uUmVjb3ZlcmFibGVFcnJvcihyZWNvdmVyYWJsZUVycm9yLnZhbHVlLCB7XG4gICAgICAgIGNvbXBvbmVudFN0YWNrOiBjb21wb25lbnRTdGFjayxcbiAgICAgICAgZGlnZXN0OiBkaWdlc3RcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChoYXNVbmNhdWdodEVycm9yKSB7XG4gICAgaGFzVW5jYXVnaHRFcnJvciA9IGZhbHNlO1xuICAgIHZhciBlcnJvciQxID0gZmlyc3RVbmNhdWdodEVycm9yO1xuICAgIGZpcnN0VW5jYXVnaHRFcnJvciA9IG51bGw7XG4gICAgdGhyb3cgZXJyb3IkMTtcbiAgfSAvLyBJZiB0aGUgcGFzc2l2ZSBlZmZlY3RzIGFyZSB0aGUgcmVzdWx0IG9mIGEgZGlzY3JldGUgcmVuZGVyLCBmbHVzaCB0aGVtXG4gIC8vIHN5bmNocm9ub3VzbHkgYXQgdGhlIGVuZCBvZiB0aGUgY3VycmVudCB0YXNrIHNvIHRoYXQgdGhlIHJlc3VsdCBpc1xuICAvLyBpbW1lZGlhdGVseSBvYnNlcnZhYmxlLiBPdGhlcndpc2UsIHdlIGFzc3VtZSB0aGF0IHRoZXkgYXJlIG5vdFxuICAvLyBvcmRlci1kZXBlbmRlbnQgYW5kIGRvIG5vdCBuZWVkIHRvIGJlIG9ic2VydmVkIGJ5IGV4dGVybmFsIHN5c3RlbXMsIHNvIHdlXG4gIC8vIGNhbiB3YWl0IHVudGlsIGFmdGVyIHBhaW50LlxuICAvLyBUT0RPOiBXZSBjYW4gb3B0aW1pemUgdGhpcyBieSBub3Qgc2NoZWR1bGluZyB0aGUgY2FsbGJhY2sgZWFybGllci4gU2luY2Ugd2VcbiAgLy8gY3VycmVudGx5IHNjaGVkdWxlIHRoZSBjYWxsYmFjayBpbiBtdWx0aXBsZSBwbGFjZXMsIHdpbGwgd2FpdCB1bnRpbCB0aG9zZVxuICAvLyBhcmUgY29uc29saWRhdGVkLlxuXG5cbiAgaWYgKGluY2x1ZGVzU29tZUxhbmUocGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMsIFN5bmNMYW5lKSAmJiByb290LnRhZyAhPT0gTGVnYWN5Um9vdCkge1xuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgfSAvLyBSZWFkIHRoaXMgYWdhaW4sIHNpbmNlIGEgcGFzc2l2ZSBlZmZlY3QgbWlnaHQgaGF2ZSB1cGRhdGVkIGl0XG5cblxuICByZW1haW5pbmdMYW5lcyA9IHJvb3QucGVuZGluZ0xhbmVzO1xuXG4gIGlmIChpbmNsdWRlc1NvbWVMYW5lKHJlbWFpbmluZ0xhbmVzLCBTeW5jTGFuZSkpIHtcbiAgICB7XG4gICAgICBtYXJrTmVzdGVkVXBkYXRlU2NoZWR1bGVkKCk7XG4gICAgfSAvLyBDb3VudCB0aGUgbnVtYmVyIG9mIHRpbWVzIHRoZSByb290IHN5bmNocm9ub3VzbHkgcmUtcmVuZGVycyB3aXRob3V0XG4gICAgLy8gZmluaXNoaW5nLiBJZiB0aGVyZSBhcmUgdG9vIG1hbnksIGl0IGluZGljYXRlcyBhbiBpbmZpbml0ZSB1cGRhdGUgbG9vcC5cblxuXG4gICAgaWYgKHJvb3QgPT09IHJvb3RXaXRoTmVzdGVkVXBkYXRlcykge1xuICAgICAgbmVzdGVkVXBkYXRlQ291bnQrKztcbiAgICB9IGVsc2Uge1xuICAgICAgbmVzdGVkVXBkYXRlQ291bnQgPSAwO1xuICAgICAgcm9vdFdpdGhOZXN0ZWRVcGRhdGVzID0gcm9vdDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbmVzdGVkVXBkYXRlQ291bnQgPSAwO1xuICB9IC8vIElmIGxheW91dCB3b3JrIHdhcyBzY2hlZHVsZWQsIGZsdXNoIGl0IG5vdy5cblxuXG4gIGZsdXNoU3luY0NhbGxiYWNrcygpO1xuXG4gIHtcbiAgICBtYXJrQ29tbWl0U3RvcHBlZCgpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKSB7XG4gIC8vIFJldHVybnMgd2hldGhlciBwYXNzaXZlIGVmZmVjdHMgd2VyZSBmbHVzaGVkLlxuICAvLyBUT0RPOiBDb21iaW5lIHRoaXMgY2hlY2sgd2l0aCB0aGUgb25lIGluIGZsdXNoUGFzc2l2ZUVGZmVjdHNJbXBsLiBXZSBzaG91bGRcbiAgLy8gcHJvYmFibHkganVzdCBjb21iaW5lIHRoZSB0d28gZnVuY3Rpb25zLiBJIGJlbGlldmUgdGhleSB3ZXJlIG9ubHkgc2VwYXJhdGVcbiAgLy8gaW4gdGhlIGZpcnN0IHBsYWNlIGJlY2F1c2Ugd2UgdXNlZCB0byB3cmFwIGl0IHdpdGhcbiAgLy8gYFNjaGVkdWxlci5ydW5XaXRoUHJpb3JpdHlgLCB3aGljaCBhY2NlcHRzIGEgZnVuY3Rpb24uIEJ1dCBub3cgd2UgdHJhY2sgdGhlXG4gIC8vIHByaW9yaXR5IHdpdGhpbiBSZWFjdCBpdHNlbGYsIHNvIHdlIGNhbiBtdXRhdGUgdGhlIHZhcmlhYmxlIGRpcmVjdGx5LlxuICBpZiAocm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMgIT09IG51bGwpIHtcbiAgICB2YXIgcmVuZGVyUHJpb3JpdHkgPSBsYW5lc1RvRXZlbnRQcmlvcml0eShwZW5kaW5nUGFzc2l2ZUVmZmVjdHNMYW5lcyk7XG4gICAgdmFyIHByaW9yaXR5ID0gbG93ZXJFdmVudFByaW9yaXR5KERlZmF1bHRFdmVudFByaW9yaXR5LCByZW5kZXJQcmlvcml0eSk7XG4gICAgdmFyIHByZXZUcmFuc2l0aW9uID0gUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uO1xuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5ID0gZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KCk7XG5cbiAgICB0cnkge1xuICAgICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gbnVsbDtcbiAgICAgIHNldEN1cnJlbnRVcGRhdGVQcmlvcml0eShwcmlvcml0eSk7XG4gICAgICByZXR1cm4gZmx1c2hQYXNzaXZlRWZmZWN0c0ltcGwoKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgc2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KHByZXZpb3VzUHJpb3JpdHkpO1xuICAgICAgUmVhY3RDdXJyZW50QmF0Y2hDb25maWckMy50cmFuc2l0aW9uID0gcHJldlRyYW5zaXRpb247IC8vIE9uY2UgcGFzc2l2ZSBlZmZlY3RzIGhhdmUgcnVuIGZvciB0aGUgdHJlZSAtIGdpdmluZyBjb21wb25lbnRzIGFcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBlbnF1ZXVlUGVuZGluZ1Bhc3NpdmVQcm9maWxlckVmZmVjdChmaWJlcikge1xuICB7XG4gICAgcGVuZGluZ1Bhc3NpdmVQcm9maWxlckVmZmVjdHMucHVzaChmaWJlcik7XG5cbiAgICBpZiAoIXJvb3REb2VzSGF2ZVBhc3NpdmVFZmZlY3RzKSB7XG4gICAgICByb290RG9lc0hhdmVQYXNzaXZlRWZmZWN0cyA9IHRydWU7XG4gICAgICBzY2hlZHVsZUNhbGxiYWNrJDEoTm9ybWFsUHJpb3JpdHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZmx1c2hQYXNzaXZlRWZmZWN0cygpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmbHVzaFBhc3NpdmVFZmZlY3RzSW1wbCgpIHtcbiAgaWYgKHJvb3RXaXRoUGVuZGluZ1Bhc3NpdmVFZmZlY3RzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IC8vIENhY2hlIGFuZCBjbGVhciB0aGUgdHJhbnNpdGlvbnMgZmxhZ1xuXG5cbiAgdmFyIHRyYW5zaXRpb25zID0gcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucztcbiAgcGVuZGluZ1Bhc3NpdmVUcmFuc2l0aW9ucyA9IG51bGw7XG4gIHZhciByb290ID0gcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHM7XG4gIHZhciBsYW5lcyA9IHBlbmRpbmdQYXNzaXZlRWZmZWN0c0xhbmVzO1xuICByb290V2l0aFBlbmRpbmdQYXNzaXZlRWZmZWN0cyA9IG51bGw7IC8vIFRPRE86IFRoaXMgaXMgc29tZXRpbWVzIG91dCBvZiBzeW5jIHdpdGggcm9vdFdpdGhQZW5kaW5nUGFzc2l2ZUVmZmVjdHMuXG4gIC8vIEZpZ3VyZSBvdXQgd2h5IGFuZCBmaXggaXQuIEl0J3Mgbm90IGNhdXNpbmcgYW55IGtub3duIGlzc3VlcyAocHJvYmFibHlcbiAgLy8gYmVjYXVzZSBpdCdzIG9ubHkgdXNlZCBmb3IgcHJvZmlsaW5nKSwgYnV0IGl0J3MgYSByZWZhY3RvciBoYXphcmQuXG5cbiAgcGVuZGluZ1Bhc3NpdmVFZmZlY3RzTGFuZXMgPSBOb0xhbmVzO1xuXG4gIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIChSZW5kZXJDb250ZXh0IHwgQ29tbWl0Q29udGV4dCkpICE9PSBOb0NvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmbHVzaCBwYXNzaXZlIGVmZmVjdHMgd2hpbGUgYWxyZWFkeSByZW5kZXJpbmcuJyk7XG4gIH1cblxuICB7XG4gICAgaXNGbHVzaGluZ1Bhc3NpdmVFZmZlY3RzID0gdHJ1ZTtcbiAgICBkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzID0gZmFsc2U7XG4gIH1cblxuICB7XG4gICAgbWFya1Bhc3NpdmVFZmZlY3RzU3RhcnRlZChsYW5lcyk7XG4gIH1cblxuICB2YXIgcHJldkV4ZWN1dGlvbkNvbnRleHQgPSBleGVjdXRpb25Db250ZXh0O1xuICBleGVjdXRpb25Db250ZXh0IHw9IENvbW1pdENvbnRleHQ7XG4gIGNvbW1pdFBhc3NpdmVVbm1vdW50RWZmZWN0cyhyb290LmN1cnJlbnQpO1xuICBjb21taXRQYXNzaXZlTW91bnRFZmZlY3RzKHJvb3QsIHJvb3QuY3VycmVudCwgbGFuZXMsIHRyYW5zaXRpb25zKTsgLy8gVE9ETzogTW92ZSB0byBjb21taXRQYXNzaXZlTW91bnRFZmZlY3RzXG5cbiAge1xuICAgIHZhciBwcm9maWxlckVmZmVjdHMgPSBwZW5kaW5nUGFzc2l2ZVByb2ZpbGVyRWZmZWN0cztcbiAgICBwZW5kaW5nUGFzc2l2ZVByb2ZpbGVyRWZmZWN0cyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9maWxlckVmZmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBfZmliZXIgPSBwcm9maWxlckVmZmVjdHNbaV07XG4gICAgICBjb21taXRQYXNzaXZlRWZmZWN0RHVyYXRpb25zKHJvb3QsIF9maWJlcik7XG4gICAgfVxuICB9XG5cbiAge1xuICAgIG1hcmtQYXNzaXZlRWZmZWN0c1N0b3BwZWQoKTtcbiAgfVxuXG4gIHtcbiAgICBjb21taXREb3VibGVJbnZva2VFZmZlY3RzSW5ERVYocm9vdC5jdXJyZW50LCB0cnVlKTtcbiAgfVxuXG4gIGV4ZWN1dGlvbkNvbnRleHQgPSBwcmV2RXhlY3V0aW9uQ29udGV4dDtcbiAgZmx1c2hTeW5jQ2FsbGJhY2tzKCk7XG5cbiAge1xuICAgIC8vIElmIGFkZGl0aW9uYWwgcGFzc2l2ZSBlZmZlY3RzIHdlcmUgc2NoZWR1bGVkLCBpbmNyZW1lbnQgYSBjb3VudGVyLiBJZiB0aGlzXG4gICAgLy8gZXhjZWVkcyB0aGUgbGltaXQsIHdlJ2xsIGZpcmUgYSB3YXJuaW5nLlxuICAgIGlmIChkaWRTY2hlZHVsZVVwZGF0ZUR1cmluZ1Bhc3NpdmVFZmZlY3RzKSB7XG4gICAgICBpZiAocm9vdCA9PT0gcm9vdFdpdGhQYXNzaXZlTmVzdGVkVXBkYXRlcykge1xuICAgICAgICBuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5lc3RlZFBhc3NpdmVVcGRhdGVDb3VudCA9IDA7XG4gICAgICAgIHJvb3RXaXRoUGFzc2l2ZU5lc3RlZFVwZGF0ZXMgPSByb290O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQgPSAwO1xuICAgIH1cblxuICAgIGlzRmx1c2hpbmdQYXNzaXZlRWZmZWN0cyA9IGZhbHNlO1xuICAgIGRpZFNjaGVkdWxlVXBkYXRlRHVyaW5nUGFzc2l2ZUVmZmVjdHMgPSBmYWxzZTtcbiAgfSAvLyBUT0RPOiBNb3ZlIHRvIGNvbW1pdFBhc3NpdmVNb3VudEVmZmVjdHNcblxuXG4gIG9uUG9zdENvbW1pdFJvb3Qocm9vdCk7XG5cbiAge1xuICAgIHZhciBzdGF0ZU5vZGUgPSByb290LmN1cnJlbnQuc3RhdGVOb2RlO1xuICAgIHN0YXRlTm9kZS5lZmZlY3REdXJhdGlvbiA9IDA7XG4gICAgc3RhdGVOb2RlLnBhc3NpdmVFZmZlY3REdXJhdGlvbiA9IDA7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkge1xuICByZXR1cm4gbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQgIT09IG51bGwgJiYgbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQuaGFzKGluc3RhbmNlKTtcbn1cbmZ1bmN0aW9uIG1hcmtMZWdhY3lFcnJvckJvdW5kYXJ5QXNGYWlsZWQoaW5zdGFuY2UpIHtcbiAgaWYgKGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkID09PSBudWxsKSB7XG4gICAgbGVnYWN5RXJyb3JCb3VuZGFyaWVzVGhhdEFscmVhZHlGYWlsZWQgPSBuZXcgU2V0KFtpbnN0YW5jZV0pO1xuICB9IGVsc2Uge1xuICAgIGxlZ2FjeUVycm9yQm91bmRhcmllc1RoYXRBbHJlYWR5RmFpbGVkLmFkZChpbnN0YW5jZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJlcGFyZVRvVGhyb3dVbmNhdWdodEVycm9yKGVycm9yKSB7XG4gIGlmICghaGFzVW5jYXVnaHRFcnJvcikge1xuICAgIGhhc1VuY2F1Z2h0RXJyb3IgPSB0cnVlO1xuICAgIGZpcnN0VW5jYXVnaHRFcnJvciA9IGVycm9yO1xuICB9XG59XG5cbnZhciBvblVuY2F1Z2h0RXJyb3IgPSBwcmVwYXJlVG9UaHJvd1VuY2F1Z2h0RXJyb3I7XG5cbmZ1bmN0aW9uIGNhcHR1cmVDb21taXRQaGFzZUVycm9yT25Sb290KHJvb3RGaWJlciwgc291cmNlRmliZXIsIGVycm9yKSB7XG4gIHZhciBlcnJvckluZm8gPSBjcmVhdGVDYXB0dXJlZFZhbHVlQXRGaWJlcihlcnJvciwgc291cmNlRmliZXIpO1xuICB2YXIgdXBkYXRlID0gY3JlYXRlUm9vdEVycm9yVXBkYXRlKHJvb3RGaWJlciwgZXJyb3JJbmZvLCBTeW5jTGFuZSk7XG4gIHZhciByb290ID0gZW5xdWV1ZVVwZGF0ZShyb290RmliZXIsIHVwZGF0ZSwgU3luY0xhbmUpO1xuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIFN5bmNMYW5lLCBldmVudFRpbWUpO1xuICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNhcHR1cmVDb21taXRQaGFzZUVycm9yKHNvdXJjZUZpYmVyLCBuZWFyZXN0TW91bnRlZEFuY2VzdG9yLCBlcnJvciQxKSB7XG4gIHtcbiAgICByZXBvcnRVbmNhdWdodEVycm9ySW5ERVYoZXJyb3IkMSk7XG4gICAgc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGZhbHNlKTtcbiAgfVxuXG4gIGlmIChzb3VyY2VGaWJlci50YWcgPT09IEhvc3RSb290KSB7XG4gICAgLy8gRXJyb3Igd2FzIHRocm93biBhdCB0aGUgcm9vdC4gVGhlcmUgaXMgbm8gcGFyZW50LCBzbyB0aGUgcm9vdFxuICAgIC8vIGl0c2VsZiBzaG91bGQgY2FwdHVyZSBpdC5cbiAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvck9uUm9vdChzb3VyY2VGaWJlciwgc291cmNlRmliZXIsIGVycm9yJDEpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBmaWJlciA9IG51bGw7XG5cbiAge1xuICAgIGZpYmVyID0gbmVhcmVzdE1vdW50ZWRBbmNlc3RvcjtcbiAgfVxuXG4gIHdoaWxlIChmaWJlciAhPT0gbnVsbCkge1xuICAgIGlmIChmaWJlci50YWcgPT09IEhvc3RSb290KSB7XG4gICAgICBjYXB0dXJlQ29tbWl0UGhhc2VFcnJvck9uUm9vdChmaWJlciwgc291cmNlRmliZXIsIGVycm9yJDEpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoZmliZXIudGFnID09PSBDbGFzc0NvbXBvbmVudCkge1xuICAgICAgdmFyIGN0b3IgPSBmaWJlci50eXBlO1xuICAgICAgdmFyIGluc3RhbmNlID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICBpZiAodHlwZW9mIGN0b3IuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yID09PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBpbnN0YW5jZS5jb21wb25lbnREaWRDYXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiAhaXNBbHJlYWR5RmFpbGVkTGVnYWN5RXJyb3JCb3VuZGFyeShpbnN0YW5jZSkpIHtcbiAgICAgICAgdmFyIGVycm9ySW5mbyA9IGNyZWF0ZUNhcHR1cmVkVmFsdWVBdEZpYmVyKGVycm9yJDEsIHNvdXJjZUZpYmVyKTtcbiAgICAgICAgdmFyIHVwZGF0ZSA9IGNyZWF0ZUNsYXNzRXJyb3JVcGRhdGUoZmliZXIsIGVycm9ySW5mbywgU3luY0xhbmUpO1xuICAgICAgICB2YXIgcm9vdCA9IGVucXVldWVVcGRhdGUoZmliZXIsIHVwZGF0ZSwgU3luY0xhbmUpO1xuICAgICAgICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuXG4gICAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgbWFya1Jvb3RVcGRhdGVkKHJvb3QsIFN5bmNMYW5lLCBldmVudFRpbWUpO1xuICAgICAgICAgIGVuc3VyZVJvb3RJc1NjaGVkdWxlZChyb290LCBldmVudFRpbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZpYmVyID0gZmliZXIucmV0dXJuO1xuICB9XG5cbiAge1xuICAgIC8vIFRPRE86IFVudGlsIHdlIHJlLWxhbmQgc2tpcFVubW91bnRlZEJvdW5kYXJpZXMgKHNlZSAjMjAxNDcpLCB0aGlzIHdhcm5pbmdcbiAgICAvLyB3aWxsIGZpcmUgZm9yIGVycm9ycyB0aGF0IGFyZSB0aHJvd24gYnkgZGVzdHJveSBmdW5jdGlvbnMgaW5zaWRlIGRlbGV0ZWRcbiAgICAvLyB0cmVlcy4gV2hhdCBpdCBzaG91bGQgaW5zdGVhZCBkbyBpcyBwcm9wYWdhdGUgdGhlIGVycm9yIHRvIHRoZSBwYXJlbnQgb2ZcbiAgICAvLyB0aGUgZGVsZXRlZCB0cmVlLiBJbiB0aGUgbWVhbnRpbWUsIGRvIG5vdCBhZGQgdGhpcyB3YXJuaW5nIHRvIHRoZVxuICAgIC8vIGFsbG93bGlzdDsgdGhpcyBpcyBvbmx5IGZvciBvdXIgaW50ZXJuYWwgdXNlLlxuICAgIGVycm9yKCdJbnRlcm5hbCBSZWFjdCBlcnJvcjogQXR0ZW1wdGVkIHRvIGNhcHR1cmUgYSBjb21taXQgcGhhc2UgZXJyb3IgJyArICdpbnNpZGUgYSBkZXRhY2hlZCB0cmVlLiBUaGlzIGluZGljYXRlcyBhIGJ1ZyBpbiBSZWFjdC4gTGlrZWx5ICcgKyAnY2F1c2VzIGluY2x1ZGUgZGVsZXRpbmcgdGhlIHNhbWUgZmliZXIgbW9yZSB0aGFuIG9uY2UsIGNvbW1pdHRpbmcgYW4gJyArICdhbHJlYWR5LWZpbmlzaGVkIHRyZWUsIG9yIGFuIGluY29uc2lzdGVudCByZXR1cm4gcG9pbnRlci5cXG5cXG4nICsgJ0Vycm9yIG1lc3NhZ2U6XFxuXFxuJXMnLCBlcnJvciQxKTtcbiAgfVxufVxuZnVuY3Rpb24gcGluZ1N1c3BlbmRlZFJvb3Qocm9vdCwgd2FrZWFibGUsIHBpbmdlZExhbmVzKSB7XG4gIHZhciBwaW5nQ2FjaGUgPSByb290LnBpbmdDYWNoZTtcblxuICBpZiAocGluZ0NhY2hlICE9PSBudWxsKSB7XG4gICAgLy8gVGhlIHdha2VhYmxlIHJlc29sdmVkLCBzbyB3ZSBubyBsb25nZXIgbmVlZCB0byBtZW1vaXplLCBiZWNhdXNlIGl0IHdpbGxcbiAgICAvLyBuZXZlciBiZSB0aHJvd24gYWdhaW4uXG4gICAgcGluZ0NhY2hlLmRlbGV0ZSh3YWtlYWJsZSk7XG4gIH1cblxuICB2YXIgZXZlbnRUaW1lID0gcmVxdWVzdEV2ZW50VGltZSgpO1xuICBtYXJrUm9vdFBpbmdlZChyb290LCBwaW5nZWRMYW5lcyk7XG4gIHdhcm5JZlN1c3BlbnNlUmVzb2x1dGlvbk5vdFdyYXBwZWRXaXRoQWN0REVWKHJvb3QpO1xuXG4gIGlmICh3b3JrSW5Qcm9ncmVzc1Jvb3QgPT09IHJvb3QgJiYgaXNTdWJzZXRPZkxhbmVzKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzLCBwaW5nZWRMYW5lcykpIHtcbiAgICAvLyBSZWNlaXZlZCBhIHBpbmcgYXQgdGhlIHNhbWUgcHJpb3JpdHkgbGV2ZWwgYXQgd2hpY2ggd2UncmUgY3VycmVudGx5XG4gICAgLy8gcmVuZGVyaW5nLiBXZSBtaWdodCB3YW50IHRvIHJlc3RhcnQgdGhpcyByZW5kZXIuIFRoaXMgc2hvdWxkIG1pcnJvclxuICAgIC8vIHRoZSBsb2dpYyBvZiB3aGV0aGVyIG9yIG5vdCBhIHJvb3Qgc3VzcGVuZHMgb25jZSBpdCBjb21wbGV0ZXMuXG4gICAgLy8gVE9ETzogSWYgd2UncmUgcmVuZGVyaW5nIHN5bmMgZWl0aGVyIGR1ZSB0byBTeW5jLCBCYXRjaGVkIG9yIGV4cGlyZWQsXG4gICAgLy8gd2Ugc2hvdWxkIHByb2JhYmx5IG5ldmVyIHJlc3RhcnQuXG4gICAgLy8gSWYgd2UncmUgc3VzcGVuZGVkIHdpdGggZGVsYXksIG9yIGlmIGl0J3MgYSByZXRyeSwgd2UnbGwgYWx3YXlzIHN1c3BlbmRcbiAgICAvLyBzbyB3ZSBjYW4gYWx3YXlzIHJlc3RhcnQuXG4gICAgaWYgKHdvcmtJblByb2dyZXNzUm9vdEV4aXRTdGF0dXMgPT09IFJvb3RTdXNwZW5kZWRXaXRoRGVsYXkgfHwgd29ya0luUHJvZ3Jlc3NSb290RXhpdFN0YXR1cyA9PT0gUm9vdFN1c3BlbmRlZCAmJiBpbmNsdWRlc09ubHlSZXRyaWVzKHdvcmtJblByb2dyZXNzUm9vdFJlbmRlckxhbmVzKSAmJiBub3coKSAtIGdsb2JhbE1vc3RSZWNlbnRGYWxsYmFja1RpbWUgPCBGQUxMQkFDS19USFJPVFRMRV9NUykge1xuICAgICAgLy8gUmVzdGFydCBmcm9tIHRoZSByb290LlxuICAgICAgcHJlcGFyZUZyZXNoU3RhY2socm9vdCwgTm9MYW5lcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEV2ZW4gdGhvdWdoIHdlIGNhbid0IHJlc3RhcnQgcmlnaHQgbm93LCB3ZSBtaWdodCBnZXQgYW5cbiAgICAgIC8vIG9wcG9ydHVuaXR5IGxhdGVyLiBTbyB3ZSBtYXJrIHRoaXMgcmVuZGVyIGFzIGhhdmluZyBhIHBpbmcuXG4gICAgICB3b3JrSW5Qcm9ncmVzc1Jvb3RQaW5nZWRMYW5lcyA9IG1lcmdlTGFuZXMod29ya0luUHJvZ3Jlc3NSb290UGluZ2VkTGFuZXMsIHBpbmdlZExhbmVzKTtcbiAgICB9XG4gIH1cblxuICBlbnN1cmVSb290SXNTY2hlZHVsZWQocm9vdCwgZXZlbnRUaW1lKTtcbn1cblxuZnVuY3Rpb24gcmV0cnlUaW1lZE91dEJvdW5kYXJ5KGJvdW5kYXJ5RmliZXIsIHJldHJ5TGFuZSkge1xuICAvLyBUaGUgYm91bmRhcnkgZmliZXIgKGEgU3VzcGVuc2UgY29tcG9uZW50IG9yIFN1c3BlbnNlTGlzdCBjb21wb25lbnQpXG4gIC8vIHByZXZpb3VzbHkgd2FzIHJlbmRlcmVkIGluIGl0cyBmYWxsYmFjayBzdGF0ZS4gT25lIG9mIHRoZSBwcm9taXNlcyB0aGF0XG4gIC8vIHN1c3BlbmRlZCBpdCBoYXMgcmVzb2x2ZWQsIHdoaWNoIG1lYW5zIGF0IGxlYXN0IHBhcnQgb2YgdGhlIHRyZWUgd2FzXG4gIC8vIGxpa2VseSB1bmJsb2NrZWQuIFRyeSByZW5kZXJpbmcgYWdhaW4sIGF0IGEgbmV3IGxhbmVzLlxuICBpZiAocmV0cnlMYW5lID09PSBOb0xhbmUpIHtcbiAgICAvLyBUT0RPOiBBc3NpZ24gdGhpcyB0byBgc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmVgPyB0byBhdm9pZFxuICAgIC8vIHVubmVjZXNzYXJ5IGVudGFuZ2xlbWVudD9cbiAgICByZXRyeUxhbmUgPSByZXF1ZXN0UmV0cnlMYW5lKGJvdW5kYXJ5RmliZXIpO1xuICB9IC8vIFRPRE86IFNwZWNpYWwgY2FzZSBpZGxlIHByaW9yaXR5P1xuXG5cbiAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIG1hcmtSb290VXBkYXRlZChyb290LCByZXRyeUxhbmUsIGV2ZW50VGltZSk7XG4gICAgZW5zdXJlUm9vdElzU2NoZWR1bGVkKHJvb3QsIGV2ZW50VGltZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmV0cnlEZWh5ZHJhdGVkU3VzcGVuc2VCb3VuZGFyeShib3VuZGFyeUZpYmVyKSB7XG4gIHZhciBzdXNwZW5zZVN0YXRlID0gYm91bmRhcnlGaWJlci5tZW1vaXplZFN0YXRlO1xuICB2YXIgcmV0cnlMYW5lID0gTm9MYW5lO1xuXG4gIGlmIChzdXNwZW5zZVN0YXRlICE9PSBudWxsKSB7XG4gICAgcmV0cnlMYW5lID0gc3VzcGVuc2VTdGF0ZS5yZXRyeUxhbmU7XG4gIH1cblxuICByZXRyeVRpbWVkT3V0Qm91bmRhcnkoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKTtcbn1cbmZ1bmN0aW9uIHJlc29sdmVSZXRyeVdha2VhYmxlKGJvdW5kYXJ5RmliZXIsIHdha2VhYmxlKSB7XG4gIHZhciByZXRyeUxhbmUgPSBOb0xhbmU7IC8vIERlZmF1bHRcblxuICB2YXIgcmV0cnlDYWNoZTtcblxuICBzd2l0Y2ggKGJvdW5kYXJ5RmliZXIudGFnKSB7XG4gICAgY2FzZSBTdXNwZW5zZUNvbXBvbmVudDpcbiAgICAgIHJldHJ5Q2FjaGUgPSBib3VuZGFyeUZpYmVyLnN0YXRlTm9kZTtcbiAgICAgIHZhciBzdXNwZW5zZVN0YXRlID0gYm91bmRhcnlGaWJlci5tZW1vaXplZFN0YXRlO1xuXG4gICAgICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICByZXRyeUxhbmUgPSBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZTtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFN1c3BlbnNlTGlzdENvbXBvbmVudDpcbiAgICAgIHJldHJ5Q2FjaGUgPSBib3VuZGFyeUZpYmVyLnN0YXRlTm9kZTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGluZ2VkIHVua25vd24gc3VzcGVuc2UgYm91bmRhcnkgdHlwZS4gJyArICdUaGlzIGlzIHByb2JhYmx5IGEgYnVnIGluIFJlYWN0LicpO1xuICB9XG5cbiAgaWYgKHJldHJ5Q2FjaGUgIT09IG51bGwpIHtcbiAgICAvLyBUaGUgd2FrZWFibGUgcmVzb2x2ZWQsIHNvIHdlIG5vIGxvbmdlciBuZWVkIHRvIG1lbW9pemUsIGJlY2F1c2UgaXQgd2lsbFxuICAgIC8vIG5ldmVyIGJlIHRocm93biBhZ2Fpbi5cbiAgICByZXRyeUNhY2hlLmRlbGV0ZSh3YWtlYWJsZSk7XG4gIH1cblxuICByZXRyeVRpbWVkT3V0Qm91bmRhcnkoYm91bmRhcnlGaWJlciwgcmV0cnlMYW5lKTtcbn0gLy8gQ29tcHV0ZXMgdGhlIG5leHQgSnVzdCBOb3RpY2VhYmxlIERpZmZlcmVuY2UgKEpORCkgYm91bmRhcnkuXG4vLyBUaGUgdGhlb3J5IGlzIHRoYXQgYSBwZXJzb24gY2FuJ3QgdGVsbCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHNtYWxsIGRpZmZlcmVuY2VzIGluIHRpbWUuXG4vLyBUaGVyZWZvcmUsIGlmIHdlIHdhaXQgYSBiaXQgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IHRoYXQgd29uJ3QgdHJhbnNsYXRlIHRvIGEgbm90aWNlYWJsZVxuLy8gZGlmZmVyZW5jZSBpbiB0aGUgZXhwZXJpZW5jZS4gSG93ZXZlciwgd2FpdGluZyBmb3IgbG9uZ2VyIG1pZ2h0IG1lYW4gdGhhdCB3ZSBjYW4gYXZvaWRcbi8vIHNob3dpbmcgYW4gaW50ZXJtZWRpYXRlIGxvYWRpbmcgc3RhdGUuIFRoZSBsb25nZXIgd2UgaGF2ZSBhbHJlYWR5IHdhaXRlZCwgdGhlIGhhcmRlciBpdFxuLy8gaXMgdG8gdGVsbCBzbWFsbCBkaWZmZXJlbmNlcyBpbiB0aW1lLiBUaGVyZWZvcmUsIHRoZSBsb25nZXIgd2UndmUgYWxyZWFkeSB3YWl0ZWQsXG4vLyB0aGUgbG9uZ2VyIHdlIGNhbiB3YWl0IGFkZGl0aW9uYWxseS4gQXQgc29tZSBwb2ludCB3ZSBoYXZlIHRvIGdpdmUgdXAgdGhvdWdoLlxuLy8gV2UgcGljayBhIHRyYWluIG1vZGVsIHdoZXJlIHRoZSBuZXh0IGJvdW5kYXJ5IGNvbW1pdHMgYXQgYSBjb25zaXN0ZW50IHNjaGVkdWxlLlxuLy8gVGhlc2UgcGFydGljdWxhciBudW1iZXJzIGFyZSB2YWd1ZSBlc3RpbWF0ZXMuIFdlIGV4cGVjdCB0byBhZGp1c3QgdGhlbSBiYXNlZCBvbiByZXNlYXJjaC5cblxuZnVuY3Rpb24gam5kKHRpbWVFbGFwc2VkKSB7XG4gIHJldHVybiB0aW1lRWxhcHNlZCA8IDEyMCA/IDEyMCA6IHRpbWVFbGFwc2VkIDwgNDgwID8gNDgwIDogdGltZUVsYXBzZWQgPCAxMDgwID8gMTA4MCA6IHRpbWVFbGFwc2VkIDwgMTkyMCA/IDE5MjAgOiB0aW1lRWxhcHNlZCA8IDMwMDAgPyAzMDAwIDogdGltZUVsYXBzZWQgPCA0MzIwID8gNDMyMCA6IGNlaWwodGltZUVsYXBzZWQgLyAxOTYwKSAqIDE5NjA7XG59XG5cbmZ1bmN0aW9uIGNoZWNrRm9yTmVzdGVkVXBkYXRlcygpIHtcbiAgaWYgKG5lc3RlZFVwZGF0ZUNvdW50ID4gTkVTVEVEX1VQREFURV9MSU1JVCkge1xuICAgIG5lc3RlZFVwZGF0ZUNvdW50ID0gMDtcbiAgICByb290V2l0aE5lc3RlZFVwZGF0ZXMgPSBudWxsO1xuICAgIHRocm93IG5ldyBFcnJvcignTWF4aW11bSB1cGRhdGUgZGVwdGggZXhjZWVkZWQuIFRoaXMgY2FuIGhhcHBlbiB3aGVuIGEgY29tcG9uZW50ICcgKyAncmVwZWF0ZWRseSBjYWxscyBzZXRTdGF0ZSBpbnNpZGUgY29tcG9uZW50V2lsbFVwZGF0ZSBvciAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZS4gUmVhY3QgbGltaXRzIHRoZSBudW1iZXIgb2YgbmVzdGVkIHVwZGF0ZXMgdG8gJyArICdwcmV2ZW50IGluZmluaXRlIGxvb3BzLicpO1xuICB9XG5cbiAge1xuICAgIGlmIChuZXN0ZWRQYXNzaXZlVXBkYXRlQ291bnQgPiBORVNURURfUEFTU0lWRV9VUERBVEVfTElNSVQpIHtcbiAgICAgIG5lc3RlZFBhc3NpdmVVcGRhdGVDb3VudCA9IDA7XG4gICAgICByb290V2l0aFBhc3NpdmVOZXN0ZWRVcGRhdGVzID0gbnVsbDtcblxuICAgICAgZXJyb3IoJ01heGltdW0gdXBkYXRlIGRlcHRoIGV4Y2VlZGVkLiBUaGlzIGNhbiBoYXBwZW4gd2hlbiBhIGNvbXBvbmVudCAnICsgXCJjYWxscyBzZXRTdGF0ZSBpbnNpZGUgdXNlRWZmZWN0LCBidXQgdXNlRWZmZWN0IGVpdGhlciBkb2Vzbid0IFwiICsgJ2hhdmUgYSBkZXBlbmRlbmN5IGFycmF5LCBvciBvbmUgb2YgdGhlIGRlcGVuZGVuY2llcyBjaGFuZ2VzIG9uICcgKyAnZXZlcnkgcmVuZGVyLicpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmbHVzaFJlbmRlclBoYXNlU3RyaWN0TW9kZVdhcm5pbmdzSW5ERVYoKSB7XG4gIHtcbiAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaExlZ2FjeUNvbnRleHRXYXJuaW5nKCk7XG5cbiAgICB7XG4gICAgICBSZWFjdFN0cmljdE1vZGVXYXJuaW5ncy5mbHVzaFBlbmRpbmdVbnNhZmVMaWZlY3ljbGVXYXJuaW5ncygpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21taXREb3VibGVJbnZva2VFZmZlY3RzSW5ERVYoZmliZXIsIGhhc1Bhc3NpdmVFZmZlY3RzKSB7XG4gIHtcbiAgICAvLyBUT0RPIChTdHJpY3RFZmZlY3RzKSBTaG91bGQgd2Ugc2V0IGEgbWFya2VyIG9uIHRoZSByb290IGlmIGl0IGNvbnRhaW5zIHN0cmljdCBlZmZlY3RzXG4gICAgLy8gc28gd2UgZG9uJ3QgdHJhdmVyc2UgdW5uZWNlc3NhcmlseT8gc2ltaWxhciB0byBzdWJ0cmVlRmxhZ3MgYnV0IGp1c3QgYXQgdGhlIHJvb3QgbGV2ZWwuXG4gICAgLy8gTWF5YmUgbm90IGEgYmlnIGRlYWwgc2luY2UgdGhpcyBpcyBERVYgb25seSBiZWhhdmlvci5cbiAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgIGludm9rZUVmZmVjdHNJbkRldihmaWJlciwgTW91bnRMYXlvdXREZXYsIGludm9rZUxheW91dEVmZmVjdFVubW91bnRJbkRFVik7XG5cbiAgICBpZiAoaGFzUGFzc2l2ZUVmZmVjdHMpIHtcbiAgICAgIGludm9rZUVmZmVjdHNJbkRldihmaWJlciwgTW91bnRQYXNzaXZlRGV2LCBpbnZva2VQYXNzaXZlRWZmZWN0VW5tb3VudEluREVWKTtcbiAgICB9XG5cbiAgICBpbnZva2VFZmZlY3RzSW5EZXYoZmliZXIsIE1vdW50TGF5b3V0RGV2LCBpbnZva2VMYXlvdXRFZmZlY3RNb3VudEluREVWKTtcblxuICAgIGlmIChoYXNQYXNzaXZlRWZmZWN0cykge1xuICAgICAgaW52b2tlRWZmZWN0c0luRGV2KGZpYmVyLCBNb3VudFBhc3NpdmVEZXYsIGludm9rZVBhc3NpdmVFZmZlY3RNb3VudEluREVWKTtcbiAgICB9XG5cbiAgICByZXNldEN1cnJlbnRGaWJlcigpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZUVmZmVjdHNJbkRldihmaXJzdENoaWxkLCBmaWJlckZsYWdzLCBpbnZva2VFZmZlY3RGbikge1xuICB7XG4gICAgLy8gV2UgZG9uJ3QgbmVlZCB0byByZS1jaGVjayBTdHJpY3RFZmZlY3RzTW9kZSBoZXJlLlxuICAgIC8vIFRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWQgaWYgdGhhdCBjaGVjayBoYXMgYWxyZWFkeSBwYXNzZWQuXG4gICAgdmFyIGN1cnJlbnQgPSBmaXJzdENoaWxkO1xuICAgIHZhciBzdWJ0cmVlUm9vdCA9IG51bGw7XG5cbiAgICB3aGlsZSAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgdmFyIHByaW1hcnlTdWJ0cmVlRmxhZyA9IGN1cnJlbnQuc3VidHJlZUZsYWdzICYgZmliZXJGbGFncztcblxuICAgICAgaWYgKGN1cnJlbnQgIT09IHN1YnRyZWVSb290ICYmIGN1cnJlbnQuY2hpbGQgIT09IG51bGwgJiYgcHJpbWFyeVN1YnRyZWVGbGFnICE9PSBOb0ZsYWdzKSB7XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LmNoaWxkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKChjdXJyZW50LmZsYWdzICYgZmliZXJGbGFncykgIT09IE5vRmxhZ3MpIHtcbiAgICAgICAgICBpbnZva2VFZmZlY3RGbihjdXJyZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjdXJyZW50LnNpYmxpbmcgIT09IG51bGwpIHtcbiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5zaWJsaW5nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGN1cnJlbnQgPSBzdWJ0cmVlUm9vdCA9IGN1cnJlbnQucmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50ID0gbnVsbDtcbmZ1bmN0aW9uIHdhcm5BYm91dFVwZGF0ZU9uTm90WWV0TW91bnRlZEZpYmVySW5ERVYoZmliZXIpIHtcbiAge1xuICAgIGlmICgoZXhlY3V0aW9uQ29udGV4dCAmIFJlbmRlckNvbnRleHQpICE9PSBOb0NvbnRleHQpIHtcbiAgICAgIC8vIFdlIGxldCB0aGUgb3RoZXIgd2FybmluZyBhYm91dCByZW5kZXIgcGhhc2UgdXBkYXRlcyBkZWFsIHdpdGggdGhpcyBvbmUuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCEoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0YWcgPSBmaWJlci50YWc7XG5cbiAgICBpZiAodGFnICE9PSBJbmRldGVybWluYXRlQ29tcG9uZW50ICYmIHRhZyAhPT0gSG9zdFJvb3QgJiYgdGFnICE9PSBDbGFzc0NvbXBvbmVudCAmJiB0YWcgIT09IEZ1bmN0aW9uQ29tcG9uZW50ICYmIHRhZyAhPT0gRm9yd2FyZFJlZiAmJiB0YWcgIT09IE1lbW9Db21wb25lbnQgJiYgdGFnICE9PSBTaW1wbGVNZW1vQ29tcG9uZW50KSB7XG4gICAgICAvLyBPbmx5IHdhcm4gZm9yIHVzZXItZGVmaW5lZCBjb21wb25lbnRzLCBub3QgaW50ZXJuYWwgb25lcyBsaWtlIFN1c3BlbnNlLlxuICAgICAgcmV0dXJuO1xuICAgIH0gLy8gV2Ugc2hvdyB0aGUgd2hvbGUgc3RhY2sgYnV0IGRlZHVwZSBvbiB0aGUgdG9wIGNvbXBvbmVudCdzIG5hbWUgYmVjYXVzZVxuICAgIC8vIHRoZSBwcm9ibGVtYXRpYyBjb2RlIGFsbW9zdCBhbHdheXMgbGllcyBpbnNpZGUgdGhhdCBjb21wb25lbnQuXG5cblxuICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ1JlYWN0Q29tcG9uZW50JztcblxuICAgIGlmIChkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50ICE9PSBudWxsKSB7XG4gICAgICBpZiAoZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudC5oYXMoY29tcG9uZW50TmFtZSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBkaWRXYXJuU3RhdGVVcGRhdGVGb3JOb3RZZXRNb3VudGVkQ29tcG9uZW50LmFkZChjb21wb25lbnROYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGlkV2FyblN0YXRlVXBkYXRlRm9yTm90WWV0TW91bnRlZENvbXBvbmVudCA9IG5ldyBTZXQoW2NvbXBvbmVudE5hbWVdKTtcbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICB0cnkge1xuICAgICAgc2V0Q3VycmVudEZpYmVyKGZpYmVyKTtcblxuICAgICAgZXJyb3IoXCJDYW4ndCBwZXJmb3JtIGEgUmVhY3Qgc3RhdGUgdXBkYXRlIG9uIGEgY29tcG9uZW50IHRoYXQgaGFzbid0IG1vdW50ZWQgeWV0LiBcIiArICdUaGlzIGluZGljYXRlcyB0aGF0IHlvdSBoYXZlIGEgc2lkZS1lZmZlY3QgaW4geW91ciByZW5kZXIgZnVuY3Rpb24gdGhhdCAnICsgJ2FzeW5jaHJvbm91c2x5IGxhdGVyIGNhbGxzIHRyaWVzIHRvIHVwZGF0ZSB0aGUgY29tcG9uZW50LiBNb3ZlIHRoaXMgd29yayB0byAnICsgJ3VzZUVmZmVjdCBpbnN0ZWFkLicpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAocHJldmlvdXNGaWJlcikge1xuICAgICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRDdXJyZW50RmliZXIoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbnZhciBiZWdpbldvcmskMTtcblxue1xuICB2YXIgZHVtbXlGaWJlciA9IG51bGw7XG5cbiAgYmVnaW5Xb3JrJDEgPSBmdW5jdGlvbiAoY3VycmVudCwgdW5pdE9mV29yaywgbGFuZXMpIHtcbiAgICAvLyBJZiBhIGNvbXBvbmVudCB0aHJvd3MgYW4gZXJyb3IsIHdlIHJlcGxheSBpdCBhZ2FpbiBpbiBhIHN5bmNocm9ub3VzbHlcbiAgICAvLyBkaXNwYXRjaGVkIGV2ZW50LCBzbyB0aGF0IHRoZSBkZWJ1Z2dlciB3aWxsIHRyZWF0IGl0IGFzIGFuIHVuY2F1Z2h0XG4gICAgLy8gZXJyb3IgU2VlIFJlYWN0RXJyb3JVdGlscyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICAvLyBCZWZvcmUgZW50ZXJpbmcgdGhlIGJlZ2luIHBoYXNlLCBjb3B5IHRoZSB3b3JrLWluLXByb2dyZXNzIG9udG8gYSBkdW1teVxuICAgIC8vIGZpYmVyLiBJZiBiZWdpbldvcmsgdGhyb3dzLCB3ZSdsbCB1c2UgdGhpcyB0byByZXNldCB0aGUgc3RhdGUuXG4gICAgdmFyIG9yaWdpbmFsV29ya0luUHJvZ3Jlc3NDb3B5ID0gYXNzaWduRmliZXJQcm9wZXJ0aWVzSW5ERVYoZHVtbXlGaWJlciwgdW5pdE9mV29yayk7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGJlZ2luV29yayhjdXJyZW50LCB1bml0T2ZXb3JrLCBsYW5lcyk7XG4gICAgfSBjYXRjaCAob3JpZ2luYWxFcnJvcikge1xuICAgICAgaWYgKGRpZFN1c3BlbmRPckVycm9yV2hpbGVIeWRyYXRpbmdERVYoKSB8fCBvcmlnaW5hbEVycm9yICE9PSBudWxsICYmIHR5cGVvZiBvcmlnaW5hbEVycm9yID09PSAnb2JqZWN0JyAmJiB0eXBlb2Ygb3JpZ2luYWxFcnJvci50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIERvbid0IHJlcGxheSBwcm9taXNlcy5cbiAgICAgICAgLy8gRG9uJ3QgcmVwbGF5IGVycm9ycyBpZiB3ZSBhcmUgaHlkcmF0aW5nIGFuZCBoYXZlIGFscmVhZHkgc3VzcGVuZGVkIG9yIGhhbmRsZWQgYW4gZXJyb3JcbiAgICAgICAgdGhyb3cgb3JpZ2luYWxFcnJvcjtcbiAgICAgIH0gLy8gS2VlcCB0aGlzIGNvZGUgaW4gc3luYyB3aXRoIGhhbmRsZUVycm9yOyBhbnkgY2hhbmdlcyBoZXJlIG11c3QgaGF2ZVxuICAgICAgLy8gY29ycmVzcG9uZGluZyBjaGFuZ2VzIHRoZXJlLlxuXG5cbiAgICAgIHJlc2V0Q29udGV4dERlcGVuZGVuY2llcygpO1xuICAgICAgcmVzZXRIb29rc0FmdGVyVGhyb3coKTsgLy8gRG9uJ3QgcmVzZXQgY3VycmVudCBkZWJ1ZyBmaWJlciwgc2luY2Ugd2UncmUgYWJvdXQgdG8gd29yayBvbiB0aGVcbiAgICAgIC8vIHNhbWUgZmliZXIgYWdhaW4uXG4gICAgICAvLyBVbndpbmQgdGhlIGZhaWxlZCBzdGFjayBmcmFtZVxuXG4gICAgICB1bndpbmRJbnRlcnJ1cHRlZFdvcmsoY3VycmVudCwgdW5pdE9mV29yayk7IC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3BlcnRpZXMgb2YgdGhlIGZpYmVyLlxuXG4gICAgICBhc3NpZ25GaWJlclByb3BlcnRpZXNJbkRFVih1bml0T2ZXb3JrLCBvcmlnaW5hbFdvcmtJblByb2dyZXNzQ29weSk7XG5cbiAgICAgIGlmICggdW5pdE9mV29yay5tb2RlICYgUHJvZmlsZU1vZGUpIHtcbiAgICAgICAgLy8gUmVzZXQgdGhlIHByb2ZpbGVyIHRpbWVyLlxuICAgICAgICBzdGFydFByb2ZpbGVyVGltZXIodW5pdE9mV29yayk7XG4gICAgICB9IC8vIFJ1biBiZWdpbldvcmsgYWdhaW4uXG5cblxuICAgICAgaW52b2tlR3VhcmRlZENhbGxiYWNrKG51bGwsIGJlZ2luV29yaywgbnVsbCwgY3VycmVudCwgdW5pdE9mV29yaywgbGFuZXMpO1xuXG4gICAgICBpZiAoaGFzQ2F1Z2h0RXJyb3IoKSkge1xuICAgICAgICB2YXIgcmVwbGF5RXJyb3IgPSBjbGVhckNhdWdodEVycm9yKCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiByZXBsYXlFcnJvciA9PT0gJ29iamVjdCcgJiYgcmVwbGF5RXJyb3IgIT09IG51bGwgJiYgcmVwbGF5RXJyb3IuX3N1cHByZXNzTG9nZ2luZyAmJiB0eXBlb2Ygb3JpZ2luYWxFcnJvciA9PT0gJ29iamVjdCcgJiYgb3JpZ2luYWxFcnJvciAhPT0gbnVsbCAmJiAhb3JpZ2luYWxFcnJvci5fc3VwcHJlc3NMb2dnaW5nKSB7XG4gICAgICAgICAgLy8gSWYgc3VwcHJlc3NlZCwgbGV0IHRoZSBmbGFnIGNhcnJ5IG92ZXIgdG8gdGhlIG9yaWdpbmFsIGVycm9yIHdoaWNoIGlzIHRoZSBvbmUgd2UnbGwgcmV0aHJvdy5cbiAgICAgICAgICBvcmlnaW5hbEVycm9yLl9zdXBwcmVzc0xvZ2dpbmcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9IC8vIFdlIGFsd2F5cyB0aHJvdyB0aGUgb3JpZ2luYWwgZXJyb3IgaW4gY2FzZSB0aGUgc2Vjb25kIHJlbmRlciBwYXNzIGlzIG5vdCBpZGVtcG90ZW50LlxuICAgICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIGEgbWVtb2l6ZWQgZnVuY3Rpb24gb3IgQ29tbW9uSlMgbW9kdWxlIGRvZXNuJ3QgdGhyb3cgYWZ0ZXIgZmlyc3QgaW52b2NhdGlvbi5cblxuXG4gICAgICB0aHJvdyBvcmlnaW5hbEVycm9yO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyID0gZmFsc2U7XG52YXIgZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXJGb3JBbm90aGVyQ29tcG9uZW50O1xuXG57XG4gIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyRm9yQW5vdGhlckNvbXBvbmVudCA9IG5ldyBTZXQoKTtcbn1cblxuZnVuY3Rpb24gd2FybkFib3V0UmVuZGVyUGhhc2VVcGRhdGVzSW5ERVYoZmliZXIpIHtcbiAge1xuICAgIGlmIChpc1JlbmRlcmluZyAmJiAhZ2V0SXNVcGRhdGluZ09wYXF1ZVZhbHVlSW5SZW5kZXJQaGFzZUluREVWKCkpIHtcbiAgICAgIHN3aXRjaCAoZmliZXIudGFnKSB7XG4gICAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHZhciByZW5kZXJpbmdDb21wb25lbnROYW1lID0gd29ya0luUHJvZ3Jlc3MgJiYgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcih3b3JrSW5Qcm9ncmVzcykgfHwgJ1Vua25vd24nOyAvLyBEZWR1cGUgYnkgdGhlIHJlbmRlcmluZyBjb21wb25lbnQgYmVjYXVzZSBpdCdzIHRoZSBvbmUgdGhhdCBuZWVkcyB0byBiZSBmaXhlZC5cblxuICAgICAgICAgICAgdmFyIGRlZHVwZUtleSA9IHJlbmRlcmluZ0NvbXBvbmVudE5hbWU7XG5cbiAgICAgICAgICAgIGlmICghZGlkV2FybkFib3V0VXBkYXRlSW5SZW5kZXJGb3JBbm90aGVyQ29tcG9uZW50LmhhcyhkZWR1cGVLZXkpKSB7XG4gICAgICAgICAgICAgIGRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyRm9yQW5vdGhlckNvbXBvbmVudC5hZGQoZGVkdXBlS2V5KTtcbiAgICAgICAgICAgICAgdmFyIHNldFN0YXRlQ29tcG9uZW50TmFtZSA9IGdldENvbXBvbmVudE5hbWVGcm9tRmliZXIoZmliZXIpIHx8ICdVbmtub3duJztcblxuICAgICAgICAgICAgICBlcnJvcignQ2Fubm90IHVwZGF0ZSBhIGNvbXBvbmVudCAoYCVzYCkgd2hpbGUgcmVuZGVyaW5nIGEgJyArICdkaWZmZXJlbnQgY29tcG9uZW50IChgJXNgKS4gVG8gbG9jYXRlIHRoZSBiYWQgc2V0U3RhdGUoKSBjYWxsIGluc2lkZSBgJXNgLCAnICsgJ2ZvbGxvdyB0aGUgc3RhY2sgdHJhY2UgYXMgZGVzY3JpYmVkIGluIGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zZXRzdGF0ZS1pbi1yZW5kZXInLCBzZXRTdGF0ZUNvbXBvbmVudE5hbWUsIHJlbmRlcmluZ0NvbXBvbmVudE5hbWUsIHJlbmRlcmluZ0NvbXBvbmVudE5hbWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZiAoIWRpZFdhcm5BYm91dFVwZGF0ZUluUmVuZGVyKSB7XG4gICAgICAgICAgICAgIGVycm9yKCdDYW5ub3QgdXBkYXRlIGR1cmluZyBhbiBleGlzdGluZyBzdGF0ZSB0cmFuc2l0aW9uIChzdWNoIGFzICcgKyAnd2l0aGluIGByZW5kZXJgKS4gUmVuZGVyIG1ldGhvZHMgc2hvdWxkIGJlIGEgcHVyZSAnICsgJ2Z1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4nKTtcblxuICAgICAgICAgICAgICBkaWRXYXJuQWJvdXRVcGRhdGVJblJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzdG9yZVBlbmRpbmdVcGRhdGVycyhyb290LCBsYW5lcykge1xuICB7XG4gICAgaWYgKGlzRGV2VG9vbHNQcmVzZW50KSB7XG4gICAgICB2YXIgbWVtb2l6ZWRVcGRhdGVycyA9IHJvb3QubWVtb2l6ZWRVcGRhdGVycztcbiAgICAgIG1lbW9pemVkVXBkYXRlcnMuZm9yRWFjaChmdW5jdGlvbiAoc2NoZWR1bGluZ0ZpYmVyKSB7XG4gICAgICAgIGFkZEZpYmVyVG9MYW5lc01hcChyb290LCBzY2hlZHVsaW5nRmliZXIsIGxhbmVzKTtcbiAgICAgIH0pOyAvLyBUaGlzIGZ1bmN0aW9uIGludGVudGlvbmFsbHkgZG9lcyBub3QgY2xlYXIgbWVtb2l6ZWQgdXBkYXRlcnMuXG4gICAgICAvLyBUaG9zZSBtYXkgc3RpbGwgYmUgcmVsZXZhbnQgdG8gdGhlIGN1cnJlbnQgY29tbWl0XG4gICAgICAvLyBhbmQgYSBmdXR1cmUgb25lIChlLmcuIFN1c3BlbnNlKS5cbiAgICB9XG4gIH1cbn1cbnZhciBmYWtlQWN0Q2FsbGJhY2tOb2RlID0ge307XG5cbmZ1bmN0aW9uIHNjaGVkdWxlQ2FsbGJhY2skMShwcmlvcml0eUxldmVsLCBjYWxsYmFjaykge1xuICB7XG4gICAgLy8gSWYgd2UncmUgY3VycmVudGx5IGluc2lkZSBhbiBgYWN0YCBzY29wZSwgYnlwYXNzIFNjaGVkdWxlciBhbmQgcHVzaCB0b1xuICAgIC8vIHRoZSBgYWN0YCBxdWV1ZSBpbnN0ZWFkLlxuICAgIHZhciBhY3RRdWV1ZSA9IFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudDtcblxuICAgIGlmIChhY3RRdWV1ZSAhPT0gbnVsbCkge1xuICAgICAgYWN0UXVldWUucHVzaChjYWxsYmFjayk7XG4gICAgICByZXR1cm4gZmFrZUFjdENhbGxiYWNrTm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNjaGVkdWxlQ2FsbGJhY2socHJpb3JpdHlMZXZlbCwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjYW5jZWxDYWxsYmFjayQxKGNhbGxiYWNrTm9kZSkge1xuICBpZiAoIGNhbGxiYWNrTm9kZSA9PT0gZmFrZUFjdENhbGxiYWNrTm9kZSkge1xuICAgIHJldHVybjtcbiAgfSAvLyBJbiBwcm9kdWN0aW9uLCBhbHdheXMgY2FsbCBTY2hlZHVsZXIuIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBzdHJpcHBlZCBvdXQuXG5cblxuICByZXR1cm4gY2FuY2VsQ2FsbGJhY2soY2FsbGJhY2tOb2RlKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkRm9yY2VGbHVzaEZhbGxiYWNrc0luREVWKCkge1xuICAvLyBOZXZlciBmb3JjZSBmbHVzaCBpbiBwcm9kdWN0aW9uLiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBnZXQgc3RyaXBwZWQgb3V0LlxuICByZXR1cm4gIFJlYWN0Q3VycmVudEFjdFF1ZXVlJDEuY3VycmVudCAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gd2FybklmVXBkYXRlc05vdFdyYXBwZWRXaXRoQWN0REVWKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAoZmliZXIubW9kZSAmIENvbmN1cnJlbnRNb2RlKSB7XG4gICAgICBpZiAoIWlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkpIHtcbiAgICAgICAgLy8gTm90IGluIGFuIGFjdCBlbnZpcm9ubWVudC4gTm8gbmVlZCB0byB3YXJuLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIExlZ2FjeSBtb2RlIGhhcyBhZGRpdGlvbmFsIGNhc2VzIHdoZXJlIHdlIHN1cHByZXNzIGEgd2FybmluZy5cbiAgICAgIGlmICghaXNMZWdhY3lBY3RFbnZpcm9ubWVudCgpKSB7XG4gICAgICAgIC8vIE5vdCBpbiBhbiBhY3QgZW52aXJvbm1lbnQuIE5vIG5lZWQgdG8gd2Fybi5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXhlY3V0aW9uQ29udGV4dCAhPT0gTm9Db250ZXh0KSB7XG4gICAgICAgIC8vIExlZ2FjeSBtb2RlIGRvZXNuJ3Qgd2FybiBpZiB0aGUgdXBkYXRlIGlzIGJhdGNoZWQsIGkuZS5cbiAgICAgICAgLy8gYmF0Y2hlZFVwZGF0ZXMgb3IgZmx1c2hTeW5jLlxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWJlci50YWcgIT09IEZ1bmN0aW9uQ29tcG9uZW50ICYmIGZpYmVyLnRhZyAhPT0gRm9yd2FyZFJlZiAmJiBmaWJlci50YWcgIT09IFNpbXBsZU1lbW9Db21wb25lbnQpIHtcbiAgICAgICAgLy8gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdpdGggcHJlLWhvb2tzIGNvZGUsIGxlZ2FjeSBtb2RlIG9ubHlcbiAgICAgICAgLy8gd2FybnMgZm9yIHVwZGF0ZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSBhIGhvb2suXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHNldEN1cnJlbnRGaWJlcihmaWJlcik7XG5cbiAgICAgICAgZXJyb3IoJ0FuIHVwZGF0ZSB0byAlcyBpbnNpZGUgYSB0ZXN0IHdhcyBub3Qgd3JhcHBlZCBpbiBhY3QoLi4uKS5cXG5cXG4nICsgJ1doZW4gdGVzdGluZywgY29kZSB0aGF0IGNhdXNlcyBSZWFjdCBzdGF0ZSB1cGRhdGVzIHNob3VsZCBiZSAnICsgJ3dyYXBwZWQgaW50byBhY3QoLi4uKTpcXG5cXG4nICsgJ2FjdCgoKSA9PiB7XFxuJyArICcgIC8qIGZpcmUgZXZlbnRzIHRoYXQgdXBkYXRlIHN0YXRlICovXFxuJyArICd9KTtcXG4nICsgJy8qIGFzc2VydCBvbiB0aGUgb3V0cHV0ICovXFxuXFxuJyArIFwiVGhpcyBlbnN1cmVzIHRoYXQgeW91J3JlIHRlc3RpbmcgdGhlIGJlaGF2aW9yIHRoZSB1c2VyIHdvdWxkIHNlZSBcIiArICdpbiB0aGUgYnJvd3Nlci4nICsgJyBMZWFybiBtb3JlIGF0IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay93cmFwLXRlc3RzLXdpdGgtYWN0JywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKHByZXZpb3VzRmliZXIpIHtcbiAgICAgICAgICBzZXRDdXJyZW50RmliZXIoZmliZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gd2FybklmU3VzcGVuc2VSZXNvbHV0aW9uTm90V3JhcHBlZFdpdGhBY3RERVYocm9vdCkge1xuICB7XG4gICAgaWYgKHJvb3QudGFnICE9PSBMZWdhY3lSb290ICYmIGlzQ29uY3VycmVudEFjdEVudmlyb25tZW50KCkgJiYgUmVhY3RDdXJyZW50QWN0UXVldWUkMS5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICBlcnJvcignQSBzdXNwZW5kZWQgcmVzb3VyY2UgZmluaXNoZWQgbG9hZGluZyBpbnNpZGUgYSB0ZXN0LCBidXQgdGhlIGV2ZW50ICcgKyAnd2FzIG5vdCB3cmFwcGVkIGluIGFjdCguLi4pLlxcblxcbicgKyAnV2hlbiB0ZXN0aW5nLCBjb2RlIHRoYXQgcmVzb2x2ZXMgc3VzcGVuZGVkIGRhdGEgc2hvdWxkIGJlIHdyYXBwZWQgJyArICdpbnRvIGFjdCguLi4pOlxcblxcbicgKyAnYWN0KCgpID0+IHtcXG4nICsgJyAgLyogZmluaXNoIGxvYWRpbmcgc3VzcGVuZGVkIGRhdGEgKi9cXG4nICsgJ30pO1xcbicgKyAnLyogYXNzZXJ0IG9uIHRoZSBvdXRwdXQgKi9cXG5cXG4nICsgXCJUaGlzIGVuc3VyZXMgdGhhdCB5b3UncmUgdGVzdGluZyB0aGUgYmVoYXZpb3IgdGhlIHVzZXIgd291bGQgc2VlIFwiICsgJ2luIHRoZSBicm93c2VyLicgKyAnIExlYXJuIG1vcmUgYXQgaHR0cHM6Ly9yZWFjdGpzLm9yZy9saW5rL3dyYXAtdGVzdHMtd2l0aC1hY3QnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0SXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0KGlzUnVubmluZykge1xuICB7XG4gICAgaXNSdW5uaW5nSW5zZXJ0aW9uRWZmZWN0ID0gaXNSdW5uaW5nO1xuICB9XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIHJlYWN0LWludGVybmFsL3Byb2QtZXJyb3ItY29kZXMgKi9cbnZhciByZXNvbHZlRmFtaWx5ID0gbnVsbDsgLy8gJEZsb3dGaXhNZSBGbG93IGdldHMgY29uZnVzZWQgYnkgYSBXZWFrU2V0IGZlYXR1cmUgY2hlY2sgYmVsb3cuXG5cbnZhciBmYWlsZWRCb3VuZGFyaWVzID0gbnVsbDtcbnZhciBzZXRSZWZyZXNoSGFuZGxlciA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gIHtcbiAgICByZXNvbHZlRmFtaWx5ID0gaGFuZGxlcjtcbiAgfVxufTtcbmZ1bmN0aW9uIHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyh0eXBlKSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH1cblxuICAgIHZhciBmYW1pbHkgPSByZXNvbHZlRmFtaWx5KHR5cGUpO1xuXG4gICAgaWYgKGZhbWlseSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9IC8vIFVzZSB0aGUgbGF0ZXN0IGtub3duIGltcGxlbWVudGF0aW9uLlxuXG5cbiAgICByZXR1cm4gZmFtaWx5LmN1cnJlbnQ7XG4gIH1cbn1cbmZ1bmN0aW9uIHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyh0eXBlKSB7XG4gIC8vIE5vIGltcGxlbWVudGF0aW9uIGRpZmZlcmVuY2VzLlxuICByZXR1cm4gcmVzb2x2ZUZ1bmN0aW9uRm9ySG90UmVsb2FkaW5nKHR5cGUpO1xufVxuZnVuY3Rpb24gcmVzb2x2ZUZvcndhcmRSZWZGb3JIb3RSZWxvYWRpbmcodHlwZSkge1xuICB7XG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIC8vIEhvdCByZWxvYWRpbmcgaXMgZGlzYWJsZWQuXG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9XG5cbiAgICB2YXIgZmFtaWx5ID0gcmVzb2x2ZUZhbWlseSh0eXBlKTtcblxuICAgIGlmIChmYW1pbHkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQ2hlY2sgaWYgd2UncmUgZGVhbGluZyB3aXRoIGEgcmVhbCBmb3J3YXJkUmVmLiBEb24ndCB3YW50IHRvIGNyYXNoIGVhcmx5LlxuICAgICAgaWYgKHR5cGUgIT09IG51bGwgJiYgdHlwZSAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiB0eXBlLnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBGb3J3YXJkUmVmIGlzIHNwZWNpYWwgYmVjYXVzZSBpdHMgcmVzb2x2ZWQgLnR5cGUgaXMgYW4gb2JqZWN0LFxuICAgICAgICAvLyBidXQgaXQncyBwb3NzaWJsZSB0aGF0IHdlIG9ubHkgaGF2ZSBpdHMgaW5uZXIgcmVuZGVyIGZ1bmN0aW9uIGluIHRoZSBtYXAuXG4gICAgICAgIC8vIElmIHRoYXQgaW5uZXIgcmVuZGVyIGZ1bmN0aW9uIGlzIGRpZmZlcmVudCwgd2UnbGwgYnVpbGQgYSBuZXcgZm9yd2FyZFJlZiB0eXBlLlxuICAgICAgICB2YXIgY3VycmVudFJlbmRlciA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyh0eXBlLnJlbmRlcik7XG5cbiAgICAgICAgaWYgKHR5cGUucmVuZGVyICE9PSBjdXJyZW50UmVuZGVyKSB7XG4gICAgICAgICAgdmFyIHN5bnRoZXRpY1R5cGUgPSB7XG4gICAgICAgICAgICAkJHR5cGVvZjogUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSxcbiAgICAgICAgICAgIHJlbmRlcjogY3VycmVudFJlbmRlclxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBpZiAodHlwZS5kaXNwbGF5TmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBzeW50aGV0aWNUeXBlLmRpc3BsYXlOYW1lID0gdHlwZS5kaXNwbGF5TmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gc3ludGhldGljVHlwZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHlwZTtcbiAgICB9IC8vIFVzZSB0aGUgbGF0ZXN0IGtub3duIGltcGxlbWVudGF0aW9uLlxuXG5cbiAgICByZXR1cm4gZmFtaWx5LmN1cnJlbnQ7XG4gIH1cbn1cbmZ1bmN0aW9uIGlzQ29tcGF0aWJsZUZhbWlseUZvckhvdFJlbG9hZGluZyhmaWJlciwgZWxlbWVudCkge1xuICB7XG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIC8vIEhvdCByZWxvYWRpbmcgaXMgZGlzYWJsZWQuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHByZXZUeXBlID0gZmliZXIuZWxlbWVudFR5cGU7XG4gICAgdmFyIG5leHRUeXBlID0gZWxlbWVudC50eXBlOyAvLyBJZiB3ZSBnb3QgaGVyZSwgd2Uga25vdyB0eXBlcyBhcmVuJ3QgPT09IGVxdWFsLlxuXG4gICAgdmFyIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gZmFsc2U7XG4gICAgdmFyICQkdHlwZW9mTmV4dFR5cGUgPSB0eXBlb2YgbmV4dFR5cGUgPT09ICdvYmplY3QnICYmIG5leHRUeXBlICE9PSBudWxsID8gbmV4dFR5cGUuJCR0eXBlb2YgOiBudWxsO1xuXG4gICAgc3dpdGNoIChmaWJlci50YWcpIHtcbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5leHRUeXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBuZWVkc0NvbXBhcmVGYW1pbGllcyA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBGdW5jdGlvbkNvbXBvbmVudDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICh0eXBlb2YgbmV4dFR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCQkdHlwZW9mTmV4dFR5cGUgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyB0aGUgaW5uZXIgdHlwZSB5ZXQuXG4gICAgICAgICAgICAvLyBXZSdyZSBnb2luZyB0byBhc3N1bWUgdGhhdCB0aGUgbGF6eSBpbm5lciB0eXBlIGlzIHN0YWJsZSxcbiAgICAgICAgICAgIC8vIGFuZCBzbyBpdCBpcyBzdWZmaWNpZW50IHRvIGF2b2lkIHJlY29uY2lsaW5nIGl0IGF3YXkuXG4gICAgICAgICAgICAvLyBXZSdyZSBub3QgZ29pbmcgdG8gdW53cmFwIG9yIGFjdHVhbGx5IHVzZSB0aGUgbmV3IGxhenkgdHlwZS5cbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSkge1xuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoJCR0eXBlb2ZOZXh0VHlwZSA9PT0gUkVBQ1RfTEFaWV9UWVBFKSB7XG4gICAgICAgICAgICBuZWVkc0NvbXBhcmVGYW1pbGllcyA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgY2FzZSBNZW1vQ29tcG9uZW50OlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgICB7XG4gICAgICAgICAgaWYgKCQkdHlwZW9mTmV4dFR5cGUgPT09IFJFQUNUX01FTU9fVFlQRSkge1xuICAgICAgICAgICAgLy8gVE9ETzogaWYgaXQgd2FzIGJ1dCBjYW4gbm8gbG9uZ2VyIGJlIHNpbXBsZSxcbiAgICAgICAgICAgIC8vIHdlIHNob3VsZG4ndCBzZXQgdGhpcy5cbiAgICAgICAgICAgIG5lZWRzQ29tcGFyZUZhbWlsaWVzID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCQkdHlwZW9mTmV4dFR5cGUgPT09IFJFQUNUX0xBWllfVFlQRSkge1xuICAgICAgICAgICAgbmVlZHNDb21wYXJlRmFtaWxpZXMgPSB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IC8vIENoZWNrIGlmIGJvdGggdHlwZXMgaGF2ZSBhIGZhbWlseSBhbmQgaXQncyB0aGUgc2FtZSBvbmUuXG5cblxuICAgIGlmIChuZWVkc0NvbXBhcmVGYW1pbGllcykge1xuICAgICAgLy8gTm90ZTogbWVtbygpIGFuZCBmb3J3YXJkUmVmKCkgd2UnbGwgY29tcGFyZSBvdXRlciByYXRoZXIgdGhhbiBpbm5lciB0eXBlLlxuICAgICAgLy8gVGhpcyBtZWFucyBib3RoIG9mIHRoZW0gbmVlZCB0byBiZSByZWdpc3RlcmVkIHRvIHByZXNlcnZlIHN0YXRlLlxuICAgICAgLy8gSWYgd2UgdW53cmFwcGVkIGFuZCBjb21wYXJlZCB0aGUgaW5uZXIgdHlwZXMgZm9yIHdyYXBwZXJzIGluc3RlYWQsXG4gICAgICAvLyB0aGVuIHdlIHdvdWxkIHJpc2sgZmFsc2VseSBzYXlpbmcgdHdvIHNlcGFyYXRlIG1lbW8oRm9vKVxuICAgICAgLy8gY2FsbHMgYXJlIGVxdWl2YWxlbnQgYmVjYXVzZSB0aGV5IHdyYXAgdGhlIHNhbWUgRm9vIGZ1bmN0aW9uLlxuICAgICAgdmFyIHByZXZGYW1pbHkgPSByZXNvbHZlRmFtaWx5KHByZXZUeXBlKTtcblxuICAgICAgaWYgKHByZXZGYW1pbHkgIT09IHVuZGVmaW5lZCAmJiBwcmV2RmFtaWx5ID09PSByZXNvbHZlRmFtaWx5KG5leHRUeXBlKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbmZ1bmN0aW9uIG1hcmtGYWlsZWRFcnJvckJvdW5kYXJ5Rm9ySG90UmVsb2FkaW5nKGZpYmVyKSB7XG4gIHtcbiAgICBpZiAocmVzb2x2ZUZhbWlseSA9PT0gbnVsbCkge1xuICAgICAgLy8gSG90IHJlbG9hZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIFdlYWtTZXQgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZmFpbGVkQm91bmRhcmllcyA9PT0gbnVsbCkge1xuICAgICAgZmFpbGVkQm91bmRhcmllcyA9IG5ldyBXZWFrU2V0KCk7XG4gICAgfVxuXG4gICAgZmFpbGVkQm91bmRhcmllcy5hZGQoZmliZXIpO1xuICB9XG59XG52YXIgc2NoZWR1bGVSZWZyZXNoID0gZnVuY3Rpb24gKHJvb3QsIHVwZGF0ZSkge1xuICB7XG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIC8vIEhvdCByZWxvYWRpbmcgaXMgZGlzYWJsZWQuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHN0YWxlRmFtaWxpZXMgPSB1cGRhdGUuc3RhbGVGYW1pbGllcyxcbiAgICAgICAgdXBkYXRlZEZhbWlsaWVzID0gdXBkYXRlLnVwZGF0ZWRGYW1pbGllcztcbiAgICBmbHVzaFBhc3NpdmVFZmZlY3RzKCk7XG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNjaGVkdWxlRmliZXJzV2l0aEZhbWlsaWVzUmVjdXJzaXZlbHkocm9vdC5jdXJyZW50LCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpO1xuICAgIH0pO1xuICB9XG59O1xudmFyIHNjaGVkdWxlUm9vdCA9IGZ1bmN0aW9uIChyb290LCBlbGVtZW50KSB7XG4gIHtcbiAgICBpZiAocm9vdC5jb250ZXh0ICE9PSBlbXB0eUNvbnRleHRPYmplY3QpIHtcbiAgICAgIC8vIFN1cGVyIGVkZ2UgY2FzZTogcm9vdCBoYXMgYSBsZWdhY3kgX3JlbmRlclN1YnRyZWUgY29udGV4dFxuICAgICAgLy8gYnV0IHdlIGRvbid0IGtub3cgdGhlIHBhcmVudENvbXBvbmVudCBzbyB3ZSBjYW4ndCBwYXNzIGl0LlxuICAgICAgLy8gSnVzdCBpZ25vcmUuIFdlJ2xsIGRlbGV0ZSB0aGlzIHdpdGggX3JlbmRlclN1YnRyZWUgY29kZSBwYXRoIGxhdGVyLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZsdXNoUGFzc2l2ZUVmZmVjdHMoKTtcbiAgICBmbHVzaFN5bmMoZnVuY3Rpb24gKCkge1xuICAgICAgdXBkYXRlQ29udGFpbmVyKGVsZW1lbnQsIHJvb3QsIG51bGwsIG51bGwpO1xuICAgIH0pO1xuICB9XG59O1xuXG5mdW5jdGlvbiBzY2hlZHVsZUZpYmVyc1dpdGhGYW1pbGllc1JlY3Vyc2l2ZWx5KGZpYmVyLCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpIHtcbiAge1xuICAgIHZhciBhbHRlcm5hdGUgPSBmaWJlci5hbHRlcm5hdGUsXG4gICAgICAgIGNoaWxkID0gZmliZXIuY2hpbGQsXG4gICAgICAgIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nLFxuICAgICAgICB0YWcgPSBmaWJlci50YWcsXG4gICAgICAgIHR5cGUgPSBmaWJlci50eXBlO1xuICAgIHZhciBjYW5kaWRhdGVUeXBlID0gbnVsbDtcblxuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgY2FuZGlkYXRlVHlwZSA9IHR5cGU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICAgIGNhbmRpZGF0ZVR5cGUgPSB0eXBlLnJlbmRlcjtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHJlc29sdmVGYW1pbHkgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgcmVzb2x2ZUZhbWlseSB0byBiZSBzZXQgZHVyaW5nIGhvdCByZWxvYWQuJyk7XG4gICAgfVxuXG4gICAgdmFyIG5lZWRzUmVuZGVyID0gZmFsc2U7XG4gICAgdmFyIG5lZWRzUmVtb3VudCA9IGZhbHNlO1xuXG4gICAgaWYgKGNhbmRpZGF0ZVR5cGUgIT09IG51bGwpIHtcbiAgICAgIHZhciBmYW1pbHkgPSByZXNvbHZlRmFtaWx5KGNhbmRpZGF0ZVR5cGUpO1xuXG4gICAgICBpZiAoZmFtaWx5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHN0YWxlRmFtaWxpZXMuaGFzKGZhbWlseSkpIHtcbiAgICAgICAgICBuZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHVwZGF0ZWRGYW1pbGllcy5oYXMoZmFtaWx5KSkge1xuICAgICAgICAgIGlmICh0YWcgPT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgICAgICAgICBuZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZWVkc1JlbmRlciA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGZhaWxlZEJvdW5kYXJpZXMgIT09IG51bGwpIHtcbiAgICAgIGlmIChmYWlsZWRCb3VuZGFyaWVzLmhhcyhmaWJlcikgfHwgYWx0ZXJuYXRlICE9PSBudWxsICYmIGZhaWxlZEJvdW5kYXJpZXMuaGFzKGFsdGVybmF0ZSkpIHtcbiAgICAgICAgbmVlZHNSZW1vdW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobmVlZHNSZW1vdW50KSB7XG4gICAgICBmaWJlci5fZGVidWdOZWVkc1JlbW91bnQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChuZWVkc1JlbW91bnQgfHwgbmVlZHNSZW5kZXIpIHtcbiAgICAgIHZhciBfcm9vdCA9IGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShmaWJlciwgU3luY0xhbmUpO1xuXG4gICAgICBpZiAoX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKF9yb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2hpbGQgIT09IG51bGwgJiYgIW5lZWRzUmVtb3VudCkge1xuICAgICAgc2NoZWR1bGVGaWJlcnNXaXRoRmFtaWxpZXNSZWN1cnNpdmVseShjaGlsZCwgdXBkYXRlZEZhbWlsaWVzLCBzdGFsZUZhbWlsaWVzKTtcbiAgICB9XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgc2NoZWR1bGVGaWJlcnNXaXRoRmFtaWxpZXNSZWN1cnNpdmVseShzaWJsaW5nLCB1cGRhdGVkRmFtaWxpZXMsIHN0YWxlRmFtaWxpZXMpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoID0gZnVuY3Rpb24gKHJvb3QsIGZhbWlsaWVzKSB7XG4gIHtcbiAgICB2YXIgaG9zdEluc3RhbmNlcyA9IG5ldyBTZXQoKTtcbiAgICB2YXIgdHlwZXMgPSBuZXcgU2V0KGZhbWlsaWVzLm1hcChmdW5jdGlvbiAoZmFtaWx5KSB7XG4gICAgICByZXR1cm4gZmFtaWx5LmN1cnJlbnQ7XG4gICAgfSkpO1xuICAgIGZpbmRIb3N0SW5zdGFuY2VzRm9yTWF0Y2hpbmdGaWJlcnNSZWN1cnNpdmVseShyb290LmN1cnJlbnQsIHR5cGVzLCBob3N0SW5zdGFuY2VzKTtcbiAgICByZXR1cm4gaG9zdEluc3RhbmNlcztcbiAgfVxufTtcblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZXNGb3JNYXRjaGluZ0ZpYmVyc1JlY3Vyc2l2ZWx5KGZpYmVyLCB0eXBlcywgaG9zdEluc3RhbmNlcykge1xuICB7XG4gICAgdmFyIGNoaWxkID0gZmliZXIuY2hpbGQsXG4gICAgICAgIHNpYmxpbmcgPSBmaWJlci5zaWJsaW5nLFxuICAgICAgICB0YWcgPSBmaWJlci50YWcsXG4gICAgICAgIHR5cGUgPSBmaWJlci50eXBlO1xuICAgIHZhciBjYW5kaWRhdGVUeXBlID0gbnVsbDtcblxuICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICBjYXNlIEZ1bmN0aW9uQ29tcG9uZW50OlxuICAgICAgY2FzZSBTaW1wbGVNZW1vQ29tcG9uZW50OlxuICAgICAgY2FzZSBDbGFzc0NvbXBvbmVudDpcbiAgICAgICAgY2FuZGlkYXRlVHlwZSA9IHR5cGU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEZvcndhcmRSZWY6XG4gICAgICAgIGNhbmRpZGF0ZVR5cGUgPSB0eXBlLnJlbmRlcjtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdmFyIGRpZE1hdGNoID0gZmFsc2U7XG5cbiAgICBpZiAoY2FuZGlkYXRlVHlwZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKHR5cGVzLmhhcyhjYW5kaWRhdGVUeXBlKSkge1xuICAgICAgICBkaWRNYXRjaCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRpZE1hdGNoKSB7XG4gICAgICAvLyBXZSBoYXZlIGEgbWF0Y2guIFRoaXMgb25seSBkcmlsbHMgZG93biB0byB0aGUgY2xvc2VzdCBob3N0IGNvbXBvbmVudHMuXG4gICAgICAvLyBUaGVyZSdzIG5vIG5lZWQgdG8gc2VhcmNoIGRlZXBlciBiZWNhdXNlIGZvciB0aGUgcHVycG9zZSBvZiBnaXZpbmdcbiAgICAgIC8vIHZpc3VhbCBmZWVkYmFjaywgXCJmbGFzaGluZ1wiIG91dGVybW9zdCBwYXJlbnQgcmVjdGFuZ2xlcyBpcyBzdWZmaWNpZW50LlxuICAgICAgZmluZEhvc3RJbnN0YW5jZXNGb3JGaWJlclNoYWxsb3dseShmaWJlciwgaG9zdEluc3RhbmNlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gbWF0Y2gsIG1heWJlIHRoZXJlIHdpbGwgYmUgb25lIGZ1cnRoZXIgZG93biBpbiB0aGUgY2hpbGQgdHJlZS5cbiAgICAgIGlmIChjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICBmaW5kSG9zdEluc3RhbmNlc0Zvck1hdGNoaW5nRmliZXJzUmVjdXJzaXZlbHkoY2hpbGQsIHR5cGVzLCBob3N0SW5zdGFuY2VzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2libGluZyAhPT0gbnVsbCkge1xuICAgICAgZmluZEhvc3RJbnN0YW5jZXNGb3JNYXRjaGluZ0ZpYmVyc1JlY3Vyc2l2ZWx5KHNpYmxpbmcsIHR5cGVzLCBob3N0SW5zdGFuY2VzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZXNGb3JGaWJlclNoYWxsb3dseShmaWJlciwgaG9zdEluc3RhbmNlcykge1xuICB7XG4gICAgdmFyIGZvdW5kSG9zdEluc3RhbmNlcyA9IGZpbmRDaGlsZEhvc3RJbnN0YW5jZXNGb3JGaWJlclNoYWxsb3dseShmaWJlciwgaG9zdEluc3RhbmNlcyk7XG5cbiAgICBpZiAoZm91bmRIb3N0SW5zdGFuY2VzKSB7XG4gICAgICByZXR1cm47XG4gICAgfSAvLyBJZiB3ZSBkaWRuJ3QgZmluZCBhbnkgaG9zdCBjaGlsZHJlbiwgZmFsbGJhY2sgdG8gY2xvc2VzdCBob3N0IHBhcmVudC5cblxuXG4gICAgdmFyIG5vZGUgPSBmaWJlcjtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBzd2l0Y2ggKG5vZGUudGFnKSB7XG4gICAgICAgIGNhc2UgSG9zdENvbXBvbmVudDpcbiAgICAgICAgICBob3N0SW5zdGFuY2VzLmFkZChub2RlLnN0YXRlTm9kZSk7XG4gICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNhc2UgSG9zdFBvcnRhbDpcbiAgICAgICAgICBob3N0SW5zdGFuY2VzLmFkZChub2RlLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKTtcbiAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2FzZSBIb3N0Um9vdDpcbiAgICAgICAgICBob3N0SW5zdGFuY2VzLmFkZChub2RlLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLnJldHVybiA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIHJlYWNoIHJvb3QgZmlyc3QuJyk7XG4gICAgICB9XG5cbiAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZENoaWxkSG9zdEluc3RhbmNlc0ZvckZpYmVyU2hhbGxvd2x5KGZpYmVyLCBob3N0SW5zdGFuY2VzKSB7XG4gIHtcbiAgICB2YXIgbm9kZSA9IGZpYmVyO1xuICAgIHZhciBmb3VuZEhvc3RJbnN0YW5jZXMgPSBmYWxzZTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAobm9kZS50YWcgPT09IEhvc3RDb21wb25lbnQpIHtcbiAgICAgICAgLy8gV2UgZ290IGEgbWF0Y2guXG4gICAgICAgIGZvdW5kSG9zdEluc3RhbmNlcyA9IHRydWU7XG4gICAgICAgIGhvc3RJbnN0YW5jZXMuYWRkKG5vZGUuc3RhdGVOb2RlKTsgLy8gVGhlcmUgbWF5IHN0aWxsIGJlIG1vcmUsIHNvIGtlZXAgc2VhcmNoaW5nLlxuICAgICAgfSBlbHNlIGlmIChub2RlLmNoaWxkICE9PSBudWxsKSB7XG4gICAgICAgIG5vZGUuY2hpbGQucmV0dXJuID0gbm9kZTtcbiAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQ7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAobm9kZSA9PT0gZmliZXIpIHtcbiAgICAgICAgcmV0dXJuIGZvdW5kSG9zdEluc3RhbmNlcztcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKG5vZGUuc2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICBpZiAobm9kZS5yZXR1cm4gPT09IG51bGwgfHwgbm9kZS5yZXR1cm4gPT09IGZpYmVyKSB7XG4gICAgICAgICAgcmV0dXJuIGZvdW5kSG9zdEluc3RhbmNlcztcbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBub2RlLnJldHVybjtcbiAgICAgIH1cblxuICAgICAgbm9kZS5zaWJsaW5nLnJldHVybiA9IG5vZGUucmV0dXJuO1xuICAgICAgbm9kZSA9IG5vZGUuc2libGluZztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBoYXNCYWRNYXBQb2x5ZmlsbDtcblxue1xuICBoYXNCYWRNYXBQb2x5ZmlsbCA9IGZhbHNlO1xuXG4gIHRyeSB7XG4gICAgdmFyIG5vbkV4dGVuc2libGVPYmplY3QgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pO1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldyAqL1xuXG4gICAgbmV3IE1hcChbW25vbkV4dGVuc2libGVPYmplY3QsIG51bGxdXSk7XG4gICAgbmV3IFNldChbbm9uRXh0ZW5zaWJsZU9iamVjdF0pO1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tbmV3ICovXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBUT0RPOiBDb25zaWRlciB3YXJuaW5nIGFib3V0IGJhZCBwb2x5ZmlsbHNcbiAgICBoYXNCYWRNYXBQb2x5ZmlsbCA9IHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gRmliZXJOb2RlKHRhZywgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpIHtcbiAgLy8gSW5zdGFuY2VcbiAgdGhpcy50YWcgPSB0YWc7XG4gIHRoaXMua2V5ID0ga2V5O1xuICB0aGlzLmVsZW1lbnRUeXBlID0gbnVsbDtcbiAgdGhpcy50eXBlID0gbnVsbDtcbiAgdGhpcy5zdGF0ZU5vZGUgPSBudWxsOyAvLyBGaWJlclxuXG4gIHRoaXMucmV0dXJuID0gbnVsbDtcbiAgdGhpcy5jaGlsZCA9IG51bGw7XG4gIHRoaXMuc2libGluZyA9IG51bGw7XG4gIHRoaXMuaW5kZXggPSAwO1xuICB0aGlzLnJlZiA9IG51bGw7XG4gIHRoaXMucGVuZGluZ1Byb3BzID0gcGVuZGluZ1Byb3BzO1xuICB0aGlzLm1lbW9pemVkUHJvcHMgPSBudWxsO1xuICB0aGlzLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgdGhpcy5tZW1vaXplZFN0YXRlID0gbnVsbDtcbiAgdGhpcy5kZXBlbmRlbmNpZXMgPSBudWxsO1xuICB0aGlzLm1vZGUgPSBtb2RlOyAvLyBFZmZlY3RzXG5cbiAgdGhpcy5mbGFncyA9IE5vRmxhZ3M7XG4gIHRoaXMuc3VidHJlZUZsYWdzID0gTm9GbGFncztcbiAgdGhpcy5kZWxldGlvbnMgPSBudWxsO1xuICB0aGlzLmxhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5hbHRlcm5hdGUgPSBudWxsO1xuXG4gIHtcbiAgICAvLyBOb3RlOiBUaGUgZm9sbG93aW5nIGlzIGRvbmUgdG8gYXZvaWQgYSB2OCBwZXJmb3JtYW5jZSBjbGlmZi5cbiAgICAvL1xuICAgIC8vIEluaXRpYWxpemluZyB0aGUgZmllbGRzIGJlbG93IHRvIHNtaXMgYW5kIGxhdGVyIHVwZGF0aW5nIHRoZW0gd2l0aFxuICAgIC8vIGRvdWJsZSB2YWx1ZXMgd2lsbCBjYXVzZSBGaWJlcnMgdG8gZW5kIHVwIGhhdmluZyBzZXBhcmF0ZSBzaGFwZXMuXG4gICAgLy8gVGhpcyBiZWhhdmlvci9idWcgaGFzIHNvbWV0aGluZyB0byBkbyB3aXRoIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9uKCkuXG4gICAgLy8gRm9ydHVuYXRlbHkgdGhpcyBvbmx5IGltcGFjdHMgREVWIGJ1aWxkcy5cbiAgICAvLyBVbmZvcnR1bmF0ZWx5IGl0IG1ha2VzIFJlYWN0IHVudXNhYmx5IHNsb3cgZm9yIHNvbWUgYXBwbGljYXRpb25zLlxuICAgIC8vIFRvIHdvcmsgYXJvdW5kIHRoaXMsIGluaXRpYWxpemUgdGhlIGZpZWxkcyBiZWxvdyB3aXRoIGRvdWJsZXMuXG4gICAgLy9cbiAgICAvLyBMZWFybiBtb3JlIGFib3V0IHRoaXMgaGVyZTpcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzE0MzY1XG4gICAgLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9ODUzOFxuICAgIHRoaXMuYWN0dWFsRHVyYXRpb24gPSBOdW1iZXIuTmFOO1xuICAgIHRoaXMuYWN0dWFsU3RhcnRUaW1lID0gTnVtYmVyLk5hTjtcbiAgICB0aGlzLnNlbGZCYXNlRHVyYXRpb24gPSBOdW1iZXIuTmFOO1xuICAgIHRoaXMudHJlZUJhc2VEdXJhdGlvbiA9IE51bWJlci5OYU47IC8vIEl0J3Mgb2theSB0byByZXBsYWNlIHRoZSBpbml0aWFsIGRvdWJsZXMgd2l0aCBzbWlzIGFmdGVyIGluaXRpYWxpemF0aW9uLlxuICAgIC8vIFRoaXMgd29uJ3QgdHJpZ2dlciB0aGUgcGVyZm9ybWFuY2UgY2xpZmYgbWVudGlvbmVkIGFib3ZlLFxuICAgIC8vIGFuZCBpdCBzaW1wbGlmaWVzIG90aGVyIHByb2ZpbGVyIGNvZGUgKGluY2x1ZGluZyBEZXZUb29scykuXG5cbiAgICB0aGlzLmFjdHVhbER1cmF0aW9uID0gMDtcbiAgICB0aGlzLmFjdHVhbFN0YXJ0VGltZSA9IC0xO1xuICAgIHRoaXMuc2VsZkJhc2VEdXJhdGlvbiA9IDA7XG4gICAgdGhpcy50cmVlQmFzZUR1cmF0aW9uID0gMDtcbiAgfVxuXG4gIHtcbiAgICAvLyBUaGlzIGlzbid0IGRpcmVjdGx5IHVzZWQgYnV0IGlzIGhhbmR5IGZvciBkZWJ1Z2dpbmcgaW50ZXJuYWxzOlxuICAgIHRoaXMuX2RlYnVnU291cmNlID0gbnVsbDtcbiAgICB0aGlzLl9kZWJ1Z093bmVyID0gbnVsbDtcbiAgICB0aGlzLl9kZWJ1Z05lZWRzUmVtb3VudCA9IGZhbHNlO1xuICAgIHRoaXMuX2RlYnVnSG9va1R5cGVzID0gbnVsbDtcblxuICAgIGlmICghaGFzQmFkTWFwUG9seWZpbGwgJiYgdHlwZW9mIE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHRoaXMpO1xuICAgIH1cbiAgfVxufSAvLyBUaGlzIGlzIGEgY29uc3RydWN0b3IgZnVuY3Rpb24sIHJhdGhlciB0aGFuIGEgUE9KTyBjb25zdHJ1Y3Rvciwgc3RpbGxcbi8vIHBsZWFzZSBlbnN1cmUgd2UgZG8gdGhlIGZvbGxvd2luZzpcbi8vIDEpIE5vYm9keSBzaG91bGQgYWRkIGFueSBpbnN0YW5jZSBtZXRob2RzIG9uIHRoaXMuIEluc3RhbmNlIG1ldGhvZHMgY2FuIGJlXG4vLyAgICBtb3JlIGRpZmZpY3VsdCB0byBwcmVkaWN0IHdoZW4gdGhleSBnZXQgb3B0aW1pemVkIGFuZCB0aGV5IGFyZSBhbG1vc3Rcbi8vICAgIG5ldmVyIGlubGluZWQgcHJvcGVybHkgaW4gc3RhdGljIGNvbXBpbGVycy5cbi8vIDIpIE5vYm9keSBzaG91bGQgcmVseSBvbiBgaW5zdGFuY2VvZiBGaWJlcmAgZm9yIHR5cGUgdGVzdGluZy4gV2Ugc2hvdWxkXG4vLyAgICBhbHdheXMga25vdyB3aGVuIGl0IGlzIGEgZmliZXIuXG4vLyAzKSBXZSBtaWdodCB3YW50IHRvIGV4cGVyaW1lbnQgd2l0aCB1c2luZyBudW1lcmljIGtleXMgc2luY2UgdGhleSBhcmUgZWFzaWVyXG4vLyAgICB0byBvcHRpbWl6ZSBpbiBhIG5vbi1KSVQgZW52aXJvbm1lbnQuXG4vLyA0KSBXZSBjYW4gZWFzaWx5IGdvIGZyb20gYSBjb25zdHJ1Y3RvciB0byBhIGNyZWF0ZUZpYmVyIG9iamVjdCBsaXRlcmFsIGlmIHRoYXRcbi8vICAgIGlzIGZhc3Rlci5cbi8vIDUpIEl0IHNob3VsZCBiZSBlYXN5IHRvIHBvcnQgdGhpcyB0byBhIEMgc3RydWN0IGFuZCBrZWVwIGEgQyBpbXBsZW1lbnRhdGlvblxuLy8gICAgY29tcGF0aWJsZS5cblxuXG52YXIgY3JlYXRlRmliZXIgPSBmdW5jdGlvbiAodGFnLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSkge1xuICAvLyAkRmxvd0ZpeE1lOiB0aGUgc2hhcGVzIGFyZSBleGFjdCBoZXJlIGJ1dCBGbG93IGRvZXNuJ3QgbGlrZSBjb25zdHJ1Y3RvcnNcbiAgcmV0dXJuIG5ldyBGaWJlck5vZGUodGFnLCBwZW5kaW5nUHJvcHMsIGtleSwgbW9kZSk7XG59O1xuXG5mdW5jdGlvbiBzaG91bGRDb25zdHJ1Y3QkMShDb21wb25lbnQpIHtcbiAgdmFyIHByb3RvdHlwZSA9IENvbXBvbmVudC5wcm90b3R5cGU7XG4gIHJldHVybiAhIShwcm90b3R5cGUgJiYgcHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQpO1xufVxuXG5mdW5jdGlvbiBpc1NpbXBsZUZ1bmN0aW9uQ29tcG9uZW50KHR5cGUpIHtcbiAgcmV0dXJuIHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nICYmICFzaG91bGRDb25zdHJ1Y3QkMSh0eXBlKSAmJiB0eXBlLmRlZmF1bHRQcm9wcyA9PT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gcmVzb2x2ZUxhenlDb21wb25lbnRUYWcoQ29tcG9uZW50KSB7XG4gIGlmICh0eXBlb2YgQ29tcG9uZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHNob3VsZENvbnN0cnVjdCQxKENvbXBvbmVudCkgPyBDbGFzc0NvbXBvbmVudCA6IEZ1bmN0aW9uQ29tcG9uZW50O1xuICB9IGVsc2UgaWYgKENvbXBvbmVudCAhPT0gdW5kZWZpbmVkICYmIENvbXBvbmVudCAhPT0gbnVsbCkge1xuICAgIHZhciAkJHR5cGVvZiA9IENvbXBvbmVudC4kJHR5cGVvZjtcblxuICAgIGlmICgkJHR5cGVvZiA9PT0gUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRSkge1xuICAgICAgcmV0dXJuIEZvcndhcmRSZWY7XG4gICAgfVxuXG4gICAgaWYgKCQkdHlwZW9mID09PSBSRUFDVF9NRU1PX1RZUEUpIHtcbiAgICAgIHJldHVybiBNZW1vQ29tcG9uZW50O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBJbmRldGVybWluYXRlQ29tcG9uZW50O1xufSAvLyBUaGlzIGlzIHVzZWQgdG8gY3JlYXRlIGFuIGFsdGVybmF0ZSBmaWJlciB0byBkbyB3b3JrIG9uLlxuXG5mdW5jdGlvbiBjcmVhdGVXb3JrSW5Qcm9ncmVzcyhjdXJyZW50LCBwZW5kaW5nUHJvcHMpIHtcbiAgdmFyIHdvcmtJblByb2dyZXNzID0gY3VycmVudC5hbHRlcm5hdGU7XG5cbiAgaWYgKHdvcmtJblByb2dyZXNzID09PSBudWxsKSB7XG4gICAgLy8gV2UgdXNlIGEgZG91YmxlIGJ1ZmZlcmluZyBwb29saW5nIHRlY2huaXF1ZSBiZWNhdXNlIHdlIGtub3cgdGhhdCB3ZSdsbFxuICAgIC8vIG9ubHkgZXZlciBuZWVkIGF0IG1vc3QgdHdvIHZlcnNpb25zIG9mIGEgdHJlZS4gV2UgcG9vbCB0aGUgXCJvdGhlclwiIHVudXNlZFxuICAgIC8vIG5vZGUgdGhhdCB3ZSdyZSBmcmVlIHRvIHJldXNlLiBUaGlzIGlzIGxhemlseSBjcmVhdGVkIHRvIGF2b2lkIGFsbG9jYXRpbmdcbiAgICAvLyBleHRyYSBvYmplY3RzIGZvciB0aGluZ3MgdGhhdCBhcmUgbmV2ZXIgdXBkYXRlZC4gSXQgYWxzbyBhbGxvdyB1cyB0b1xuICAgIC8vIHJlY2xhaW0gdGhlIGV4dHJhIG1lbW9yeSBpZiBuZWVkZWQuXG4gICAgd29ya0luUHJvZ3Jlc3MgPSBjcmVhdGVGaWJlcihjdXJyZW50LnRhZywgcGVuZGluZ1Byb3BzLCBjdXJyZW50LmtleSwgY3VycmVudC5tb2RlKTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5lbGVtZW50VHlwZSA9IGN1cnJlbnQuZWxlbWVudFR5cGU7XG4gICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IGN1cnJlbnQudHlwZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy5zdGF0ZU5vZGUgPSBjdXJyZW50LnN0YXRlTm9kZTtcblxuICAgIHtcbiAgICAgIC8vIERFVi1vbmx5IGZpZWxkc1xuICAgICAgd29ya0luUHJvZ3Jlc3MuX2RlYnVnU291cmNlID0gY3VycmVudC5fZGVidWdTb3VyY2U7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5fZGVidWdPd25lciA9IGN1cnJlbnQuX2RlYnVnT3duZXI7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy5fZGVidWdIb29rVHlwZXMgPSBjdXJyZW50Ll9kZWJ1Z0hvb2tUeXBlcztcbiAgICB9XG5cbiAgICB3b3JrSW5Qcm9ncmVzcy5hbHRlcm5hdGUgPSBjdXJyZW50O1xuICAgIGN1cnJlbnQuYWx0ZXJuYXRlID0gd29ya0luUHJvZ3Jlc3M7XG4gIH0gZWxzZSB7XG4gICAgd29ya0luUHJvZ3Jlc3MucGVuZGluZ1Byb3BzID0gcGVuZGluZ1Byb3BzOyAvLyBOZWVkZWQgYmVjYXVzZSBCbG9ja3Mgc3RvcmUgZGF0YSBvbiB0eXBlLlxuXG4gICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IGN1cnJlbnQudHlwZTsgLy8gV2UgYWxyZWFkeSBoYXZlIGFuIGFsdGVybmF0ZS5cbiAgICAvLyBSZXNldCB0aGUgZWZmZWN0IHRhZy5cblxuICAgIHdvcmtJblByb2dyZXNzLmZsYWdzID0gTm9GbGFnczsgLy8gVGhlIGVmZmVjdHMgYXJlIG5vIGxvbmdlciB2YWxpZC5cblxuICAgIHdvcmtJblByb2dyZXNzLnN1YnRyZWVGbGFncyA9IE5vRmxhZ3M7XG4gICAgd29ya0luUHJvZ3Jlc3MuZGVsZXRpb25zID0gbnVsbDtcblxuICAgIHtcbiAgICAgIC8vIFdlIGludGVudGlvbmFsbHkgcmVzZXQsIHJhdGhlciB0aGFuIGNvcHksIGFjdHVhbER1cmF0aW9uICYgYWN0dWFsU3RhcnRUaW1lLlxuICAgICAgLy8gVGhpcyBwcmV2ZW50cyB0aW1lIGZyb20gZW5kbGVzc2x5IGFjY3VtdWxhdGluZyBpbiBuZXcgY29tbWl0cy5cbiAgICAgIC8vIFRoaXMgaGFzIHRoZSBkb3duc2lkZSBvZiByZXNldHRpbmcgdmFsdWVzIGZvciBkaWZmZXJlbnQgcHJpb3JpdHkgcmVuZGVycyxcbiAgICAgIC8vIEJ1dCB3b3JrcyBmb3IgeWllbGRpbmcgKHRoZSBjb21tb24gY2FzZSkgYW5kIHNob3VsZCBzdXBwb3J0IHJlc3VtaW5nLlxuICAgICAgd29ya0luUHJvZ3Jlc3MuYWN0dWFsRHVyYXRpb24gPSAwO1xuICAgICAgd29ya0luUHJvZ3Jlc3MuYWN0dWFsU3RhcnRUaW1lID0gLTE7XG4gICAgfVxuICB9IC8vIFJlc2V0IGFsbCBlZmZlY3RzIGV4Y2VwdCBzdGF0aWMgb25lcy5cbiAgLy8gU3RhdGljIGVmZmVjdHMgYXJlIG5vdCBzcGVjaWZpYyB0byBhIHJlbmRlci5cblxuXG4gIHdvcmtJblByb2dyZXNzLmZsYWdzID0gY3VycmVudC5mbGFncyAmIFN0YXRpY01hc2s7XG4gIHdvcmtJblByb2dyZXNzLmNoaWxkTGFuZXMgPSBjdXJyZW50LmNoaWxkTGFuZXM7XG4gIHdvcmtJblByb2dyZXNzLmxhbmVzID0gY3VycmVudC5sYW5lcztcbiAgd29ya0luUHJvZ3Jlc3MuY2hpbGQgPSBjdXJyZW50LmNoaWxkO1xuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFByb3BzID0gY3VycmVudC5tZW1vaXplZFByb3BzO1xuICB3b3JrSW5Qcm9ncmVzcy5tZW1vaXplZFN0YXRlID0gY3VycmVudC5tZW1vaXplZFN0YXRlO1xuICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IGN1cnJlbnQudXBkYXRlUXVldWU7IC8vIENsb25lIHRoZSBkZXBlbmRlbmNpZXMgb2JqZWN0LiBUaGlzIGlzIG11dGF0ZWQgZHVyaW5nIHRoZSByZW5kZXIgcGhhc2UsIHNvXG4gIC8vIGl0IGNhbm5vdCBiZSBzaGFyZWQgd2l0aCB0aGUgY3VycmVudCBmaWJlci5cblxuICB2YXIgY3VycmVudERlcGVuZGVuY2llcyA9IGN1cnJlbnQuZGVwZW5kZW5jaWVzO1xuICB3b3JrSW5Qcm9ncmVzcy5kZXBlbmRlbmNpZXMgPSBjdXJyZW50RGVwZW5kZW5jaWVzID09PSBudWxsID8gbnVsbCA6IHtcbiAgICBsYW5lczogY3VycmVudERlcGVuZGVuY2llcy5sYW5lcyxcbiAgICBmaXJzdENvbnRleHQ6IGN1cnJlbnREZXBlbmRlbmNpZXMuZmlyc3RDb250ZXh0XG4gIH07IC8vIFRoZXNlIHdpbGwgYmUgb3ZlcnJpZGRlbiBkdXJpbmcgdGhlIHBhcmVudCdzIHJlY29uY2lsaWF0aW9uXG5cbiAgd29ya0luUHJvZ3Jlc3Muc2libGluZyA9IGN1cnJlbnQuc2libGluZztcbiAgd29ya0luUHJvZ3Jlc3MuaW5kZXggPSBjdXJyZW50LmluZGV4O1xuICB3b3JrSW5Qcm9ncmVzcy5yZWYgPSBjdXJyZW50LnJlZjtcblxuICB7XG4gICAgd29ya0luUHJvZ3Jlc3Muc2VsZkJhc2VEdXJhdGlvbiA9IGN1cnJlbnQuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uID0gY3VycmVudC50cmVlQmFzZUR1cmF0aW9uO1xuICB9XG5cbiAge1xuICAgIHdvcmtJblByb2dyZXNzLl9kZWJ1Z05lZWRzUmVtb3VudCA9IGN1cnJlbnQuX2RlYnVnTmVlZHNSZW1vdW50O1xuXG4gICAgc3dpdGNoICh3b3JrSW5Qcm9ncmVzcy50YWcpIHtcbiAgICAgIGNhc2UgSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDpcbiAgICAgIGNhc2UgRnVuY3Rpb25Db21wb25lbnQ6XG4gICAgICBjYXNlIFNpbXBsZU1lbW9Db21wb25lbnQ6XG4gICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSByZXNvbHZlRnVuY3Rpb25Gb3JIb3RSZWxvYWRpbmcoY3VycmVudC50eXBlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgQ2xhc3NDb21wb25lbnQ6XG4gICAgICAgIHdvcmtJblByb2dyZXNzLnR5cGUgPSByZXNvbHZlQ2xhc3NGb3JIb3RSZWxvYWRpbmcoY3VycmVudC50eXBlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgRm9yd2FyZFJlZjpcbiAgICAgICAgd29ya0luUHJvZ3Jlc3MudHlwZSA9IHJlc29sdmVGb3J3YXJkUmVmRm9ySG90UmVsb2FkaW5nKGN1cnJlbnQudHlwZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbn0gLy8gVXNlZCB0byByZXVzZSBhIEZpYmVyIGZvciBhIHNlY29uZCBwYXNzLlxuXG5mdW5jdGlvbiByZXNldFdvcmtJblByb2dyZXNzKHdvcmtJblByb2dyZXNzLCByZW5kZXJMYW5lcykge1xuICAvLyBUaGlzIHJlc2V0cyB0aGUgRmliZXIgdG8gd2hhdCBjcmVhdGVGaWJlciBvciBjcmVhdGVXb3JrSW5Qcm9ncmVzcyB3b3VsZFxuICAvLyBoYXZlIHNldCB0aGUgdmFsdWVzIHRvIGJlZm9yZSBkdXJpbmcgdGhlIGZpcnN0IHBhc3MuIElkZWFsbHkgdGhpcyB3b3VsZG4ndFxuICAvLyBiZSBuZWNlc3NhcnkgYnV0IHVuZm9ydHVuYXRlbHkgbWFueSBjb2RlIHBhdGhzIHJlYWRzIGZyb20gdGhlIHdvcmtJblByb2dyZXNzXG4gIC8vIHdoZW4gdGhleSBzaG91bGQgYmUgcmVhZGluZyBmcm9tIGN1cnJlbnQgYW5kIHdyaXRpbmcgdG8gd29ya0luUHJvZ3Jlc3MuXG4gIC8vIFdlIGFzc3VtZSBwZW5kaW5nUHJvcHMsIGluZGV4LCBrZXksIHJlZiwgcmV0dXJuIGFyZSBzdGlsbCB1bnRvdWNoZWQgdG9cbiAgLy8gYXZvaWQgZG9pbmcgYW5vdGhlciByZWNvbmNpbGlhdGlvbi5cbiAgLy8gUmVzZXQgdGhlIGVmZmVjdCBmbGFncyBidXQga2VlcCBhbnkgUGxhY2VtZW50IHRhZ3MsIHNpbmNlIHRoYXQncyBzb21ldGhpbmdcbiAgLy8gdGhhdCBjaGlsZCBmaWJlciBpcyBzZXR0aW5nLCBub3QgdGhlIHJlY29uY2lsaWF0aW9uLlxuICB3b3JrSW5Qcm9ncmVzcy5mbGFncyAmPSBTdGF0aWNNYXNrIHwgUGxhY2VtZW50OyAvLyBUaGUgZWZmZWN0cyBhcmUgbm8gbG9uZ2VyIHZhbGlkLlxuXG4gIHZhciBjdXJyZW50ID0gd29ya0luUHJvZ3Jlc3MuYWx0ZXJuYXRlO1xuXG4gIGlmIChjdXJyZW50ID09PSBudWxsKSB7XG4gICAgLy8gUmVzZXQgdG8gY3JlYXRlRmliZXIncyBpbml0aWFsIHZhbHVlcy5cbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzID0gTm9MYW5lcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5sYW5lcyA9IHJlbmRlckxhbmVzO1xuICAgIHdvcmtJblByb2dyZXNzLmNoaWxkID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5zdWJ0cmVlRmxhZ3MgPSBOb0ZsYWdzO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkU3RhdGUgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLnVwZGF0ZVF1ZXVlID0gbnVsbDtcbiAgICB3b3JrSW5Qcm9ncmVzcy5kZXBlbmRlbmNpZXMgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLnN0YXRlTm9kZSA9IG51bGw7XG5cbiAgICB7XG4gICAgICAvLyBOb3RlOiBXZSBkb24ndCByZXNldCB0aGUgYWN0dWFsVGltZSBjb3VudHMuIEl0J3MgdXNlZnVsIHRvIGFjY3VtdWxhdGVcbiAgICAgIC8vIGFjdHVhbCB0aW1lIGFjcm9zcyBtdWx0aXBsZSByZW5kZXIgcGFzc2VzLlxuICAgICAgd29ya0luUHJvZ3Jlc3Muc2VsZkJhc2VEdXJhdGlvbiA9IDA7XG4gICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uID0gMDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gUmVzZXQgdG8gdGhlIGNsb25lZCB2YWx1ZXMgdGhhdCBjcmVhdGVXb3JrSW5Qcm9ncmVzcyB3b3VsZCd2ZS5cbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZExhbmVzID0gY3VycmVudC5jaGlsZExhbmVzO1xuICAgIHdvcmtJblByb2dyZXNzLmxhbmVzID0gY3VycmVudC5sYW5lcztcbiAgICB3b3JrSW5Qcm9ncmVzcy5jaGlsZCA9IGN1cnJlbnQuY2hpbGQ7XG4gICAgd29ya0luUHJvZ3Jlc3Muc3VidHJlZUZsYWdzID0gTm9GbGFncztcbiAgICB3b3JrSW5Qcm9ncmVzcy5kZWxldGlvbnMgPSBudWxsO1xuICAgIHdvcmtJblByb2dyZXNzLm1lbW9pemVkUHJvcHMgPSBjdXJyZW50Lm1lbW9pemVkUHJvcHM7XG4gICAgd29ya0luUHJvZ3Jlc3MubWVtb2l6ZWRTdGF0ZSA9IGN1cnJlbnQubWVtb2l6ZWRTdGF0ZTtcbiAgICB3b3JrSW5Qcm9ncmVzcy51cGRhdGVRdWV1ZSA9IGN1cnJlbnQudXBkYXRlUXVldWU7IC8vIE5lZWRlZCBiZWNhdXNlIEJsb2NrcyBzdG9yZSBkYXRhIG9uIHR5cGUuXG5cbiAgICB3b3JrSW5Qcm9ncmVzcy50eXBlID0gY3VycmVudC50eXBlOyAvLyBDbG9uZSB0aGUgZGVwZW5kZW5jaWVzIG9iamVjdC4gVGhpcyBpcyBtdXRhdGVkIGR1cmluZyB0aGUgcmVuZGVyIHBoYXNlLCBzb1xuICAgIC8vIGl0IGNhbm5vdCBiZSBzaGFyZWQgd2l0aCB0aGUgY3VycmVudCBmaWJlci5cblxuICAgIHZhciBjdXJyZW50RGVwZW5kZW5jaWVzID0gY3VycmVudC5kZXBlbmRlbmNpZXM7XG4gICAgd29ya0luUHJvZ3Jlc3MuZGVwZW5kZW5jaWVzID0gY3VycmVudERlcGVuZGVuY2llcyA9PT0gbnVsbCA/IG51bGwgOiB7XG4gICAgICBsYW5lczogY3VycmVudERlcGVuZGVuY2llcy5sYW5lcyxcbiAgICAgIGZpcnN0Q29udGV4dDogY3VycmVudERlcGVuZGVuY2llcy5maXJzdENvbnRleHRcbiAgICB9O1xuXG4gICAge1xuICAgICAgLy8gTm90ZTogV2UgZG9uJ3QgcmVzZXQgdGhlIGFjdHVhbFRpbWUgY291bnRzLiBJdCdzIHVzZWZ1bCB0byBhY2N1bXVsYXRlXG4gICAgICAvLyBhY3R1YWwgdGltZSBhY3Jvc3MgbXVsdGlwbGUgcmVuZGVyIHBhc3Nlcy5cbiAgICAgIHdvcmtJblByb2dyZXNzLnNlbGZCYXNlRHVyYXRpb24gPSBjdXJyZW50LnNlbGZCYXNlRHVyYXRpb247XG4gICAgICB3b3JrSW5Qcm9ncmVzcy50cmVlQmFzZUR1cmF0aW9uID0gY3VycmVudC50cmVlQmFzZUR1cmF0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3b3JrSW5Qcm9ncmVzcztcbn1cbmZ1bmN0aW9uIGNyZWF0ZUhvc3RSb290RmliZXIodGFnLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUpIHtcbiAgdmFyIG1vZGU7XG5cbiAgaWYgKHRhZyA9PT0gQ29uY3VycmVudFJvb3QpIHtcbiAgICBtb2RlID0gQ29uY3VycmVudE1vZGU7XG5cbiAgICBpZiAoaXNTdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBtb2RlIHw9IFN0cmljdExlZ2FjeU1vZGU7XG5cbiAgICAgIHtcbiAgICAgICAgbW9kZSB8PSBTdHJpY3RFZmZlY3RzTW9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbW9kZSA9IE5vTW9kZTtcbiAgfVxuXG4gIGlmICggaXNEZXZUb29sc1ByZXNlbnQpIHtcbiAgICAvLyBBbHdheXMgY29sbGVjdCBwcm9maWxlIHRpbWluZ3Mgd2hlbiBEZXZUb29scyBhcmUgcHJlc2VudC5cbiAgICAvLyBUaGlzIGVuYWJsZXMgRGV2VG9vbHMgdG8gc3RhcnQgY2FwdHVyaW5nIHRpbWluZyBhdCBhbnkgcG9pbnTigJNcbiAgICAvLyBXaXRob3V0IHNvbWUgbm9kZXMgaW4gdGhlIHRyZWUgaGF2aW5nIGVtcHR5IGJhc2UgdGltZXMuXG4gICAgbW9kZSB8PSBQcm9maWxlTW9kZTtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVGaWJlcihIb3N0Um9vdCwgbnVsbCwgbnVsbCwgbW9kZSk7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21UeXBlQW5kUHJvcHModHlwZSwgLy8gUmVhY3QkRWxlbWVudFR5cGVcbmtleSwgcGVuZGluZ1Byb3BzLCBvd25lciwgbW9kZSwgbGFuZXMpIHtcbiAgdmFyIGZpYmVyVGFnID0gSW5kZXRlcm1pbmF0ZUNvbXBvbmVudDsgLy8gVGhlIHJlc29sdmVkIHR5cGUgaXMgc2V0IGlmIHdlIGtub3cgd2hhdCB0aGUgZmluYWwgdHlwZSB3aWxsIGJlLiBJLmUuIGl0J3Mgbm90IGxhenkuXG5cbiAgdmFyIHJlc29sdmVkVHlwZSA9IHR5cGU7XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgaWYgKHNob3VsZENvbnN0cnVjdCQxKHR5cGUpKSB7XG4gICAgICBmaWJlclRhZyA9IENsYXNzQ29tcG9uZW50O1xuXG4gICAgICB7XG4gICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVDbGFzc0ZvckhvdFJlbG9hZGluZyhyZXNvbHZlZFR5cGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB7XG4gICAgICAgIHJlc29sdmVkVHlwZSA9IHJlc29sdmVGdW5jdGlvbkZvckhvdFJlbG9hZGluZyhyZXNvbHZlZFR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBmaWJlclRhZyA9IEhvc3RDb21wb25lbnQ7XG4gIH0gZWxzZSB7XG4gICAgZ2V0VGFnOiBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgUkVBQ1RfRlJBR01FTlRfVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KHBlbmRpbmdQcm9wcy5jaGlsZHJlbiwgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfU1RSSUNUX01PREVfVFlQRTpcbiAgICAgICAgZmliZXJUYWcgPSBNb2RlO1xuICAgICAgICBtb2RlIHw9IFN0cmljdExlZ2FjeU1vZGU7XG5cbiAgICAgICAgaWYgKCAobW9kZSAmIENvbmN1cnJlbnRNb2RlKSAhPT0gTm9Nb2RlKSB7XG4gICAgICAgICAgLy8gU3RyaWN0IGVmZmVjdHMgc2hvdWxkIG5ldmVyIHJ1biBvbiBsZWdhY3kgcm9vdHNcbiAgICAgICAgICBtb2RlIHw9IFN0cmljdEVmZmVjdHNNb2RlO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgUkVBQ1RfUFJPRklMRVJfVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbVByb2ZpbGVyKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfVFlQRTpcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUZpYmVyRnJvbVN1c3BlbnNlKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfU1VTUEVOU0VfTElTVF9UWVBFOlxuICAgICAgICByZXR1cm4gY3JlYXRlRmliZXJGcm9tU3VzcGVuc2VMaXN0KHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSk7XG5cbiAgICAgIGNhc2UgUkVBQ1RfT0ZGU0NSRUVOX1RZUEU6XG4gICAgICAgIHJldHVybiBjcmVhdGVGaWJlckZyb21PZmZzY3JlZW4ocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KTtcblxuICAgICAgY2FzZSBSRUFDVF9MRUdBQ1lfSElEREVOX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX1NDT1BFX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX0NBQ0hFX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX1RSQUNJTkdfTUFSS0VSX1RZUEU6XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuXG4gICAgICBjYXNlIFJFQUNUX0RFQlVHX1RSQUNJTkdfTU9ERV9UWVBFOlxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZmFsbHRocm91Z2hcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAge1xuICAgICAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlLiQkdHlwZW9mKSB7XG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfUFJPVklERVJfVFlQRTpcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IENvbnRleHRQcm92aWRlcjtcbiAgICAgICAgICAgICAgICBicmVhayBnZXRUYWc7XG5cbiAgICAgICAgICAgICAgY2FzZSBSRUFDVF9DT05URVhUX1RZUEU6XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIGNvbnN1bWVyXG4gICAgICAgICAgICAgICAgZmliZXJUYWcgPSBDb250ZXh0Q29uc3VtZXI7XG4gICAgICAgICAgICAgICAgYnJlYWsgZ2V0VGFnO1xuXG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfRk9SV0FSRF9SRUZfVFlQRTpcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IEZvcndhcmRSZWY7XG5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlZFR5cGUgPSByZXNvbHZlRm9yd2FyZFJlZkZvckhvdFJlbG9hZGluZyhyZXNvbHZlZFR5cGUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrIGdldFRhZztcblxuICAgICAgICAgICAgICBjYXNlIFJFQUNUX01FTU9fVFlQRTpcbiAgICAgICAgICAgICAgICBmaWJlclRhZyA9IE1lbW9Db21wb25lbnQ7XG4gICAgICAgICAgICAgICAgYnJlYWsgZ2V0VGFnO1xuXG4gICAgICAgICAgICAgIGNhc2UgUkVBQ1RfTEFaWV9UWVBFOlxuICAgICAgICAgICAgICAgIGZpYmVyVGFnID0gTGF6eUNvbXBvbmVudDtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFR5cGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGJyZWFrIGdldFRhZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgaW5mbyA9ICcnO1xuXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdHlwZSA9PT0gJ29iamVjdCcgJiYgdHlwZSAhPT0gbnVsbCAmJiBPYmplY3Qua2V5cyh0eXBlKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgaW5mbyArPSAnIFlvdSBsaWtlbHkgZm9yZ290IHRvIGV4cG9ydCB5b3VyIGNvbXBvbmVudCBmcm9tIHRoZSBmaWxlICcgKyBcIml0J3MgZGVmaW5lZCBpbiwgb3IgeW91IG1pZ2h0IGhhdmUgbWl4ZWQgdXAgZGVmYXVsdCBhbmQgXCIgKyAnbmFtZWQgaW1wb3J0cy4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgb3duZXJOYW1lID0gb3duZXIgPyBnZXRDb21wb25lbnROYW1lRnJvbUZpYmVyKG93bmVyKSA6IG51bGw7XG5cbiAgICAgICAgICAgIGlmIChvd25lck5hbWUpIHtcbiAgICAgICAgICAgICAgaW5mbyArPSAnXFxuXFxuQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgYCcgKyBvd25lck5hbWUgKyAnYC4nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRWxlbWVudCB0eXBlIGlzIGludmFsaWQ6IGV4cGVjdGVkIGEgc3RyaW5nIChmb3IgYnVpbHQtaW4gJyArICdjb21wb25lbnRzKSBvciBhIGNsYXNzL2Z1bmN0aW9uIChmb3IgY29tcG9zaXRlIGNvbXBvbmVudHMpICcgKyAoXCJidXQgZ290OiBcIiArICh0eXBlID09IG51bGwgPyB0eXBlIDogdHlwZW9mIHR5cGUpICsgXCIuXCIgKyBpbmZvKSk7XG4gICAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihmaWJlclRhZywgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9IHR5cGU7XG4gIGZpYmVyLnR5cGUgPSByZXNvbHZlZFR5cGU7XG4gIGZpYmVyLmxhbmVzID0gbGFuZXM7XG5cbiAge1xuICAgIGZpYmVyLl9kZWJ1Z093bmVyID0gb3duZXI7XG4gIH1cblxuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21FbGVtZW50KGVsZW1lbnQsIG1vZGUsIGxhbmVzKSB7XG4gIHZhciBvd25lciA9IG51bGw7XG5cbiAge1xuICAgIG93bmVyID0gZWxlbWVudC5fb3duZXI7XG4gIH1cblxuICB2YXIgdHlwZSA9IGVsZW1lbnQudHlwZTtcbiAgdmFyIGtleSA9IGVsZW1lbnQua2V5O1xuICB2YXIgcGVuZGluZ1Byb3BzID0gZWxlbWVudC5wcm9wcztcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXJGcm9tVHlwZUFuZFByb3BzKHR5cGUsIGtleSwgcGVuZGluZ1Byb3BzLCBvd25lciwgbW9kZSwgbGFuZXMpO1xuXG4gIHtcbiAgICBmaWJlci5fZGVidWdTb3VyY2UgPSBlbGVtZW50Ll9zb3VyY2U7XG4gICAgZmliZXIuX2RlYnVnT3duZXIgPSBlbGVtZW50Ll9vd25lcjtcbiAgfVxuXG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbUZyYWdtZW50KGVsZW1lbnRzLCBtb2RlLCBsYW5lcywga2V5KSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKEZyYWdtZW50LCBlbGVtZW50cywga2V5LCBtb2RlKTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgcmV0dXJuIGZpYmVyO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21Qcm9maWxlcihwZW5kaW5nUHJvcHMsIG1vZGUsIGxhbmVzLCBrZXkpIHtcbiAge1xuICAgIGlmICh0eXBlb2YgcGVuZGluZ1Byb3BzLmlkICE9PSAnc3RyaW5nJykge1xuICAgICAgZXJyb3IoJ1Byb2ZpbGVyIG11c3Qgc3BlY2lmeSBhbiBcImlkXCIgb2YgdHlwZSBgc3RyaW5nYCBhcyBhIHByb3AuIFJlY2VpdmVkIHRoZSB0eXBlIGAlc2AgaW5zdGVhZC4nLCB0eXBlb2YgcGVuZGluZ1Byb3BzLmlkKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihQcm9maWxlciwgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUgfCBQcm9maWxlTW9kZSk7XG4gIGZpYmVyLmVsZW1lbnRUeXBlID0gUkVBQ1RfUFJPRklMRVJfVFlQRTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcblxuICB7XG4gICAgZmliZXIuc3RhdGVOb2RlID0ge1xuICAgICAgZWZmZWN0RHVyYXRpb246IDAsXG4gICAgICBwYXNzaXZlRWZmZWN0RHVyYXRpb246IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIGZpYmVyO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21TdXNwZW5zZShwZW5kaW5nUHJvcHMsIG1vZGUsIGxhbmVzLCBrZXkpIHtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoU3VzcGVuc2VDb21wb25lbnQsIHBlbmRpbmdQcm9wcywga2V5LCBtb2RlKTtcbiAgZmliZXIuZWxlbWVudFR5cGUgPSBSRUFDVF9TVVNQRU5TRV9UWVBFO1xuICBmaWJlci5sYW5lcyA9IGxhbmVzO1xuICByZXR1cm4gZmliZXI7XG59XG5mdW5jdGlvbiBjcmVhdGVGaWJlckZyb21TdXNwZW5zZUxpc3QocGVuZGluZ1Byb3BzLCBtb2RlLCBsYW5lcywga2V5KSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKFN1c3BlbnNlTGlzdENvbXBvbmVudCwgcGVuZGluZ1Byb3BzLCBrZXksIG1vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9IFJFQUNUX1NVU1BFTlNFX0xJU1RfVFlQRTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tT2Zmc2NyZWVuKHBlbmRpbmdQcm9wcywgbW9kZSwgbGFuZXMsIGtleSkge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihPZmZzY3JlZW5Db21wb25lbnQsIHBlbmRpbmdQcm9wcywga2V5LCBtb2RlKTtcbiAgZmliZXIuZWxlbWVudFR5cGUgPSBSRUFDVF9PRkZTQ1JFRU5fVFlQRTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgdmFyIHByaW1hcnlDaGlsZEluc3RhbmNlID0ge1xuICAgIGlzSGlkZGVuOiBmYWxzZVxuICB9O1xuICBmaWJlci5zdGF0ZU5vZGUgPSBwcmltYXJ5Q2hpbGRJbnN0YW5jZTtcbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tVGV4dChjb250ZW50LCBtb2RlLCBsYW5lcykge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihIb3N0VGV4dCwgY29udGVudCwgbnVsbCwgbW9kZSk7XG4gIGZpYmVyLmxhbmVzID0gbGFuZXM7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbUhvc3RJbnN0YW5jZUZvckRlbGV0aW9uKCkge1xuICB2YXIgZmliZXIgPSBjcmVhdGVGaWJlcihIb3N0Q29tcG9uZW50LCBudWxsLCBudWxsLCBOb01vZGUpO1xuICBmaWJlci5lbGVtZW50VHlwZSA9ICdERUxFVEVEJztcbiAgcmV0dXJuIGZpYmVyO1xufVxuZnVuY3Rpb24gY3JlYXRlRmliZXJGcm9tRGVoeWRyYXRlZEZyYWdtZW50KGRlaHlkcmF0ZWROb2RlKSB7XG4gIHZhciBmaWJlciA9IGNyZWF0ZUZpYmVyKERlaHlkcmF0ZWRGcmFnbWVudCwgbnVsbCwgbnVsbCwgTm9Nb2RlKTtcbiAgZmliZXIuc3RhdGVOb2RlID0gZGVoeWRyYXRlZE5vZGU7XG4gIHJldHVybiBmaWJlcjtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUZpYmVyRnJvbVBvcnRhbChwb3J0YWwsIG1vZGUsIGxhbmVzKSB7XG4gIHZhciBwZW5kaW5nUHJvcHMgPSBwb3J0YWwuY2hpbGRyZW4gIT09IG51bGwgPyBwb3J0YWwuY2hpbGRyZW4gOiBbXTtcbiAgdmFyIGZpYmVyID0gY3JlYXRlRmliZXIoSG9zdFBvcnRhbCwgcGVuZGluZ1Byb3BzLCBwb3J0YWwua2V5LCBtb2RlKTtcbiAgZmliZXIubGFuZXMgPSBsYW5lcztcbiAgZmliZXIuc3RhdGVOb2RlID0ge1xuICAgIGNvbnRhaW5lckluZm86IHBvcnRhbC5jb250YWluZXJJbmZvLFxuICAgIHBlbmRpbmdDaGlsZHJlbjogbnVsbCxcbiAgICAvLyBVc2VkIGJ5IHBlcnNpc3RlbnQgdXBkYXRlc1xuICAgIGltcGxlbWVudGF0aW9uOiBwb3J0YWwuaW1wbGVtZW50YXRpb25cbiAgfTtcbiAgcmV0dXJuIGZpYmVyO1xufSAvLyBVc2VkIGZvciBzdGFzaGluZyBXSVAgcHJvcGVydGllcyB0byByZXBsYXkgZmFpbGVkIHdvcmsgaW4gREVWLlxuXG5mdW5jdGlvbiBhc3NpZ25GaWJlclByb3BlcnRpZXNJbkRFVih0YXJnZXQsIHNvdXJjZSkge1xuICBpZiAodGFyZ2V0ID09PSBudWxsKSB7XG4gICAgLy8gVGhpcyBGaWJlcidzIGluaXRpYWwgcHJvcGVydGllcyB3aWxsIGFsd2F5cyBiZSBvdmVyd3JpdHRlbi5cbiAgICAvLyBXZSBvbmx5IHVzZSBhIEZpYmVyIHRvIGVuc3VyZSB0aGUgc2FtZSBoaWRkZW4gY2xhc3Mgc28gREVWIGlzbid0IHNsb3cuXG4gICAgdGFyZ2V0ID0gY3JlYXRlRmliZXIoSW5kZXRlcm1pbmF0ZUNvbXBvbmVudCwgbnVsbCwgbnVsbCwgTm9Nb2RlKTtcbiAgfSAvLyBUaGlzIGlzIGludGVudGlvbmFsbHkgd3JpdHRlbiBhcyBhIGxpc3Qgb2YgYWxsIHByb3BlcnRpZXMuXG4gIC8vIFdlIHRyaWVkIHRvIHVzZSBPYmplY3QuYXNzaWduKCkgaW5zdGVhZCBidXQgdGhpcyBpcyBjYWxsZWQgaW5cbiAgLy8gdGhlIGhvdHRlc3QgcGF0aCwgYW5kIE9iamVjdC5hc3NpZ24oKSB3YXMgdG9vIHNsb3c6XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWFjdC9pc3N1ZXMvMTI1MDJcbiAgLy8gVGhpcyBjb2RlIGlzIERFVi1vbmx5IHNvIHNpemUgaXMgbm90IGEgY29uY2Vybi5cblxuXG4gIHRhcmdldC50YWcgPSBzb3VyY2UudGFnO1xuICB0YXJnZXQua2V5ID0gc291cmNlLmtleTtcbiAgdGFyZ2V0LmVsZW1lbnRUeXBlID0gc291cmNlLmVsZW1lbnRUeXBlO1xuICB0YXJnZXQudHlwZSA9IHNvdXJjZS50eXBlO1xuICB0YXJnZXQuc3RhdGVOb2RlID0gc291cmNlLnN0YXRlTm9kZTtcbiAgdGFyZ2V0LnJldHVybiA9IHNvdXJjZS5yZXR1cm47XG4gIHRhcmdldC5jaGlsZCA9IHNvdXJjZS5jaGlsZDtcbiAgdGFyZ2V0LnNpYmxpbmcgPSBzb3VyY2Uuc2libGluZztcbiAgdGFyZ2V0LmluZGV4ID0gc291cmNlLmluZGV4O1xuICB0YXJnZXQucmVmID0gc291cmNlLnJlZjtcbiAgdGFyZ2V0LnBlbmRpbmdQcm9wcyA9IHNvdXJjZS5wZW5kaW5nUHJvcHM7XG4gIHRhcmdldC5tZW1vaXplZFByb3BzID0gc291cmNlLm1lbW9pemVkUHJvcHM7XG4gIHRhcmdldC51cGRhdGVRdWV1ZSA9IHNvdXJjZS51cGRhdGVRdWV1ZTtcbiAgdGFyZ2V0Lm1lbW9pemVkU3RhdGUgPSBzb3VyY2UubWVtb2l6ZWRTdGF0ZTtcbiAgdGFyZ2V0LmRlcGVuZGVuY2llcyA9IHNvdXJjZS5kZXBlbmRlbmNpZXM7XG4gIHRhcmdldC5tb2RlID0gc291cmNlLm1vZGU7XG4gIHRhcmdldC5mbGFncyA9IHNvdXJjZS5mbGFncztcbiAgdGFyZ2V0LnN1YnRyZWVGbGFncyA9IHNvdXJjZS5zdWJ0cmVlRmxhZ3M7XG4gIHRhcmdldC5kZWxldGlvbnMgPSBzb3VyY2UuZGVsZXRpb25zO1xuICB0YXJnZXQubGFuZXMgPSBzb3VyY2UubGFuZXM7XG4gIHRhcmdldC5jaGlsZExhbmVzID0gc291cmNlLmNoaWxkTGFuZXM7XG4gIHRhcmdldC5hbHRlcm5hdGUgPSBzb3VyY2UuYWx0ZXJuYXRlO1xuXG4gIHtcbiAgICB0YXJnZXQuYWN0dWFsRHVyYXRpb24gPSBzb3VyY2UuYWN0dWFsRHVyYXRpb247XG4gICAgdGFyZ2V0LmFjdHVhbFN0YXJ0VGltZSA9IHNvdXJjZS5hY3R1YWxTdGFydFRpbWU7XG4gICAgdGFyZ2V0LnNlbGZCYXNlRHVyYXRpb24gPSBzb3VyY2Uuc2VsZkJhc2VEdXJhdGlvbjtcbiAgICB0YXJnZXQudHJlZUJhc2VEdXJhdGlvbiA9IHNvdXJjZS50cmVlQmFzZUR1cmF0aW9uO1xuICB9XG5cbiAgdGFyZ2V0Ll9kZWJ1Z1NvdXJjZSA9IHNvdXJjZS5fZGVidWdTb3VyY2U7XG4gIHRhcmdldC5fZGVidWdPd25lciA9IHNvdXJjZS5fZGVidWdPd25lcjtcbiAgdGFyZ2V0Ll9kZWJ1Z05lZWRzUmVtb3VudCA9IHNvdXJjZS5fZGVidWdOZWVkc1JlbW91bnQ7XG4gIHRhcmdldC5fZGVidWdIb29rVHlwZXMgPSBzb3VyY2UuX2RlYnVnSG9va1R5cGVzO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBGaWJlclJvb3ROb2RlKGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0ZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKSB7XG4gIHRoaXMudGFnID0gdGFnO1xuICB0aGlzLmNvbnRhaW5lckluZm8gPSBjb250YWluZXJJbmZvO1xuICB0aGlzLnBlbmRpbmdDaGlsZHJlbiA9IG51bGw7XG4gIHRoaXMuY3VycmVudCA9IG51bGw7XG4gIHRoaXMucGluZ0NhY2hlID0gbnVsbDtcbiAgdGhpcy5maW5pc2hlZFdvcmsgPSBudWxsO1xuICB0aGlzLnRpbWVvdXRIYW5kbGUgPSBub1RpbWVvdXQ7XG4gIHRoaXMuY29udGV4dCA9IG51bGw7XG4gIHRoaXMucGVuZGluZ0NvbnRleHQgPSBudWxsO1xuICB0aGlzLmNhbGxiYWNrTm9kZSA9IG51bGw7XG4gIHRoaXMuY2FsbGJhY2tQcmlvcml0eSA9IE5vTGFuZTtcbiAgdGhpcy5ldmVudFRpbWVzID0gY3JlYXRlTGFuZU1hcChOb0xhbmVzKTtcbiAgdGhpcy5leHBpcmF0aW9uVGltZXMgPSBjcmVhdGVMYW5lTWFwKE5vVGltZXN0YW1wKTtcbiAgdGhpcy5wZW5kaW5nTGFuZXMgPSBOb0xhbmVzO1xuICB0aGlzLnN1c3BlbmRlZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5waW5nZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMuZXhwaXJlZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5tdXRhYmxlUmVhZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5maW5pc2hlZExhbmVzID0gTm9MYW5lcztcbiAgdGhpcy5lbnRhbmdsZWRMYW5lcyA9IE5vTGFuZXM7XG4gIHRoaXMuZW50YW5nbGVtZW50cyA9IGNyZWF0ZUxhbmVNYXAoTm9MYW5lcyk7XG4gIHRoaXMuaWRlbnRpZmllclByZWZpeCA9IGlkZW50aWZpZXJQcmVmaXg7XG4gIHRoaXMub25SZWNvdmVyYWJsZUVycm9yID0gb25SZWNvdmVyYWJsZUVycm9yO1xuXG4gIHtcbiAgICB0aGlzLm11dGFibGVTb3VyY2VFYWdlckh5ZHJhdGlvbkRhdGEgPSBudWxsO1xuICB9XG5cbiAge1xuICAgIHRoaXMuZWZmZWN0RHVyYXRpb24gPSAwO1xuICAgIHRoaXMucGFzc2l2ZUVmZmVjdER1cmF0aW9uID0gMDtcbiAgfVxuXG4gIHtcbiAgICB0aGlzLm1lbW9pemVkVXBkYXRlcnMgPSBuZXcgU2V0KCk7XG4gICAgdmFyIHBlbmRpbmdVcGRhdGVyc0xhbmVNYXAgPSB0aGlzLnBlbmRpbmdVcGRhdGVyc0xhbmVNYXAgPSBbXTtcblxuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBUb3RhbExhbmVzOyBfaSsrKSB7XG4gICAgICBwZW5kaW5nVXBkYXRlcnNMYW5lTWFwLnB1c2gobmV3IFNldCgpKTtcbiAgICB9XG4gIH1cblxuICB7XG4gICAgc3dpdGNoICh0YWcpIHtcbiAgICAgIGNhc2UgQ29uY3VycmVudFJvb3Q6XG4gICAgICAgIHRoaXMuX2RlYnVnUm9vdFR5cGUgPSBoeWRyYXRlID8gJ2h5ZHJhdGVSb290KCknIDogJ2NyZWF0ZVJvb3QoKSc7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIExlZ2FjeVJvb3Q6XG4gICAgICAgIHRoaXMuX2RlYnVnUm9vdFR5cGUgPSBoeWRyYXRlID8gJ2h5ZHJhdGUoKScgOiAncmVuZGVyKCknO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRmliZXJSb290KGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0ZSwgaW5pdGlhbENoaWxkcmVuLCBoeWRyYXRpb25DYWxsYmFja3MsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgLy8gVE9ETzogV2UgaGF2ZSBzZXZlcmFsIG9mIHRoZXNlIGFyZ3VtZW50cyB0aGF0IGFyZSBjb25jZXB0dWFsbHkgcGFydCBvZiB0aGVcbi8vIGhvc3QgY29uZmlnLCBidXQgYmVjYXVzZSB0aGV5IGFyZSBwYXNzZWQgaW4gYXQgcnVudGltZSwgd2UgaGF2ZSB0byB0aHJlYWRcbi8vIHRoZW0gdGhyb3VnaCB0aGUgcm9vdCBjb25zdHJ1Y3Rvci4gUGVyaGFwcyB3ZSBzaG91bGQgcHV0IHRoZW0gYWxsIGludG8gYVxuLy8gc2luZ2xlIHR5cGUsIGxpa2UgYSBEeW5hbWljSG9zdENvbmZpZyB0aGF0IGlzIGRlZmluZWQgYnkgdGhlIHJlbmRlcmVyLlxuaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yLCB0cmFuc2l0aW9uQ2FsbGJhY2tzKSB7XG4gIHZhciByb290ID0gbmV3IEZpYmVyUm9vdE5vZGUoY29udGFpbmVySW5mbywgdGFnLCBoeWRyYXRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IpO1xuICAvLyBzdGF0ZU5vZGUgaXMgYW55LlxuXG5cbiAgdmFyIHVuaW5pdGlhbGl6ZWRGaWJlciA9IGNyZWF0ZUhvc3RSb290RmliZXIodGFnLCBpc1N0cmljdE1vZGUpO1xuICByb290LmN1cnJlbnQgPSB1bmluaXRpYWxpemVkRmliZXI7XG4gIHVuaW5pdGlhbGl6ZWRGaWJlci5zdGF0ZU5vZGUgPSByb290O1xuXG4gIHtcbiAgICB2YXIgX2luaXRpYWxTdGF0ZSA9IHtcbiAgICAgIGVsZW1lbnQ6IGluaXRpYWxDaGlsZHJlbixcbiAgICAgIGlzRGVoeWRyYXRlZDogaHlkcmF0ZSxcbiAgICAgIGNhY2hlOiBudWxsLFxuICAgICAgLy8gbm90IGVuYWJsZWQgeWV0XG4gICAgICB0cmFuc2l0aW9uczogbnVsbCxcbiAgICAgIHBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXM6IG51bGxcbiAgICB9O1xuICAgIHVuaW5pdGlhbGl6ZWRGaWJlci5tZW1vaXplZFN0YXRlID0gX2luaXRpYWxTdGF0ZTtcbiAgfVxuXG4gIGluaXRpYWxpemVVcGRhdGVRdWV1ZSh1bmluaXRpYWxpemVkRmliZXIpO1xuICByZXR1cm4gcm9vdDtcbn1cblxudmFyIFJlYWN0VmVyc2lvbiA9ICcxOC4yLjAnO1xuXG5mdW5jdGlvbiBjcmVhdGVQb3J0YWwoY2hpbGRyZW4sIGNvbnRhaW5lckluZm8sIC8vIFRPRE86IGZpZ3VyZSBvdXQgdGhlIEFQSSBmb3IgY3Jvc3MtcmVuZGVyZXIgaW1wbGVtZW50YXRpb24uXG5pbXBsZW1lbnRhdGlvbikge1xuICB2YXIga2V5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBudWxsO1xuXG4gIHtcbiAgICBjaGVja0tleVN0cmluZ0NvZXJjaW9uKGtleSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC8vIFRoaXMgdGFnIGFsbG93IHVzIHRvIHVuaXF1ZWx5IGlkZW50aWZ5IHRoaXMgYXMgYSBSZWFjdCBQb3J0YWxcbiAgICAkJHR5cGVvZjogUkVBQ1RfUE9SVEFMX1RZUEUsXG4gICAga2V5OiBrZXkgPT0gbnVsbCA/IG51bGwgOiAnJyArIGtleSxcbiAgICBjaGlsZHJlbjogY2hpbGRyZW4sXG4gICAgY29udGFpbmVySW5mbzogY29udGFpbmVySW5mbyxcbiAgICBpbXBsZW1lbnRhdGlvbjogaW1wbGVtZW50YXRpb25cbiAgfTtcbn1cblxudmFyIGRpZFdhcm5BYm91dE5lc3RlZFVwZGF0ZXM7XG52YXIgZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGU7XG5cbntcbiAgZGlkV2FybkFib3V0TmVzdGVkVXBkYXRlcyA9IGZhbHNlO1xuICBkaWRXYXJuQWJvdXRGaW5kTm9kZUluU3RyaWN0TW9kZSA9IHt9O1xufVxuXG5mdW5jdGlvbiBnZXRDb250ZXh0Rm9yU3VidHJlZShwYXJlbnRDb21wb25lbnQpIHtcbiAgaWYgKCFwYXJlbnRDb21wb25lbnQpIHtcbiAgICByZXR1cm4gZW1wdHlDb250ZXh0T2JqZWN0O1xuICB9XG5cbiAgdmFyIGZpYmVyID0gZ2V0KHBhcmVudENvbXBvbmVudCk7XG4gIHZhciBwYXJlbnRDb250ZXh0ID0gZmluZEN1cnJlbnRVbm1hc2tlZENvbnRleHQoZmliZXIpO1xuXG4gIGlmIChmaWJlci50YWcgPT09IENsYXNzQ29tcG9uZW50KSB7XG4gICAgdmFyIENvbXBvbmVudCA9IGZpYmVyLnR5cGU7XG5cbiAgICBpZiAoaXNDb250ZXh0UHJvdmlkZXIoQ29tcG9uZW50KSkge1xuICAgICAgcmV0dXJuIHByb2Nlc3NDaGlsZENvbnRleHQoZmliZXIsIENvbXBvbmVudCwgcGFyZW50Q29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcmVudENvbnRleHQ7XG59XG5cbmZ1bmN0aW9uIGZpbmRIb3N0SW5zdGFuY2VXaXRoV2FybmluZyhjb21wb25lbnQsIG1ldGhvZE5hbWUpIHtcbiAge1xuICAgIHZhciBmaWJlciA9IGdldChjb21wb25lbnQpO1xuXG4gICAgaWYgKGZpYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eXBlb2YgY29tcG9uZW50LnJlbmRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmaW5kIG5vZGUgb24gYW4gdW5tb3VudGVkIGNvbXBvbmVudC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMoY29tcG9uZW50KS5qb2luKCcsJyk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkFyZ3VtZW50IGFwcGVhcnMgdG8gbm90IGJlIGEgUmVhY3RDb21wb25lbnQuIEtleXM6IFwiICsga2V5cyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGhvc3RGaWJlciA9IGZpbmRDdXJyZW50SG9zdEZpYmVyKGZpYmVyKTtcblxuICAgIGlmIChob3N0RmliZXIgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChob3N0RmliZXIubW9kZSAmIFN0cmljdExlZ2FjeU1vZGUpIHtcbiAgICAgIHZhciBjb21wb25lbnROYW1lID0gZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihmaWJlcikgfHwgJ0NvbXBvbmVudCc7XG5cbiAgICAgIGlmICghZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGVbY29tcG9uZW50TmFtZV0pIHtcbiAgICAgICAgZGlkV2FybkFib3V0RmluZE5vZGVJblN0cmljdE1vZGVbY29tcG9uZW50TmFtZV0gPSB0cnVlO1xuICAgICAgICB2YXIgcHJldmlvdXNGaWJlciA9IGN1cnJlbnQ7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBzZXRDdXJyZW50RmliZXIoaG9zdEZpYmVyKTtcblxuICAgICAgICAgIGlmIChmaWJlci5tb2RlICYgU3RyaWN0TGVnYWN5TW9kZSkge1xuICAgICAgICAgICAgZXJyb3IoJyVzIGlzIGRlcHJlY2F0ZWQgaW4gU3RyaWN0TW9kZS4gJyArICclcyB3YXMgcGFzc2VkIGFuIGluc3RhbmNlIG9mICVzIHdoaWNoIGlzIGluc2lkZSBTdHJpY3RNb2RlLiAnICsgJ0luc3RlYWQsIGFkZCBhIHJlZiBkaXJlY3RseSB0byB0aGUgZWxlbWVudCB5b3Ugd2FudCB0byByZWZlcmVuY2UuICcgKyAnTGVhcm4gbW9yZSBhYm91dCB1c2luZyByZWZzIHNhZmVseSBoZXJlOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zdHJpY3QtbW9kZS1maW5kLW5vZGUnLCBtZXRob2ROYW1lLCBtZXRob2ROYW1lLCBjb21wb25lbnROYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZXJyb3IoJyVzIGlzIGRlcHJlY2F0ZWQgaW4gU3RyaWN0TW9kZS4gJyArICclcyB3YXMgcGFzc2VkIGFuIGluc3RhbmNlIG9mICVzIHdoaWNoIHJlbmRlcnMgU3RyaWN0TW9kZSBjaGlsZHJlbi4gJyArICdJbnN0ZWFkLCBhZGQgYSByZWYgZGlyZWN0bHkgdG8gdGhlIGVsZW1lbnQgeW91IHdhbnQgdG8gcmVmZXJlbmNlLiAnICsgJ0xlYXJuIG1vcmUgYWJvdXQgdXNpbmcgcmVmcyBzYWZlbHkgaGVyZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3RyaWN0LW1vZGUtZmluZC1ub2RlJywgbWV0aG9kTmFtZSwgbWV0aG9kTmFtZSwgY29tcG9uZW50TmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIC8vIElkZWFsbHkgdGhpcyBzaG91bGQgcmVzZXQgdG8gcHJldmlvdXMgYnV0IHRoaXMgc2hvdWxkbid0IGJlIGNhbGxlZCBpblxuICAgICAgICAgIC8vIHJlbmRlciBhbmQgdGhlcmUncyBhbm90aGVyIHdhcm5pbmcgZm9yIHRoYXQgYW55d2F5LlxuICAgICAgICAgIGlmIChwcmV2aW91c0ZpYmVyKSB7XG4gICAgICAgICAgICBzZXRDdXJyZW50RmliZXIocHJldmlvdXNGaWJlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc2V0Q3VycmVudEZpYmVyKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhvc3RGaWJlci5zdGF0ZU5vZGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lckluZm8sIHRhZywgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvciwgdHJhbnNpdGlvbkNhbGxiYWNrcykge1xuICB2YXIgaHlkcmF0ZSA9IGZhbHNlO1xuICB2YXIgaW5pdGlhbENoaWxkcmVuID0gbnVsbDtcbiAgcmV0dXJuIGNyZWF0ZUZpYmVyUm9vdChjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGUsIGluaXRpYWxDaGlsZHJlbiwgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvcik7XG59XG5mdW5jdGlvbiBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCAvLyBUT0RPOiBSZW1vdmUgYGNhbGxiYWNrYCB3aGVuIHdlIGRlbGV0ZSBsZWdhY3kgbW9kZS5cbmNhbGxiYWNrLCBjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGlvbkNhbGxiYWNrcywgaXNTdHJpY3RNb2RlLCBjb25jdXJyZW50VXBkYXRlc0J5RGVmYXVsdE92ZXJyaWRlLCBpZGVudGlmaWVyUHJlZml4LCBvblJlY292ZXJhYmxlRXJyb3IsIHRyYW5zaXRpb25DYWxsYmFja3MpIHtcbiAgdmFyIGh5ZHJhdGUgPSB0cnVlO1xuICB2YXIgcm9vdCA9IGNyZWF0ZUZpYmVyUm9vdChjb250YWluZXJJbmZvLCB0YWcsIGh5ZHJhdGUsIGluaXRpYWxDaGlsZHJlbiwgaHlkcmF0aW9uQ2FsbGJhY2tzLCBpc1N0cmljdE1vZGUsIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsIGlkZW50aWZpZXJQcmVmaXgsIG9uUmVjb3ZlcmFibGVFcnJvcik7IC8vIFRPRE86IE1vdmUgdGhpcyB0byBGaWJlclJvb3QgY29uc3RydWN0b3JcblxuICByb290LmNvbnRleHQgPSBnZXRDb250ZXh0Rm9yU3VidHJlZShudWxsKTsgLy8gU2NoZWR1bGUgdGhlIGluaXRpYWwgcmVuZGVyLiBJbiBhIGh5ZHJhdGlvbiByb290LCB0aGlzIGlzIGRpZmZlcmVudCBmcm9tXG4gIC8vIGEgcmVndWxhciB1cGRhdGUgYmVjYXVzZSB0aGUgaW5pdGlhbCByZW5kZXIgbXVzdCBtYXRjaCB3YXMgd2FzIHJlbmRlcmVkXG4gIC8vIG9uIHRoZSBzZXJ2ZXIuXG4gIC8vIE5PVEU6IFRoaXMgdXBkYXRlIGludGVudGlvbmFsbHkgZG9lc24ndCBoYXZlIGEgcGF5bG9hZC4gV2UncmUgb25seSB1c2luZ1xuICAvLyB0aGUgdXBkYXRlIHRvIHNjaGVkdWxlIHdvcmsgb24gdGhlIHJvb3QgZmliZXIgKGFuZCwgZm9yIGxlZ2FjeSByb290cywgdG9cbiAgLy8gZW5xdWV1ZSB0aGUgY2FsbGJhY2sgaWYgb25lIGlzIHByb3ZpZGVkKS5cblxuICB2YXIgY3VycmVudCA9IHJvb3QuY3VycmVudDtcbiAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgdmFyIGxhbmUgPSByZXF1ZXN0VXBkYXRlTGFuZShjdXJyZW50KTtcbiAgdmFyIHVwZGF0ZSA9IGNyZWF0ZVVwZGF0ZShldmVudFRpbWUsIGxhbmUpO1xuICB1cGRhdGUuY2FsbGJhY2sgPSBjYWxsYmFjayAhPT0gdW5kZWZpbmVkICYmIGNhbGxiYWNrICE9PSBudWxsID8gY2FsbGJhY2sgOiBudWxsO1xuICBlbnF1ZXVlVXBkYXRlKGN1cnJlbnQsIHVwZGF0ZSwgbGFuZSk7XG4gIHNjaGVkdWxlSW5pdGlhbEh5ZHJhdGlvbk9uUm9vdChyb290LCBsYW5lLCBldmVudFRpbWUpO1xuICByZXR1cm4gcm9vdDtcbn1cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRhaW5lcihlbGVtZW50LCBjb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgY2FsbGJhY2spIHtcbiAge1xuICAgIG9uU2NoZWR1bGVSb290KGNvbnRhaW5lciwgZWxlbWVudCk7XG4gIH1cblxuICB2YXIgY3VycmVudCQxID0gY29udGFpbmVyLmN1cnJlbnQ7XG4gIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gIHZhciBsYW5lID0gcmVxdWVzdFVwZGF0ZUxhbmUoY3VycmVudCQxKTtcblxuICB7XG4gICAgbWFya1JlbmRlclNjaGVkdWxlZChsYW5lKTtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0gZ2V0Q29udGV4dEZvclN1YnRyZWUocGFyZW50Q29tcG9uZW50KTtcblxuICBpZiAoY29udGFpbmVyLmNvbnRleHQgPT09IG51bGwpIHtcbiAgICBjb250YWluZXIuY29udGV4dCA9IGNvbnRleHQ7XG4gIH0gZWxzZSB7XG4gICAgY29udGFpbmVyLnBlbmRpbmdDb250ZXh0ID0gY29udGV4dDtcbiAgfVxuXG4gIHtcbiAgICBpZiAoaXNSZW5kZXJpbmcgJiYgY3VycmVudCAhPT0gbnVsbCAmJiAhZGlkV2FybkFib3V0TmVzdGVkVXBkYXRlcykge1xuICAgICAgZGlkV2FybkFib3V0TmVzdGVkVXBkYXRlcyA9IHRydWU7XG5cbiAgICAgIGVycm9yKCdSZW5kZXIgbWV0aG9kcyBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZTsgJyArICd0cmlnZ2VyaW5nIG5lc3RlZCBjb21wb25lbnQgdXBkYXRlcyBmcm9tIHJlbmRlciBpcyBub3QgYWxsb3dlZC4gJyArICdJZiBuZWNlc3NhcnksIHRyaWdnZXIgbmVzdGVkIHVwZGF0ZXMgaW4gY29tcG9uZW50RGlkVXBkYXRlLlxcblxcbicgKyAnQ2hlY2sgdGhlIHJlbmRlciBtZXRob2Qgb2YgJXMuJywgZ2V0Q29tcG9uZW50TmFtZUZyb21GaWJlcihjdXJyZW50KSB8fCAnVW5rbm93bicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciB1cGRhdGUgPSBjcmVhdGVVcGRhdGUoZXZlbnRUaW1lLCBsYW5lKTsgLy8gQ2F1dGlvbjogUmVhY3QgRGV2VG9vbHMgY3VycmVudGx5IGRlcGVuZHMgb24gdGhpcyBwcm9wZXJ0eVxuICAvLyBiZWluZyBjYWxsZWQgXCJlbGVtZW50XCIuXG5cbiAgdXBkYXRlLnBheWxvYWQgPSB7XG4gICAgZWxlbWVudDogZWxlbWVudFxuICB9O1xuICBjYWxsYmFjayA9IGNhbGxiYWNrID09PSB1bmRlZmluZWQgPyBudWxsIDogY2FsbGJhY2s7XG5cbiAgaWYgKGNhbGxiYWNrICE9PSBudWxsKSB7XG4gICAge1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlcnJvcigncmVuZGVyKC4uLik6IEV4cGVjdGVkIHRoZSBsYXN0IG9wdGlvbmFsIGBjYWxsYmFja2AgYXJndW1lbnQgdG8gYmUgYSAnICsgJ2Z1bmN0aW9uLiBJbnN0ZWFkIHJlY2VpdmVkOiAlcy4nLCBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdXBkYXRlLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gIH1cblxuICB2YXIgcm9vdCA9IGVucXVldWVVcGRhdGUoY3VycmVudCQxLCB1cGRhdGUsIGxhbmUpO1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKHJvb3QsIGN1cnJlbnQkMSwgbGFuZSwgZXZlbnRUaW1lKTtcbiAgICBlbnRhbmdsZVRyYW5zaXRpb25zKHJvb3QsIGN1cnJlbnQkMSwgbGFuZSk7XG4gIH1cblxuICByZXR1cm4gbGFuZTtcbn1cbmZ1bmN0aW9uIGdldFB1YmxpY1Jvb3RJbnN0YW5jZShjb250YWluZXIpIHtcbiAgdmFyIGNvbnRhaW5lckZpYmVyID0gY29udGFpbmVyLmN1cnJlbnQ7XG5cbiAgaWYgKCFjb250YWluZXJGaWJlci5jaGlsZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3dpdGNoIChjb250YWluZXJGaWJlci5jaGlsZC50YWcpIHtcbiAgICBjYXNlIEhvc3RDb21wb25lbnQ6XG4gICAgICByZXR1cm4gZ2V0UHVibGljSW5zdGFuY2UoY29udGFpbmVyRmliZXIuY2hpbGQuc3RhdGVOb2RlKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gY29udGFpbmVyRmliZXIuY2hpbGQuc3RhdGVOb2RlO1xuICB9XG59XG5mdW5jdGlvbiBhdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24kMShmaWJlcikge1xuICBzd2l0Y2ggKGZpYmVyLnRhZykge1xuICAgIGNhc2UgSG9zdFJvb3Q6XG4gICAgICB7XG4gICAgICAgIHZhciByb290ID0gZmliZXIuc3RhdGVOb2RlO1xuXG4gICAgICAgIGlmIChpc1Jvb3REZWh5ZHJhdGVkKHJvb3QpKSB7XG4gICAgICAgICAgLy8gRmx1c2ggdGhlIGZpcnN0IHNjaGVkdWxlZCBcInVwZGF0ZVwiLlxuICAgICAgICAgIHZhciBsYW5lcyA9IGdldEhpZ2hlc3RQcmlvcml0eVBlbmRpbmdMYW5lcyhyb290KTtcbiAgICAgICAgICBmbHVzaFJvb3Qocm9vdCwgbGFuZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIFN1c3BlbnNlQ29tcG9uZW50OlxuICAgICAge1xuICAgICAgICBmbHVzaFN5bmMoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgICAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICAgICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIGV2ZW50VGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTsgLy8gSWYgd2UncmUgc3RpbGwgYmxvY2tlZCBhZnRlciB0aGlzLCB3ZSBuZWVkIHRvIGluY3JlYXNlXG4gICAgICAgIC8vIHRoZSBwcmlvcml0eSBvZiBhbnkgcHJvbWlzZXMgcmVzb2x2aW5nIHdpdGhpbiB0aGlzXG4gICAgICAgIC8vIGJvdW5kYXJ5IHNvIHRoYXQgdGhleSBuZXh0IGF0dGVtcHQgYWxzbyBoYXMgaGlnaGVyIHByaS5cblxuICAgICAgICB2YXIgcmV0cnlMYW5lID0gU3luY0xhbmU7XG4gICAgICAgIG1hcmtSZXRyeUxhbmVJZk5vdEh5ZHJhdGVkKGZpYmVyLCByZXRyeUxhbmUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBtYXJrUmV0cnlMYW5lSW1wbChmaWJlciwgcmV0cnlMYW5lKSB7XG4gIHZhciBzdXNwZW5zZVN0YXRlID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICBpZiAoc3VzcGVuc2VTdGF0ZSAhPT0gbnVsbCAmJiBzdXNwZW5zZVN0YXRlLmRlaHlkcmF0ZWQgIT09IG51bGwpIHtcbiAgICBzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSA9IGhpZ2hlclByaW9yaXR5TGFuZShzdXNwZW5zZVN0YXRlLnJldHJ5TGFuZSwgcmV0cnlMYW5lKTtcbiAgfVxufSAvLyBJbmNyZWFzZXMgdGhlIHByaW9yaXR5IG9mIHRoZW5hYmxlcyB3aGVuIHRoZXkgcmVzb2x2ZSB3aXRoaW4gdGhpcyBib3VuZGFyeS5cblxuXG5mdW5jdGlvbiBtYXJrUmV0cnlMYW5lSWZOb3RIeWRyYXRlZChmaWJlciwgcmV0cnlMYW5lKSB7XG4gIG1hcmtSZXRyeUxhbmVJbXBsKGZpYmVyLCByZXRyeUxhbmUpO1xuICB2YXIgYWx0ZXJuYXRlID0gZmliZXIuYWx0ZXJuYXRlO1xuXG4gIGlmIChhbHRlcm5hdGUpIHtcbiAgICBtYXJrUmV0cnlMYW5lSW1wbChhbHRlcm5hdGUsIHJldHJ5TGFuZSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGF0dGVtcHRDb250aW51b3VzSHlkcmF0aW9uJDEoZmliZXIpIHtcbiAgaWYgKGZpYmVyLnRhZyAhPT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAvLyBXZSBpZ25vcmUgSG9zdFJvb3RzIGhlcmUgYmVjYXVzZSB3ZSBjYW4ndCBpbmNyZWFzZVxuICAgIC8vIHRoZWlyIHByaW9yaXR5IGFuZCB0aGV5IHNob3VsZCBub3Qgc3VzcGVuZCBvbiBJL08sXG4gICAgLy8gc2luY2UgeW91IGhhdmUgdG8gd3JhcCBhbnl0aGluZyB0aGF0IG1pZ2h0IHN1c3BlbmQgaW5cbiAgICAvLyBTdXNwZW5zZS5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbGFuZSA9IFNlbGVjdGl2ZUh5ZHJhdGlvbkxhbmU7XG4gIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBsYW5lKTtcblxuICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgIHZhciBldmVudFRpbWUgPSByZXF1ZXN0RXZlbnRUaW1lKCk7XG4gICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKHJvb3QsIGZpYmVyLCBsYW5lLCBldmVudFRpbWUpO1xuICB9XG5cbiAgbWFya1JldHJ5TGFuZUlmTm90SHlkcmF0ZWQoZmliZXIsIGxhbmUpO1xufVxuZnVuY3Rpb24gYXR0ZW1wdEh5ZHJhdGlvbkF0Q3VycmVudFByaW9yaXR5JDEoZmliZXIpIHtcbiAgaWYgKGZpYmVyLnRhZyAhPT0gU3VzcGVuc2VDb21wb25lbnQpIHtcbiAgICAvLyBXZSBpZ25vcmUgSG9zdFJvb3RzIGhlcmUgYmVjYXVzZSB3ZSBjYW4ndCBpbmNyZWFzZVxuICAgIC8vIHRoZWlyIHByaW9yaXR5IG90aGVyIHRoYW4gc3luY2hyb25vdXNseSBmbHVzaCBpdC5cbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbGFuZSA9IHJlcXVlc3RVcGRhdGVMYW5lKGZpYmVyKTtcbiAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIGxhbmUpO1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgdmFyIGV2ZW50VGltZSA9IHJlcXVlc3RFdmVudFRpbWUoKTtcbiAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIGxhbmUsIGV2ZW50VGltZSk7XG4gIH1cblxuICBtYXJrUmV0cnlMYW5lSWZOb3RIeWRyYXRlZChmaWJlciwgbGFuZSk7XG59XG5mdW5jdGlvbiBmaW5kSG9zdEluc3RhbmNlV2l0aE5vUG9ydGFscyhmaWJlcikge1xuICB2YXIgaG9zdEZpYmVyID0gZmluZEN1cnJlbnRIb3N0RmliZXJXaXRoTm9Qb3J0YWxzKGZpYmVyKTtcblxuICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9zdEZpYmVyLnN0YXRlTm9kZTtcbn1cblxudmFyIHNob3VsZEVycm9ySW1wbCA9IGZ1bmN0aW9uIChmaWJlcikge1xuICByZXR1cm4gbnVsbDtcbn07XG5cbmZ1bmN0aW9uIHNob3VsZEVycm9yKGZpYmVyKSB7XG4gIHJldHVybiBzaG91bGRFcnJvckltcGwoZmliZXIpO1xufVxuXG52YXIgc2hvdWxkU3VzcGVuZEltcGwgPSBmdW5jdGlvbiAoZmliZXIpIHtcbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gc2hvdWxkU3VzcGVuZChmaWJlcikge1xuICByZXR1cm4gc2hvdWxkU3VzcGVuZEltcGwoZmliZXIpO1xufVxudmFyIG92ZXJyaWRlSG9va1N0YXRlID0gbnVsbDtcbnZhciBvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGggPSBudWxsO1xudmFyIG92ZXJyaWRlSG9va1N0YXRlUmVuYW1lUGF0aCA9IG51bGw7XG52YXIgb3ZlcnJpZGVQcm9wcyA9IG51bGw7XG52YXIgb3ZlcnJpZGVQcm9wc0RlbGV0ZVBhdGggPSBudWxsO1xudmFyIG92ZXJyaWRlUHJvcHNSZW5hbWVQYXRoID0gbnVsbDtcbnZhciBzY2hlZHVsZVVwZGF0ZSA9IG51bGw7XG52YXIgc2V0RXJyb3JIYW5kbGVyID0gbnVsbDtcbnZhciBzZXRTdXNwZW5zZUhhbmRsZXIgPSBudWxsO1xuXG57XG4gIHZhciBjb3B5V2l0aERlbGV0ZUltcGwgPSBmdW5jdGlvbiAob2JqLCBwYXRoLCBpbmRleCkge1xuICAgIHZhciBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICB2YXIgdXBkYXRlZCA9IGlzQXJyYXkob2JqKSA/IG9iai5zbGljZSgpIDogYXNzaWduKHt9LCBvYmopO1xuXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gcGF0aC5sZW5ndGgpIHtcbiAgICAgIGlmIChpc0FycmF5KHVwZGF0ZWQpKSB7XG4gICAgICAgIHVwZGF0ZWQuc3BsaWNlKGtleSwgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgdXBkYXRlZFtrZXldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICB9IC8vICRGbG93Rml4TWUgbnVtYmVyIG9yIHN0cmluZyBpcyBmaW5lIGhlcmVcblxuXG4gICAgdXBkYXRlZFtrZXldID0gY29weVdpdGhEZWxldGVJbXBsKG9ialtrZXldLCBwYXRoLCBpbmRleCArIDEpO1xuICAgIHJldHVybiB1cGRhdGVkO1xuICB9O1xuXG4gIHZhciBjb3B5V2l0aERlbGV0ZSA9IGZ1bmN0aW9uIChvYmosIHBhdGgpIHtcbiAgICByZXR1cm4gY29weVdpdGhEZWxldGVJbXBsKG9iaiwgcGF0aCwgMCk7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoUmVuYW1lSW1wbCA9IGZ1bmN0aW9uIChvYmosIG9sZFBhdGgsIG5ld1BhdGgsIGluZGV4KSB7XG4gICAgdmFyIG9sZEtleSA9IG9sZFBhdGhbaW5kZXhdO1xuICAgIHZhciB1cGRhdGVkID0gaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBhc3NpZ24oe30sIG9iaik7XG5cbiAgICBpZiAoaW5kZXggKyAxID09PSBvbGRQYXRoLmxlbmd0aCkge1xuICAgICAgdmFyIG5ld0tleSA9IG5ld1BhdGhbaW5kZXhdOyAvLyAkRmxvd0ZpeE1lIG51bWJlciBvciBzdHJpbmcgaXMgZmluZSBoZXJlXG5cbiAgICAgIHVwZGF0ZWRbbmV3S2V5XSA9IHVwZGF0ZWRbb2xkS2V5XTtcblxuICAgICAgaWYgKGlzQXJyYXkodXBkYXRlZCkpIHtcbiAgICAgICAgdXBkYXRlZC5zcGxpY2Uob2xkS2V5LCAxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVkW29sZEtleV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vICRGbG93Rml4TWUgbnVtYmVyIG9yIHN0cmluZyBpcyBmaW5lIGhlcmVcbiAgICAgIHVwZGF0ZWRbb2xkS2V5XSA9IGNvcHlXaXRoUmVuYW1lSW1wbCggLy8gJEZsb3dGaXhNZSBudW1iZXIgb3Igc3RyaW5nIGlzIGZpbmUgaGVyZVxuICAgICAgb2JqW29sZEtleV0sIG9sZFBhdGgsIG5ld1BhdGgsIGluZGV4ICsgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVwZGF0ZWQ7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoUmVuYW1lID0gZnVuY3Rpb24gKG9iaiwgb2xkUGF0aCwgbmV3UGF0aCkge1xuICAgIGlmIChvbGRQYXRoLmxlbmd0aCAhPT0gbmV3UGF0aC5sZW5ndGgpIHtcbiAgICAgIHdhcm4oJ2NvcHlXaXRoUmVuYW1lKCkgZXhwZWN0cyBwYXRocyBvZiB0aGUgc2FtZSBsZW5ndGgnKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5ld1BhdGgubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGlmIChvbGRQYXRoW2ldICE9PSBuZXdQYXRoW2ldKSB7XG4gICAgICAgICAgd2FybignY29weVdpdGhSZW5hbWUoKSBleHBlY3RzIHBhdGhzIHRvIGJlIHRoZSBzYW1lIGV4Y2VwdCBmb3IgdGhlIGRlZXBlc3Qga2V5Jyk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29weVdpdGhSZW5hbWVJbXBsKG9iaiwgb2xkUGF0aCwgbmV3UGF0aCwgMCk7XG4gIH07XG5cbiAgdmFyIGNvcHlXaXRoU2V0SW1wbCA9IGZ1bmN0aW9uIChvYmosIHBhdGgsIGluZGV4LCB2YWx1ZSkge1xuICAgIGlmIChpbmRleCA+PSBwYXRoLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHZhciBrZXkgPSBwYXRoW2luZGV4XTtcbiAgICB2YXIgdXBkYXRlZCA9IGlzQXJyYXkob2JqKSA/IG9iai5zbGljZSgpIDogYXNzaWduKHt9LCBvYmopOyAvLyAkRmxvd0ZpeE1lIG51bWJlciBvciBzdHJpbmcgaXMgZmluZSBoZXJlXG5cbiAgICB1cGRhdGVkW2tleV0gPSBjb3B5V2l0aFNldEltcGwob2JqW2tleV0sIHBhdGgsIGluZGV4ICsgMSwgdmFsdWUpO1xuICAgIHJldHVybiB1cGRhdGVkO1xuICB9O1xuXG4gIHZhciBjb3B5V2l0aFNldCA9IGZ1bmN0aW9uIChvYmosIHBhdGgsIHZhbHVlKSB7XG4gICAgcmV0dXJuIGNvcHlXaXRoU2V0SW1wbChvYmosIHBhdGgsIDAsIHZhbHVlKTtcbiAgfTtcblxuICB2YXIgZmluZEhvb2sgPSBmdW5jdGlvbiAoZmliZXIsIGlkKSB7XG4gICAgLy8gRm9yIG5vdywgdGhlIFwiaWRcIiBvZiBzdGF0ZWZ1bCBob29rcyBpcyBqdXN0IHRoZSBzdGF0ZWZ1bCBob29rIGluZGV4LlxuICAgIC8vIFRoaXMgbWF5IGNoYW5nZSBpbiB0aGUgZnV0dXJlIHdpdGggZS5nLiBuZXN0ZWQgaG9va3MuXG4gICAgdmFyIGN1cnJlbnRIb29rID0gZmliZXIubWVtb2l6ZWRTdGF0ZTtcblxuICAgIHdoaWxlIChjdXJyZW50SG9vayAhPT0gbnVsbCAmJiBpZCA+IDApIHtcbiAgICAgIGN1cnJlbnRIb29rID0gY3VycmVudEhvb2submV4dDtcbiAgICAgIGlkLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRIb29rO1xuICB9OyAvLyBTdXBwb3J0IERldlRvb2xzIGVkaXRhYmxlIHZhbHVlcyBmb3IgdXNlU3RhdGUgYW5kIHVzZVJlZHVjZXIuXG5cblxuICBvdmVycmlkZUhvb2tTdGF0ZSA9IGZ1bmN0aW9uIChmaWJlciwgaWQsIHBhdGgsIHZhbHVlKSB7XG4gICAgdmFyIGhvb2sgPSBmaW5kSG9vayhmaWJlciwgaWQpO1xuXG4gICAgaWYgKGhvb2sgIT09IG51bGwpIHtcbiAgICAgIHZhciBuZXdTdGF0ZSA9IGNvcHlXaXRoU2V0KGhvb2subWVtb2l6ZWRTdGF0ZSwgcGF0aCwgdmFsdWUpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVIb29rU3RhdGVEZWxldGVQYXRoID0gZnVuY3Rpb24gKGZpYmVyLCBpZCwgcGF0aCkge1xuICAgIHZhciBob29rID0gZmluZEhvb2soZmliZXIsIGlkKTtcblxuICAgIGlmIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgbmV3U3RhdGUgPSBjb3B5V2l0aERlbGV0ZShob29rLm1lbW9pemVkU3RhdGUsIHBhdGgpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVIb29rU3RhdGVSZW5hbWVQYXRoID0gZnVuY3Rpb24gKGZpYmVyLCBpZCwgb2xkUGF0aCwgbmV3UGF0aCkge1xuICAgIHZhciBob29rID0gZmluZEhvb2soZmliZXIsIGlkKTtcblxuICAgIGlmIChob29rICE9PSBudWxsKSB7XG4gICAgICB2YXIgbmV3U3RhdGUgPSBjb3B5V2l0aFJlbmFtZShob29rLm1lbW9pemVkU3RhdGUsIG9sZFBhdGgsIG5ld1BhdGgpO1xuICAgICAgaG9vay5tZW1vaXplZFN0YXRlID0gbmV3U3RhdGU7XG4gICAgICBob29rLmJhc2VTdGF0ZSA9IG5ld1N0YXRlOyAvLyBXZSBhcmVuJ3QgYWN0dWFsbHkgYWRkaW5nIGFuIHVwZGF0ZSB0byB0aGUgcXVldWUsXG4gICAgICAvLyBiZWNhdXNlIHRoZXJlIGlzIG5vIHVwZGF0ZSB3ZSBjYW4gYWRkIGZvciB1c2VSZWR1Y2VyIGhvb2tzIHRoYXQgd29uJ3QgdHJpZ2dlciBhbiBlcnJvci5cbiAgICAgIC8vIChUaGVyZSdzIG5vIGFwcHJvcHJpYXRlIGFjdGlvbiB0eXBlIGZvciBEZXZUb29scyBvdmVycmlkZXMuKVxuICAgICAgLy8gQXMgYSByZXN1bHQgdGhvdWdoLCBSZWFjdCB3aWxsIHNlZSB0aGUgc2NoZWR1bGVkIHVwZGF0ZSBhcyBhIG5vb3AgYW5kIGJhaWxvdXQuXG4gICAgICAvLyBTaGFsbG93IGNsb25pbmcgcHJvcHMgd29ya3MgYXMgYSB3b3JrYXJvdW5kIGZvciBub3cgdG8gYnlwYXNzIHRoZSBiYWlsb3V0IGNoZWNrLlxuXG4gICAgICBmaWJlci5tZW1vaXplZFByb3BzID0gYXNzaWduKHt9LCBmaWJlci5tZW1vaXplZFByb3BzKTtcbiAgICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICAgIH1cbiAgICB9XG4gIH07IC8vIFN1cHBvcnQgRGV2VG9vbHMgcHJvcHMgZm9yIGZ1bmN0aW9uIGNvbXBvbmVudHMsIGZvcndhcmRSZWYsIG1lbW8sIGhvc3QgY29tcG9uZW50cywgZXRjLlxuXG5cbiAgb3ZlcnJpZGVQcm9wcyA9IGZ1bmN0aW9uIChmaWJlciwgcGF0aCwgdmFsdWUpIHtcbiAgICBmaWJlci5wZW5kaW5nUHJvcHMgPSBjb3B5V2l0aFNldChmaWJlci5tZW1vaXplZFByb3BzLCBwYXRoLCB2YWx1ZSk7XG5cbiAgICBpZiAoZmliZXIuYWx0ZXJuYXRlKSB7XG4gICAgICBmaWJlci5hbHRlcm5hdGUucGVuZGluZ1Byb3BzID0gZmliZXIucGVuZGluZ1Byb3BzO1xuICAgIH1cblxuICAgIHZhciByb290ID0gZW5xdWV1ZUNvbmN1cnJlbnRSZW5kZXJGb3JMYW5lKGZpYmVyLCBTeW5jTGFuZSk7XG5cbiAgICBpZiAocm9vdCAhPT0gbnVsbCkge1xuICAgICAgc2NoZWR1bGVVcGRhdGVPbkZpYmVyKHJvb3QsIGZpYmVyLCBTeW5jTGFuZSwgTm9UaW1lc3RhbXApO1xuICAgIH1cbiAgfTtcblxuICBvdmVycmlkZVByb3BzRGVsZXRlUGF0aCA9IGZ1bmN0aW9uIChmaWJlciwgcGF0aCkge1xuICAgIGZpYmVyLnBlbmRpbmdQcm9wcyA9IGNvcHlXaXRoRGVsZXRlKGZpYmVyLm1lbW9pemVkUHJvcHMsIHBhdGgpO1xuXG4gICAgaWYgKGZpYmVyLmFsdGVybmF0ZSkge1xuICAgICAgZmliZXIuYWx0ZXJuYXRlLnBlbmRpbmdQcm9wcyA9IGZpYmVyLnBlbmRpbmdQcm9wcztcbiAgICB9XG5cbiAgICB2YXIgcm9vdCA9IGVucXVldWVDb25jdXJyZW50UmVuZGVyRm9yTGFuZShmaWJlciwgU3luY0xhbmUpO1xuXG4gICAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAgIHNjaGVkdWxlVXBkYXRlT25GaWJlcihyb290LCBmaWJlciwgU3luY0xhbmUsIE5vVGltZXN0YW1wKTtcbiAgICB9XG4gIH07XG5cbiAgb3ZlcnJpZGVQcm9wc1JlbmFtZVBhdGggPSBmdW5jdGlvbiAoZmliZXIsIG9sZFBhdGgsIG5ld1BhdGgpIHtcbiAgICBmaWJlci5wZW5kaW5nUHJvcHMgPSBjb3B5V2l0aFJlbmFtZShmaWJlci5tZW1vaXplZFByb3BzLCBvbGRQYXRoLCBuZXdQYXRoKTtcblxuICAgIGlmIChmaWJlci5hbHRlcm5hdGUpIHtcbiAgICAgIGZpYmVyLmFsdGVybmF0ZS5wZW5kaW5nUHJvcHMgPSBmaWJlci5wZW5kaW5nUHJvcHM7XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIFN5bmNMYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIFN5bmNMYW5lLCBOb1RpbWVzdGFtcCk7XG4gICAgfVxuICB9O1xuXG4gIHNjaGVkdWxlVXBkYXRlID0gZnVuY3Rpb24gKGZpYmVyKSB7XG4gICAgdmFyIHJvb3QgPSBlbnF1ZXVlQ29uY3VycmVudFJlbmRlckZvckxhbmUoZmliZXIsIFN5bmNMYW5lKTtcblxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICBzY2hlZHVsZVVwZGF0ZU9uRmliZXIocm9vdCwgZmliZXIsIFN5bmNMYW5lLCBOb1RpbWVzdGFtcCk7XG4gICAgfVxuICB9O1xuXG4gIHNldEVycm9ySGFuZGxlciA9IGZ1bmN0aW9uIChuZXdTaG91bGRFcnJvckltcGwpIHtcbiAgICBzaG91bGRFcnJvckltcGwgPSBuZXdTaG91bGRFcnJvckltcGw7XG4gIH07XG5cbiAgc2V0U3VzcGVuc2VIYW5kbGVyID0gZnVuY3Rpb24gKG5ld1Nob3VsZFN1c3BlbmRJbXBsKSB7XG4gICAgc2hvdWxkU3VzcGVuZEltcGwgPSBuZXdTaG91bGRTdXNwZW5kSW1wbDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmluZEhvc3RJbnN0YW5jZUJ5RmliZXIoZmliZXIpIHtcbiAgdmFyIGhvc3RGaWJlciA9IGZpbmRDdXJyZW50SG9zdEZpYmVyKGZpYmVyKTtcblxuICBpZiAoaG9zdEZpYmVyID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaG9zdEZpYmVyLnN0YXRlTm9kZTtcbn1cblxuZnVuY3Rpb24gZW1wdHlGaW5kRmliZXJCeUhvc3RJbnN0YW5jZShpbnN0YW5jZSkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudEZpYmVyRm9yRGV2VG9vbHMoKSB7XG4gIHJldHVybiBjdXJyZW50O1xufVxuXG5mdW5jdGlvbiBpbmplY3RJbnRvRGV2VG9vbHMoZGV2VG9vbHNDb25maWcpIHtcbiAgdmFyIGZpbmRGaWJlckJ5SG9zdEluc3RhbmNlID0gZGV2VG9vbHNDb25maWcuZmluZEZpYmVyQnlIb3N0SW5zdGFuY2U7XG4gIHZhciBSZWFjdEN1cnJlbnREaXNwYXRjaGVyID0gUmVhY3RTaGFyZWRJbnRlcm5hbHMuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcjtcbiAgcmV0dXJuIGluamVjdEludGVybmFscyh7XG4gICAgYnVuZGxlVHlwZTogZGV2VG9vbHNDb25maWcuYnVuZGxlVHlwZSxcbiAgICB2ZXJzaW9uOiBkZXZUb29sc0NvbmZpZy52ZXJzaW9uLFxuICAgIHJlbmRlcmVyUGFja2FnZU5hbWU6IGRldlRvb2xzQ29uZmlnLnJlbmRlcmVyUGFja2FnZU5hbWUsXG4gICAgcmVuZGVyZXJDb25maWc6IGRldlRvb2xzQ29uZmlnLnJlbmRlcmVyQ29uZmlnLFxuICAgIG92ZXJyaWRlSG9va1N0YXRlOiBvdmVycmlkZUhvb2tTdGF0ZSxcbiAgICBvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGg6IG92ZXJyaWRlSG9va1N0YXRlRGVsZXRlUGF0aCxcbiAgICBvdmVycmlkZUhvb2tTdGF0ZVJlbmFtZVBhdGg6IG92ZXJyaWRlSG9va1N0YXRlUmVuYW1lUGF0aCxcbiAgICBvdmVycmlkZVByb3BzOiBvdmVycmlkZVByb3BzLFxuICAgIG92ZXJyaWRlUHJvcHNEZWxldGVQYXRoOiBvdmVycmlkZVByb3BzRGVsZXRlUGF0aCxcbiAgICBvdmVycmlkZVByb3BzUmVuYW1lUGF0aDogb3ZlcnJpZGVQcm9wc1JlbmFtZVBhdGgsXG4gICAgc2V0RXJyb3JIYW5kbGVyOiBzZXRFcnJvckhhbmRsZXIsXG4gICAgc2V0U3VzcGVuc2VIYW5kbGVyOiBzZXRTdXNwZW5zZUhhbmRsZXIsXG4gICAgc2NoZWR1bGVVcGRhdGU6IHNjaGVkdWxlVXBkYXRlLFxuICAgIGN1cnJlbnREaXNwYXRjaGVyUmVmOiBSZWFjdEN1cnJlbnREaXNwYXRjaGVyLFxuICAgIGZpbmRIb3N0SW5zdGFuY2VCeUZpYmVyOiBmaW5kSG9zdEluc3RhbmNlQnlGaWJlcixcbiAgICBmaW5kRmliZXJCeUhvc3RJbnN0YW5jZTogZmluZEZpYmVyQnlIb3N0SW5zdGFuY2UgfHwgZW1wdHlGaW5kRmliZXJCeUhvc3RJbnN0YW5jZSxcbiAgICAvLyBSZWFjdCBSZWZyZXNoXG4gICAgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoOiAgZmluZEhvc3RJbnN0YW5jZXNGb3JSZWZyZXNoICxcbiAgICBzY2hlZHVsZVJlZnJlc2g6ICBzY2hlZHVsZVJlZnJlc2ggLFxuICAgIHNjaGVkdWxlUm9vdDogIHNjaGVkdWxlUm9vdCAsXG4gICAgc2V0UmVmcmVzaEhhbmRsZXI6ICBzZXRSZWZyZXNoSGFuZGxlciAsXG4gICAgLy8gRW5hYmxlcyBEZXZUb29scyB0byBhcHBlbmQgb3duZXIgc3RhY2tzIHRvIGVycm9yIG1lc3NhZ2VzIGluIERFViBtb2RlLlxuICAgIGdldEN1cnJlbnRGaWJlcjogIGdldEN1cnJlbnRGaWJlckZvckRldlRvb2xzICxcbiAgICAvLyBFbmFibGVzIERldlRvb2xzIHRvIGRldGVjdCByZWNvbmNpbGVyIHZlcnNpb24gcmF0aGVyIHRoYW4gcmVuZGVyZXIgdmVyc2lvblxuICAgIC8vIHdoaWNoIG1heSBub3QgbWF0Y2ggZm9yIHRoaXJkIHBhcnR5IHJlbmRlcmVycy5cbiAgICByZWNvbmNpbGVyVmVyc2lvbjogUmVhY3RWZXJzaW9uXG4gIH0pO1xufVxuXG4vKiBnbG9iYWwgcmVwb3J0RXJyb3IgKi9cblxudmFyIGRlZmF1bHRPblJlY292ZXJhYmxlRXJyb3IgPSB0eXBlb2YgcmVwb3J0RXJyb3IgPT09ICdmdW5jdGlvbicgPyAvLyBJbiBtb2Rlcm4gYnJvd3NlcnMsIHJlcG9ydEVycm9yIHdpbGwgZGlzcGF0Y2ggYW4gZXJyb3IgZXZlbnQsXG4vLyBlbXVsYXRpbmcgYW4gdW5jYXVnaHQgSmF2YVNjcmlwdCBlcnJvci5cbnJlcG9ydEVycm9yIDogZnVuY3Rpb24gKGVycm9yKSB7XG4gIC8vIEluIG9sZGVyIGJyb3dzZXJzIGFuZCB0ZXN0IGVudmlyb25tZW50cywgZmFsbGJhY2sgdG8gY29uc29sZS5lcnJvci5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWludGVybmFsL25vLXByb2R1Y3Rpb24tbG9nZ2luZ1xuICBjb25zb2xlWydlcnJvciddKGVycm9yKTtcbn07XG5cbmZ1bmN0aW9uIFJlYWN0RE9NUm9vdChpbnRlcm5hbFJvb3QpIHtcbiAgdGhpcy5faW50ZXJuYWxSb290ID0gaW50ZXJuYWxSb290O1xufVxuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnJlbmRlciA9IFJlYWN0RE9NUm9vdC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gIHZhciByb290ID0gdGhpcy5faW50ZXJuYWxSb290O1xuXG4gIGlmIChyb290ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgdXBkYXRlIGFuIHVubW91bnRlZCByb290LicpO1xuICB9XG5cbiAge1xuICAgIGlmICh0eXBlb2YgYXJndW1lbnRzWzFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBlcnJvcigncmVuZGVyKC4uLik6IGRvZXMgbm90IHN1cHBvcnQgdGhlIHNlY29uZCBjYWxsYmFjayBhcmd1bWVudC4gJyArICdUbyBleGVjdXRlIGEgc2lkZSBlZmZlY3QgYWZ0ZXIgcmVuZGVyaW5nLCBkZWNsYXJlIGl0IGluIGEgY29tcG9uZW50IGJvZHkgd2l0aCB1c2VFZmZlY3QoKS4nKTtcbiAgICB9IGVsc2UgaWYgKGlzVmFsaWRDb250YWluZXIoYXJndW1lbnRzWzFdKSkge1xuICAgICAgZXJyb3IoJ1lvdSBwYXNzZWQgYSBjb250YWluZXIgdG8gdGhlIHNlY29uZCBhcmd1bWVudCBvZiByb290LnJlbmRlciguLi4pLiAnICsgXCJZb3UgZG9uJ3QgbmVlZCB0byBwYXNzIGl0IGFnYWluIHNpbmNlIHlvdSBhbHJlYWR5IHBhc3NlZCBpdCB0byBjcmVhdGUgdGhlIHJvb3QuXCIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGFyZ3VtZW50c1sxXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGVycm9yKCdZb3UgcGFzc2VkIGEgc2Vjb25kIGFyZ3VtZW50IHRvIHJvb3QucmVuZGVyKC4uLikgYnV0IGl0IG9ubHkgYWNjZXB0cyAnICsgJ29uZSBhcmd1bWVudC4nKTtcbiAgICB9XG5cbiAgICB2YXIgY29udGFpbmVyID0gcm9vdC5jb250YWluZXJJbmZvO1xuXG4gICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgaG9zdEluc3RhbmNlID0gZmluZEhvc3RJbnN0YW5jZVdpdGhOb1BvcnRhbHMocm9vdC5jdXJyZW50KTtcblxuICAgICAgaWYgKGhvc3RJbnN0YW5jZSkge1xuICAgICAgICBpZiAoaG9zdEluc3RhbmNlLnBhcmVudE5vZGUgIT09IGNvbnRhaW5lcikge1xuICAgICAgICAgIGVycm9yKCdyZW5kZXIoLi4uKTogSXQgbG9va3MgbGlrZSB0aGUgUmVhY3QtcmVuZGVyZWQgY29udGVudCBvZiB0aGUgJyArICdyb290IGNvbnRhaW5lciB3YXMgcmVtb3ZlZCB3aXRob3V0IHVzaW5nIFJlYWN0LiBUaGlzIGlzIG5vdCAnICsgJ3N1cHBvcnRlZCBhbmQgd2lsbCBjYXVzZSBlcnJvcnMuIEluc3RlYWQsIGNhbGwgJyArIFwicm9vdC51bm1vdW50KCkgdG8gZW1wdHkgYSByb290J3MgY29udGFpbmVyLlwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNvbnRhaW5lcihjaGlsZHJlbiwgcm9vdCwgbnVsbCwgbnVsbCk7XG59O1xuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnVubW91bnQgPSBSZWFjdERPTVJvb3QucHJvdG90eXBlLnVubW91bnQgPSBmdW5jdGlvbiAoKSB7XG4gIHtcbiAgICBpZiAodHlwZW9mIGFyZ3VtZW50c1swXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgZXJyb3IoJ3VubW91bnQoLi4uKTogZG9lcyBub3Qgc3VwcG9ydCBhIGNhbGxiYWNrIGFyZ3VtZW50LiAnICsgJ1RvIGV4ZWN1dGUgYSBzaWRlIGVmZmVjdCBhZnRlciByZW5kZXJpbmcsIGRlY2xhcmUgaXQgaW4gYSBjb21wb25lbnQgYm9keSB3aXRoIHVzZUVmZmVjdCgpLicpO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gdGhpcy5faW50ZXJuYWxSb290O1xuXG4gIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgdGhpcy5faW50ZXJuYWxSb290ID0gbnVsbDtcbiAgICB2YXIgY29udGFpbmVyID0gcm9vdC5jb250YWluZXJJbmZvO1xuXG4gICAge1xuICAgICAgaWYgKGlzQWxyZWFkeVJlbmRlcmluZygpKSB7XG4gICAgICAgIGVycm9yKCdBdHRlbXB0ZWQgdG8gc3luY2hyb25vdXNseSB1bm1vdW50IGEgcm9vdCB3aGlsZSBSZWFjdCB3YXMgYWxyZWFkeSAnICsgJ3JlbmRlcmluZy4gUmVhY3QgY2Fubm90IGZpbmlzaCB1bm1vdW50aW5nIHRoZSByb290IHVudGlsIHRoZSAnICsgJ2N1cnJlbnQgcmVuZGVyIGhhcyBjb21wbGV0ZWQsIHdoaWNoIG1heSBsZWFkIHRvIGEgcmFjZSBjb25kaXRpb24uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHVwZGF0ZUNvbnRhaW5lcihudWxsLCByb290LCBudWxsLCBudWxsKTtcbiAgICB9KTtcbiAgICB1bm1hcmtDb250YWluZXJBc1Jvb3QoY29udGFpbmVyKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gY3JlYXRlUm9vdChjb250YWluZXIsIG9wdGlvbnMpIHtcbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyKGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NyZWF0ZVJvb3QoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHdhcm5JZlJlYWN0RE9NQ29udGFpbmVySW5ERVYoY29udGFpbmVyKTtcbiAgdmFyIGlzU3RyaWN0TW9kZSA9IGZhbHNlO1xuICB2YXIgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSA9IGZhbHNlO1xuICB2YXIgaWRlbnRpZmllclByZWZpeCA9ICcnO1xuICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gZGVmYXVsdE9uUmVjb3ZlcmFibGVFcnJvcjtcbiAgdmFyIHRyYW5zaXRpb25DYWxsYmFja3MgPSBudWxsO1xuXG4gIGlmIChvcHRpb25zICE9PSBudWxsICYmIG9wdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgIHtcbiAgICAgIGlmIChvcHRpb25zLmh5ZHJhdGUpIHtcbiAgICAgICAgd2FybignaHlkcmF0ZSB0aHJvdWdoIGNyZWF0ZVJvb3QgaXMgZGVwcmVjYXRlZC4gVXNlIFJlYWN0RE9NQ2xpZW50Lmh5ZHJhdGVSb290KGNvbnRhaW5lciwgPEFwcCAvPikgaW5zdGVhZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCAmJiBvcHRpb25zLiQkdHlwZW9mID09PSBSRUFDVF9FTEVNRU5UX1RZUEUpIHtcbiAgICAgICAgICBlcnJvcignWW91IHBhc3NlZCBhIEpTWCBlbGVtZW50IHRvIGNyZWF0ZVJvb3QuIFlvdSBwcm9iYWJseSBtZWFudCB0byAnICsgJ2NhbGwgcm9vdC5yZW5kZXIgaW5zdGVhZC4gJyArICdFeGFtcGxlIHVzYWdlOlxcblxcbicgKyAnICBsZXQgcm9vdCA9IGNyZWF0ZVJvb3QoZG9tQ29udGFpbmVyKTtcXG4nICsgJyAgcm9vdC5yZW5kZXIoPEFwcCAvPik7Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy51bnN0YWJsZV9zdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBpc1N0cmljdE1vZGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmlkZW50aWZpZXJQcmVmaXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWRlbnRpZmllclByZWZpeCA9IG9wdGlvbnMuaWRlbnRpZmllclByZWZpeDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb25SZWNvdmVyYWJsZUVycm9yID0gb3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3I7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudHJhbnNpdGlvbkNhbGxiYWNrcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0cmFuc2l0aW9uQ2FsbGJhY2tzID0gb3B0aW9ucy50cmFuc2l0aW9uQ2FsbGJhY2tzO1xuICAgIH1cbiAgfVxuXG4gIHZhciByb290ID0gY3JlYXRlQ29udGFpbmVyKGNvbnRhaW5lciwgQ29uY3VycmVudFJvb3QsIG51bGwsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG4gIHZhciByb290Q29udGFpbmVyRWxlbWVudCA9IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFID8gY29udGFpbmVyLnBhcmVudE5vZGUgOiBjb250YWluZXI7XG4gIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKHJvb3RDb250YWluZXJFbGVtZW50KTtcbiAgcmV0dXJuIG5ldyBSZWFjdERPTVJvb3Qocm9vdCk7XG59XG5cbmZ1bmN0aW9uIFJlYWN0RE9NSHlkcmF0aW9uUm9vdChpbnRlcm5hbFJvb3QpIHtcbiAgdGhpcy5faW50ZXJuYWxSb290ID0gaW50ZXJuYWxSb290O1xufVxuXG5mdW5jdGlvbiBzY2hlZHVsZUh5ZHJhdGlvbih0YXJnZXQpIHtcbiAgaWYgKHRhcmdldCkge1xuICAgIHF1ZXVlRXhwbGljaXRIeWRyYXRpb25UYXJnZXQodGFyZ2V0KTtcbiAgfVxufVxuXG5SZWFjdERPTUh5ZHJhdGlvblJvb3QucHJvdG90eXBlLnVuc3RhYmxlX3NjaGVkdWxlSHlkcmF0aW9uID0gc2NoZWR1bGVIeWRyYXRpb247XG5mdW5jdGlvbiBoeWRyYXRlUm9vdChjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgb3B0aW9ucykge1xuICBpZiAoIWlzVmFsaWRDb250YWluZXIoY29udGFpbmVyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaHlkcmF0ZVJvb3QoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHdhcm5JZlJlYWN0RE9NQ29udGFpbmVySW5ERVYoY29udGFpbmVyKTtcblxuICB7XG4gICAgaWYgKGluaXRpYWxDaGlsZHJlbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvcignTXVzdCBwcm92aWRlIGluaXRpYWwgY2hpbGRyZW4gYXMgc2Vjb25kIGFyZ3VtZW50IHRvIGh5ZHJhdGVSb290LiAnICsgJ0V4YW1wbGUgdXNhZ2U6IGh5ZHJhdGVSb290KGRvbUNvbnRhaW5lciwgPEFwcCAvPiknKTtcbiAgICB9XG4gIH0gLy8gRm9yIG5vdyB3ZSByZXVzZSB0aGUgd2hvbGUgYmFnIG9mIG9wdGlvbnMgc2luY2UgdGhleSBjb250YWluXG4gIC8vIHRoZSBoeWRyYXRpb24gY2FsbGJhY2tzLlxuXG5cbiAgdmFyIGh5ZHJhdGlvbkNhbGxiYWNrcyA9IG9wdGlvbnMgIT0gbnVsbCA/IG9wdGlvbnMgOiBudWxsOyAvLyBUT0RPOiBEZWxldGUgdGhpcyBvcHRpb25cblxuICB2YXIgbXV0YWJsZVNvdXJjZXMgPSBvcHRpb25zICE9IG51bGwgJiYgb3B0aW9ucy5oeWRyYXRlZFNvdXJjZXMgfHwgbnVsbDtcbiAgdmFyIGlzU3RyaWN0TW9kZSA9IGZhbHNlO1xuICB2YXIgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSA9IGZhbHNlO1xuICB2YXIgaWRlbnRpZmllclByZWZpeCA9ICcnO1xuICB2YXIgb25SZWNvdmVyYWJsZUVycm9yID0gZGVmYXVsdE9uUmVjb3ZlcmFibGVFcnJvcjtcblxuICBpZiAob3B0aW9ucyAhPT0gbnVsbCAmJiBvcHRpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAob3B0aW9ucy51bnN0YWJsZV9zdHJpY3RNb2RlID09PSB0cnVlKSB7XG4gICAgICBpc1N0cmljdE1vZGUgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmlkZW50aWZpZXJQcmVmaXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWRlbnRpZmllclByZWZpeCA9IG9wdGlvbnMuaWRlbnRpZmllclByZWZpeDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb25SZWNvdmVyYWJsZUVycm9yID0gb3B0aW9ucy5vblJlY292ZXJhYmxlRXJyb3I7XG4gICAgfVxuICB9XG5cbiAgdmFyIHJvb3QgPSBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCBudWxsLCBjb250YWluZXIsIENvbmN1cnJlbnRSb290LCBoeWRyYXRpb25DYWxsYmFja3MsIGlzU3RyaWN0TW9kZSwgY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSwgaWRlbnRpZmllclByZWZpeCwgb25SZWNvdmVyYWJsZUVycm9yKTtcbiAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7IC8vIFRoaXMgY2FuJ3QgYmUgYSBjb21tZW50IG5vZGUgc2luY2UgaHlkcmF0aW9uIGRvZXNuJ3Qgd29yayBvbiBjb21tZW50IG5vZGVzIGFueXdheS5cblxuICBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhjb250YWluZXIpO1xuXG4gIGlmIChtdXRhYmxlU291cmNlcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXV0YWJsZVNvdXJjZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBtdXRhYmxlU291cmNlID0gbXV0YWJsZVNvdXJjZXNbaV07XG4gICAgICByZWdpc3Rlck11dGFibGVTb3VyY2VGb3JIeWRyYXRpb24ocm9vdCwgbXV0YWJsZVNvdXJjZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBSZWFjdERPTUh5ZHJhdGlvblJvb3Qocm9vdCk7XG59XG5mdW5jdGlvbiBpc1ZhbGlkQ29udGFpbmVyKG5vZGUpIHtcbiAgcmV0dXJuICEhKG5vZGUgJiYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgIWRpc2FibGVDb21tZW50c0FzRE9NQ29udGFpbmVycyAgKSk7XG59IC8vIFRPRE86IFJlbW92ZSB0aGlzIGZ1bmN0aW9uIHdoaWNoIGFsc28gaW5jbHVkZXMgY29tbWVudCBub2Rlcy5cbi8vIFdlIG9ubHkgdXNlIGl0IGluIHBsYWNlcyB0aGF0IGFyZSBjdXJyZW50bHkgbW9yZSByZWxheGVkLlxuXG5mdW5jdGlvbiBpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KG5vZGUpIHtcbiAgcmV0dXJuICEhKG5vZGUgJiYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFIHx8IG5vZGUubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUgfHwgbm9kZS5ub2RlVHlwZSA9PT0gQ09NTUVOVF9OT0RFICYmIG5vZGUubm9kZVZhbHVlID09PSAnIHJlYWN0LW1vdW50LXBvaW50LXVuc3RhYmxlICcpKTtcbn1cblxuZnVuY3Rpb24gd2FybklmUmVhY3RET01Db250YWluZXJJbkRFVihjb250YWluZXIpIHtcbiAge1xuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSAmJiBjb250YWluZXIudGFnTmFtZSAmJiBjb250YWluZXIudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSAnQk9EWScpIHtcbiAgICAgIGVycm9yKCdjcmVhdGVSb290KCk6IENyZWF0aW5nIHJvb3RzIGRpcmVjdGx5IHdpdGggZG9jdW1lbnQuYm9keSBpcyAnICsgJ2Rpc2NvdXJhZ2VkLCBzaW5jZSBpdHMgY2hpbGRyZW4gYXJlIG9mdGVuIG1hbmlwdWxhdGVkIGJ5IHRoaXJkLXBhcnR5ICcgKyAnc2NyaXB0cyBhbmQgYnJvd3NlciBleHRlbnNpb25zLiBUaGlzIG1heSBsZWFkIHRvIHN1YnRsZSAnICsgJ3JlY29uY2lsaWF0aW9uIGlzc3Vlcy4gVHJ5IHVzaW5nIGEgY29udGFpbmVyIGVsZW1lbnQgY3JlYXRlZCAnICsgJ2ZvciB5b3VyIGFwcC4nKTtcbiAgICB9XG5cbiAgICBpZiAoaXNDb250YWluZXJNYXJrZWRBc1Jvb3QoY29udGFpbmVyKSkge1xuICAgICAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyKSB7XG4gICAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpIG9uIGEgY29udGFpbmVyIHRoYXQgd2FzIHByZXZpb3VzbHkgJyArICdwYXNzZWQgdG8gUmVhY3RET00ucmVuZGVyKCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpIG9uIGEgY29udGFpbmVyIHRoYXQgJyArICdoYXMgYWxyZWFkeSBiZWVuIHBhc3NlZCB0byBjcmVhdGVSb290KCkgYmVmb3JlLiBJbnN0ZWFkLCBjYWxsICcgKyAncm9vdC5yZW5kZXIoKSBvbiB0aGUgZXhpc3Rpbmcgcm9vdCBpbnN0ZWFkIGlmIHlvdSB3YW50IHRvIHVwZGF0ZSBpdC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxudmFyIFJlYWN0Q3VycmVudE93bmVyJDMgPSBSZWFjdFNoYXJlZEludGVybmFscy5SZWFjdEN1cnJlbnRPd25lcjtcbnZhciB0b3BMZXZlbFVwZGF0ZVdhcm5pbmdzO1xuXG57XG4gIHRvcExldmVsVXBkYXRlV2FybmluZ3MgPSBmdW5jdGlvbiAoY29udGFpbmVyKSB7XG4gICAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyICYmIGNvbnRhaW5lci5ub2RlVHlwZSAhPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICB2YXIgaG9zdEluc3RhbmNlID0gZmluZEhvc3RJbnN0YW5jZVdpdGhOb1BvcnRhbHMoY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIuY3VycmVudCk7XG5cbiAgICAgIGlmIChob3N0SW5zdGFuY2UpIHtcbiAgICAgICAgaWYgKGhvc3RJbnN0YW5jZS5wYXJlbnROb2RlICE9PSBjb250YWluZXIpIHtcbiAgICAgICAgICBlcnJvcigncmVuZGVyKC4uLik6IEl0IGxvb2tzIGxpa2UgdGhlIFJlYWN0LXJlbmRlcmVkIGNvbnRlbnQgb2YgdGhpcyAnICsgJ2NvbnRhaW5lciB3YXMgcmVtb3ZlZCB3aXRob3V0IHVzaW5nIFJlYWN0LiBUaGlzIGlzIG5vdCAnICsgJ3N1cHBvcnRlZCBhbmQgd2lsbCBjYXVzZSBlcnJvcnMuIEluc3RlYWQsIGNhbGwgJyArICdSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlIHRvIGVtcHR5IGEgY29udGFpbmVyLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGlzUm9vdFJlbmRlcmVkQnlTb21lUmVhY3QgPSAhIWNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyO1xuICAgIHZhciByb290RWwgPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcbiAgICB2YXIgaGFzTm9uUm9vdFJlYWN0Q2hpbGQgPSAhIShyb290RWwgJiYgZ2V0SW5zdGFuY2VGcm9tTm9kZShyb290RWwpKTtcblxuICAgIGlmIChoYXNOb25Sb290UmVhY3RDaGlsZCAmJiAhaXNSb290UmVuZGVyZWRCeVNvbWVSZWFjdCkge1xuICAgICAgZXJyb3IoJ3JlbmRlciguLi4pOiBSZXBsYWNpbmcgUmVhY3QtcmVuZGVyZWQgY2hpbGRyZW4gd2l0aCBhIG5ldyByb290ICcgKyAnY29tcG9uZW50LiBJZiB5b3UgaW50ZW5kZWQgdG8gdXBkYXRlIHRoZSBjaGlsZHJlbiBvZiB0aGlzIG5vZGUsICcgKyAneW91IHNob3VsZCBpbnN0ZWFkIGhhdmUgdGhlIGV4aXN0aW5nIGNoaWxkcmVuIHVwZGF0ZSB0aGVpciBzdGF0ZSAnICsgJ2FuZCByZW5kZXIgdGhlIG5ldyBjb21wb25lbnRzIGluc3RlYWQgb2YgY2FsbGluZyBSZWFjdERPTS5yZW5kZXIuJyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFICYmIGNvbnRhaW5lci50YWdOYW1lICYmIGNvbnRhaW5lci50YWdOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdCT0RZJykge1xuICAgICAgZXJyb3IoJ3JlbmRlcigpOiBSZW5kZXJpbmcgY29tcG9uZW50cyBkaXJlY3RseSBpbnRvIGRvY3VtZW50LmJvZHkgaXMgJyArICdkaXNjb3VyYWdlZCwgc2luY2UgaXRzIGNoaWxkcmVuIGFyZSBvZnRlbiBtYW5pcHVsYXRlZCBieSB0aGlyZC1wYXJ0eSAnICsgJ3NjcmlwdHMgYW5kIGJyb3dzZXIgZXh0ZW5zaW9ucy4gVGhpcyBtYXkgbGVhZCB0byBzdWJ0bGUgJyArICdyZWNvbmNpbGlhdGlvbiBpc3N1ZXMuIFRyeSByZW5kZXJpbmcgaW50byBhIGNvbnRhaW5lciBlbGVtZW50IGNyZWF0ZWQgJyArICdmb3IgeW91ciBhcHAuJyk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKSB7XG4gIGlmICghY29udGFpbmVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBET0NVTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5kb2N1bWVudEVsZW1lbnQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvbnRhaW5lci5maXJzdENoaWxkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vb3BPblJlY292ZXJhYmxlRXJyb3IoKSB7Ly8gVGhpcyBpc24ndCByZWFjaGFibGUgYmVjYXVzZSBvblJlY292ZXJhYmxlRXJyb3IgaXNuJ3QgY2FsbGVkIGluIHRoZVxuICAvLyBsZWdhY3kgQVBJLlxufVxuXG5mdW5jdGlvbiBsZWdhY3lDcmVhdGVSb290RnJvbURPTUNvbnRhaW5lcihjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBjYWxsYmFjaywgaXNIeWRyYXRpb25Db250YWluZXIpIHtcbiAgaWYgKGlzSHlkcmF0aW9uQ29udGFpbmVyKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFyIG9yaWdpbmFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFB1YmxpY1Jvb3RJbnN0YW5jZShyb290KTtcbiAgICAgICAgb3JpZ2luYWxDYWxsYmFjay5jYWxsKGluc3RhbmNlKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJvb3QgPSBjcmVhdGVIeWRyYXRpb25Db250YWluZXIoaW5pdGlhbENoaWxkcmVuLCBjYWxsYmFjaywgY29udGFpbmVyLCBMZWdhY3lSb290LCBudWxsLCAvLyBoeWRyYXRpb25DYWxsYmFja3NcbiAgICBmYWxzZSwgLy8gaXNTdHJpY3RNb2RlXG4gICAgZmFsc2UsIC8vIGNvbmN1cnJlbnRVcGRhdGVzQnlEZWZhdWx0T3ZlcnJpZGUsXG4gICAgJycsIC8vIGlkZW50aWZpZXJQcmVmaXhcbiAgICBub29wT25SZWNvdmVyYWJsZUVycm9yKTtcbiAgICBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lciA9IHJvb3Q7XG4gICAgbWFya0NvbnRhaW5lckFzUm9vdChyb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG4gICAgdmFyIHJvb3RDb250YWluZXJFbGVtZW50ID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lcjtcbiAgICBsaXN0ZW5Ub0FsbFN1cHBvcnRlZEV2ZW50cyhyb290Q29udGFpbmVyRWxlbWVudCk7XG4gICAgZmx1c2hTeW5jKCk7XG4gICAgcmV0dXJuIHJvb3Q7XG4gIH0gZWxzZSB7XG4gICAgLy8gRmlyc3QgY2xlYXIgYW55IGV4aXN0aW5nIGNvbnRlbnQuXG4gICAgdmFyIHJvb3RTaWJsaW5nO1xuXG4gICAgd2hpbGUgKHJvb3RTaWJsaW5nID0gY29udGFpbmVyLmxhc3RDaGlsZCkge1xuICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHJvb3RTaWJsaW5nKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgX29yaWdpbmFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBpbnN0YW5jZSA9IGdldFB1YmxpY1Jvb3RJbnN0YW5jZShfcm9vdCk7XG5cbiAgICAgICAgX29yaWdpbmFsQ2FsbGJhY2suY2FsbChpbnN0YW5jZSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBfcm9vdCA9IGNyZWF0ZUNvbnRhaW5lcihjb250YWluZXIsIExlZ2FjeVJvb3QsIG51bGwsIC8vIGh5ZHJhdGlvbkNhbGxiYWNrc1xuICAgIGZhbHNlLCAvLyBpc1N0cmljdE1vZGVcbiAgICBmYWxzZSwgLy8gY29uY3VycmVudFVwZGF0ZXNCeURlZmF1bHRPdmVycmlkZSxcbiAgICAnJywgLy8gaWRlbnRpZmllclByZWZpeFxuICAgIG5vb3BPblJlY292ZXJhYmxlRXJyb3IpO1xuXG4gICAgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPSBfcm9vdDtcbiAgICBtYXJrQ29udGFpbmVyQXNSb290KF9yb290LmN1cnJlbnQsIGNvbnRhaW5lcik7XG5cbiAgICB2YXIgX3Jvb3RDb250YWluZXJFbGVtZW50ID0gY29udGFpbmVyLm5vZGVUeXBlID09PSBDT01NRU5UX05PREUgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lcjtcblxuICAgIGxpc3RlblRvQWxsU3VwcG9ydGVkRXZlbnRzKF9yb290Q29udGFpbmVyRWxlbWVudCk7IC8vIEluaXRpYWwgbW91bnQgc2hvdWxkIG5vdCBiZSBiYXRjaGVkLlxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIHVwZGF0ZUNvbnRhaW5lcihpbml0aWFsQ2hpbGRyZW4sIF9yb290LCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgICByZXR1cm4gX3Jvb3Q7XG4gIH1cbn1cblxuZnVuY3Rpb24gd2Fybk9uSW52YWxpZENhbGxiYWNrJDEoY2FsbGJhY2ssIGNhbGxlck5hbWUpIHtcbiAge1xuICAgIGlmIChjYWxsYmFjayAhPT0gbnVsbCAmJiB0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGVycm9yKCclcyguLi4pOiBFeHBlY3RlZCB0aGUgbGFzdCBvcHRpb25hbCBgY2FsbGJhY2tgIGFyZ3VtZW50IHRvIGJlIGEgJyArICdmdW5jdGlvbi4gSW5zdGVhZCByZWNlaXZlZDogJXMuJywgY2FsbGVyTmFtZSwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBsZWdhY3lSZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcihwYXJlbnRDb21wb25lbnQsIGNoaWxkcmVuLCBjb250YWluZXIsIGZvcmNlSHlkcmF0ZSwgY2FsbGJhY2spIHtcbiAge1xuICAgIHRvcExldmVsVXBkYXRlV2FybmluZ3MoY29udGFpbmVyKTtcbiAgICB3YXJuT25JbnZhbGlkQ2FsbGJhY2skMShjYWxsYmFjayA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGNhbGxiYWNrLCAncmVuZGVyJyk7XG4gIH1cblxuICB2YXIgbWF5YmVSb290ID0gY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXI7XG4gIHZhciByb290O1xuXG4gIGlmICghbWF5YmVSb290KSB7XG4gICAgLy8gSW5pdGlhbCBtb3VudFxuICAgIHJvb3QgPSBsZWdhY3lDcmVhdGVSb290RnJvbURPTUNvbnRhaW5lcihjb250YWluZXIsIGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIGNhbGxiYWNrLCBmb3JjZUh5ZHJhdGUpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QgPSBtYXliZVJvb3Q7XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB2YXIgb3JpZ2luYWxDYWxsYmFjayA9IGNhbGxiYWNrO1xuXG4gICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gZ2V0UHVibGljUm9vdEluc3RhbmNlKHJvb3QpO1xuICAgICAgICBvcmlnaW5hbENhbGxiYWNrLmNhbGwoaW5zdGFuY2UpO1xuICAgICAgfTtcbiAgICB9IC8vIFVwZGF0ZVxuXG5cbiAgICB1cGRhdGVDb250YWluZXIoY2hpbGRyZW4sIHJvb3QsIHBhcmVudENvbXBvbmVudCwgY2FsbGJhY2spO1xuICB9XG5cbiAgcmV0dXJuIGdldFB1YmxpY1Jvb3RJbnN0YW5jZShyb290KTtcbn1cblxuZnVuY3Rpb24gZmluZERPTU5vZGUoY29tcG9uZW50T3JFbGVtZW50KSB7XG4gIHtcbiAgICB2YXIgb3duZXIgPSBSZWFjdEN1cnJlbnRPd25lciQzLmN1cnJlbnQ7XG5cbiAgICBpZiAob3duZXIgIT09IG51bGwgJiYgb3duZXIuc3RhdGVOb2RlICE9PSBudWxsKSB7XG4gICAgICB2YXIgd2FybmVkQWJvdXRSZWZzSW5SZW5kZXIgPSBvd25lci5zdGF0ZU5vZGUuX3dhcm5lZEFib3V0UmVmc0luUmVuZGVyO1xuXG4gICAgICBpZiAoIXdhcm5lZEFib3V0UmVmc0luUmVuZGVyKSB7XG4gICAgICAgIGVycm9yKCclcyBpcyBhY2Nlc3NpbmcgZmluZERPTU5vZGUgaW5zaWRlIGl0cyByZW5kZXIoKS4gJyArICdyZW5kZXIoKSBzaG91bGQgYmUgYSBwdXJlIGZ1bmN0aW9uIG9mIHByb3BzIGFuZCBzdGF0ZS4gSXQgc2hvdWxkICcgKyAnbmV2ZXIgYWNjZXNzIHNvbWV0aGluZyB0aGF0IHJlcXVpcmVzIHN0YWxlIGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgJyArICdyZW5kZXIsIHN1Y2ggYXMgcmVmcy4gTW92ZSB0aGlzIGxvZ2ljIHRvIGNvbXBvbmVudERpZE1vdW50IGFuZCAnICsgJ2NvbXBvbmVudERpZFVwZGF0ZSBpbnN0ZWFkLicsIGdldENvbXBvbmVudE5hbWVGcm9tVHlwZShvd25lci50eXBlKSB8fCAnQSBjb21wb25lbnQnKTtcbiAgICAgIH1cblxuICAgICAgb3duZXIuc3RhdGVOb2RlLl93YXJuZWRBYm91dFJlZnNJblJlbmRlciA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbXBvbmVudE9yRWxlbWVudCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoY29tcG9uZW50T3JFbGVtZW50Lm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICByZXR1cm4gY29tcG9uZW50T3JFbGVtZW50O1xuICB9XG5cbiAge1xuICAgIHJldHVybiBmaW5kSG9zdEluc3RhbmNlV2l0aFdhcm5pbmcoY29tcG9uZW50T3JFbGVtZW50LCAnZmluZERPTU5vZGUnKTtcbiAgfVxufVxuZnVuY3Rpb24gaHlkcmF0ZShlbGVtZW50LCBjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gIHtcbiAgICBlcnJvcignUmVhY3RET00uaHlkcmF0ZSBpcyBubyBsb25nZXIgc3VwcG9ydGVkIGluIFJlYWN0IDE4LiBVc2UgaHlkcmF0ZVJvb3QgJyArICdpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvIHRoZSBuZXcgQVBJLCB5b3VyIGFwcCB3aWxsIGJlaGF2ZSBhcyAnICsgXCJpZiBpdCdzIHJ1bm5pbmcgUmVhY3QgMTcuIExlYXJuIFwiICsgJ21vcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zd2l0Y2gtdG8tY3JlYXRlcm9vdCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJyk7XG4gIH1cblxuICB7XG4gICAgdmFyIGlzTW9kZXJuUm9vdCA9IGlzQ29udGFpbmVyTWFya2VkQXNSb290KGNvbnRhaW5lcikgJiYgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc01vZGVyblJvb3QpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET00uaHlkcmF0ZSgpIG9uIGEgY29udGFpbmVyIHRoYXQgd2FzIHByZXZpb3VzbHkgJyArICdwYXNzZWQgdG8gUmVhY3RET01DbGllbnQuY3JlYXRlUm9vdCgpLiBUaGlzIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnRGlkIHlvdSBtZWFuIHRvIGNhbGwgaHlkcmF0ZVJvb3QoY29udGFpbmVyLCBlbGVtZW50KT8nKTtcbiAgICB9XG4gIH0gLy8gVE9ETzogdGhyb3cgb3Igd2FybiBpZiB3ZSBjb3VsZG4ndCBoeWRyYXRlP1xuXG5cbiAgcmV0dXJuIGxlZ2FjeVJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIGVsZW1lbnQsIGNvbnRhaW5lciwgdHJ1ZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gcmVuZGVyKGVsZW1lbnQsIGNvbnRhaW5lciwgY2FsbGJhY2spIHtcbiAge1xuICAgIGVycm9yKCdSZWFjdERPTS5yZW5kZXIgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCBpbiBSZWFjdCAxOC4gVXNlIGNyZWF0ZVJvb3QgJyArICdpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvIHRoZSBuZXcgQVBJLCB5b3VyIGFwcCB3aWxsIGJlaGF2ZSBhcyAnICsgXCJpZiBpdCdzIHJ1bm5pbmcgUmVhY3QgMTcuIExlYXJuIFwiICsgJ21vcmU6IGh0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9zd2l0Y2gtdG8tY3JlYXRlcm9vdCcpO1xuICB9XG5cbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RhcmdldCBjb250YWluZXIgaXMgbm90IGEgRE9NIGVsZW1lbnQuJyk7XG4gIH1cblxuICB7XG4gICAgdmFyIGlzTW9kZXJuUm9vdCA9IGlzQ29udGFpbmVyTWFya2VkQXNSb290KGNvbnRhaW5lcikgJiYgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPT09IHVuZGVmaW5lZDtcblxuICAgIGlmIChpc01vZGVyblJvb3QpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGNhbGxpbmcgUmVhY3RET00ucmVuZGVyKCkgb24gYSBjb250YWluZXIgdGhhdCB3YXMgcHJldmlvdXNseSAnICsgJ3Bhc3NlZCB0byBSZWFjdERPTUNsaWVudC5jcmVhdGVSb290KCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4gJyArICdEaWQgeW91IG1lYW4gdG8gY2FsbCByb290LnJlbmRlcihlbGVtZW50KT8nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbGVnYWN5UmVuZGVyU3VidHJlZUludG9Db250YWluZXIobnVsbCwgZWxlbWVudCwgY29udGFpbmVyLCBmYWxzZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gdW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjaykge1xuICB7XG4gICAgZXJyb3IoJ1JlYWN0RE9NLnVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKCkgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCAnICsgJ2luIFJlYWN0IDE4LiBDb25zaWRlciB1c2luZyBhIHBvcnRhbCBpbnN0ZWFkLiBVbnRpbCB5b3Ugc3dpdGNoIHRvICcgKyBcInRoZSBjcmVhdGVSb290IEFQSSwgeW91ciBhcHAgd2lsbCBiZWhhdmUgYXMgaWYgaXQncyBydW5uaW5nIFJlYWN0IFwiICsgJzE3LiBMZWFybiBtb3JlOiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvc3dpdGNoLXRvLWNyZWF0ZXJvb3QnKTtcbiAgfVxuXG4gIGlmICghaXNWYWxpZENvbnRhaW5lckxlZ2FjeShjb250YWluZXJOb2RlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIGlmIChwYXJlbnRDb21wb25lbnQgPT0gbnVsbCB8fCAhaGFzKHBhcmVudENvbXBvbmVudCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhcmVudENvbXBvbmVudCBtdXN0IGJlIGEgdmFsaWQgUmVhY3QgQ29tcG9uZW50Jyk7XG4gIH1cblxuICByZXR1cm4gbGVnYWN5UmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBmYWxzZSwgY2FsbGJhY2spO1xufVxuZnVuY3Rpb24gdW5tb3VudENvbXBvbmVudEF0Tm9kZShjb250YWluZXIpIHtcbiAgaWYgKCFpc1ZhbGlkQ29udGFpbmVyTGVnYWN5KGNvbnRhaW5lcikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VubW91bnRDb21wb25lbnRBdE5vZGUoLi4uKTogVGFyZ2V0IGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudC4nKTtcbiAgfVxuXG4gIHtcbiAgICB2YXIgaXNNb2Rlcm5Sb290ID0gaXNDb250YWluZXJNYXJrZWRBc1Jvb3QoY29udGFpbmVyKSAmJiBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lciA9PT0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGlzTW9kZXJuUm9vdCkge1xuICAgICAgZXJyb3IoJ1lvdSBhcmUgY2FsbGluZyBSZWFjdERPTS51bm1vdW50Q29tcG9uZW50QXROb2RlKCkgb24gYSBjb250YWluZXIgdGhhdCB3YXMgcHJldmlvdXNseSAnICsgJ3Bhc3NlZCB0byBSZWFjdERPTUNsaWVudC5jcmVhdGVSb290KCkuIFRoaXMgaXMgbm90IHN1cHBvcnRlZC4gRGlkIHlvdSBtZWFuIHRvIGNhbGwgcm9vdC51bm1vdW50KCk/Jyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNvbnRhaW5lci5fcmVhY3RSb290Q29udGFpbmVyKSB7XG4gICAge1xuICAgICAgdmFyIHJvb3RFbCA9IGdldFJlYWN0Um9vdEVsZW1lbnRJbkNvbnRhaW5lcihjb250YWluZXIpO1xuICAgICAgdmFyIHJlbmRlcmVkQnlEaWZmZXJlbnRSZWFjdCA9IHJvb3RFbCAmJiAhZ2V0SW5zdGFuY2VGcm9tTm9kZShyb290RWwpO1xuXG4gICAgICBpZiAocmVuZGVyZWRCeURpZmZlcmVudFJlYWN0KSB7XG4gICAgICAgIGVycm9yKFwidW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBUaGUgbm9kZSB5b3UncmUgYXR0ZW1wdGluZyB0byB1bm1vdW50IFwiICsgJ3dhcyByZW5kZXJlZCBieSBhbm90aGVyIGNvcHkgb2YgUmVhY3QuJyk7XG4gICAgICB9XG4gICAgfSAvLyBVbm1vdW50IHNob3VsZCBub3QgYmUgYmF0Y2hlZC5cblxuXG4gICAgZmx1c2hTeW5jKGZ1bmN0aW9uICgpIHtcbiAgICAgIGxlZ2FjeVJlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyKG51bGwsIG51bGwsIGNvbnRhaW5lciwgZmFsc2UsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gJEZsb3dGaXhNZSBUaGlzIHNob3VsZCBwcm9iYWJseSB1c2UgYGRlbGV0ZSBjb250YWluZXIuX3JlYWN0Um9vdENvbnRhaW5lcmBcbiAgICAgICAgY29udGFpbmVyLl9yZWFjdFJvb3RDb250YWluZXIgPSBudWxsO1xuICAgICAgICB1bm1hcmtDb250YWluZXJBc1Jvb3QoY29udGFpbmVyKTtcbiAgICAgIH0pO1xuICAgIH0pOyAvLyBJZiB5b3UgY2FsbCB1bm1vdW50Q29tcG9uZW50QXROb2RlIHR3aWNlIGluIHF1aWNrIHN1Y2Nlc3Npb24sIHlvdSdsbFxuICAgIC8vIGdldCBgdHJ1ZWAgdHdpY2UuIFRoYXQncyBwcm9iYWJseSBmaW5lP1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAge1xuICAgICAgdmFyIF9yb290RWwgPSBnZXRSZWFjdFJvb3RFbGVtZW50SW5Db250YWluZXIoY29udGFpbmVyKTtcblxuICAgICAgdmFyIGhhc05vblJvb3RSZWFjdENoaWxkID0gISEoX3Jvb3RFbCAmJiBnZXRJbnN0YW5jZUZyb21Ob2RlKF9yb290RWwpKTsgLy8gQ2hlY2sgaWYgdGhlIGNvbnRhaW5lciBpdHNlbGYgaXMgYSBSZWFjdCByb290IG5vZGUuXG5cbiAgICAgIHZhciBpc0NvbnRhaW5lclJlYWN0Um9vdCA9IGNvbnRhaW5lci5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFICYmIGlzVmFsaWRDb250YWluZXJMZWdhY3koY29udGFpbmVyLnBhcmVudE5vZGUpICYmICEhY29udGFpbmVyLnBhcmVudE5vZGUuX3JlYWN0Um9vdENvbnRhaW5lcjtcblxuICAgICAgaWYgKGhhc05vblJvb3RSZWFjdENoaWxkKSB7XG4gICAgICAgIGVycm9yKFwidW5tb3VudENvbXBvbmVudEF0Tm9kZSgpOiBUaGUgbm9kZSB5b3UncmUgYXR0ZW1wdGluZyB0byB1bm1vdW50IFwiICsgJ3dhcyByZW5kZXJlZCBieSBSZWFjdCBhbmQgaXMgbm90IGEgdG9wLWxldmVsIGNvbnRhaW5lci4gJXMnLCBpc0NvbnRhaW5lclJlYWN0Um9vdCA/ICdZb3UgbWF5IGhhdmUgYWNjaWRlbnRhbGx5IHBhc3NlZCBpbiBhIFJlYWN0IHJvb3Qgbm9kZSBpbnN0ZWFkICcgKyAnb2YgaXRzIGNvbnRhaW5lci4nIDogJ0luc3RlYWQsIGhhdmUgdGhlIHBhcmVudCBjb21wb25lbnQgdXBkYXRlIGl0cyBzdGF0ZSBhbmQgJyArICdyZXJlbmRlciBpbiBvcmRlciB0byByZW1vdmUgdGhpcyBjb21wb25lbnQuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbnNldEF0dGVtcHRTeW5jaHJvbm91c0h5ZHJhdGlvbihhdHRlbXB0U3luY2hyb25vdXNIeWRyYXRpb24kMSk7XG5zZXRBdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbihhdHRlbXB0Q29udGludW91c0h5ZHJhdGlvbiQxKTtcbnNldEF0dGVtcHRIeWRyYXRpb25BdEN1cnJlbnRQcmlvcml0eShhdHRlbXB0SHlkcmF0aW9uQXRDdXJyZW50UHJpb3JpdHkkMSk7XG5zZXRHZXRDdXJyZW50VXBkYXRlUHJpb3JpdHkoZ2V0Q3VycmVudFVwZGF0ZVByaW9yaXR5KTtcbnNldEF0dGVtcHRIeWRyYXRpb25BdFByaW9yaXR5KHJ1bldpdGhQcmlvcml0eSk7XG5cbntcbiAgaWYgKHR5cGVvZiBNYXAgIT09ICdmdW5jdGlvbicgfHwgLy8gJEZsb3dJc3N1ZSBGbG93IGluY29ycmVjdGx5IHRoaW5rcyBNYXAgaGFzIG5vIHByb3RvdHlwZVxuICBNYXAucHJvdG90eXBlID09IG51bGwgfHwgdHlwZW9mIE1hcC5wcm90b3R5cGUuZm9yRWFjaCAhPT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgU2V0ICE9PSAnZnVuY3Rpb24nIHx8IC8vICRGbG93SXNzdWUgRmxvdyBpbmNvcnJlY3RseSB0aGlua3MgU2V0IGhhcyBubyBwcm90b3R5cGVcbiAgU2V0LnByb3RvdHlwZSA9PSBudWxsIHx8IHR5cGVvZiBTZXQucHJvdG90eXBlLmNsZWFyICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBTZXQucHJvdG90eXBlLmZvckVhY2ggIT09ICdmdW5jdGlvbicpIHtcbiAgICBlcnJvcignUmVhY3QgZGVwZW5kcyBvbiBNYXAgYW5kIFNldCBidWlsdC1pbiB0eXBlcy4gTWFrZSBzdXJlIHRoYXQgeW91IGxvYWQgYSAnICsgJ3BvbHlmaWxsIGluIG9sZGVyIGJyb3dzZXJzLiBodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVhY3QtcG9seWZpbGxzJyk7XG4gIH1cbn1cblxuc2V0UmVzdG9yZUltcGxlbWVudGF0aW9uKHJlc3RvcmVDb250cm9sbGVkU3RhdGUkMyk7XG5zZXRCYXRjaGluZ0ltcGxlbWVudGF0aW9uKGJhdGNoZWRVcGRhdGVzJDEsIGRpc2NyZXRlVXBkYXRlcywgZmx1c2hTeW5jKTtcblxuZnVuY3Rpb24gY3JlYXRlUG9ydGFsJDEoY2hpbGRyZW4sIGNvbnRhaW5lcikge1xuICB2YXIga2V5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBudWxsO1xuXG4gIGlmICghaXNWYWxpZENvbnRhaW5lcihjb250YWluZXIpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUYXJnZXQgY29udGFpbmVyIGlzIG5vdCBhIERPTSBlbGVtZW50LicpO1xuICB9IC8vIFRPRE86IHBhc3MgUmVhY3RET00gcG9ydGFsIGltcGxlbWVudGF0aW9uIGFzIHRoaXJkIGFyZ3VtZW50XG4gIC8vICRGbG93Rml4TWUgVGhlIEZsb3cgdHlwZSBpcyBvcGFxdWUgYnV0IHRoZXJlJ3Mgbm8gd2F5IHRvIGFjdHVhbGx5IGNyZWF0ZSBpdC5cblxuXG4gIHJldHVybiBjcmVhdGVQb3J0YWwoY2hpbGRyZW4sIGNvbnRhaW5lciwgbnVsbCwga2V5KTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIocGFyZW50Q29tcG9uZW50LCBlbGVtZW50LCBjb250YWluZXJOb2RlLCBjYWxsYmFjayk7XG59XG5cbnZhciBJbnRlcm5hbHMgPSB7XG4gIHVzaW5nQ2xpZW50RW50cnlQb2ludDogZmFsc2UsXG4gIC8vIEtlZXAgaW4gc3luYyB3aXRoIFJlYWN0VGVzdFV0aWxzLmpzLlxuICAvLyBUaGlzIGlzIGFuIGFycmF5IGZvciBiZXR0ZXIgbWluaWZpY2F0aW9uLlxuICBFdmVudHM6IFtnZXRJbnN0YW5jZUZyb21Ob2RlLCBnZXROb2RlRnJvbUluc3RhbmNlLCBnZXRGaWJlckN1cnJlbnRQcm9wc0Zyb21Ob2RlLCBlbnF1ZXVlU3RhdGVSZXN0b3JlLCByZXN0b3JlU3RhdGVJZk5lZWRlZCwgYmF0Y2hlZFVwZGF0ZXMkMV1cbn07XG5cbmZ1bmN0aW9uIGNyZWF0ZVJvb3QkMShjb250YWluZXIsIG9wdGlvbnMpIHtcbiAge1xuICAgIGlmICghSW50ZXJuYWxzLnVzaW5nQ2xpZW50RW50cnlQb2ludCAmJiAhZmFsc2UpIHtcbiAgICAgIGVycm9yKCdZb3UgYXJlIGltcG9ydGluZyBjcmVhdGVSb290IGZyb20gXCJyZWFjdC1kb21cIiB3aGljaCBpcyBub3Qgc3VwcG9ydGVkLiAnICsgJ1lvdSBzaG91bGQgaW5zdGVhZCBpbXBvcnQgaXQgZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIi4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3JlYXRlUm9vdChjb250YWluZXIsIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBoeWRyYXRlUm9vdCQxKGNvbnRhaW5lciwgaW5pdGlhbENoaWxkcmVuLCBvcHRpb25zKSB7XG4gIHtcbiAgICBpZiAoIUludGVybmFscy51c2luZ0NsaWVudEVudHJ5UG9pbnQgJiYgIWZhbHNlKSB7XG4gICAgICBlcnJvcignWW91IGFyZSBpbXBvcnRpbmcgaHlkcmF0ZVJvb3QgZnJvbSBcInJlYWN0LWRvbVwiIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQuICcgKyAnWW91IHNob3VsZCBpbnN0ZWFkIGltcG9ydCBpdCBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiLicpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoeWRyYXRlUm9vdChjb250YWluZXIsIGluaXRpYWxDaGlsZHJlbiwgb3B0aW9ucyk7XG59IC8vIE92ZXJsb2FkIHRoZSBkZWZpbml0aW9uIHRvIHRoZSB0d28gdmFsaWQgc2lnbmF0dXJlcy5cbi8vIFdhcm5pbmcsIHRoaXMgb3B0cy1vdXQgb2YgY2hlY2tpbmcgdGhlIGZ1bmN0aW9uIGJvZHkuXG5cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlZGVjbGFyZVxuZnVuY3Rpb24gZmx1c2hTeW5jJDEoZm4pIHtcbiAge1xuICAgIGlmIChpc0FscmVhZHlSZW5kZXJpbmcoKSkge1xuICAgICAgZXJyb3IoJ2ZsdXNoU3luYyB3YXMgY2FsbGVkIGZyb20gaW5zaWRlIGEgbGlmZWN5Y2xlIG1ldGhvZC4gUmVhY3QgY2Fubm90ICcgKyAnZmx1c2ggd2hlbiBSZWFjdCBpcyBhbHJlYWR5IHJlbmRlcmluZy4gQ29uc2lkZXIgbW92aW5nIHRoaXMgY2FsbCB0byAnICsgJ2Egc2NoZWR1bGVyIHRhc2sgb3IgbWljcm8gdGFzay4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmx1c2hTeW5jKGZuKTtcbn1cbnZhciBmb3VuZERldlRvb2xzID0gaW5qZWN0SW50b0RldlRvb2xzKHtcbiAgZmluZEZpYmVyQnlIb3N0SW5zdGFuY2U6IGdldENsb3Nlc3RJbnN0YW5jZUZyb21Ob2RlLFxuICBidW5kbGVUeXBlOiAgMSAsXG4gIHZlcnNpb246IFJlYWN0VmVyc2lvbixcbiAgcmVuZGVyZXJQYWNrYWdlTmFtZTogJ3JlYWN0LWRvbSdcbn0pO1xuXG57XG4gIGlmICghZm91bmREZXZUb29scyAmJiBjYW5Vc2VET00gJiYgd2luZG93LnRvcCA9PT0gd2luZG93LnNlbGYpIHtcbiAgICAvLyBJZiB3ZSdyZSBpbiBDaHJvbWUgb3IgRmlyZWZveCwgcHJvdmlkZSBhIGRvd25sb2FkIGxpbmsgaWYgbm90IGluc3RhbGxlZC5cbiAgICBpZiAobmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdDaHJvbWUnKSA+IC0xICYmIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpID09PSAtMSB8fCBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0ZpcmVmb3gnKSA+IC0xKSB7XG4gICAgICB2YXIgcHJvdG9jb2wgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2w7IC8vIERvbid0IHdhcm4gaW4gZXhvdGljIGNhc2VzIGxpa2UgY2hyb21lLWV4dGVuc2lvbjovLy5cblxuICAgICAgaWYgKC9eKGh0dHBzP3xmaWxlKTokLy50ZXN0KHByb3RvY29sKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaW50ZXJuYWwvbm8tcHJvZHVjdGlvbi1sb2dnaW5nXG4gICAgICAgIGNvbnNvbGUuaW5mbygnJWNEb3dubG9hZCB0aGUgUmVhY3QgRGV2VG9vbHMgJyArICdmb3IgYSBiZXR0ZXIgZGV2ZWxvcG1lbnQgZXhwZXJpZW5jZTogJyArICdodHRwczovL3JlYWN0anMub3JnL2xpbmsvcmVhY3QtZGV2dG9vbHMnICsgKHByb3RvY29sID09PSAnZmlsZTonID8gJ1xcbllvdSBtaWdodCBuZWVkIHRvIHVzZSBhIGxvY2FsIEhUVFAgc2VydmVyIChpbnN0ZWFkIG9mIGZpbGU6Ly8pOiAnICsgJ2h0dHBzOi8vcmVhY3Rqcy5vcmcvbGluay9yZWFjdC1kZXZ0b29scy1mYXEnIDogJycpLCAnZm9udC13ZWlnaHQ6Ym9sZCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnRzLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEID0gSW50ZXJuYWxzO1xuZXhwb3J0cy5jcmVhdGVQb3J0YWwgPSBjcmVhdGVQb3J0YWwkMTtcbmV4cG9ydHMuY3JlYXRlUm9vdCA9IGNyZWF0ZVJvb3QkMTtcbmV4cG9ydHMuZmluZERPTU5vZGUgPSBmaW5kRE9NTm9kZTtcbmV4cG9ydHMuZmx1c2hTeW5jID0gZmx1c2hTeW5jJDE7XG5leHBvcnRzLmh5ZHJhdGUgPSBoeWRyYXRlO1xuZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGh5ZHJhdGVSb290JDE7XG5leHBvcnRzLnJlbmRlciA9IHJlbmRlcjtcbmV4cG9ydHMudW5tb3VudENvbXBvbmVudEF0Tm9kZSA9IHVubW91bnRDb21wb25lbnRBdE5vZGU7XG5leHBvcnRzLnVuc3RhYmxlX2JhdGNoZWRVcGRhdGVzID0gYmF0Y2hlZFVwZGF0ZXMkMTtcbmV4cG9ydHMudW5zdGFibGVfcmVuZGVyU3VidHJlZUludG9Db250YWluZXIgPSByZW5kZXJTdWJ0cmVlSW50b0NvbnRhaW5lcjtcbmV4cG9ydHMudmVyc2lvbiA9IFJlYWN0VmVyc2lvbjtcbiAgICAgICAgICAvKiBnbG9iYWwgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fICovXG5pZiAoXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gIT09ICd1bmRlZmluZWQnICYmXG4gIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18ucmVnaXN0ZXJJbnRlcm5hbE1vZHVsZVN0b3AgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcChuZXcgRXJyb3IoKSk7XG59XG4gICAgICAgIFxuICB9KSgpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3NjaGVkdWxlci5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiIsIi8qKlxuICogQGxpY2Vuc2UgUmVhY3RcbiAqIHNjaGVkdWxlci5kZXZlbG9wbWVudC5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSBcInByb2R1Y3Rpb25cIikge1xuICAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgICAndXNlIHN0cmljdCc7XG5cbi8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQgPT09XG4gICAgJ2Z1bmN0aW9uJ1xuKSB7XG4gIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RhcnQobmV3IEVycm9yKCkpO1xufVxuICAgICAgICAgIHZhciBlbmFibGVTY2hlZHVsZXJEZWJ1Z2dpbmcgPSBmYWxzZTtcbnZhciBlbmFibGVQcm9maWxpbmcgPSBmYWxzZTtcbnZhciBmcmFtZVlpZWxkTXMgPSA1O1xuXG5mdW5jdGlvbiBwdXNoKGhlYXAsIG5vZGUpIHtcbiAgdmFyIGluZGV4ID0gaGVhcC5sZW5ndGg7XG4gIGhlYXAucHVzaChub2RlKTtcbiAgc2lmdFVwKGhlYXAsIG5vZGUsIGluZGV4KTtcbn1cbmZ1bmN0aW9uIHBlZWsoaGVhcCkge1xuICByZXR1cm4gaGVhcC5sZW5ndGggPT09IDAgPyBudWxsIDogaGVhcFswXTtcbn1cbmZ1bmN0aW9uIHBvcChoZWFwKSB7XG4gIGlmIChoZWFwLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGZpcnN0ID0gaGVhcFswXTtcbiAgdmFyIGxhc3QgPSBoZWFwLnBvcCgpO1xuXG4gIGlmIChsYXN0ICE9PSBmaXJzdCkge1xuICAgIGhlYXBbMF0gPSBsYXN0O1xuICAgIHNpZnREb3duKGhlYXAsIGxhc3QsIDApO1xuICB9XG5cbiAgcmV0dXJuIGZpcnN0O1xufVxuXG5mdW5jdGlvbiBzaWZ0VXAoaGVhcCwgbm9kZSwgaSkge1xuICB2YXIgaW5kZXggPSBpO1xuXG4gIHdoaWxlIChpbmRleCA+IDApIHtcbiAgICB2YXIgcGFyZW50SW5kZXggPSBpbmRleCAtIDEgPj4+IDE7XG4gICAgdmFyIHBhcmVudCA9IGhlYXBbcGFyZW50SW5kZXhdO1xuXG4gICAgaWYgKGNvbXBhcmUocGFyZW50LCBub2RlKSA+IDApIHtcbiAgICAgIC8vIFRoZSBwYXJlbnQgaXMgbGFyZ2VyLiBTd2FwIHBvc2l0aW9ucy5cbiAgICAgIGhlYXBbcGFyZW50SW5kZXhdID0gbm9kZTtcbiAgICAgIGhlYXBbaW5kZXhdID0gcGFyZW50O1xuICAgICAgaW5kZXggPSBwYXJlbnRJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIHBhcmVudCBpcyBzbWFsbGVyLiBFeGl0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzaWZ0RG93bihoZWFwLCBub2RlLCBpKSB7XG4gIHZhciBpbmRleCA9IGk7XG4gIHZhciBsZW5ndGggPSBoZWFwLmxlbmd0aDtcbiAgdmFyIGhhbGZMZW5ndGggPSBsZW5ndGggPj4+IDE7XG5cbiAgd2hpbGUgKGluZGV4IDwgaGFsZkxlbmd0aCkge1xuICAgIHZhciBsZWZ0SW5kZXggPSAoaW5kZXggKyAxKSAqIDIgLSAxO1xuICAgIHZhciBsZWZ0ID0gaGVhcFtsZWZ0SW5kZXhdO1xuICAgIHZhciByaWdodEluZGV4ID0gbGVmdEluZGV4ICsgMTtcbiAgICB2YXIgcmlnaHQgPSBoZWFwW3JpZ2h0SW5kZXhdOyAvLyBJZiB0aGUgbGVmdCBvciByaWdodCBub2RlIGlzIHNtYWxsZXIsIHN3YXAgd2l0aCB0aGUgc21hbGxlciBvZiB0aG9zZS5cblxuICAgIGlmIChjb21wYXJlKGxlZnQsIG5vZGUpIDwgMCkge1xuICAgICAgaWYgKHJpZ2h0SW5kZXggPCBsZW5ndGggJiYgY29tcGFyZShyaWdodCwgbGVmdCkgPCAwKSB7XG4gICAgICAgIGhlYXBbaW5kZXhdID0gcmlnaHQ7XG4gICAgICAgIGhlYXBbcmlnaHRJbmRleF0gPSBub2RlO1xuICAgICAgICBpbmRleCA9IHJpZ2h0SW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoZWFwW2luZGV4XSA9IGxlZnQ7XG4gICAgICAgIGhlYXBbbGVmdEluZGV4XSA9IG5vZGU7XG4gICAgICAgIGluZGV4ID0gbGVmdEluZGV4O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmlnaHRJbmRleCA8IGxlbmd0aCAmJiBjb21wYXJlKHJpZ2h0LCBub2RlKSA8IDApIHtcbiAgICAgIGhlYXBbaW5kZXhdID0gcmlnaHQ7XG4gICAgICBoZWFwW3JpZ2h0SW5kZXhdID0gbm9kZTtcbiAgICAgIGluZGV4ID0gcmlnaHRJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmVpdGhlciBjaGlsZCBpcyBzbWFsbGVyLiBFeGl0LlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgLy8gQ29tcGFyZSBzb3J0IGluZGV4IGZpcnN0LCB0aGVuIHRhc2sgaWQuXG4gIHZhciBkaWZmID0gYS5zb3J0SW5kZXggLSBiLnNvcnRJbmRleDtcbiAgcmV0dXJuIGRpZmYgIT09IDAgPyBkaWZmIDogYS5pZCAtIGIuaWQ7XG59XG5cbi8vIFRPRE86IFVzZSBzeW1ib2xzP1xudmFyIEltbWVkaWF0ZVByaW9yaXR5ID0gMTtcbnZhciBVc2VyQmxvY2tpbmdQcmlvcml0eSA9IDI7XG52YXIgTm9ybWFsUHJpb3JpdHkgPSAzO1xudmFyIExvd1ByaW9yaXR5ID0gNDtcbnZhciBJZGxlUHJpb3JpdHkgPSA1O1xuXG5mdW5jdGlvbiBtYXJrVGFza0Vycm9yZWQodGFzaywgbXMpIHtcbn1cblxuLyogZXNsaW50LWRpc2FibGUgbm8tdmFyICovXG5cbnZhciBoYXNQZXJmb3JtYW5jZU5vdyA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIHBlcmZvcm1hbmNlLm5vdyA9PT0gJ2Z1bmN0aW9uJztcblxuaWYgKGhhc1BlcmZvcm1hbmNlTm93KSB7XG4gIHZhciBsb2NhbFBlcmZvcm1hbmNlID0gcGVyZm9ybWFuY2U7XG5cbiAgZXhwb3J0cy51bnN0YWJsZV9ub3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGxvY2FsUGVyZm9ybWFuY2Uubm93KCk7XG4gIH07XG59IGVsc2Uge1xuICB2YXIgbG9jYWxEYXRlID0gRGF0ZTtcbiAgdmFyIGluaXRpYWxUaW1lID0gbG9jYWxEYXRlLm5vdygpO1xuXG4gIGV4cG9ydHMudW5zdGFibGVfbm93ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBsb2NhbERhdGUubm93KCkgLSBpbml0aWFsVGltZTtcbiAgfTtcbn0gLy8gTWF4IDMxIGJpdCBpbnRlZ2VyLiBUaGUgbWF4IGludGVnZXIgc2l6ZSBpbiBWOCBmb3IgMzItYml0IHN5c3RlbXMuXG4vLyBNYXRoLnBvdygyLCAzMCkgLSAxXG4vLyAwYjExMTExMTExMTExMTExMTExMTExMTExMTExMTExMVxuXG5cbnZhciBtYXhTaWduZWQzMUJpdEludCA9IDEwNzM3NDE4MjM7IC8vIFRpbWVzIG91dCBpbW1lZGlhdGVseVxuXG52YXIgSU1NRURJQVRFX1BSSU9SSVRZX1RJTUVPVVQgPSAtMTsgLy8gRXZlbnR1YWxseSB0aW1lcyBvdXRcblxudmFyIFVTRVJfQkxPQ0tJTkdfUFJJT1JJVFlfVElNRU9VVCA9IDI1MDtcbnZhciBOT1JNQUxfUFJJT1JJVFlfVElNRU9VVCA9IDUwMDA7XG52YXIgTE9XX1BSSU9SSVRZX1RJTUVPVVQgPSAxMDAwMDsgLy8gTmV2ZXIgdGltZXMgb3V0XG5cbnZhciBJRExFX1BSSU9SSVRZX1RJTUVPVVQgPSBtYXhTaWduZWQzMUJpdEludDsgLy8gVGFza3MgYXJlIHN0b3JlZCBvbiBhIG1pbiBoZWFwXG5cbnZhciB0YXNrUXVldWUgPSBbXTtcbnZhciB0aW1lclF1ZXVlID0gW107IC8vIEluY3JlbWVudGluZyBpZCBjb3VudGVyLiBVc2VkIHRvIG1haW50YWluIGluc2VydGlvbiBvcmRlci5cblxudmFyIHRhc2tJZENvdW50ZXIgPSAxOyAvLyBQYXVzaW5nIHRoZSBzY2hlZHVsZXIgaXMgdXNlZnVsIGZvciBkZWJ1Z2dpbmcuXG52YXIgY3VycmVudFRhc2sgPSBudWxsO1xudmFyIGN1cnJlbnRQcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7IC8vIFRoaXMgaXMgc2V0IHdoaWxlIHBlcmZvcm1pbmcgd29yaywgdG8gcHJldmVudCByZS1lbnRyYW5jZS5cblxudmFyIGlzUGVyZm9ybWluZ1dvcmsgPSBmYWxzZTtcbnZhciBpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCA9IGZhbHNlO1xudmFyIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTsgLy8gQ2FwdHVyZSBsb2NhbCByZWZlcmVuY2VzIHRvIG5hdGl2ZSBBUElzLCBpbiBjYXNlIGEgcG9seWZpbGwgb3ZlcnJpZGVzIHRoZW0uXG5cbnZhciBsb2NhbFNldFRpbWVvdXQgPSB0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IHNldFRpbWVvdXQgOiBudWxsO1xudmFyIGxvY2FsQ2xlYXJUaW1lb3V0ID0gdHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJyA/IGNsZWFyVGltZW91dCA6IG51bGw7XG52YXIgbG9jYWxTZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSAndW5kZWZpbmVkJyA/IHNldEltbWVkaWF0ZSA6IG51bGw7IC8vIElFIGFuZCBOb2RlLmpzICsganNkb21cblxudmFyIGlzSW5wdXRQZW5kaW5nID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnNjaGVkdWxpbmcgIT09IHVuZGVmaW5lZCAmJiBuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZyAhPT0gdW5kZWZpbmVkID8gbmF2aWdhdG9yLnNjaGVkdWxpbmcuaXNJbnB1dFBlbmRpbmcuYmluZChuYXZpZ2F0b3Iuc2NoZWR1bGluZykgOiBudWxsO1xuXG5mdW5jdGlvbiBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKSB7XG4gIC8vIENoZWNrIGZvciB0YXNrcyB0aGF0IGFyZSBubyBsb25nZXIgZGVsYXllZCBhbmQgYWRkIHRoZW0gdG8gdGhlIHF1ZXVlLlxuICB2YXIgdGltZXIgPSBwZWVrKHRpbWVyUXVldWUpO1xuXG4gIHdoaWxlICh0aW1lciAhPT0gbnVsbCkge1xuICAgIGlmICh0aW1lci5jYWxsYmFjayA9PT0gbnVsbCkge1xuICAgICAgLy8gVGltZXIgd2FzIGNhbmNlbGxlZC5cbiAgICAgIHBvcCh0aW1lclF1ZXVlKTtcbiAgICB9IGVsc2UgaWYgKHRpbWVyLnN0YXJ0VGltZSA8PSBjdXJyZW50VGltZSkge1xuICAgICAgLy8gVGltZXIgZmlyZWQuIFRyYW5zZmVyIHRvIHRoZSB0YXNrIHF1ZXVlLlxuICAgICAgcG9wKHRpbWVyUXVldWUpO1xuICAgICAgdGltZXIuc29ydEluZGV4ID0gdGltZXIuZXhwaXJhdGlvblRpbWU7XG4gICAgICBwdXNoKHRhc2tRdWV1ZSwgdGltZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZW1haW5pbmcgdGltZXJzIGFyZSBwZW5kaW5nLlxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRpbWVyID0gcGVlayh0aW1lclF1ZXVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVUaW1lb3V0KGN1cnJlbnRUaW1lKSB7XG4gIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgYWR2YW5jZVRpbWVycyhjdXJyZW50VGltZSk7XG5cbiAgaWYgKCFpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCkge1xuICAgIGlmIChwZWVrKHRhc2tRdWV1ZSkgIT09IG51bGwpIHtcbiAgICAgIGlzSG9zdENhbGxiYWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RIb3N0Q2FsbGJhY2soZmx1c2hXb3JrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpcnN0VGltZXIgPSBwZWVrKHRpbWVyUXVldWUpO1xuXG4gICAgICBpZiAoZmlyc3RUaW1lciAhPT0gbnVsbCkge1xuICAgICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgZmlyc3RUaW1lci5zdGFydFRpbWUgLSBjdXJyZW50VGltZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZsdXNoV29yayhoYXNUaW1lUmVtYWluaW5nLCBpbml0aWFsVGltZSkge1xuXG5cbiAgaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgPSBmYWxzZTtcblxuICBpZiAoaXNIb3N0VGltZW91dFNjaGVkdWxlZCkge1xuICAgIC8vIFdlIHNjaGVkdWxlZCBhIHRpbWVvdXQgYnV0IGl0J3Mgbm8gbG9uZ2VyIG5lZWRlZC4gQ2FuY2VsIGl0LlxuICAgIGlzSG9zdFRpbWVvdXRTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICBjYW5jZWxIb3N0VGltZW91dCgpO1xuICB9XG5cbiAgaXNQZXJmb3JtaW5nV29yayA9IHRydWU7XG4gIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcblxuICB0cnkge1xuICAgIGlmIChlbmFibGVQcm9maWxpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB3b3JrTG9vcChoYXNUaW1lUmVtYWluaW5nLCBpbml0aWFsVGltZSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoY3VycmVudFRhc2sgIT09IG51bGwpIHtcbiAgICAgICAgICB2YXIgY3VycmVudFRpbWUgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpO1xuICAgICAgICAgIG1hcmtUYXNrRXJyb3JlZChjdXJyZW50VGFzaywgY3VycmVudFRpbWUpO1xuICAgICAgICAgIGN1cnJlbnRUYXNrLmlzUXVldWVkID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gY2F0Y2ggaW4gcHJvZCBjb2RlIHBhdGguXG4gICAgICByZXR1cm4gd29ya0xvb3AoaGFzVGltZVJlbWFpbmluZywgaW5pdGlhbFRpbWUpO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50VGFzayA9IG51bGw7XG4gICAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBwcmV2aW91c1ByaW9yaXR5TGV2ZWw7XG4gICAgaXNQZXJmb3JtaW5nV29yayA9IGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHdvcmtMb29wKGhhc1RpbWVSZW1haW5pbmcsIGluaXRpYWxUaW1lKSB7XG4gIHZhciBjdXJyZW50VGltZSA9IGluaXRpYWxUaW1lO1xuICBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKTtcbiAgY3VycmVudFRhc2sgPSBwZWVrKHRhc2tRdWV1ZSk7XG5cbiAgd2hpbGUgKGN1cnJlbnRUYXNrICE9PSBudWxsICYmICEoZW5hYmxlU2NoZWR1bGVyRGVidWdnaW5nICkpIHtcbiAgICBpZiAoY3VycmVudFRhc2suZXhwaXJhdGlvblRpbWUgPiBjdXJyZW50VGltZSAmJiAoIWhhc1RpbWVSZW1haW5pbmcgfHwgc2hvdWxkWWllbGRUb0hvc3QoKSkpIHtcbiAgICAgIC8vIFRoaXMgY3VycmVudFRhc2sgaGFzbid0IGV4cGlyZWQsIGFuZCB3ZSd2ZSByZWFjaGVkIHRoZSBkZWFkbGluZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHZhciBjYWxsYmFjayA9IGN1cnJlbnRUYXNrLmNhbGxiYWNrO1xuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY3VycmVudFRhc2suY2FsbGJhY2sgPSBudWxsO1xuICAgICAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBjdXJyZW50VGFzay5wcmlvcml0eUxldmVsO1xuICAgICAgdmFyIGRpZFVzZXJDYWxsYmFja1RpbWVvdXQgPSBjdXJyZW50VGFzay5leHBpcmF0aW9uVGltZSA8PSBjdXJyZW50VGltZTtcblxuICAgICAgdmFyIGNvbnRpbnVhdGlvbkNhbGxiYWNrID0gY2FsbGJhY2soZGlkVXNlckNhbGxiYWNrVGltZW91dCk7XG4gICAgICBjdXJyZW50VGltZSA9IGV4cG9ydHMudW5zdGFibGVfbm93KCk7XG5cbiAgICAgIGlmICh0eXBlb2YgY29udGludWF0aW9uQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY3VycmVudFRhc2suY2FsbGJhY2sgPSBjb250aW51YXRpb25DYWxsYmFjaztcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRUYXNrID09PSBwZWVrKHRhc2tRdWV1ZSkpIHtcbiAgICAgICAgICBwb3AodGFza1F1ZXVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhZHZhbmNlVGltZXJzKGN1cnJlbnRUaW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9wKHRhc2tRdWV1ZSk7XG4gICAgfVxuXG4gICAgY3VycmVudFRhc2sgPSBwZWVrKHRhc2tRdWV1ZSk7XG4gIH0gLy8gUmV0dXJuIHdoZXRoZXIgdGhlcmUncyBhZGRpdGlvbmFsIHdvcmtcblxuXG4gIGlmIChjdXJyZW50VGFzayAhPT0gbnVsbCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHZhciBmaXJzdFRpbWVyID0gcGVlayh0aW1lclF1ZXVlKTtcblxuICAgIGlmIChmaXJzdFRpbWVyICE9PSBudWxsKSB7XG4gICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgZmlyc3RUaW1lci5zdGFydFRpbWUgLSBjdXJyZW50VGltZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX3J1bldpdGhQcmlvcml0eShwcmlvcml0eUxldmVsLCBldmVudEhhbmRsZXIpIHtcbiAgc3dpdGNoIChwcmlvcml0eUxldmVsKSB7XG4gICAgY2FzZSBJbW1lZGlhdGVQcmlvcml0eTpcbiAgICBjYXNlIFVzZXJCbG9ja2luZ1ByaW9yaXR5OlxuICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgY2FzZSBMb3dQcmlvcml0eTpcbiAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHByaW9yaXR5TGV2ZWwgPSBOb3JtYWxQcmlvcml0eTtcbiAgfVxuXG4gIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgY3VycmVudFByaW9yaXR5TGV2ZWwgPSBwcmlvcml0eUxldmVsO1xuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGV2ZW50SGFuZGxlcigpO1xuICB9IGZpbmFsbHkge1xuICAgIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJldmlvdXNQcmlvcml0eUxldmVsO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX25leHQoZXZlbnRIYW5kbGVyKSB7XG4gIHZhciBwcmlvcml0eUxldmVsO1xuXG4gIHN3aXRjaCAoY3VycmVudFByaW9yaXR5TGV2ZWwpIHtcbiAgICBjYXNlIEltbWVkaWF0ZVByaW9yaXR5OlxuICAgIGNhc2UgVXNlckJsb2NraW5nUHJpb3JpdHk6XG4gICAgY2FzZSBOb3JtYWxQcmlvcml0eTpcbiAgICAgIC8vIFNoaWZ0IGRvd24gdG8gbm9ybWFsIHByaW9yaXR5XG4gICAgICBwcmlvcml0eUxldmVsID0gTm9ybWFsUHJpb3JpdHk7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICAvLyBBbnl0aGluZyBsb3dlciB0aGFuIG5vcm1hbCBwcmlvcml0eSBzaG91bGQgcmVtYWluIGF0IHRoZSBjdXJyZW50IGxldmVsLlxuICAgICAgcHJpb3JpdHlMZXZlbCA9IGN1cnJlbnRQcmlvcml0eUxldmVsO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICB2YXIgcHJldmlvdXNQcmlvcml0eUxldmVsID0gY3VycmVudFByaW9yaXR5TGV2ZWw7XG4gIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJpb3JpdHlMZXZlbDtcblxuICB0cnkge1xuICAgIHJldHVybiBldmVudEhhbmRsZXIoKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBjdXJyZW50UHJpb3JpdHlMZXZlbCA9IHByZXZpb3VzUHJpb3JpdHlMZXZlbDtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV93cmFwQ2FsbGJhY2soY2FsbGJhY2spIHtcbiAgdmFyIHBhcmVudFByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBUaGlzIGlzIGEgZm9yayBvZiBydW5XaXRoUHJpb3JpdHksIGlubGluZWQgZm9yIHBlcmZvcm1hbmNlLlxuICAgIHZhciBwcmV2aW91c1ByaW9yaXR5TGV2ZWwgPSBjdXJyZW50UHJpb3JpdHlMZXZlbDtcbiAgICBjdXJyZW50UHJpb3JpdHlMZXZlbCA9IHBhcmVudFByaW9yaXR5TGV2ZWw7XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGN1cnJlbnRQcmlvcml0eUxldmVsID0gcHJldmlvdXNQcmlvcml0eUxldmVsO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gdW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjayhwcmlvcml0eUxldmVsLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICB2YXIgY3VycmVudFRpbWUgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpO1xuICB2YXIgc3RhcnRUaW1lO1xuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCkge1xuICAgIHZhciBkZWxheSA9IG9wdGlvbnMuZGVsYXk7XG5cbiAgICBpZiAodHlwZW9mIGRlbGF5ID09PSAnbnVtYmVyJyAmJiBkZWxheSA+IDApIHtcbiAgICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lICsgZGVsYXk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzdGFydFRpbWUgPSBjdXJyZW50VGltZTtcbiAgfVxuXG4gIHZhciB0aW1lb3V0O1xuXG4gIHN3aXRjaCAocHJpb3JpdHlMZXZlbCkge1xuICAgIGNhc2UgSW1tZWRpYXRlUHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gSU1NRURJQVRFX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgVXNlckJsb2NraW5nUHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gVVNFUl9CTE9DS0lOR19QUklPUklUWV9USU1FT1VUO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIElkbGVQcmlvcml0eTpcbiAgICAgIHRpbWVvdXQgPSBJRExFX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgTG93UHJpb3JpdHk6XG4gICAgICB0aW1lb3V0ID0gTE9XX1BSSU9SSVRZX1RJTUVPVVQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgTm9ybWFsUHJpb3JpdHk6XG4gICAgZGVmYXVsdDpcbiAgICAgIHRpbWVvdXQgPSBOT1JNQUxfUFJJT1JJVFlfVElNRU9VVDtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgdmFyIGV4cGlyYXRpb25UaW1lID0gc3RhcnRUaW1lICsgdGltZW91dDtcbiAgdmFyIG5ld1Rhc2sgPSB7XG4gICAgaWQ6IHRhc2tJZENvdW50ZXIrKyxcbiAgICBjYWxsYmFjazogY2FsbGJhY2ssXG4gICAgcHJpb3JpdHlMZXZlbDogcHJpb3JpdHlMZXZlbCxcbiAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICBleHBpcmF0aW9uVGltZTogZXhwaXJhdGlvblRpbWUsXG4gICAgc29ydEluZGV4OiAtMVxuICB9O1xuXG4gIGlmIChzdGFydFRpbWUgPiBjdXJyZW50VGltZSkge1xuICAgIC8vIFRoaXMgaXMgYSBkZWxheWVkIHRhc2suXG4gICAgbmV3VGFzay5zb3J0SW5kZXggPSBzdGFydFRpbWU7XG4gICAgcHVzaCh0aW1lclF1ZXVlLCBuZXdUYXNrKTtcblxuICAgIGlmIChwZWVrKHRhc2tRdWV1ZSkgPT09IG51bGwgJiYgbmV3VGFzayA9PT0gcGVlayh0aW1lclF1ZXVlKSkge1xuICAgICAgLy8gQWxsIHRhc2tzIGFyZSBkZWxheWVkLCBhbmQgdGhpcyBpcyB0aGUgdGFzayB3aXRoIHRoZSBlYXJsaWVzdCBkZWxheS5cbiAgICAgIGlmIChpc0hvc3RUaW1lb3V0U2NoZWR1bGVkKSB7XG4gICAgICAgIC8vIENhbmNlbCBhbiBleGlzdGluZyB0aW1lb3V0LlxuICAgICAgICBjYW5jZWxIb3N0VGltZW91dCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXNIb3N0VGltZW91dFNjaGVkdWxlZCA9IHRydWU7XG4gICAgICB9IC8vIFNjaGVkdWxlIGEgdGltZW91dC5cblxuXG4gICAgICByZXF1ZXN0SG9zdFRpbWVvdXQoaGFuZGxlVGltZW91dCwgc3RhcnRUaW1lIC0gY3VycmVudFRpbWUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBuZXdUYXNrLnNvcnRJbmRleCA9IGV4cGlyYXRpb25UaW1lO1xuICAgIHB1c2godGFza1F1ZXVlLCBuZXdUYXNrKTtcbiAgICAvLyB3YWl0IHVudGlsIHRoZSBuZXh0IHRpbWUgd2UgeWllbGQuXG5cblxuICAgIGlmICghaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgJiYgIWlzUGVyZm9ybWluZ1dvcmspIHtcbiAgICAgIGlzSG9zdENhbGxiYWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgIHJlcXVlc3RIb3N0Q2FsbGJhY2soZmx1c2hXb3JrKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3VGFzaztcbn1cblxuZnVuY3Rpb24gdW5zdGFibGVfcGF1c2VFeGVjdXRpb24oKSB7XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX2NvbnRpbnVlRXhlY3V0aW9uKCkge1xuXG4gIGlmICghaXNIb3N0Q2FsbGJhY2tTY2hlZHVsZWQgJiYgIWlzUGVyZm9ybWluZ1dvcmspIHtcbiAgICBpc0hvc3RDYWxsYmFja1NjaGVkdWxlZCA9IHRydWU7XG4gICAgcmVxdWVzdEhvc3RDYWxsYmFjayhmbHVzaFdvcmspO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuc3RhYmxlX2dldEZpcnN0Q2FsbGJhY2tOb2RlKCkge1xuICByZXR1cm4gcGVlayh0YXNrUXVldWUpO1xufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV9jYW5jZWxDYWxsYmFjayh0YXNrKSB7XG4gIC8vIHJlbW92ZSBmcm9tIHRoZSBxdWV1ZSBiZWNhdXNlIHlvdSBjYW4ndCByZW1vdmUgYXJiaXRyYXJ5IG5vZGVzIGZyb20gYW5cbiAgLy8gYXJyYXkgYmFzZWQgaGVhcCwgb25seSB0aGUgZmlyc3Qgb25lLilcblxuXG4gIHRhc2suY2FsbGJhY2sgPSBudWxsO1xufVxuXG5mdW5jdGlvbiB1bnN0YWJsZV9nZXRDdXJyZW50UHJpb3JpdHlMZXZlbCgpIHtcbiAgcmV0dXJuIGN1cnJlbnRQcmlvcml0eUxldmVsO1xufVxuXG52YXIgaXNNZXNzYWdlTG9vcFJ1bm5pbmcgPSBmYWxzZTtcbnZhciBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBudWxsO1xudmFyIHRhc2tUaW1lb3V0SUQgPSAtMTsgLy8gU2NoZWR1bGVyIHBlcmlvZGljYWxseSB5aWVsZHMgaW4gY2FzZSB0aGVyZSBpcyBvdGhlciB3b3JrIG9uIHRoZSBtYWluXG4vLyB0aHJlYWQsIGxpa2UgdXNlciBldmVudHMuIEJ5IGRlZmF1bHQsIGl0IHlpZWxkcyBtdWx0aXBsZSB0aW1lcyBwZXIgZnJhbWUuXG4vLyBJdCBkb2VzIG5vdCBhdHRlbXB0IHRvIGFsaWduIHdpdGggZnJhbWUgYm91bmRhcmllcywgc2luY2UgbW9zdCB0YXNrcyBkb24ndFxuLy8gbmVlZCB0byBiZSBmcmFtZSBhbGlnbmVkOyBmb3IgdGhvc2UgdGhhdCBkbywgdXNlIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cblxudmFyIGZyYW1lSW50ZXJ2YWwgPSBmcmFtZVlpZWxkTXM7XG52YXIgc3RhcnRUaW1lID0gLTE7XG5cbmZ1bmN0aW9uIHNob3VsZFlpZWxkVG9Ib3N0KCkge1xuICB2YXIgdGltZUVsYXBzZWQgPSBleHBvcnRzLnVuc3RhYmxlX25vdygpIC0gc3RhcnRUaW1lO1xuXG4gIGlmICh0aW1lRWxhcHNlZCA8IGZyYW1lSW50ZXJ2YWwpIHtcbiAgICAvLyBUaGUgbWFpbiB0aHJlYWQgaGFzIG9ubHkgYmVlbiBibG9ja2VkIGZvciBhIHJlYWxseSBzaG9ydCBhbW91bnQgb2YgdGltZTtcbiAgICAvLyBzbWFsbGVyIHRoYW4gYSBzaW5nbGUgZnJhbWUuIERvbid0IHlpZWxkIHlldC5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0gLy8gVGhlIG1haW4gdGhyZWFkIGhhcyBiZWVuIGJsb2NrZWQgZm9yIGEgbm9uLW5lZ2xpZ2libGUgYW1vdW50IG9mIHRpbWUuIFdlXG5cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFBhaW50KCkge1xuXG59XG5cbmZ1bmN0aW9uIGZvcmNlRnJhbWVSYXRlKGZwcykge1xuICBpZiAoZnBzIDwgMCB8fCBmcHMgPiAxMjUpIHtcbiAgICAvLyBVc2luZyBjb25zb2xlWydlcnJvciddIHRvIGV2YWRlIEJhYmVsIGFuZCBFU0xpbnRcbiAgICBjb25zb2xlWydlcnJvciddKCdmb3JjZUZyYW1lUmF0ZSB0YWtlcyBhIHBvc2l0aXZlIGludCBiZXR3ZWVuIDAgYW5kIDEyNSwgJyArICdmb3JjaW5nIGZyYW1lIHJhdGVzIGhpZ2hlciB0aGFuIDEyNSBmcHMgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChmcHMgPiAwKSB7XG4gICAgZnJhbWVJbnRlcnZhbCA9IE1hdGguZmxvb3IoMTAwMCAvIGZwcyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVzZXQgdGhlIGZyYW1lcmF0ZVxuICAgIGZyYW1lSW50ZXJ2YWwgPSBmcmFtZVlpZWxkTXM7XG4gIH1cbn1cblxudmFyIHBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHNjaGVkdWxlZEhvc3RDYWxsYmFjayAhPT0gbnVsbCkge1xuICAgIHZhciBjdXJyZW50VGltZSA9IGV4cG9ydHMudW5zdGFibGVfbm93KCk7IC8vIEtlZXAgdHJhY2sgb2YgdGhlIHN0YXJ0IHRpbWUgc28gd2UgY2FuIG1lYXN1cmUgaG93IGxvbmcgdGhlIG1haW4gdGhyZWFkXG4gICAgLy8gaGFzIGJlZW4gYmxvY2tlZC5cblxuICAgIHN0YXJ0VGltZSA9IGN1cnJlbnRUaW1lO1xuICAgIHZhciBoYXNUaW1lUmVtYWluaW5nID0gdHJ1ZTsgLy8gSWYgYSBzY2hlZHVsZXIgdGFzayB0aHJvd3MsIGV4aXQgdGhlIGN1cnJlbnQgYnJvd3NlciB0YXNrIHNvIHRoZVxuICAgIC8vIGVycm9yIGNhbiBiZSBvYnNlcnZlZC5cbiAgICAvL1xuICAgIC8vIEludGVudGlvbmFsbHkgbm90IHVzaW5nIGEgdHJ5LWNhdGNoLCBzaW5jZSB0aGF0IG1ha2VzIHNvbWUgZGVidWdnaW5nXG4gICAgLy8gdGVjaG5pcXVlcyBoYXJkZXIuIEluc3RlYWQsIGlmIGBzY2hlZHVsZWRIb3N0Q2FsbGJhY2tgIGVycm9ycywgdGhlblxuICAgIC8vIGBoYXNNb3JlV29ya2Agd2lsbCByZW1haW4gdHJ1ZSwgYW5kIHdlJ2xsIGNvbnRpbnVlIHRoZSB3b3JrIGxvb3AuXG5cbiAgICB2YXIgaGFzTW9yZVdvcmsgPSB0cnVlO1xuXG4gICAgdHJ5IHtcbiAgICAgIGhhc01vcmVXb3JrID0gc2NoZWR1bGVkSG9zdENhbGxiYWNrKGhhc1RpbWVSZW1haW5pbmcsIGN1cnJlbnRUaW1lKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKGhhc01vcmVXb3JrKSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3MgbW9yZSB3b3JrLCBzY2hlZHVsZSB0aGUgbmV4dCBtZXNzYWdlIGV2ZW50IGF0IHRoZSBlbmRcbiAgICAgICAgLy8gb2YgdGhlIHByZWNlZGluZyBvbmUuXG4gICAgICAgIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpc01lc3NhZ2VMb29wUnVubmluZyA9IGZhbHNlO1xuICAgICAgICBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpc01lc3NhZ2VMb29wUnVubmluZyA9IGZhbHNlO1xuICB9IC8vIFlpZWxkaW5nIHRvIHRoZSBicm93c2VyIHdpbGwgZ2l2ZSBpdCBhIGNoYW5jZSB0byBwYWludCwgc28gd2UgY2FuXG59O1xuXG52YXIgc2NoZWR1bGVQZXJmb3JtV29ya1VudGlsRGVhZGxpbmU7XG5cbmlmICh0eXBlb2YgbG9jYWxTZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gTm9kZS5qcyBhbmQgb2xkIElFLlxuICAvLyBUaGVyZSdzIGEgZmV3IHJlYXNvbnMgZm9yIHdoeSB3ZSBwcmVmZXIgc2V0SW1tZWRpYXRlLlxuICAvL1xuICAvLyBVbmxpa2UgTWVzc2FnZUNoYW5uZWwsIGl0IGRvZXNuJ3QgcHJldmVudCBhIE5vZGUuanMgcHJvY2VzcyBmcm9tIGV4aXRpbmcuXG4gIC8vIChFdmVuIHRob3VnaCB0aGlzIGlzIGEgRE9NIGZvcmsgb2YgdGhlIFNjaGVkdWxlciwgeW91IGNvdWxkIGdldCBoZXJlXG4gIC8vIHdpdGggYSBtaXggb2YgTm9kZS5qcyAxNSssIHdoaWNoIGhhcyBhIE1lc3NhZ2VDaGFubmVsLCBhbmQganNkb20uKVxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVhY3QvaXNzdWVzLzIwNzU2XG4gIC8vXG4gIC8vIEJ1dCBhbHNvLCBpdCBydW5zIGVhcmxpZXIgd2hpY2ggaXMgdGhlIHNlbWFudGljIHdlIHdhbnQuXG4gIC8vIElmIG90aGVyIGJyb3dzZXJzIGV2ZXIgaW1wbGVtZW50IGl0LCBpdCdzIGJldHRlciB0byB1c2UgaXQuXG4gIC8vIEFsdGhvdWdoIGJvdGggb2YgdGhlc2Ugd291bGQgYmUgaW5mZXJpb3IgdG8gbmF0aXZlIHNjaGVkdWxpbmcuXG4gIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lID0gZnVuY3Rpb24gKCkge1xuICAgIGxvY2FsU2V0SW1tZWRpYXRlKHBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSk7XG4gIH07XG59IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgLy8gRE9NIGFuZCBXb3JrZXIgZW52aXJvbm1lbnRzLlxuICAvLyBXZSBwcmVmZXIgTWVzc2FnZUNoYW5uZWwgYmVjYXVzZSBvZiB0aGUgNG1zIHNldFRpbWVvdXQgY2xhbXBpbmcuXG4gIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gIHZhciBwb3J0ID0gY2hhbm5lbC5wb3J0MjtcbiAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBwZXJmb3JtV29ya1VudGlsRGVhZGxpbmU7XG5cbiAgc2NoZWR1bGVQZXJmb3JtV29ya1VudGlsRGVhZGxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcG9ydC5wb3N0TWVzc2FnZShudWxsKTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIFdlIHNob3VsZCBvbmx5IGZhbGxiYWNrIGhlcmUgaW4gbm9uLWJyb3dzZXIgZW52aXJvbm1lbnRzLlxuICBzY2hlZHVsZVBlcmZvcm1Xb3JrVW50aWxEZWFkbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBsb2NhbFNldFRpbWVvdXQocGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lLCAwKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhvc3RDYWxsYmFjayhjYWxsYmFjaykge1xuICBzY2hlZHVsZWRIb3N0Q2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBpZiAoIWlzTWVzc2FnZUxvb3BSdW5uaW5nKSB7XG4gICAgaXNNZXNzYWdlTG9vcFJ1bm5pbmcgPSB0cnVlO1xuICAgIHNjaGVkdWxlUGVyZm9ybVdvcmtVbnRpbERlYWRsaW5lKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhvc3RUaW1lb3V0KGNhbGxiYWNrLCBtcykge1xuICB0YXNrVGltZW91dElEID0gbG9jYWxTZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBjYWxsYmFjayhleHBvcnRzLnVuc3RhYmxlX25vdygpKTtcbiAgfSwgbXMpO1xufVxuXG5mdW5jdGlvbiBjYW5jZWxIb3N0VGltZW91dCgpIHtcbiAgbG9jYWxDbGVhclRpbWVvdXQodGFza1RpbWVvdXRJRCk7XG4gIHRhc2tUaW1lb3V0SUQgPSAtMTtcbn1cblxudmFyIHVuc3RhYmxlX3JlcXVlc3RQYWludCA9IHJlcXVlc3RQYWludDtcbnZhciB1bnN0YWJsZV9Qcm9maWxpbmcgPSAgbnVsbDtcblxuZXhwb3J0cy51bnN0YWJsZV9JZGxlUHJpb3JpdHkgPSBJZGxlUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5ID0gSW1tZWRpYXRlUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX0xvd1ByaW9yaXR5ID0gTG93UHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5ID0gTm9ybWFsUHJpb3JpdHk7XG5leHBvcnRzLnVuc3RhYmxlX1Byb2ZpbGluZyA9IHVuc3RhYmxlX1Byb2ZpbGluZztcbmV4cG9ydHMudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHkgPSBVc2VyQmxvY2tpbmdQcmlvcml0eTtcbmV4cG9ydHMudW5zdGFibGVfY2FuY2VsQ2FsbGJhY2sgPSB1bnN0YWJsZV9jYW5jZWxDYWxsYmFjaztcbmV4cG9ydHMudW5zdGFibGVfY29udGludWVFeGVjdXRpb24gPSB1bnN0YWJsZV9jb250aW51ZUV4ZWN1dGlvbjtcbmV4cG9ydHMudW5zdGFibGVfZm9yY2VGcmFtZVJhdGUgPSBmb3JjZUZyYW1lUmF0ZTtcbmV4cG9ydHMudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWwgPSB1bnN0YWJsZV9nZXRDdXJyZW50UHJpb3JpdHlMZXZlbDtcbmV4cG9ydHMudW5zdGFibGVfZ2V0Rmlyc3RDYWxsYmFja05vZGUgPSB1bnN0YWJsZV9nZXRGaXJzdENhbGxiYWNrTm9kZTtcbmV4cG9ydHMudW5zdGFibGVfbmV4dCA9IHVuc3RhYmxlX25leHQ7XG5leHBvcnRzLnVuc3RhYmxlX3BhdXNlRXhlY3V0aW9uID0gdW5zdGFibGVfcGF1c2VFeGVjdXRpb247XG5leHBvcnRzLnVuc3RhYmxlX3JlcXVlc3RQYWludCA9IHVuc3RhYmxlX3JlcXVlc3RQYWludDtcbmV4cG9ydHMudW5zdGFibGVfcnVuV2l0aFByaW9yaXR5ID0gdW5zdGFibGVfcnVuV2l0aFByaW9yaXR5O1xuZXhwb3J0cy51bnN0YWJsZV9zY2hlZHVsZUNhbGxiYWNrID0gdW5zdGFibGVfc2NoZWR1bGVDYWxsYmFjaztcbmV4cG9ydHMudW5zdGFibGVfc2hvdWxkWWllbGQgPSBzaG91bGRZaWVsZFRvSG9zdDtcbmV4cG9ydHMudW5zdGFibGVfd3JhcENhbGxiYWNrID0gdW5zdGFibGVfd3JhcENhbGxiYWNrO1xuICAgICAgICAgIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbmlmIChcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5yZWdpc3RlckludGVybmFsTW9kdWxlU3RvcCA9PT1cbiAgICAnZnVuY3Rpb24nXG4pIHtcbiAgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fLnJlZ2lzdGVySW50ZXJuYWxNb2R1bGVTdG9wKG5ldyBFcnJvcigpKTtcbn1cbiAgICAgICAgXG4gIH0pKCk7XG59XG4iLCJpbXBvcnQgeyBGcmFnbWVudCwgdHlwZSBGQywgdHlwZSBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIlxuXG5leHBvcnQgY29uc3QgZ2V0TGF5b3V0ID0gKFJhd0ltcG9ydDogYW55KTogRkM8eyBjaGlsZHJlbjogUmVhY3ROb2RlIH0+ID0+XG4gIHR5cGVvZiBSYXdJbXBvcnQuTGF5b3V0ID09PSBcImZ1bmN0aW9uXCJcbiAgICA/IFJhd0ltcG9ydC5MYXlvdXRcbiAgICA6IHR5cGVvZiBSYXdJbXBvcnQuZ2V0R2xvYmFsUHJvdmlkZXIgPT09IFwiZnVuY3Rpb25cIlxuICAgID8gUmF3SW1wb3J0LmdldEdsb2JhbFByb3ZpZGVyKClcbiAgICA6IEZyYWdtZW50XG4iLCJleHBvcnRzLmludGVyb3BEZWZhdWx0ID0gZnVuY3Rpb24gKGEpIHtcbiAgcmV0dXJuIGEgJiYgYS5fX2VzTW9kdWxlID8gYSA6IHtkZWZhdWx0OiBhfTtcbn07XG5cbmV4cG9ydHMuZGVmaW5lSW50ZXJvcEZsYWcgPSBmdW5jdGlvbiAoYSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYSwgJ19fZXNNb2R1bGUnLCB7dmFsdWU6IHRydWV9KTtcbn07XG5cbmV4cG9ydHMuZXhwb3J0QWxsID0gZnVuY3Rpb24gKHNvdXJjZSwgZGVzdCkge1xuICBPYmplY3Qua2V5cyhzb3VyY2UpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIGlmIChrZXkgPT09ICdkZWZhdWx0JyB8fCBrZXkgPT09ICdfX2VzTW9kdWxlJyB8fCBkZXN0Lmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGVzdCwga2V5LCB7XG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2Vba2V5XTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZXhwb3J0cy5leHBvcnQgPSBmdW5jdGlvbiAoZGVzdCwgZGVzdE5hbWUsIGdldCkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZGVzdCwgZGVzdE5hbWUsIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGdldDogZ2V0LFxuICB9KTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIFJlZnJlc2ggPSByZXF1aXJlKCdyZWFjdC1yZWZyZXNoL3J1bnRpbWUnKTtcbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIGRlbGF5KSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgICBmdW5jLmNhbGwobnVsbCwgYXJncyk7XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgdGltZW91dCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgbGFzdFRpbWUgPSAwO1xuICAgIHJldHVybiBmdW5jdGlvbiAoYXJncykge1xuICAgICAgLy8gQ2FsbCBpbW1lZGlhdGVseSBpZiBsYXN0IGNhbGwgd2FzIG1vcmUgdGhhbiB0aGUgZGVsYXkgYWdvLlxuICAgICAgLy8gT3RoZXJ3aXNlLCBzZXQgYSB0aW1lb3V0LiBUaGlzIG1lYW5zIHRoZSBmaXJzdCBjYWxsIGlzIGZhc3RcbiAgICAgIC8vIChmb3IgdGhlIGNvbW1vbiBjYXNlIG9mIGEgc2luZ2xlIHVwZGF0ZSksIGFuZCBzdWJzZXF1ZW50IHVwZGF0ZXNcbiAgICAgIC8vIGFyZSBiYXRjaGVkLlxuICAgICAgbGV0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBpZiAobm93IC0gbGFzdFRpbWUgPiBkZWxheSkge1xuICAgICAgICBsYXN0VGltZSA9IG5vdztcbiAgICAgICAgZnVuYy5jYWxsKG51bGwsIGFyZ3MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGltZW91dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBsYXN0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgZnVuYy5jYWxsKG51bGwsIGFyZ3MpO1xuICAgICAgICB9LCBkZWxheSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufVxudmFyIGVucXVldWVVcGRhdGUgPSBkZWJvdW5jZShmdW5jdGlvbiAoKSB7XG4gIFJlZnJlc2gucGVyZm9ybVJlYWN0UmVmcmVzaCgpO1xufSwgMzApO1xuXG4vLyBFdmVydGhpbmcgYmVsb3cgaXMgZWl0aGVyIGFkYXB0ZWQgb3IgY29waWVkIGZyb21cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9tZXRyby9ibG9iLzYxZGUxNmJkMWVkZDdlNzM4ZGQwMzExYzg5NTU1YTY0NDAyM2FiMmQvcGFja2FnZXMvbWV0cm8vc3JjL2xpYi9wb2x5ZmlsbHMvcmVxdWlyZS5qc1xuLy8gTUlUIExpY2Vuc2UgLSBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cblxubW9kdWxlLmV4cG9ydHMucHJlbHVkZSA9IGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgd2luZG93LiRSZWZyZXNoUmVnJCA9IGZ1bmN0aW9uICh0eXBlLCBpZCkge1xuICAgIFJlZnJlc2gucmVnaXN0ZXIodHlwZSwgbW9kdWxlLmlkICsgJyAnICsgaWQpO1xuICB9O1xuICB3aW5kb3cuJFJlZnJlc2hTaWckID0gUmVmcmVzaC5jcmVhdGVTaWduYXR1cmVGdW5jdGlvbkZvclRyYW5zZm9ybTtcbn07XG5tb2R1bGUuZXhwb3J0cy5wb3N0bHVkZSA9IGZ1bmN0aW9uIChtb2R1bGUpIHtcbiAgaWYgKGlzUmVhY3RSZWZyZXNoQm91bmRhcnkobW9kdWxlLmV4cG9ydHMpKSB7XG4gICAgcmVnaXN0ZXJFeHBvcnRzRm9yUmVhY3RSZWZyZXNoKG1vZHVsZSk7XG4gICAgaWYgKG1vZHVsZS5ob3QpIHtcbiAgICAgIG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICBpZiAoUmVmcmVzaC5oYXNVbnJlY292ZXJhYmxlRXJyb3JzKCkpIHtcbiAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YS5wcmV2RXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzO1xuICAgICAgfSk7XG4gICAgICBtb2R1bGUuaG90LmFjY2VwdChmdW5jdGlvbiAoZ2V0UGFyZW50cykge1xuICAgICAgICB2YXIgcHJldkV4cG9ydHMgPSBtb2R1bGUuaG90LmRhdGEucHJldkV4cG9ydHM7XG4gICAgICAgIHZhciBuZXh0RXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzO1xuICAgICAgICAvLyBTaW5jZSB3ZSBqdXN0IGV4ZWN1dGVkIHRoZSBjb2RlIGZvciBpdCwgaXQncyBwb3NzaWJsZVxuICAgICAgICAvLyB0aGF0IHRoZSBuZXcgZXhwb3J0cyBtYWtlIGl0IGluZWxpZ2libGUgZm9yIGJlaW5nIGEgYm91bmRhcnkuXG4gICAgICAgIHZhciBpc05vTG9uZ2VyQUJvdW5kYXJ5ID0gIWlzUmVhY3RSZWZyZXNoQm91bmRhcnkobmV4dEV4cG9ydHMpO1xuICAgICAgICAvLyBJdCBjYW4gYWxzbyBiZWNvbWUgaW5lbGlnaWJsZSBpZiBpdHMgZXhwb3J0cyBhcmUgaW5jb21wYXRpYmxlXG4gICAgICAgIC8vIHdpdGggdGhlIHByZXZpb3VzIGV4cG9ydHMuXG4gICAgICAgIC8vIEZvciBleGFtcGxlLCBpZiB5b3UgYWRkL3JlbW92ZS9jaGFuZ2UgZXhwb3J0cywgd2UnbGwgd2FudFxuICAgICAgICAvLyB0byByZS1leGVjdXRlIHRoZSBpbXBvcnRpbmcgbW9kdWxlcywgYW5kIGZvcmNlIHRob3NlIGNvbXBvbmVudHNcbiAgICAgICAgLy8gdG8gcmUtcmVuZGVyLiBTaW1pbGFybHksIGlmIHlvdSBjb252ZXJ0IGEgY2xhc3MgY29tcG9uZW50XG4gICAgICAgIC8vIHRvIGEgZnVuY3Rpb24sIHdlIHdhbnQgdG8gaW52YWxpZGF0ZSB0aGUgYm91bmRhcnkuXG4gICAgICAgIHZhciBkaWRJbnZhbGlkYXRlID0gc2hvdWxkSW52YWxpZGF0ZVJlYWN0UmVmcmVzaEJvdW5kYXJ5KHByZXZFeHBvcnRzLCBuZXh0RXhwb3J0cyk7XG4gICAgICAgIGlmIChpc05vTG9uZ2VyQUJvdW5kYXJ5IHx8IGRpZEludmFsaWRhdGUpIHtcbiAgICAgICAgICAvLyBXZSdsbCBiZSBjb25zZXJ2YXRpdmUuIFRoZSBvbmx5IGNhc2UgaW4gd2hpY2ggd2Ugd29uJ3QgZG8gYSBmdWxsXG4gICAgICAgICAgLy8gcmVsb2FkIGlzIGlmIGFsbCBwYXJlbnQgbW9kdWxlcyBhcmUgYWxzbyByZWZyZXNoIGJvdW5kYXJpZXMuXG4gICAgICAgICAgLy8gSW4gdGhhdCBjYXNlIHdlJ2xsIGFkZCB0aGVtIHRvIHRoZSBjdXJyZW50IHF1ZXVlLlxuICAgICAgICAgIHZhciBwYXJlbnRzID0gZ2V0UGFyZW50cygpO1xuICAgICAgICAgIGlmIChwYXJlbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gTG9va3MgbGlrZSB3ZSBidWJibGVkIHRvIHRoZSByb290LiBDYW4ndCByZWNvdmVyIGZyb20gdGhhdC5cbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHBhcmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgZW5xdWV1ZVVwZGF0ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuZnVuY3Rpb24gaXNSZWFjdFJlZnJlc2hCb3VuZGFyeShleHBvcnRzKSB7XG4gIGlmIChSZWZyZXNoLmlzTGlrZWx5Q29tcG9uZW50VHlwZShleHBvcnRzKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChleHBvcnRzID09IG51bGwgfHwgdHlwZW9mIGV4cG9ydHMgIT09ICdvYmplY3QnKSB7XG4gICAgLy8gRXhpdCBpZiB3ZSBjYW4ndCBpdGVyYXRlIG92ZXIgZXhwb3J0cy5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIGhhc0V4cG9ydHMgPSBmYWxzZTtcbiAgdmFyIGFyZUFsbEV4cG9ydHNDb21wb25lbnRzID0gdHJ1ZTtcbiAgbGV0IGlzRVNNID0gKCdfX2VzTW9kdWxlJyBpbiBleHBvcnRzKTtcbiAgZm9yICh2YXIga2V5IGluIGV4cG9ydHMpIHtcbiAgICBoYXNFeHBvcnRzID0gdHJ1ZTtcbiAgICBpZiAoa2V5ID09PSAnX19lc01vZHVsZScpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZXhwb3J0cywga2V5KTtcbiAgICBpZiAoZGVzYyAmJiBkZXNjLmdldCAmJiAhaXNFU00pIHtcbiAgICAgIC8vIERvbid0IGludm9rZSBnZXR0ZXJzIGZvciBDSlMgYXMgdGhleSBtYXkgaGF2ZSBzaWRlIGVmZmVjdHMuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBleHBvcnRWYWx1ZSA9IGV4cG9ydHNba2V5XTtcbiAgICBpZiAoIVJlZnJlc2guaXNMaWtlbHlDb21wb25lbnRUeXBlKGV4cG9ydFZhbHVlKSkge1xuICAgICAgYXJlQWxsRXhwb3J0c0NvbXBvbmVudHMgPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGhhc0V4cG9ydHMgJiYgYXJlQWxsRXhwb3J0c0NvbXBvbmVudHM7XG59XG5mdW5jdGlvbiBzaG91bGRJbnZhbGlkYXRlUmVhY3RSZWZyZXNoQm91bmRhcnkocHJldkV4cG9ydHMsIG5leHRFeHBvcnRzKSB7XG4gIHZhciBwcmV2U2lnbmF0dXJlID0gZ2V0UmVmcmVzaEJvdW5kYXJ5U2lnbmF0dXJlKHByZXZFeHBvcnRzKTtcbiAgdmFyIG5leHRTaWduYXR1cmUgPSBnZXRSZWZyZXNoQm91bmRhcnlTaWduYXR1cmUobmV4dEV4cG9ydHMpO1xuICBpZiAocHJldlNpZ25hdHVyZS5sZW5ndGggIT09IG5leHRTaWduYXR1cmUubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZXh0U2lnbmF0dXJlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHByZXZTaWduYXR1cmVbaV0gIT09IG5leHRTaWduYXR1cmVbaV0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIFdoZW4gdGhpcyBzaWduYXR1cmUgY2hhbmdlcywgaXQncyB1bnNhZmUgdG8gc3RvcCBhdCB0aGlzIHJlZnJlc2ggYm91bmRhcnkuXG5mdW5jdGlvbiBnZXRSZWZyZXNoQm91bmRhcnlTaWduYXR1cmUoZXhwb3J0cykge1xuICB2YXIgc2lnbmF0dXJlID0gW107XG4gIHNpZ25hdHVyZS5wdXNoKFJlZnJlc2guZ2V0RmFtaWx5QnlUeXBlKGV4cG9ydHMpKTtcbiAgaWYgKGV4cG9ydHMgPT0gbnVsbCB8fCB0eXBlb2YgZXhwb3J0cyAhPT0gJ29iamVjdCcpIHtcbiAgICAvLyBFeGl0IGlmIHdlIGNhbid0IGl0ZXJhdGUgb3ZlciBleHBvcnRzLlxuICAgIC8vIChUaGlzIGlzIGltcG9ydGFudCBmb3IgbGVnYWN5IGVudmlyb25tZW50cy4pXG4gICAgcmV0dXJuIHNpZ25hdHVyZTtcbiAgfVxuICBsZXQgaXNFU00gPSAoJ19fZXNNb2R1bGUnIGluIGV4cG9ydHMpO1xuICBmb3IgKHZhciBrZXkgaW4gZXhwb3J0cykge1xuICAgIGlmIChrZXkgPT09ICdfX2VzTW9kdWxlJykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihleHBvcnRzLCBrZXkpO1xuICAgIGlmIChkZXNjICYmIGRlc2MuZ2V0ICYmICFpc0VTTSkge1xuICAgICAgLy8gRG9uJ3QgaW52b2tlIGdldHRlcnMgZm9yIENKUyBhcyB0aGV5IG1heSBoYXZlIHNpZGUgZWZmZWN0cy5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgZXhwb3J0VmFsdWUgPSBleHBvcnRzW2tleV07XG4gICAgc2lnbmF0dXJlLnB1c2goa2V5KTtcbiAgICBzaWduYXR1cmUucHVzaChSZWZyZXNoLmdldEZhbWlseUJ5VHlwZShleHBvcnRWYWx1ZSkpO1xuICB9XG4gIHJldHVybiBzaWduYXR1cmU7XG59XG5mdW5jdGlvbiByZWdpc3RlckV4cG9ydHNGb3JSZWFjdFJlZnJlc2gobW9kdWxlKSB7XG4gIHZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMsXG4gICAgaWQgPSBtb2R1bGUuaWQ7XG4gIFJlZnJlc2gucmVnaXN0ZXIoZXhwb3J0cywgaWQgKyAnICVleHBvcnRzJScpO1xuICBpZiAoZXhwb3J0cyA9PSBudWxsIHx8IHR5cGVvZiBleHBvcnRzICE9PSAnb2JqZWN0Jykge1xuICAgIC8vIEV4aXQgaWYgd2UgY2FuJ3QgaXRlcmF0ZSBvdmVyIGV4cG9ydHMuXG4gICAgLy8gKFRoaXMgaXMgaW1wb3J0YW50IGZvciBsZWdhY3kgZW52aXJvbm1lbnRzLilcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IGlzRVNNID0gKCdfX2VzTW9kdWxlJyBpbiBleHBvcnRzKTtcbiAgZm9yICh2YXIga2V5IGluIGV4cG9ydHMpIHtcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZXhwb3J0cywga2V5KTtcbiAgICBpZiAoZGVzYyAmJiBkZXNjLmdldCAmJiAhaXNFU00pIHtcbiAgICAgIC8vIERvbid0IGludm9rZSBnZXR0ZXJzIGZvciBDSlMgYXMgdGhleSBtYXkgaGF2ZSBzaWRlIGVmZmVjdHMuXG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIGV4cG9ydFZhbHVlID0gZXhwb3J0c1trZXldO1xuICAgIHZhciB0eXBlSUQgPSBpZCArICcgJWV4cG9ydHMlICcgKyBrZXk7XG4gICAgUmVmcmVzaC5yZWdpc3RlcihleHBvcnRWYWx1ZSwgdHlwZUlEKTtcbiAgfVxufSIsImltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCJcblxuZnVuY3Rpb24gSW5kZXhQb3B1cCgpIHtcbiAgY29uc3QgW2RhdGEsIHNldERhdGFdID0gdXNlU3RhdGUoXCJcIilcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIHBhZGRpbmc6IDE2XG4gICAgICB9fT5cbiAgICAgIDxoMj5cbiAgICAgICAgV2VsY29tZSB0byB5b3Vye1wiIFwifVxuICAgICAgICA8YSBocmVmPVwiaHR0cHM6Ly93d3cucGxhc21vLmNvbVwiIHRhcmdldD1cIl9ibGFua1wiPlxuICAgICAgICAgIFBsYXNtb1xuICAgICAgICA8L2E+e1wiIFwifVxuICAgICAgICBFeHRlbnNpb24hXG4gICAgICA8L2gyPlxuICAgICAgPGlucHV0IG9uQ2hhbmdlPXsoZSkgPT4gc2V0RGF0YShlLnRhcmdldC52YWx1ZSl9IHZhbHVlPXtkYXRhfSAvPlxuICAgICAgPGEgaHJlZj1cImh0dHBzOi8vZG9jcy5wbGFzbW8uY29tXCIgdGFyZ2V0PVwiX2JsYW5rXCI+XG4gICAgICAgIFZpZXcgRG9jc1xuICAgICAgPC9hPlxuICAgIDwvZGl2PlxuICApXG59XG5cbmV4cG9ydCBkZWZhdWx0IEluZGV4UG9wdXBcbiJdLCJuYW1lcyI6W10sInZlcnNpb24iOjMsImZpbGUiOiJwb3B1cC43ZmY1ODhmMy5qcy5tYXAifQ==
+ globalThis.define=__define; })(globalThis.define);
\ No newline at end of file
diff --git a/packages/whats-ext/build/chrome-mv3-dev/popup.html b/packages/whats-ext/build/chrome-mv3-dev/popup.html
new file mode 100644
index 0000000..f19b285
--- /dev/null
+++ b/packages/whats-ext/build/chrome-mv3-dev/popup.html
@@ -0,0 +1,13 @@
+
+
+
+ Example dir
+
+
+
+
+
+
+
+
+
diff --git a/packages/whats-ext/build/chrome-mv3-dev/static/background/index.js b/packages/whats-ext/build/chrome-mv3-dev/static/background/index.js
new file mode 100644
index 0000000..a1a4a74
--- /dev/null
+++ b/packages/whats-ext/build/chrome-mv3-dev/static/background/index.js
@@ -0,0 +1,382 @@
+(function(define){var __define; typeof define === "function" && (__define=define,define=null);
+// modules are defined as an array
+// [ module function, map of requires ]
+//
+// map of requires is short require name -> numeric require
+//
+// anything defined in a previous bundle is accessed via the
+// orig method which is the require for previous bundles
+
+(function (modules, entry, mainEntry, parcelRequireName, globalName) {
+ /* eslint-disable no-undef */
+ var globalObject =
+ typeof globalThis !== 'undefined'
+ ? globalThis
+ : typeof self !== 'undefined'
+ ? self
+ : typeof window !== 'undefined'
+ ? window
+ : typeof global !== 'undefined'
+ ? global
+ : {};
+ /* eslint-enable no-undef */
+
+ // Save the require from previous bundle to this closure if any
+ var previousRequire =
+ typeof globalObject[parcelRequireName] === 'function' &&
+ globalObject[parcelRequireName];
+
+ var cache = previousRequire.cache || {};
+ // Do not use `require` to prevent Webpack from trying to bundle this call
+ var nodeRequire =
+ typeof module !== 'undefined' &&
+ typeof module.require === 'function' &&
+ module.require.bind(module);
+
+ function newRequire(name, jumped) {
+ if (!cache[name]) {
+ if (!modules[name]) {
+ // if we cannot find the module within our internal map or
+ // cache jump to the current global require ie. the last bundle
+ // that was added to the page.
+ var currentRequire =
+ typeof globalObject[parcelRequireName] === 'function' &&
+ globalObject[parcelRequireName];
+ if (!jumped && currentRequire) {
+ return currentRequire(name, true);
+ }
+
+ // If there are other bundles on this page the require from the
+ // previous one is saved to 'previousRequire'. Repeat this as
+ // many times as there are bundles until the module is found or
+ // we exhaust the require chain.
+ if (previousRequire) {
+ return previousRequire(name, true);
+ }
+
+ // Try the node require function if it exists.
+ if (nodeRequire && typeof name === 'string') {
+ return nodeRequire(name);
+ }
+
+ var err = new Error("Cannot find module '" + name + "'");
+ err.code = 'MODULE_NOT_FOUND';
+ throw err;
+ }
+
+ localRequire.resolve = resolve;
+ localRequire.cache = {};
+
+ var module = (cache[name] = new newRequire.Module(name));
+
+ modules[name][0].call(
+ module.exports,
+ localRequire,
+ module,
+ module.exports,
+ this
+ );
+ }
+
+ return cache[name].exports;
+
+ function localRequire(x) {
+ var res = localRequire.resolve(x);
+ return res === false ? {} : newRequire(res);
+ }
+
+ function resolve(x) {
+ var id = modules[name][1][x];
+ return id != null ? id : x;
+ }
+ }
+
+ function Module(moduleName) {
+ this.id = moduleName;
+ this.bundle = newRequire;
+ this.exports = {};
+ }
+
+ newRequire.isParcelRequire = true;
+ newRequire.Module = Module;
+ newRequire.modules = modules;
+ newRequire.cache = cache;
+ newRequire.parent = previousRequire;
+ newRequire.register = function (id, exports) {
+ modules[id] = [
+ function (require, module) {
+ module.exports = exports;
+ },
+ {},
+ ];
+ };
+
+ Object.defineProperty(newRequire, 'root', {
+ get: function () {
+ return globalObject[parcelRequireName];
+ },
+ });
+
+ globalObject[parcelRequireName] = newRequire;
+
+ for (var i = 0; i < entry.length; i++) {
+ newRequire(entry[i]);
+ }
+
+ if (mainEntry) {
+ // Expose entry point to Node, AMD or browser globals
+ // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
+ var mainExports = newRequire(mainEntry);
+
+ // CommonJS
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
+ module.exports = mainExports;
+
+ // RequireJS
+ } else if (typeof define === 'function' && define.amd) {
+ define(function () {
+ return mainExports;
+ });
+
+ //
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- GitHub - pagenote/pagenote: 超简单的网页关键词高亮、标注SDK、能把笔记留在网页里。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
pagenote/pagenote
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- You can’t perform that action at this time.
-
-
-
-
-
-
-
You signed in with another tab or window. Reload to refresh your session.
-
You signed out in another tab or window. Reload to refresh your session.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-