// ==UserScript== // @name 更好的我来导出 // @namespace https://shenzilong.cn/ // @version 1.0.0 // @description 从我来导出markdown 文档 // @author 崮生 admin@shenzilong.cn // @include https://www.wolai.com/* // @grant unsafeWindow // @grant GM.setValue // @grant GM.getValue // @grant GM.xmlHttpRequest // @downloadURL none // ==/UserScript== // 以下代码是打包后的代码,可以去 https://github.com/2234839/userJS 查看正常代码 /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 15); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return EMPTY_ARR; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return EMPTY_OBJ; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return NO; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return NOOP; }); /* unused harmony export PatchFlagNames */ /* unused harmony export babelParserDefaultPlugins */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return camelize; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return capitalize; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return def; }); /* unused harmony export escapeHtml */ /* unused harmony export escapeHtmlComment */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return extend; }); /* unused harmony export generateCodeFrame */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return getGlobalThis; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return hasChanged; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "k", function() { return hasOwn; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return hyphenate; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "m", function() { return invokeArrayFns; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return isArray; }); /* unused harmony export isBooleanAttr */ /* unused harmony export isDate */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "o", function() { return isFunction; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "p", function() { return isGloballyWhitelisted; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "q", function() { return isHTMLTag; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "r", function() { return isIntegerKey; }); /* unused harmony export isKnownAttr */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "s", function() { return isModelListener; }); /* unused harmony export isNoUnitNumericStyleProp */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "t", function() { return isObject; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "u", function() { return isOn; }); /* unused harmony export isPlainObject */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "v", function() { return isPromise; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "w", function() { return isReservedProp; }); /* unused harmony export isSSRSafeAttrName */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "x", function() { return isSVGTag; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "y", function() { return isSpecialBooleanAttr; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "z", function() { return isString; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "A", function() { return isSymbol; }); /* unused harmony export isVoidTag */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "B", function() { return looseEqual; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "C", function() { return looseIndexOf; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "D", function() { return makeMap; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "E", function() { return normalizeClass; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "F", function() { return normalizeStyle; }); /* unused harmony export objectToString */ /* unused harmony export parseStringStyle */ /* unused harmony export propsToAttrMap */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "G", function() { return remove; }); /* unused harmony export stringifyStyle */ /* unused harmony export toDisplayString */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "H", function() { return toNumber; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "I", function() { return toRawType; }); /* unused harmony export toTypeString */ /** * Make a map and return a function for checking if a key * is in that map. * IMPORTANT: all calls of this function must be prefixed with * \/\*#\_\_PURE\_\_\*\/ * So that rollup can tree-shake them if necessary. */ function makeMap(str, expectsLowerCase) { const map = Object.create(null); const list = str.split(','); for (let i = 0; i < list.length; i++) { map[list[i]] = true; } return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]; } // Patch flags are optimization hints generated by the compiler. // when a block with dynamicChildren is encountered during diff, the algorithm // enters "optimized mode". In this mode, we know that the vdom is produced by // a render function generated by the compiler, so the algorithm only needs to // handle updates explicitly marked by these patch flags. // dev only flag -> name mapping const PatchFlagNames = { [1 /* TEXT */]: `TEXT`, [2 /* CLASS */]: `CLASS`, [4 /* STYLE */]: `STYLE`, [8 /* PROPS */]: `PROPS`, [16 /* FULL_PROPS */]: `FULL_PROPS`, [32 /* HYDRATE_EVENTS */]: `HYDRATE_EVENTS`, [64 /* STABLE_FRAGMENT */]: `STABLE_FRAGMENT`, [128 /* KEYED_FRAGMENT */]: `KEYED_FRAGMENT`, [256 /* UNKEYED_FRAGMENT */]: `UNKEYED_FRAGMENT`, [1024 /* DYNAMIC_SLOTS */]: `DYNAMIC_SLOTS`, [512 /* NEED_PATCH */]: `NEED_PATCH`, [-1 /* HOISTED */]: `HOISTED`, [-2 /* BAIL */]: `BAIL` }; const GLOBALS_WHITE_LISTED = 'Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,' + 'decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,' + 'Object,Boolean,String,RegExp,Map,Set,JSON,Intl'; const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED); const range = 2; function generateCodeFrame(source, start = 0, end = source.length) { const lines = source.split(/\r?\n/); let count = 0; const res = []; for (let i = 0; i < lines.length; i++) { count += lines[i].length + 1; if (count >= start) { for (let j = i - range; j <= i + range || end > count; j++) { if (j < 0 || j >= lines.length) continue; const line = j + 1; res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); const lineLength = lines[j].length; if (j === i) { // push underline const pad = start - (count - lineLength) + 1; const length = Math.max(1, end > count ? lineLength - pad : end - start); res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); } else if (j > i) { if (end > count) { const length = Math.max(Math.min(end - count, lineLength), 1); res.push(` | ` + '^'.repeat(length)); } count += lineLength + 1; } } break; } } return res.join('\n'); } /** * On the client we only need to offer special cases for boolean attributes that * have different names from their corresponding dom properties: * - itemscope -> N/A * - allowfullscreen -> allowFullscreen * - formnovalidate -> formNoValidate * - ismap -> isMap * - nomodule -> noModule * - novalidate -> noValidate * - readonly -> readOnly */ const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs); /** * The full list is needed during SSR to produce the correct initial markup. */ const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` + `loop,open,required,reversed,scoped,seamless,` + `checked,muted,multiple,selected`); const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/; const attrValidationCache = {}; function isSSRSafeAttrName(name) { if (attrValidationCache.hasOwnProperty(name)) { return attrValidationCache[name]; } const isUnsafe = unsafeAttrCharRE.test(name); if (isUnsafe) { console.error(`unsafe attribute name: ${name}`); } return (attrValidationCache[name] = !isUnsafe); } const propsToAttrMap = { acceptCharset: 'accept-charset', className: 'class', htmlFor: 'for', httpEquiv: 'http-equiv' }; /** * CSS properties that accept plain numbers */ const isNoUnitNumericStyleProp = /*#__PURE__*/ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,` + `border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,` + `columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,` + `grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,` + `grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,` + `line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,` + // SVG `fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,` + `stroke-miterlimit,stroke-opacity,stroke-width`); /** * Known attributes, this is used for stringification of runtime static nodes * so that we don't stringify bindings that cannot be set from HTML. * Don't also forget to allow `data-*` and `aria-*`! * Generated from https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes */ const isKnownAttr = /*#__PURE__*/ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,` + `autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,` + `border,buffered,capture,challenge,charset,checked,cite,class,code,` + `codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,` + `coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,` + `disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,` + `formaction,formenctype,formmethod,formnovalidate,formtarget,headers,` + `height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,` + `ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,` + `manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,` + `open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,` + `referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,` + `selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,` + `start,step,style,summary,tabindex,target,title,translate,type,usemap,` + `value,width,wrap`); function normalizeStyle(value) { if (isArray(value)) { const res = {}; for (let i = 0; i < value.length; i++) { const item = value[i]; const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item); if (normalized) { for (const key in normalized) { res[key] = normalized[key]; } } } return res; } else if (isObject(value)) { return value; } } const listDelimiterRE = /;(?![^(]*\))/g; const propertyDelimiterRE = /:(.+)/; function parseStringStyle(cssText) { const ret = {}; cssText.split(listDelimiterRE).forEach(item => { if (item) { const tmp = item.split(propertyDelimiterRE); tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); } }); return ret; } function stringifyStyle(styles) { let ret = ''; if (!styles) { return ret; } for (const key in styles) { const value = styles[key]; const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); if (isString(value) || (typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))) { // only render valid values ret += `${normalizedKey}:${value};`; } } return ret; } function normalizeClass(value) { let res = ''; if (isString(value)) { res = value; } else if (isArray(value)) { for (let i = 0; i < value.length; i++) { res += normalizeClass(value[i]) + ' '; } } else if (isObject(value)) { for (const name in value) { if (value[name]) { res += name + ' '; } } } return res.trim(); } // These tag configs are shared between compiler-dom and runtime-dom, so they // https://developer.mozilla.org/en-US/docs/Web/HTML/Element const HTML_TAGS = 'html,body,base,head,link,meta,style,title,address,article,aside,footer,' + 'header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,' + 'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' + 'data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,' + 'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' + 'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' + 'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' + 'option,output,progress,select,textarea,details,dialog,menu,' + 'summary,template,blockquote,iframe,tfoot'; // https://developer.mozilla.org/en-US/docs/Web/SVG/Element const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,' + 'defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,' + 'feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,' + 'feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,' + 'feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,' + 'fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,' + 'foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,' + 'mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,' + 'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' + 'text,textPath,title,tspan,unknown,use,view'; const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr'; const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS); const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS); const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS); const escapeRE = /["'&<>]/; function escapeHtml(string) { const str = '' + string; const match = escapeRE.exec(str); if (!match) { return str; } let html = ''; let escaped; let index; let lastIndex = 0; for (index = match.index; index < str.length; index++) { switch (str.charCodeAt(index)) { case 34: // " escaped = '"'; break; case 38: // & escaped = '&'; break; case 39: // ' escaped = '''; break; case 60: // < escaped = '<'; break; case 62: // > escaped = '>'; break; default: continue; } if (lastIndex !== index) { html += str.substring(lastIndex, index); } lastIndex = index + 1; html += escaped; } return lastIndex !== index ? html + str.substring(lastIndex, index) : html; } // https://www.w3.org/TR/html52/syntax.html#comments const commentStripRE = /^-?>||--!>| looseEqual(item, val)); } /** * For converting {{ interpolation }} values to displayed strings. * @private */ const toDisplayString = (val) => { return val == null ? '' : isObject(val) ? JSON.stringify(val, replacer, 2) : String(val); }; const replacer = (_key, val) => { if (val instanceof Map) { return { [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val]) => { entries[`${key} =>`] = val; return entries; }, {}) }; } else if (val instanceof Set) { return { [`Set(${val.size})`]: [...val.values()] }; } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { return String(val); } return val; }; /** * List of @babel/parser plugins that are used for template expression * transforms and SFC script transforms. By default we enable proposals slated * for ES2020. This will need to be updated as the spec moves forward. * Full list at https://babeljs.io/docs/en/next/babel-parser#plugins */ const babelParserDefaultPlugins = [ 'bigInt', 'optionalChaining', 'nullishCoalescingOperator' ]; const EMPTY_OBJ = ( false) ? undefined : {}; const EMPTY_ARR = []; const NOOP = () => { }; /** * Always return false. */ const NO = () => false; const onRE = /^on[^a-z]/; const isOn = (key) => onRE.test(key); const isModelListener = (key) => key.startsWith('onUpdate:'); const extend = Object.assign; const remove = (arr, el) => { const i = arr.indexOf(el); if (i > -1) { arr.splice(i, 1); } }; const hasOwnProperty = Object.prototype.hasOwnProperty; const hasOwn = (val, key) => hasOwnProperty.call(val, key); const isArray = Array.isArray; const isDate = (val) => val instanceof Date; const isFunction = (val) => typeof val === 'function'; const isString = (val) => typeof val === 'string'; const isSymbol = (val) => typeof val === 'symbol'; const isObject = (val) => val !== null && typeof val === 'object'; const isPromise = (val) => { return isObject(val) && isFunction(val.then) && isFunction(val.catch); }; const objectToString = Object.prototype.toString; const toTypeString = (value) => objectToString.call(value); const toRawType = (value) => { return toTypeString(value).slice(8, -1); }; const isPlainObject = (val) => toTypeString(val) === '[object Object]'; const isIntegerKey = (key) => isString(key) && key[0] !== '-' && '' + parseInt(key, 10) === key; const isReservedProp = /*#__PURE__*/ makeMap('key,ref,' + 'onVnodeBeforeMount,onVnodeMounted,' + 'onVnodeBeforeUpdate,onVnodeUpdated,' + 'onVnodeBeforeUnmount,onVnodeUnmounted'); const cacheStringFunction = (fn) => { const cache = Object.create(null); return ((str) => { const hit = cache[str]; return hit || (cache[str] = fn(str)); }); }; const camelizeRE = /-(\w)/g; /** * @private */ const camelize = cacheStringFunction((str) => { return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')); }); const hyphenateRE = /\B([A-Z])/g; /** * @private */ const hyphenate = cacheStringFunction((str) => { return str.replace(hyphenateRE, '-$1').toLowerCase(); }); /** * @private */ const capitalize = cacheStringFunction((str) => { return str.charAt(0).toUpperCase() + str.slice(1); }); // compare whether a value has changed, accounting for NaN. const hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue); const invokeArrayFns = (fns, arg) => { for (let i = 0; i < fns.length; i++) { fns[i](arg); } }; const def = (obj, key, value) => { Object.defineProperty(obj, key, { configurable: true, enumerable: false, value }); }; const toNumber = (val) => { const n = parseFloat(val); return isNaN(n) ? val : n; }; let _globalThis; const getGlobalThis = () => { return (_globalThis || (_globalThis = typeof globalThis !== 'undefined' ? globalThis : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {})); }; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(13))) /***/ }), /* 1 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return HtmlTag; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return SvelteComponent; }); /* unused harmony export SvelteComponentDev */ /* unused harmony export SvelteElement */ /* unused harmony export action_destroyer */ /* unused harmony export add_attribute */ /* unused harmony export add_classes */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return add_flush_callback; }); /* unused harmony export add_location */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return add_render_callback; }); /* unused harmony export add_resize_listener */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return add_transform; }); /* unused harmony export afterUpdate */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return append; }); /* unused harmony export append_dev */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return assign; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return attr; }); /* unused harmony export attr_dev */ /* unused harmony export beforeUpdate */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return bind; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return binding_callbacks; }); /* unused harmony export blank_object */ /* unused harmony export bubble */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "k", function() { return check_outros; }); /* unused harmony export children */ /* unused harmony export claim_component */ /* unused harmony export claim_element */ /* unused harmony export claim_space */ /* unused harmony export claim_text */ /* unused harmony export clear_loops */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return component_subscribe; }); /* unused harmony export compute_rest_props */ /* unused harmony export compute_slots */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "m", function() { return createEventDispatcher; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return create_animation; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "o", function() { return create_bidirectional_transition; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "p", function() { return create_component; }); /* unused harmony export create_in_transition */ /* unused harmony export create_out_transition */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "q", function() { return create_slot; }); /* unused harmony export create_ssr_component */ /* unused harmony export current_component */ /* unused harmony export custom_event */ /* unused harmony export dataset_dev */ /* unused harmony export debug */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "r", function() { return destroy_block; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "s", function() { return destroy_component; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "t", function() { return destroy_each; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "u", function() { return detach; }); /* unused harmony export detach_after_dev */ /* unused harmony export detach_before_dev */ /* unused harmony export detach_between_dev */ /* unused harmony export detach_dev */ /* unused harmony export dirty_components */ /* unused harmony export dispatch_dev */ /* unused harmony export each */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "v", function() { return element; }); /* unused harmony export element_is */ /* unused harmony export empty */ /* unused harmony export escape */ /* unused harmony export escaped */ /* unused harmony export exclude_internal_props */ /* unused harmony export fix_and_destroy_block */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "w", function() { return fix_and_outro_and_destroy_block; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "x", function() { return fix_position; }); /* unused harmony export flush */ /* unused harmony export getContext */ /* unused harmony export get_binding_group_value */ /* unused harmony export get_current_component */ /* unused harmony export get_slot_changes */ /* unused harmony export get_slot_context */ /* unused harmony export get_spread_object */ /* unused harmony export get_spread_update */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "y", function() { return get_store_value; }); /* unused harmony export globals */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "z", function() { return group_outros; }); /* unused harmony export handle_promise */ /* unused harmony export has_prop */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "A", function() { return identity; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "B", function() { return init; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "C", function() { return insert; }); /* unused harmony export insert_dev */ /* unused harmony export intros */ /* unused harmony export invalid_attribute_name_character */ /* unused harmony export is_client */ /* unused harmony export is_crossorigin */ /* unused harmony export is_empty */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "D", function() { return is_function; }); /* unused harmony export is_promise */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "E", function() { return listen; }); /* unused harmony export listen_dev */ /* unused harmony export loop */ /* unused harmony export loop_guard */ /* unused harmony export missing_component */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "F", function() { return mount_component; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "G", function() { return noop; }); /* unused harmony export not_equal */ /* unused harmony export now */ /* unused harmony export null_to_empty */ /* unused harmony export object_without_properties */ /* unused harmony export onDestroy */ /* unused harmony export onMount */ /* unused harmony export once */ /* unused harmony export outro_and_destroy_block */ /* unused harmony export prevent_default */ /* unused harmony export prop_dev */ /* unused harmony export query_selector_all */ /* unused harmony export raf */ /* unused harmony export run */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "H", function() { return run_all; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "I", function() { return safe_not_equal; }); /* unused harmony export schedule_update */ /* unused harmony export select_multiple_value */ /* unused harmony export select_option */ /* unused harmony export select_options */ /* unused harmony export select_value */ /* unused harmony export self */ /* unused harmony export setContext */ /* unused harmony export set_attributes */ /* unused harmony export set_current_component */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "J", function() { return set_custom_element_data; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "K", function() { return set_data; }); /* unused harmony export set_data_dev */ /* unused harmony export set_input_type */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "L", function() { return set_input_value; }); /* unused harmony export set_now */ /* unused harmony export set_raf */ /* unused harmony export set_store_value */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "M", function() { return set_style; }); /* unused harmony export set_svg_attributes */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "N", function() { return space; }); /* unused harmony export spread */ /* unused harmony export stop_propagation */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "O", function() { return subscribe; }); /* unused harmony export svg_element */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "P", function() { return text; }); /* unused harmony export tick */ /* unused harmony export time_ranges_to_array */ /* unused harmony export to_number */ /* unused harmony export toggle_class */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Q", function() { return transition_in; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "R", function() { return transition_out; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "S", function() { return update_keyed_each; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "T", function() { return update_slot; }); /* unused harmony export validate_component */ /* unused harmony export validate_each_argument */ /* unused harmony export validate_each_keys */ /* unused harmony export validate_slots */ /* unused harmony export validate_store */ /* unused harmony export xlink_attr */ function noop() { } const identity = x => x; function assign(tar, src) { // @ts-ignore for (const k in src) tar[k] = src[k]; return tar; } function is_promise(value) { return value && typeof value === 'object' && typeof value.then === 'function'; } function add_location(element, file, line, column, char) { element.__svelte_meta = { loc: { file, line, column, char } }; } function run(fn) { return fn(); } function blank_object() { return Object.create(null); } function run_all(fns) { fns.forEach(run); } function is_function(thing) { return typeof thing === 'function'; } function safe_not_equal(a, b) { return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); } function not_equal(a, b) { return a != a ? b == b : a !== b; } function is_empty(obj) { return Object.keys(obj).length === 0; } function validate_store(store, name) { if (store != null && typeof store.subscribe !== 'function') { throw new Error(`'${name}' is not a store with a 'subscribe' method`); } } function subscribe(store, ...callbacks) { if (store == null) { return noop; } const unsub = store.subscribe(...callbacks); return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub; } function get_store_value(store) { let value; subscribe(store, _ => value = _)(); return value; } function component_subscribe(component, store, callback) { component.$$.on_destroy.push(subscribe(store, callback)); } function create_slot(definition, ctx, $$scope, fn) { if (definition) { const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); return definition[0](slot_ctx); } } function get_slot_context(definition, ctx, $$scope, fn) { return definition[1] && fn ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) : $$scope.ctx; } function get_slot_changes(definition, $$scope, dirty, fn) { if (definition[2] && fn) { const lets = definition[2](fn(dirty)); if ($$scope.dirty === undefined) { return lets; } if (typeof lets === 'object') { const merged = []; const len = Math.max($$scope.dirty.length, lets.length); for (let i = 0; i < len; i += 1) { merged[i] = $$scope.dirty[i] | lets[i]; } return merged; } return $$scope.dirty | lets; } return $$scope.dirty; } function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) { const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn); if (slot_changes) { const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn); slot.p(slot_context, slot_changes); } } function exclude_internal_props(props) { const result = {}; for (const k in props) if (k[0] !== '$') result[k] = props[k]; return result; } function compute_rest_props(props, keys) { const rest = {}; keys = new Set(keys); for (const k in props) if (!keys.has(k) && k[0] !== '$') rest[k] = props[k]; return rest; } function compute_slots(slots) { const result = {}; for (const key in slots) { result[key] = true; } return result; } function once(fn) { let ran = false; return function (...args) { if (ran) return; ran = true; fn.call(this, ...args); }; } function null_to_empty(value) { return value == null ? '' : value; } function set_store_value(store, ret, value = ret) { store.set(value); return ret; } const has_prop = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); function action_destroyer(action_result) { return action_result && is_function(action_result.destroy) ? action_result.destroy : noop; } const is_client = typeof window !== 'undefined'; let now = is_client ? () => window.performance.now() : () => Date.now(); let raf = is_client ? cb => requestAnimationFrame(cb) : noop; // used internally for testing function set_now(fn) { now = fn; } function set_raf(fn) { raf = fn; } const tasks = new Set(); function run_tasks(now) { tasks.forEach(task => { if (!task.c(now)) { tasks.delete(task); task.f(); } }); if (tasks.size !== 0) raf(run_tasks); } /** * For testing purposes only! */ function clear_loops() { tasks.clear(); } /** * Creates a new task that runs on each raf frame * until it returns a falsy value or is aborted */ function loop(callback) { let task; if (tasks.size === 0) raf(run_tasks); return { promise: new Promise(fulfill => { tasks.add(task = { c: callback, f: fulfill }); }), abort() { tasks.delete(task); } }; } function append(target, node) { target.appendChild(node); } function insert(target, node, anchor) { target.insertBefore(node, anchor || null); } function detach(node) { node.parentNode.removeChild(node); } function destroy_each(iterations, detaching) { for (let i = 0; i < iterations.length; i += 1) { if (iterations[i]) iterations[i].d(detaching); } } function element(name) { return document.createElement(name); } function element_is(name, is) { return document.createElement(name, { is }); } function object_without_properties(obj, exclude) { const target = {}; for (const k in obj) { if (has_prop(obj, k) // @ts-ignore && exclude.indexOf(k) === -1) { // @ts-ignore target[k] = obj[k]; } } return target; } function svg_element(name) { return document.createElementNS('http://www.w3.org/2000/svg', name); } function text(data) { return document.createTextNode(data); } function space() { return text(' '); } function empty() { return text(''); } function listen(node, event, handler, options) { node.addEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options); } function prevent_default(fn) { return function (event) { event.preventDefault(); // @ts-ignore return fn.call(this, event); }; } function stop_propagation(fn) { return function (event) { event.stopPropagation(); // @ts-ignore return fn.call(this, event); }; } function self(fn) { return function (event) { // @ts-ignore if (event.target === this) fn.call(this, event); }; } function attr(node, attribute, value) { if (value == null) node.removeAttribute(attribute); else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value); } function set_attributes(node, attributes) { // @ts-ignore const descriptors = Object.getOwnPropertyDescriptors(node.__proto__); for (const key in attributes) { if (attributes[key] == null) { node.removeAttribute(key); } else if (key === 'style') { node.style.cssText = attributes[key]; } else if (key === '__value') { node.value = node[key] = attributes[key]; } else if (descriptors[key] && descriptors[key].set) { node[key] = attributes[key]; } else { attr(node, key, attributes[key]); } } } function set_svg_attributes(node, attributes) { for (const key in attributes) { attr(node, key, attributes[key]); } } function set_custom_element_data(node, prop, value) { if (prop in node) { node[prop] = value; } else { attr(node, prop, value); } } function xlink_attr(node, attribute, value) { node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value); } function get_binding_group_value(group, __value, checked) { const value = new Set(); for (let i = 0; i < group.length; i += 1) { if (group[i].checked) value.add(group[i].__value); } if (!checked) { value.delete(__value); } return Array.from(value); } function to_number(value) { return value === '' ? null : +value; } function time_ranges_to_array(ranges) { const array = []; for (let i = 0; i < ranges.length; i += 1) { array.push({ start: ranges.start(i), end: ranges.end(i) }); } return array; } function children(element) { return Array.from(element.childNodes); } function claim_element(nodes, name, attributes, svg) { for (let i = 0; i < nodes.length; i += 1) { const node = nodes[i]; if (node.nodeName === name) { let j = 0; const remove = []; while (j < node.attributes.length) { const attribute = node.attributes[j++]; if (!attributes[attribute.name]) { remove.push(attribute.name); } } for (let k = 0; k < remove.length; k++) { node.removeAttribute(remove[k]); } return nodes.splice(i, 1)[0]; } } return svg ? svg_element(name) : element(name); } function claim_text(nodes, data) { for (let i = 0; i < nodes.length; i += 1) { const node = nodes[i]; if (node.nodeType === 3) { node.data = '' + data; return nodes.splice(i, 1)[0]; } } return text(data); } function claim_space(nodes) { return claim_text(nodes, ' '); } function set_data(text, data) { data = '' + data; if (text.wholeText !== data) text.data = data; } function set_input_value(input, value) { input.value = value == null ? '' : value; } function set_input_type(input, type) { try { input.type = type; } catch (e) { // do nothing } } function set_style(node, key, value, important) { node.style.setProperty(key, value, important ? 'important' : ''); } function select_option(select, value) { for (let i = 0; i < select.options.length; i += 1) { const option = select.options[i]; if (option.__value === value) { option.selected = true; return; } } } function select_options(select, value) { for (let i = 0; i < select.options.length; i += 1) { const option = select.options[i]; option.selected = ~value.indexOf(option.__value); } } function select_value(select) { const selected_option = select.querySelector(':checked') || select.options[0]; return selected_option && selected_option.__value; } function select_multiple_value(select) { return [].map.call(select.querySelectorAll(':checked'), option => option.__value); } // unfortunately this can't be a constant as that wouldn't be tree-shakeable // so we cache the result instead let crossorigin; function is_crossorigin() { if (crossorigin === undefined) { crossorigin = false; try { if (typeof window !== 'undefined' && window.parent) { void window.parent.document; } } catch (error) { crossorigin = true; } } return crossorigin; } function add_resize_listener(node, fn) { const computed_style = getComputedStyle(node); const z_index = (parseInt(computed_style.zIndex) || 0) - 1; if (computed_style.position === 'static') { node.style.position = 'relative'; } const iframe = element('iframe'); iframe.setAttribute('style', `display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ` + `overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: ${z_index};`); iframe.setAttribute('aria-hidden', 'true'); iframe.tabIndex = -1; const crossorigin = is_crossorigin(); let unsubscribe; if (crossorigin) { iframe.src = `data:text/html,`; unsubscribe = listen(window, 'message', (event) => { if (event.source === iframe.contentWindow) fn(); }); } else { iframe.src = 'about:blank'; iframe.onload = () => { unsubscribe = listen(iframe.contentWindow, 'resize', fn); }; } append(node, iframe); return () => { if (crossorigin) { unsubscribe(); } else if (unsubscribe && iframe.contentWindow) { unsubscribe(); } detach(iframe); }; } function toggle_class(element, name, toggle) { element.classList[toggle ? 'add' : 'remove'](name); } function custom_event(type, detail) { const e = document.createEvent('CustomEvent'); e.initCustomEvent(type, false, false, detail); return e; } function query_selector_all(selector, parent = document.body) { return Array.from(parent.querySelectorAll(selector)); } class HtmlTag { constructor(anchor = null) { this.a = anchor; this.e = this.n = null; } m(html, target, anchor = null) { if (!this.e) { this.e = element(target.nodeName); this.t = target; this.h(html); } this.i(anchor); } h(html) { this.e.innerHTML = html; this.n = Array.from(this.e.childNodes); } i(anchor) { for (let i = 0; i < this.n.length; i += 1) { insert(this.t, this.n[i], anchor); } } p(html) { this.d(); this.h(html); this.i(this.a); } d() { this.n.forEach(detach); } } const active_docs = new Set(); let active = 0; // https://github.com/darkskyapp/string-hash/blob/master/index.js function hash(str) { let hash = 5381; let i = str.length; while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); return hash >>> 0; } function create_rule(node, a, b, duration, delay, ease, fn, uid = 0) { const step = 16.666 / duration; let keyframes = '{\n'; for (let p = 0; p <= 1; p += step) { const t = a + (b - a) * ease(p); keyframes += p * 100 + `%{${fn(t, 1 - t)}}\n`; } const rule = keyframes + `100% {${fn(b, 1 - b)}}\n}`; const name = `__svelte_${hash(rule)}_${uid}`; const doc = node.ownerDocument; active_docs.add(doc); const stylesheet = doc.__svelte_stylesheet || (doc.__svelte_stylesheet = doc.head.appendChild(element('style')).sheet); const current_rules = doc.__svelte_rules || (doc.__svelte_rules = {}); if (!current_rules[name]) { current_rules[name] = true; stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length); } const animation = node.style.animation || ''; node.style.animation = `${animation ? `${animation}, ` : ``}${name} ${duration}ms linear ${delay}ms 1 both`; active += 1; return name; } function delete_rule(node, name) { const previous = (node.style.animation || '').split(', '); const next = previous.filter(name ? anim => anim.indexOf(name) < 0 // remove specific animation : anim => anim.indexOf('__svelte') === -1 // remove all Svelte animations ); const deleted = previous.length - next.length; if (deleted) { node.style.animation = next.join(', '); active -= deleted; if (!active) clear_rules(); } } function clear_rules() { raf(() => { if (active) return; active_docs.forEach(doc => { const stylesheet = doc.__svelte_stylesheet; let i = stylesheet.cssRules.length; while (i--) stylesheet.deleteRule(i); doc.__svelte_rules = {}; }); active_docs.clear(); }); } function create_animation(node, from, fn, params) { if (!from) return noop; const to = node.getBoundingClientRect(); if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) return noop; const { delay = 0, duration = 300, easing = identity, // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation? start: start_time = now() + delay, // @ts-ignore todo: end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params); let running = true; let started = false; let name; function start() { if (css) { name = create_rule(node, 0, 1, duration, delay, easing, css); } if (!delay) { started = true; } } function stop() { if (css) delete_rule(node, name); running = false; } loop(now => { if (!started && now >= start_time) { started = true; } if (started && now >= end) { tick(1, 0); stop(); } if (!running) { return false; } if (started) { const p = now - start_time; const t = 0 + 1 * easing(p / duration); tick(t, 1 - t); } return true; }); start(); tick(0, 1); return stop; } function fix_position(node) { const style = getComputedStyle(node); if (style.position !== 'absolute' && style.position !== 'fixed') { const { width, height } = style; const a = node.getBoundingClientRect(); node.style.position = 'absolute'; node.style.width = width; node.style.height = height; add_transform(node, a); } } function add_transform(node, a) { const b = node.getBoundingClientRect(); if (a.left !== b.left || a.top !== b.top) { const style = getComputedStyle(node); const transform = style.transform === 'none' ? '' : style.transform; node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`; } } let current_component; function set_current_component(component) { current_component = component; } function get_current_component() { if (!current_component) throw new Error(`Function called outside component initialization`); return current_component; } function beforeUpdate(fn) { get_current_component().$$.before_update.push(fn); } function onMount(fn) { get_current_component().$$.on_mount.push(fn); } function afterUpdate(fn) { get_current_component().$$.after_update.push(fn); } function onDestroy(fn) { get_current_component().$$.on_destroy.push(fn); } function createEventDispatcher() { const component = get_current_component(); return (type, detail) => { const callbacks = component.$$.callbacks[type]; if (callbacks) { // TODO are there situations where events could be dispatched // in a server (non-DOM) environment? const event = custom_event(type, detail); callbacks.slice().forEach(fn => { fn.call(component, event); }); } }; } function setContext(key, context) { get_current_component().$$.context.set(key, context); } function getContext(key) { return get_current_component().$$.context.get(key); } // TODO figure out if we still want to support // shorthand events, or if we want to implement // a real bubbling mechanism function bubble(component, event) { const callbacks = component.$$.callbacks[event.type]; if (callbacks) { callbacks.slice().forEach(fn => fn(event)); } } const dirty_components = []; const intros = { enabled: false }; const binding_callbacks = []; const render_callbacks = []; const flush_callbacks = []; const resolved_promise = Promise.resolve(); let update_scheduled = false; function schedule_update() { if (!update_scheduled) { update_scheduled = true; resolved_promise.then(flush); } } function tick() { schedule_update(); return resolved_promise; } function add_render_callback(fn) { render_callbacks.push(fn); } function add_flush_callback(fn) { flush_callbacks.push(fn); } let flushing = false; const seen_callbacks = new Set(); function flush() { if (flushing) return; flushing = true; do { // first, call beforeUpdate functions // and update components for (let i = 0; i < dirty_components.length; i += 1) { const component = dirty_components[i]; set_current_component(component); update(component.$$); } set_current_component(null); dirty_components.length = 0; while (binding_callbacks.length) binding_callbacks.pop()(); // then, once components are updated, call // afterUpdate functions. This may cause // subsequent updates... for (let i = 0; i < render_callbacks.length; i += 1) { const callback = render_callbacks[i]; if (!seen_callbacks.has(callback)) { // ...so guard against infinite loops seen_callbacks.add(callback); callback(); } } render_callbacks.length = 0; } while (dirty_components.length); while (flush_callbacks.length) { flush_callbacks.pop()(); } update_scheduled = false; flushing = false; seen_callbacks.clear(); } function update($$) { if ($$.fragment !== null) { $$.update(); run_all($$.before_update); const dirty = $$.dirty; $$.dirty = [-1]; $$.fragment && $$.fragment.p($$.ctx, dirty); $$.after_update.forEach(add_render_callback); } } let promise; function wait() { if (!promise) { promise = Promise.resolve(); promise.then(() => { promise = null; }); } return promise; } function dispatch(node, direction, kind) { node.dispatchEvent(custom_event(`${direction ? 'intro' : 'outro'}${kind}`)); } const outroing = new Set(); let outros; function group_outros() { outros = { r: 0, c: [], p: outros // parent group }; } function check_outros() { if (!outros.r) { run_all(outros.c); } outros = outros.p; } function transition_in(block, local) { if (block && block.i) { outroing.delete(block); block.i(local); } } function transition_out(block, local, detach, callback) { if (block && block.o) { if (outroing.has(block)) return; outroing.add(block); outros.c.push(() => { outroing.delete(block); if (callback) { if (detach) block.d(1); callback(); } }); block.o(local); } } const null_transition = { duration: 0 }; function create_in_transition(node, fn, params) { let config = fn(node, params); let running = false; let animation_name; let task; let uid = 0; function cleanup() { if (animation_name) delete_rule(node, animation_name); } function go() { const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition; if (css) animation_name = create_rule(node, 0, 1, duration, delay, easing, css, uid++); tick(0, 1); const start_time = now() + delay; const end_time = start_time + duration; if (task) task.abort(); running = true; add_render_callback(() => dispatch(node, true, 'start')); task = loop(now => { if (running) { if (now >= end_time) { tick(1, 0); dispatch(node, true, 'end'); cleanup(); return running = false; } if (now >= start_time) { const t = easing((now - start_time) / duration); tick(t, 1 - t); } } return running; }); } let started = false; return { start() { if (started) return; delete_rule(node); if (is_function(config)) { config = config(); wait().then(go); } else { go(); } }, invalidate() { started = false; }, end() { if (running) { cleanup(); running = false; } } }; } function create_out_transition(node, fn, params) { let config = fn(node, params); let running = true; let animation_name; const group = outros; group.r += 1; function go() { const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition; if (css) animation_name = create_rule(node, 1, 0, duration, delay, easing, css); const start_time = now() + delay; const end_time = start_time + duration; add_render_callback(() => dispatch(node, false, 'start')); loop(now => { if (running) { if (now >= end_time) { tick(0, 1); dispatch(node, false, 'end'); if (!--group.r) { // this will result in `end()` being called, // so we don't need to clean up here run_all(group.c); } return false; } if (now >= start_time) { const t = easing((now - start_time) / duration); tick(1 - t, t); } } return running; }); } if (is_function(config)) { wait().then(() => { // @ts-ignore config = config(); go(); }); } else { go(); } return { end(reset) { if (reset && config.tick) { config.tick(1, 0); } if (running) { if (animation_name) delete_rule(node, animation_name); running = false; } } }; } function create_bidirectional_transition(node, fn, params, intro) { let config = fn(node, params); let t = intro ? 0 : 1; let running_program = null; let pending_program = null; let animation_name = null; function clear_animation() { if (animation_name) delete_rule(node, animation_name); } function init(program, duration) { const d = program.b - t; duration *= Math.abs(d); return { a: t, b: program.b, d, duration, start: program.start, end: program.start + duration, group: program.group }; } function go(b) { const { delay = 0, duration = 300, easing = identity, tick = noop, css } = config || null_transition; const program = { start: now() + delay, b }; if (!b) { // @ts-ignore todo: improve typings program.group = outros; outros.r += 1; } if (running_program) { pending_program = program; } else { // if this is an intro, and there's a delay, we need to do // an initial tick and/or apply CSS animation immediately if (css) { clear_animation(); animation_name = create_rule(node, t, b, duration, delay, easing, css); } if (b) tick(0, 1); running_program = init(program, duration); add_render_callback(() => dispatch(node, b, 'start')); loop(now => { if (pending_program && now > pending_program.start) { running_program = init(pending_program, duration); pending_program = null; dispatch(node, running_program.b, 'start'); if (css) { clear_animation(); animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css); } } if (running_program) { if (now >= running_program.end) { tick(t = running_program.b, 1 - t); dispatch(node, running_program.b, 'end'); if (!pending_program) { // we're done if (running_program.b) { // intro — we can tidy up immediately clear_animation(); } else { // outro — needs to be coordinated if (!--running_program.group.r) run_all(running_program.group.c); } } running_program = null; } else if (now >= running_program.start) { const p = now - running_program.start; t = running_program.a + running_program.d * easing(p / running_program.duration); tick(t, 1 - t); } } return !!(running_program || pending_program); }); } } return { run(b) { if (is_function(config)) { wait().then(() => { // @ts-ignore config = config(); go(b); }); } else { go(b); } }, end() { clear_animation(); running_program = pending_program = null; } }; } function handle_promise(promise, info) { const token = info.token = {}; function update(type, index, key, value) { if (info.token !== token) return; info.resolved = value; let child_ctx = info.ctx; if (key !== undefined) { child_ctx = child_ctx.slice(); child_ctx[key] = value; } const block = type && (info.current = type)(child_ctx); let needs_flush = false; if (info.block) { if (info.blocks) { info.blocks.forEach((block, i) => { if (i !== index && block) { group_outros(); transition_out(block, 1, 1, () => { info.blocks[i] = null; }); check_outros(); } }); } else { info.block.d(1); } block.c(); transition_in(block, 1); block.m(info.mount(), info.anchor); needs_flush = true; } info.block = block; if (info.blocks) info.blocks[index] = block; if (needs_flush) { flush(); } } if (is_promise(promise)) { const current_component = get_current_component(); promise.then(value => { set_current_component(current_component); update(info.then, 1, info.value, value); set_current_component(null); }, error => { if (!info.hasCatch) { throw error; } set_current_component(current_component); update(info.catch, 2, info.error, error); set_current_component(null); }); // if we previously had a then/catch block, destroy it if (info.current !== info.pending) { update(info.pending, 0); return true; } } else { if (info.current !== info.then) { update(info.then, 1, info.value, promise); return true; } info.resolved = promise; } } const globals = (typeof window !== 'undefined' ? window : typeof globalThis !== 'undefined' ? globalThis : global); function destroy_block(block, lookup) { block.d(1); lookup.delete(block.key); } function outro_and_destroy_block(block, lookup) { transition_out(block, 1, 1, () => { lookup.delete(block.key); }); } function fix_and_destroy_block(block, lookup) { block.f(); destroy_block(block, lookup); } function fix_and_outro_and_destroy_block(block, lookup) { block.f(); outro_and_destroy_block(block, lookup); } function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) { let o = old_blocks.length; let n = list.length; let i = o; const old_indexes = {}; while (i--) old_indexes[old_blocks[i].key] = i; const new_blocks = []; const new_lookup = new Map(); const deltas = new Map(); i = n; while (i--) { const child_ctx = get_context(ctx, list, i); const key = get_key(child_ctx); let block = lookup.get(key); if (!block) { block = create_each_block(key, child_ctx); block.c(); } else if (dynamic) { block.p(child_ctx, dirty); } new_lookup.set(key, new_blocks[i] = block); if (key in old_indexes) deltas.set(key, Math.abs(i - old_indexes[key])); } const will_move = new Set(); const did_move = new Set(); function insert(block) { transition_in(block, 1); block.m(node, next); lookup.set(block.key, block); next = block.first; n--; } while (o && n) { const new_block = new_blocks[n - 1]; const old_block = old_blocks[o - 1]; const new_key = new_block.key; const old_key = old_block.key; if (new_block === old_block) { // do nothing next = new_block.first; o--; n--; } else if (!new_lookup.has(old_key)) { // remove old block destroy(old_block, lookup); o--; } else if (!lookup.has(new_key) || will_move.has(new_key)) { insert(new_block); } else if (did_move.has(old_key)) { o--; } else if (deltas.get(new_key) > deltas.get(old_key)) { did_move.add(new_key); insert(new_block); } else { will_move.add(old_key); o--; } } while (o--) { const old_block = old_blocks[o]; if (!new_lookup.has(old_block.key)) destroy(old_block, lookup); } while (n) insert(new_blocks[n - 1]); return new_blocks; } function validate_each_keys(ctx, list, get_context, get_key) { const keys = new Set(); for (let i = 0; i < list.length; i++) { const key = get_key(get_context(ctx, list, i)); if (keys.has(key)) { throw new Error(`Cannot have duplicate keys in a keyed each`); } keys.add(key); } } function get_spread_update(levels, updates) { const update = {}; const to_null_out = {}; const accounted_for = { $$scope: 1 }; let i = levels.length; while (i--) { const o = levels[i]; const n = updates[i]; if (n) { for (const key in o) { if (!(key in n)) to_null_out[key] = 1; } for (const key in n) { if (!accounted_for[key]) { update[key] = n[key]; accounted_for[key] = 1; } } levels[i] = n; } else { for (const key in o) { accounted_for[key] = 1; } } } for (const key in to_null_out) { if (!(key in update)) update[key] = undefined; } return update; } function get_spread_object(spread_props) { return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; } // source: https://html.spec.whatwg.org/multipage/indices.html const boolean_attributes = new Set([ 'allowfullscreen', 'allowpaymentrequest', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected' ]); const invalid_attribute_name_character = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u; // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 // https://infra.spec.whatwg.org/#noncharacter function spread(args, classes_to_add) { const attributes = Object.assign({}, ...args); if (classes_to_add) { if (attributes.class == null) { attributes.class = classes_to_add; } else { attributes.class += ' ' + classes_to_add; } } let str = ''; Object.keys(attributes).forEach(name => { if (invalid_attribute_name_character.test(name)) return; const value = attributes[name]; if (value === true) str += " " + name; else if (boolean_attributes.has(name.toLowerCase())) { if (value) str += " " + name; } else if (value != null) { str += ` ${name}="${String(value).replace(/"/g, '"').replace(/'/g, ''')}"`; } }); return str; } const escaped = { '"': '"', "'": ''', '&': '&', '<': '<', '>': '>' }; function escape(html) { return String(html).replace(/["'&<>]/g, match => escaped[match]); } function each(items, fn) { let str = ''; for (let i = 0; i < items.length; i += 1) { str += fn(items[i], i); } return str; } const missing_component = { $$render: () => '' }; function validate_component(component, name) { if (!component || !component.$$render) { if (name === 'svelte:component') name += ' this={...}'; throw new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`); } return component; } function debug(file, line, column, values) { console.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`); // eslint-disable-line no-console console.log(values); // eslint-disable-line no-console return ''; } let on_destroy; function create_ssr_component(fn) { function $$render(result, props, bindings, slots) { const parent_component = current_component; const $$ = { on_destroy, context: new Map(parent_component ? parent_component.$$.context : []), // these will be immediately discarded on_mount: [], before_update: [], after_update: [], callbacks: blank_object() }; set_current_component({ $$ }); const html = fn(result, props, bindings, slots); set_current_component(parent_component); return html; } return { render: (props = {}, options = {}) => { on_destroy = []; const result = { title: '', head: '', css: new Set() }; const html = $$render(result, props, {}, options); run_all(on_destroy); return { html, css: { code: Array.from(result.css).map(css => css.code).join('\n'), map: null // TODO }, head: result.title + result.head }; }, $$render }; } function add_attribute(name, value, boolean) { if (value == null || (boolean && !value)) return ''; return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `"${value}"`}`}`; } function add_classes(classes) { return classes ? ` class="${classes}"` : ``; } function bind(component, name, callback) { const index = component.$$.props[name]; if (index !== undefined) { component.$$.bound[index] = callback; callback(component.$$.ctx[index]); } } function create_component(block) { block && block.c(); } function claim_component(block, parent_nodes) { block && block.l(parent_nodes); } function mount_component(component, target, anchor) { const { fragment, on_mount, on_destroy, after_update } = component.$$; fragment && fragment.m(target, anchor); // onMount happens before the initial afterUpdate add_render_callback(() => { const new_on_destroy = on_mount.map(run).filter(is_function); if (on_destroy) { on_destroy.push(...new_on_destroy); } else { // Edge case - component was destroyed immediately, // most likely as a result of a binding initialising run_all(new_on_destroy); } component.$$.on_mount = []; }); after_update.forEach(add_render_callback); } function destroy_component(component, detaching) { const $$ = component.$$; if ($$.fragment !== null) { run_all($$.on_destroy); $$.fragment && $$.fragment.d(detaching); // TODO null out other refs, including component.$$ (but need to // preserve final state?) $$.on_destroy = $$.fragment = null; $$.ctx = []; } } function make_dirty(component, i) { if (component.$$.dirty[0] === -1) { dirty_components.push(component); schedule_update(); component.$$.dirty.fill(0); } component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); } function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) { const parent_component = current_component; set_current_component(component); const prop_values = options.props || {}; const $$ = component.$$ = { fragment: null, ctx: null, // state props, update: noop, not_equal, bound: blank_object(), // lifecycle on_mount: [], on_destroy: [], before_update: [], after_update: [], context: new Map(parent_component ? parent_component.$$.context : []), // everything else callbacks: blank_object(), dirty, skip_bound: false }; let ready = false; $$.ctx = instance ? instance(component, prop_values, (i, ret, ...rest) => { const value = rest.length ? rest[0] : ret; if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { if (!$$.skip_bound && $$.bound[i]) $$.bound[i](value); if (ready) make_dirty(component, i); } return ret; }) : []; $$.update(); ready = true; run_all($$.before_update); // `false` as a special case of no DOM component $$.fragment = create_fragment ? create_fragment($$.ctx) : false; if (options.target) { if (options.hydrate) { const nodes = children(options.target); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion $$.fragment && $$.fragment.l(nodes); nodes.forEach(detach); } else { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion $$.fragment && $$.fragment.c(); } if (options.intro) transition_in(component.$$.fragment); mount_component(component, options.target, options.anchor); flush(); } set_current_component(parent_component); } let SvelteElement; if (typeof HTMLElement === 'function') { SvelteElement = class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { // @ts-ignore todo: improve typings for (const key in this.$$.slotted) { // @ts-ignore todo: improve typings this.appendChild(this.$$.slotted[key]); } } attributeChangedCallback(attr, _oldValue, newValue) { this[attr] = newValue; } $destroy() { destroy_component(this, 1); this.$destroy = noop; } $on(type, callback) { // TODO should this delegate to addEventListener? const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); if (index !== -1) callbacks.splice(index, 1); }; } $set($$props) { if (this.$$set && !is_empty($$props)) { this.$$.skip_bound = true; this.$$set($$props); this.$$.skip_bound = false; } } }; } class SvelteComponent { $destroy() { destroy_component(this, 1); this.$destroy = noop; } $on(type, callback) { const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); callbacks.push(callback); return () => { const index = callbacks.indexOf(callback); if (index !== -1) callbacks.splice(index, 1); }; } $set($$props) { if (this.$$set && !is_empty($$props)) { this.$$.skip_bound = true; this.$$set($$props); this.$$.skip_bound = false; } } } function dispatch_dev(type, detail) { document.dispatchEvent(custom_event(type, Object.assign({ version: '3.25.0' }, detail))); } function append_dev(target, node) { dispatch_dev("SvelteDOMInsert", { target, node }); append(target, node); } function insert_dev(target, node, anchor) { dispatch_dev("SvelteDOMInsert", { target, node, anchor }); insert(target, node, anchor); } function detach_dev(node) { dispatch_dev("SvelteDOMRemove", { node }); detach(node); } function detach_between_dev(before, after) { while (before.nextSibling && before.nextSibling !== after) { detach_dev(before.nextSibling); } } function detach_before_dev(after) { while (after.previousSibling) { detach_dev(after.previousSibling); } } function detach_after_dev(before) { while (before.nextSibling) { detach_dev(before.nextSibling); } } function listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) { const modifiers = options === true ? ["capture"] : options ? Array.from(Object.keys(options)) : []; if (has_prevent_default) modifiers.push('preventDefault'); if (has_stop_propagation) modifiers.push('stopPropagation'); dispatch_dev("SvelteDOMAddEventListener", { node, event, handler, modifiers }); const dispose = listen(node, event, handler, options); return () => { dispatch_dev("SvelteDOMRemoveEventListener", { node, event, handler, modifiers }); dispose(); }; } function attr_dev(node, attribute, value) { attr(node, attribute, value); if (value == null) dispatch_dev("SvelteDOMRemoveAttribute", { node, attribute }); else dispatch_dev("SvelteDOMSetAttribute", { node, attribute, value }); } function prop_dev(node, property, value) { node[property] = value; dispatch_dev("SvelteDOMSetProperty", { node, property, value }); } function dataset_dev(node, property, value) { node.dataset[property] = value; dispatch_dev("SvelteDOMSetDataset", { node, property, value }); } function set_data_dev(text, data) { data = '' + data; if (text.wholeText === data) return; dispatch_dev("SvelteDOMSetData", { node: text, data }); text.data = data; } function validate_each_argument(arg) { if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) { let msg = '{#each} only iterates over array-like objects.'; if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) { msg += ' You can use a spread to convert this iterable into an array.'; } throw new Error(msg); } } function validate_slots(name, slot, keys) { for (const slot_key of Object.keys(slot)) { if (!~keys.indexOf(slot_key)) { console.warn(`<${name}> received an unexpected slot "${slot_key}".`); } } } class SvelteComponentDev extends SvelteComponent { constructor(options) { if (!options || (!options.target && !options.$$inline)) { throw new Error(`'target' is a required option`); } super(); } $destroy() { super.$destroy(); this.$destroy = () => { console.warn(`Component was already destroyed`); // eslint-disable-line no-console }; } $capture_state() { } $inject_state() { } } function loop_guard(timeout) { const start = Date.now(); return () => { if (Date.now() - start > timeout) { throw new Error(`Infinite loop detected`); } }; } /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(13))) /***/ }), /* 2 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return isDev; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return elementEdit; }); /* unused harmony export config */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return AllStoreName; }); /* harmony import */ var svelte_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10); /** 是不是开发环境 */ const isDev = window.__llej__userjs__dev__ === true; /** 是否开启编辑 */ const elementEdit = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* writable */ "c"])(false); const config = Object(vue__WEBPACK_IMPORTED_MODULE_1__[/* reactive */ "a"])({ state: 0, /** 是否开启编辑 */ elementEdit: isDev, /** 服务器地址 */ serverIp: "https://shenzilong.cn/note/", /** 页面的url */ locationUrl: decodeURIComponent(location.origin + location.pathname), /** 存储登录凭证的 */ loginCredentials: "loginCredentials" }); Object(vue__WEBPACK_IMPORTED_MODULE_1__[/* watchEffect */ "b"])(() => { /** 同步是否开启编辑的状态给 writable */ elementEdit.set(config.elementEdit); }); /** 存储命令栈的地方 */ const AllStoreName = "_storeName_llej_" + config.locationUrl; /* harmony default export */ __webpack_exports__["b"] = (config); /***/ }), /* 3 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export Command */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return deleteSelect; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return editSelect; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return closeEditSelect; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return addNote; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return Highlighted; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CommandControl; }); /* harmony import */ var _ui_message__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7); /* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var _state_store__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); /* harmony import */ var svelte_store__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6); /* harmony import */ var _state_highlighted_style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(12); /* harmony import */ var _lib_store__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8); /** 每一个命令都应该实现的东西 */ class Command { constructor( /** 命令执行的元素 */ select) { this.selectEL = select; } /** 执行这个命令 */ do() { return this; } /** 撤销这个命令 */ undo() { return this; } /** 重新执行命令 */ redo() { return this.do(); } /** 将命令变成可以转化为json字符串的对象 */ toJSON() { return { selectEL: Object(_util__WEBPACK_IMPORTED_MODULE_1__[/* getSelectors */ "d"])(this.selectEL), constructor: this.__proto__.constructor.name }; } /** 用于可以使用 toJSON 生成的数据重建功能效果 */ static 重建(obj) { return new this(document.querySelector(obj.selectEL)); } /** 加载commandJSON转变为命令,通过泛型来构造对象的方式 */ static load(obj, CLASS) { return CLASS.重建(obj); } } /** 删除一个元素 */ class deleteSelect extends Command { do() { this.selectEL_display = this.selectEL.style.display; this.selectEL.style.display = "none"; return this; } undo() { this.selectEL.style.display = this.selectEL_display; return this; } } /** 使元素可编辑 */ class editSelect extends Command { do() { this.selectEL_contentEditable = this.selectEL.contentEditable; this.selectEL.contentEditable = "true"; return this; } undo() { this.selectEL.contentEditable = this.selectEL_contentEditable; return this; } } /** 使元素不可编辑 */ class closeEditSelect extends Command { do() { this.selectEL_contentEditable = this.selectEL.contentEditable; this.selectEL.contentEditable = "false"; return this; } undo() { this.selectEL.contentEditable = this.selectEL_contentEditable; return this; } } /** 新增一个笔记 */ class addNote extends Command { do() { this.selectEL; _state_store__WEBPACK_IMPORTED_MODULE_2__[/* note_list_store */ "a"].update(list => { list.push({ point: this.selectEL, content: "6666666" }); return list; }); return this; } undo() { return this; } redo() { return this; } } /** 高亮功能 */ class Highlighted extends Command { constructor(styleText) { super(); this.styleText = styleText; /** css 类名 */ this.className = `llej-page_notes-style-${_lib_store__WEBPACK_IMPORTED_MODULE_5__[/* curStore */ "a"].Highlighted_count++}`; } do() { _state_highlighted_style__WEBPACK_IMPORTED_MODULE_4__[/* styleList */ "a"].update(r => { return [...r, this.getRawStyleText()]; }); return this; } getRawStyleText() { return ` .${this.className}{ ${this.styleText} } `; } undo() { _state_highlighted_style__WEBPACK_IMPORTED_MODULE_4__[/* styleList */ "a"].update(r => { return r.filter(el => el !== this.getRawStyleText()); }); return this; } static 重建(obj) { const r = new this(obj.styleText); r.className = obj.className; return r; } toJSON() { return { selectEL: "", className: this.className, styleText: this.styleText, constructor: this.__proto__.constructor.name }; } } /** 命令控制器 */ const CommandControl = { commandStack: [], backOutStack: [], pushCommand(command) { return this.commandStack.push(command); }, run(command) { try { this.backOutStack.splice(0, this.backOutStack.length); return this.pushCommand(command.do()); } catch (error) { console.error("命令执行失败", command, error); } return -1; }, backOut() { if (this.commandStack.length === 0) { _ui_message__WEBPACK_IMPORTED_MODULE_0__[/* Message */ "a"].getMessage({ msg: "命令栈已空,无法进行撤销" }).autoHide(); return; } const command = this.commandStack.pop(); return this.backOutStack.push(command.undo()); }, reform() { if (this.backOutStack.length === 0) { _ui_message__WEBPACK_IMPORTED_MODULE_0__[/* Message */ "a"].getMessage({ msg: "撤销栈已空,无法进行重做" }).autoHide(); return; } const command = this.backOutStack.pop(); return this.commandStack.push(command.redo()); }, /** 从json重建命令栈 */ loadCommandJSON(obj) { Object(_util__WEBPACK_IMPORTED_MODULE_1__[/* log */ "e"])("-执行命令-", obj.constructor); if (obj.constructor === "deleteSelect") return Command.load(obj, deleteSelect); if (obj.constructor === "editSelect") return Command.load(obj, editSelect); if (obj.constructor === "closeEditSelect") return Command.load(obj, closeEditSelect); if (obj.constructor === "addNote") return Command.load(obj, addNote); if (obj.constructor === "Highlighted") return Command.load(obj, Highlighted); }, getCommandStackJSON() { return JSON.stringify(this.commandStack); }, loadCommandJsonAndRun(commandJSON) { commandJSON.map(this.loadCommandJSON).forEach(command => this.run(command)); return true; } }; /***/ }), /* 4 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* unused harmony export copyTitle */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return getSelectors; }); /* unused harmony export getIndex */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return nodePath; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return getJSon; }); /* unused harmony export ajax_get */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return log; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return SelectionEvent; }); /* unused harmony export getWindow */ /* harmony import */ var svelte_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); /* harmony import */ var _fun_command__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); /* harmony import */ var _state__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); /** 用于复制文本的input */ const input_copy = document.createElement("textarea"); input_copy.id = "__"; input_copy.style.display = "none"; //不能设置为none因为会导致没有可访问性 input_copy.setAttribute("style", ` position: absolute; top: -9999px; left: -9999px;`); document.body.appendChild(input_copy); /** 复制一个元素的titil 或者一段字符串到剪贴板 */ function copyTitle(el) { let title; if (typeof el === "string") title = el;else title = el.getAttribute("title"); input_copy.setAttribute("readonly", "readonly"); input_copy.setAttribute("value", title); input_copy.value = title; input_copy.select(); input_copy.setSelectionRange(0, 9999); document.execCommand("copy"); } /** 工具类 */ /* harmony default export */ __webpack_exports__["b"] = ({ copyTitle }); /** 获取一个元素的选择器 */ function getSelectors(el) { /** 通过path路径来确定元素 */ let pathSelectors = nodePath(el).reverse().map(el => { return el.nodeName + `:nth-child(${getIndex(el)})`; }).join(">"); /** 通过id以及class来确定元素 */ let id_className = ""; const id = el.id; if (id) id_className += `#${id}`; Array.from(el.classList) /** 排除自定义类名 */ .filter(el => el.includes("_llej_")).forEach(className => { id_className += `.${className}`; }); /** nth-child 选择 看它是第几个元素 */ const index = getIndex(el); /** 最终构造出来的选择器 */ return `${pathSelectors}${id_className}:nth-child(${index})`; } /** 获取元素它在第几位 */ function getIndex(el) { if (el.nodeName === "HTML") return 1; if (el.parentElement === null) { return 1; } return 1 + Array.from(el.parentElement.children).findIndex(child => child === el); } /** 获取一个元素的所有父节点到html为止 */ function nodePath(...path) { while (path[path.length - 1].parentElement != null) { path.push(path[path.length - 1].parentElement); } /** 只需要是HTMLElement的 */ const HTMLElementPath = path.filter(el => el instanceof HTMLElement); return HTMLElementPath; } async function getJSon(url, data) { const str = await ajax_get(url, data); const res = JSON.parse(str); console.log(url, data, res); return res; } /** 油猴的ajaxget */ function ajax_get(url, data) { if (data) url += "?" + jsonToURLpar(data); if (window.hasOwnProperty("GM") && window.hasOwnProperty("GM")) return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: "GET", url, onload: function (response) { resolve(response.responseText); }, onerror: reject }); });else return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.addEventListener("load", function () { resolve(xhr.responseText); }); xhr.addEventListener("error", reject); xhr.open("get", url); xhr.send(); }); } /** json 转 urlpar 只能转一层 */ function jsonToURLpar(json) { return Object.keys(json).map(function (key) { return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]); }).join("&"); } /** 开发时的调试log */ function log(...arg) { if (_config__WEBPACK_IMPORTED_MODULE_1__[/* isDev */ "d"]) console.log(`[dev] `, ...arg); } /** 用户选中事件 */ var SelectionEvent; (function (SelectionEvent) { /** 表示用户选中的对象,唯一的。不用每次去获取 */ const s = window.getSelection(); /** 是否处于 range 的选中状态 */ SelectionEvent.isRange = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* writable */ "c"])(false); /** 选区开始位置的元素的 rect */ SelectionEvent.anchorRect = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* derived */ "a"])(SelectionEvent.isRange, $isRange => { if (!$isRange) return; const node = s.anchorNode; const el = node instanceof Element ? node : node.parentElement; const rect = el.getBoundingClientRect(); return rect; }); function 高亮(options = {}) { const h = new _fun_command__WEBPACK_IMPORTED_MODULE_2__[/* Highlighted */ "b"](options.style); _fun_command__WEBPACK_IMPORTED_MODULE_2__[/* CommandControl */ "a"].run(h); const className = h.className; const tagName = "span"; let 选中的所有节点 = []; if ( /** 跨元素了 */ s.anchorNode !== s.focusNode) { const startRange = s.getRangeAt(0); const endRange = s.getRangeAt(s.rangeCount - 1); let startNode = startRange.startContainer; let endNode = endRange.endContainer; let cur = startNode; if (cur instanceof Text) { const s = startRange; const t2 = cur.splitText(s.startOffset); const t3 = t2.nextSibling; const wrap = document.createElement(tagName); wrap.appendChild(t2); cur.parentNode.insertBefore(wrap, t3); } cur = endNode; if (cur instanceof Text) { const s = endRange; const t2 = cur.splitText(s.endOffset); const wrap = document.createElement(tagName); wrap.appendChild(cur); t2.parentNode.insertBefore(wrap, t2); endNode = t2; } 选中的所有节点 = getIntermediateNodes(startNode, endNode); } else { /** 单元素类 */ const cur = s.anchorNode; if (cur instanceof Text) { const t2 = cur.splitText(s.anchorOffset); const t3 = t2.splitText(s.focusOffset); 选中的所有节点.push(t2); } else { 选中的所有节点.push(cur); } } console.log("选中的所有节点", 选中的所有节点); 选中的所有节点.forEach(node => { let el; if (node instanceof Element) { el = node; } else { /** 对纯文本节点进行包装,因为纯文本节点无法附加样式等属性 */ const wrap = document.createElement(tagName); const t2 = node.nextSibling; const parent = node.parentNode; wrap.appendChild(node); parent.insertBefore(wrap, t2); el = wrap; } el.classList.add(className); }); /** 这些元素被添加了类名,甚至被包裹了一层。属于被污染的元素,直接标记他们的父亲 */ const 共存层 = getIntermediateNodes.寻找共存层(...选中的所有节点); // console.log("[共存层]", 共存层); let parent = 共存层[0].parentElement; /** 避免标记的是不够大的元素,实际上也是因为寻找元素的方法不够好否则也用不着这个 */ while (parent.className.includes("llej-page_notes-style")) { parent = parent.parentElement; } _state__WEBPACK_IMPORTED_MODULE_3__[/* editElement */ "b"].add(parent); } SelectionEvent.高亮 = 高亮; document.addEventListener("selectionchange", () => { SelectionEvent.isRange.set(s.type === "Range"); }); })(SelectionEvent || (SelectionEvent = {})); function getIntermediateNodes(a, b) { return getIntermediateNodes.获取两元素之间的元素(a, b); } (function (getIntermediateNodes) { function 寻找共存层(...args) { if (args.length === 1) { return args; } const parentList = args.map(el => 获取父链路(el).reverse()).sort((a, b) => { return a.length - b.length; }); const 最短链路 = parentList[0]; for (let i = 0; i < 最短链路.length; i++) { const element = 最短链路[i]; const 此层是否全相似 = parentList.map(el => el[i]).every(el => el === element); if (此层是否全相似 === false) { return Array.from(最短链路[i - 1].childNodes); } } } getIntermediateNodes.寻找共存层 = 寻找共存层; /** 越接近node的元素越在前面 */ function 获取父链路(node) { const list = []; list.push(node); let cur = node; while (cur.parentNode) { list.push(cur.parentNode); cur = cur.parentNode; } return list; } getIntermediateNodes.获取父链路 = 获取父链路; function 后面的兄弟元素(node) { const list = []; let cur = node; while (cur.nextSibling) { list.push(cur.nextSibling); cur = cur.nextSibling; } return list; } getIntermediateNodes.后面的兄弟元素 = 后面的兄弟元素; function 前面的兄弟元素(node) { const list = []; let cur = node; while (cur.previousSibling) { list.push(cur.previousSibling); cur = cur.previousSibling; } return list; } getIntermediateNodes.前面的兄弟元素 = 前面的兄弟元素; function 获取两元素之间的元素(a, b) { const list = []; const aParentList = 获取父链路(a).reverse(); const bParentList = 获取父链路(b).reverse(); /** 找出 a 与 b 在共存层的父元素 */ const 短链路 = aParentList.length > bParentList.length ? bParentList : aParentList; let n1 = 短链路[0]; let n2 = 短链路[0]; for (let i = 0; i < 短链路.length; i++) { n1 = aParentList[i]; n2 = bParentList[i]; if (n1 !== n2) { break; } } /** 获取共存层中间的元素 */ let cur = n1.nextSibling; while (cur !== n2 && cur.nextSibling !== null) { list.push(cur); cur = cur.nextSibling; } /** 判断 a 是否在 b前面 */ cur = n1; let n1在前 = false; while (cur.nextSibling) { if (n2 === cur) { n1在前 = true; break; } cur = cur.nextSibling; } const [pre, next] = n1在前 ? [a, b] : [b, a]; const 共存层 = 寻找共存层(a, b); cur = pre; while (!共存层.includes(cur)) { list.push(...后面的兄弟元素(cur)); cur = cur.parentNode; } cur = next; while (!共存层.includes(cur)) { list.push(...前面的兄弟元素(cur)); cur = cur.parentNode; } return list; } getIntermediateNodes.获取两元素之间的元素 = 获取两元素之间的元素; })(getIntermediateNodes || (getIntermediateNodes = {})); function getWindow() { return typeof unsafeWindow === "undefined" ? window : unsafeWindow; } /***/ }), /* 5 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, "a", function() { return /* binding */ currentElement; }); __webpack_require__.d(__webpack_exports__, "c", function() { return /* binding */ setPath; }); __webpack_require__.d(__webpack_exports__, "b", function() { return /* binding */ editElement; }); // UNUSED EXPORTS: path // CONCATENATED MODULE: ./网页笔记/state/remote.state.ts // // Firebase App (the core Firebase SDK) is always required and // // must be listed before other Firebase SDKs // import * as firebase from "firebase/app"; // // Add the Firebase services that you want to use // import "firebase/auth"; // import "firebase/firestore"; // firebase.initializeApp({ // apiKey: "AIzaSyCXy6_GwVogqPwZyJj-KPXIb-JfQaW-MTY", // authDomain: "llej-2e851.firebaseapp.com", // databaseURL: "https://llej-2e851.firebaseio.com", // projectId: "llej-2e851", // storageBucket: "llej-2e851.appspot.com", // messagingSenderId: "419799122852", // appId: "1:419799122852:web:36ddb23180314a8b987731", // measurementId: "G-SN42ESZX78", // }); const fireStore = {}; // /** 监听用户状态改变 */ // // firebase.auth().onAuthStateChanged(function (user) { // // if (user) { // // console.log("[登录成功]", user.email); // // } // // }); // // firebase // // .auth() // // .signInWithEmailAndPassword("admin@shenzilong.cn", "987456321") // // .catch(function (error) { // // // Handle Errors here. // // var errorCode = error.code; // // var errorMessage = error.message; // // // ... // // }); // CONCATENATED MODULE: ./网页笔记/state/index.ts /** 当前被选中的元素 */ let currentElement; let path; /** 修改当前指向的元素和路径 */ function setPath(elList) { path = elList; currentElement = elList[0]; } /** 标记被修改后的元素(被污染了的元素),以便保存修改的内容 */ const editElement = new Set(); // const globalSettingRef = fireStore.doc("setting/global"); // globalSettingRef.onSnapshot({ // next(r) { // console.log("[ r]", r.data()); // }, // }); // globalSettingRef.update({ // test: 3, // }); // globalSettingRef // // .doc("samples/sandwichData") // .get() // .then((r) => {}); /***/ }), /* 6 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return derived; }); /* unused harmony export readable */ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return writable; }); /* harmony import */ var _internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "b", function() { return _internal__WEBPACK_IMPORTED_MODULE_0__["y"]; }); const subscriber_queue = []; /** * Creates a `Readable` store that allows reading by subscription. * @param value initial value * @param {StartStopNotifier}start start and stop notifications for subscriptions */ function readable(value, start) { return { subscribe: writable(value, start).subscribe }; } /** * Create a `Writable` store that allows both updating and reading by subscription. * @param {*=}value initial value * @param {StartStopNotifier=}start start and stop notifications for subscriptions */ function writable(value, start = _internal__WEBPACK_IMPORTED_MODULE_0__[/* noop */ "G"]) { let stop; const subscribers = []; function set(new_value) { if (Object(_internal__WEBPACK_IMPORTED_MODULE_0__[/* safe_not_equal */ "I"])(value, new_value)) { value = new_value; if (stop) { // store is ready const run_queue = !subscriber_queue.length; for (let i = 0; i < subscribers.length; i += 1) { const s = subscribers[i]; s[1](); subscriber_queue.push(s, value); } if (run_queue) { for (let i = 0; i < subscriber_queue.length; i += 2) { subscriber_queue[i][0](subscriber_queue[i + 1]); } subscriber_queue.length = 0; } } } } function update(fn) { set(fn(value)); } function subscribe(run, invalidate = _internal__WEBPACK_IMPORTED_MODULE_0__[/* noop */ "G"]) { const subscriber = [run, invalidate]; subscribers.push(subscriber); if (subscribers.length === 1) { stop = start(set) || _internal__WEBPACK_IMPORTED_MODULE_0__[/* noop */ "G"]; } run(value); return () => { const index = subscribers.indexOf(subscriber); if (index !== -1) { subscribers.splice(index, 1); } if (subscribers.length === 0) { stop(); stop = null; } }; } return { set, update, subscribe }; } function derived(stores, fn, initial_value) { const single = !Array.isArray(stores); const stores_array = single ? [stores] : stores; const auto = fn.length < 2; return readable(initial_value, (set) => { let inited = false; const values = []; let pending = 0; let cleanup = _internal__WEBPACK_IMPORTED_MODULE_0__[/* noop */ "G"]; const sync = () => { if (pending) { return; } cleanup(); const result = fn(single ? values[0] : values, set); if (auto) { set(result); } else { cleanup = Object(_internal__WEBPACK_IMPORTED_MODULE_0__[/* is_function */ "D"])(result) ? result : _internal__WEBPACK_IMPORTED_MODULE_0__[/* noop */ "G"]; } }; const unsubscribers = stores_array.map((store, i) => Object(_internal__WEBPACK_IMPORTED_MODULE_0__[/* subscribe */ "O"])(store, (value) => { values[i] = value; pending &= ~(1 << i); if (inited) { sync(); } }, () => { pending |= (1 << i); })); inited = true; sync(); return function stop() { Object(_internal__WEBPACK_IMPORTED_MODULE_0__[/* run_all */ "H"])(unsubscribers); cleanup(); }; }); } /***/ }), /* 7 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return messageList; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Message; }); /* harmony import */ var svelte_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /** 目前在呈现的消息列表 */ const messageList = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* writable */ "c"])([]); /** 消息的基类 扩展类记得重写 thatMessage 以免公用出现bug */ class Message { constructor(par) { this.par = par; /** 用来指向不同的类,以便扩展这个类的类的old_message不被公用 */ this.autoHideTime = 1000 * 3; } /** 展示el */ show() { messageList.update(r => [...r, this]); return this; } /** 隐藏el */ hide() { messageList.update(r => r.filter(el => this !== el)); return this; } /** 展示el autoHideTime 毫秒后隐藏*/ autoHide() { this.show(); setTimeout(() => { this.hide(); }, this.autoHideTime); return this; } /** 获取一个Message对象 */ static getMessage(par) { return new Message(par); } } /***/ }), /* 8 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return setLocalItem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return getLocalItem; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return curStore; }); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10); /* harmony import */ var _fun_fun__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9); /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2); /** 设置一条本地存储 */ async function setLocalItem(name, value) { //为了在非油猴环境下存储依旧能起一部分的作用 if (typeof unsafeWindow !== "undefined") { return await GM.setValue(name, value); } else { return await localStorage.setItem(name, String(value)); } } /** 读取一条本地存储 */ async function getLocalItem( /** 键名 */ name, /** 没有的时候的默认值 */ defaultValue) { if (typeof unsafeWindow !== "undefined") { const res = await GM.getValue(name, defaultValue); return res; } else { //为了在非油猴环境下存储依旧能起一部分的作用 const value = localStorage.getItem(name); if (value === null) return await defaultValue; return await value; } } const curStore = Object(vue__WEBPACK_IMPORTED_MODULE_0__[/* reactive */ "a"])({ CommandStack: [], element_List: {}, /** 用于记录高亮 id 避免新高亮出现重复 */ Highlighted_count: 0 }); getLocalItem(_config__WEBPACK_IMPORTED_MODULE_2__[/* AllStoreName */ "a"], "{}").then(s => { Object.assign(curStore, JSON.parse(s)); /** 自动加载本地暂存更改 */ (async () => { console.log(curStore); if (document.readyState === "complete") { Object(_fun_fun__WEBPACK_IMPORTED_MODULE_1__[/* loadChanges */ "a"])(curStore); } else { window.addEventListener("load", function () { Object(_fun_fun__WEBPACK_IMPORTED_MODULE_1__[/* loadChanges */ "a"])(curStore); }); } })(); }); /***/ }), /* 9 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, "e", function() { return /* binding */ saveChanges; }); __webpack_require__.d(__webpack_exports__, "a", function() { return /* binding */ loadChanges; }); __webpack_require__.d(__webpack_exports__, "d", function() { return /* binding */ on_mouse; }); __webpack_require__.d(__webpack_exports__, "c", function() { return /* binding */ on_keydown; }); __webpack_require__.d(__webpack_exports__, "b", function() { return /* binding */ on_input; }); // UNUSED EXPORTS: fun, KeyMap, outline, switchState // EXTERNAL MODULE: ./网页笔记/config.ts var config = __webpack_require__(2); // EXTERNAL MODULE: ./网页笔记/lib/store.ts var store = __webpack_require__(8); // EXTERNAL MODULE: ./网页笔记/ui/message.ts var message = __webpack_require__(7); // EXTERNAL MODULE: ./网页笔记/util.ts var util = __webpack_require__(4); // CONCATENATED MODULE: ./网页笔记/fun/ajax.ts /** 用来识别身份的key */ let key = ''; /** 附带登录信息的ajax */ async function au_getJSON(url, data) { if (data === undefined) data = {}; data.key = key ? key : await Object(store["b" /* getLocalItem */])(config["b" /* default */].loginCredentials); return Object(util["c" /* getJSon */])(url, data); } /** 登录 */ async function _login(par) { const res = await Object(util["c" /* getJSon */])(config["b" /* default */].serverIp + 'login', par); if (res.body && res.body.length > 0) key = res.body; Object(store["c" /* setLocalItem */])(config["b" /* default */].loginCredentials, key); return res; } /** 注册 */ async function remote_register(par) { return await Object(util["c" /* getJSon */])(config["b" /* default */].serverIp + 'register', par); } /** 获取存储库 */ async function remote_getStore(par) { return await au_getJSON(config["b" /* default */].serverIp + 'getStore', par); } /** 设置存储库 */ async function remote_setStore(par) { return await au_getJSON(config["b" /* default */].serverIp + 'setStore', par); } /** 获取存储库 */ async function remote_getAllStore() { return await au_getJSON(config["b" /* default */].serverIp + 'getAllStore'); } // EXTERNAL MODULE: ./网页笔记/fun/command.ts var command = __webpack_require__(3); // EXTERNAL MODULE: ./网页笔记/state/index.ts + 1 modules var state = __webpack_require__(5); // CONCATENATED MODULE: ./网页笔记/ui/style.ts class Style {} Style.message = ` border: 1px solid black; background-color: white; position: fixed; top: 20px; left: 30px; animation: llej_myfirst 5s; z-index:800; `; Style.warning = ` border: 1px solid black; background-color: red; position: fixed; top: 20px; left: 30px; z-index:800; `; Style.note = ` border: 1px solid black; background-color: #c6c5ba; position: sticky; top: 20px; left: 30px; width: auto; height: auto; z-index:800; `; /** 注入动画 */ const keyframes = document.createElement('style'); keyframes.innerHTML = ` @keyframes llej_myfirst { from { background: red;color:white; } to { background: yellow;color:black; } } `; document.head.appendChild(keyframes); // CONCATENATED MODULE: ./网页笔记/ui/warning.ts class warning_Warning extends message["a" /* Message */] { constructor({ msg }) { super({ msg, style: Style.warning }); } } // CONCATENATED MODULE: ./网页笔记/fun/fun.ts /** ════════════════════════🏳🌈 提供给用户使用的功能 🏳🌈════════════════════════ * ** ════════════════════════🚧 提供给用户使用的功能 🚧════════════════════════ */ const fun = { /** 使元素可编辑 */ editElement() { if (state["a" /* currentElement */].innerHTML.length > 10 * 1000) return new warning_Warning({ msg: "该元素内容过大,请选择更确定的文本元素。" }).autoHide(); command["a" /* CommandControl */].run(new command["f" /* editSelect */](state["a" /* currentElement */])); }, /** 删除元素 */ deleteElement() { command["a" /* CommandControl */].run(new command["e" /* deleteSelect */](state["a" /* currentElement */])); }, /** 复制title */ copyTitle() { util["b" /* default */].copyTitle(state["a" /* currentElement */]); }, /** 关闭可编辑 */ closeEdit() { command["a" /* CommandControl */].run(new command["d" /* closeEditSelect */](state["a" /* currentElement */])); }, /** 撤销 */ backOut() { command["a" /* CommandControl */].backOut(); }, /** 重做 */ undo() { command["a" /* CommandControl */].reform(); }, /** 新增笔记 */ addNote() { command["a" /* CommandControl */].run(new command["c" /* addNote */](state["a" /* currentElement */])); }, /** 保存所有的修改 */ saveChanges() { saveChanges(state["b" /* editElement */]); new message["a" /* Message */]({ msg: "保存成功" }).autoHide(); }, /** 将修改上传到云端 */ async uploadThe() { remote_setStore({ url: config["b" /* default */].locationUrl, store: await saveChanges(state["b" /* editElement */]) }).then(r => { new message["a" /* Message */]({ msg: "云端存储:" + r.message }).autoHide(); }); }, /** 从云端下载修改 */ downloadThe() { new message["a" /* Message */]({ msg: "正在读取云端存储" }).autoHide(); remote_getStore({ url: config["b" /* default */].locationUrl }).then(r => { if (r.body === undefined || r.body.length === 0) return new message["a" /* Message */]({ msg: "云端存储:" + r.message }).autoHide(); const allStore = JSON.parse(r.body[0].store); loadChanges(allStore); new message["a" /* Message */]({ msg: "云端存储:" + r.message }).autoHide(); }); }, /** 注册 */ register() { register(); }, /** 登录 */ login() { login(); } }; /** 按键和函数的映射关系 */ const KeyMap = { KeyQ: [fun.editElement], KeyD: [fun.deleteElement], KeyC: [fun.copyTitle], KeyW: [fun.closeEdit], KeyZ: [fun.backOut], KeyY: [fun.undo], KeyN: [fun.addNote], KeyS: [fun.saveChanges], KeyO: [fun.uploadThe], KeyP: [fun.downloadThe, fun.saveChanges], KeyK: [fun.register], KeyL: [fun.login] }; /** 保存修改 */ async function saveChanges(editElement) { const data = { element_List: {}, CommandStack: command["a" /* CommandControl */].commandStack }; /** 获取修改过的元素的html */ editElement.forEach(el => { const selectors = Object(util["d" /* getSelectors */])(el); data.element_List[selectors] = el.innerHTML; }); const data_str = JSON.stringify(Object.assign(store["a" /* curStore */], data)); await Object(store["c" /* setLocalItem */])(config["a" /* AllStoreName */], JSON.stringify(data)); return data_str; } /** 加载修改 */ async function loadChanges(allStore) { /** 将修改过的 html 写回去 */ for (const selectors in allStore.element_List) { const html = allStore.element_List[selectors]; const el = document.querySelector(selectors); if (el === null) { console.error(`${selectors} 的元素无法找到,无法重写`); } else { state["b" /* editElement */].add(el); el.innerHTML = html; Object(util["e" /* log */])("-重写-", el); } } /** 重新执行命令栈 */ command["a" /* CommandControl */].loadCommandJsonAndRun(allStore.CommandStack); } function login() { const title = ">>>网页笔记<<<\n"; const user = prompt(title + "请输入用户名"); if (user === null) return; const secret_key = prompt(title + "请输入密钥。"); if (secret_key === null) return; _login({ user, secret_key }).then(r => { new message["a" /* Message */]({ msg: r.message }).autoHide(); }); } function register() { const title = ">>>网页笔记<<<\n"; const user = prompt(title + "请输入用户名"); if (user === null) return; const secret_key = prompt(title + "请输入密钥。要记住哦,没有提供找回功能"); if (secret_key === null) return; remote_register({ user, secret_key }).then(r => { new message["a" /* Message */]({ msg: r.message }).autoHide(); }); } /** 轮廓线,用以显示当前元素 */ function outline(el) { el.classList.add("user_js_llej_outline"); setTimeout(reduction, 400); function reduction() { if (el == state["a" /* currentElement */]) { outline(el); /** 鼠标还在这个元素上,再等会 */ return; } el.classList.remove("user_js_llej_outline"); } } /** 监听鼠标移动 */ function on_mouse(event) { if (event.target instanceof HTMLElement) { Object(state["c" /* setPath */])(Object(util["f" /* nodePath */])(event.target)); if (config["b" /* default */].elementEdit) { outline(event.target); } } } /** 监测按键事件 */ async function on_keydown(event) { const code = event.code; //有元素获得焦点,视为正在输入文本,不执行指令 if (document.querySelector(":focus") || /** 如果目标元素是自定义组件的话上面这个还检测不了,需要检测 shadow 中是否存在焦点 */ event.target.shadowRoot && event.target.shadowRoot.querySelector(":focus")) { return; } /** 切换编辑模式 */ if (code === "F2" || code === "KeyM") { return switchState(event); } /** 没有开启编辑功能 */ if (config["b" /* default */].elementEdit === false) { return; } if (code in KeyMap) { /** 执行按键绑定的函数 */ const func_list = KeyMap[code]; Object(util["e" /* log */])(`[按下了] ${code},执行了:`, func_list.map(f => f.name)); func_list.forEach(func => { func(); }); } } /** 编辑事件 */ function on_input(event) { if (event.target instanceof HTMLElement) { const el = event.target; if (el.innerHTML.length > 10 * 1000) new warning_Warning({ msg: "该元素html内容过大,将不会保存这里的修改,请选择更确定的文本元素。" }).autoHide();else state["b" /* editElement */].add(el); } } /** 切换状态 */ function switchState(event) { config["b" /* default */].elementEdit = !config["b" /* default */].elementEdit; event.preventDefault(); event.returnValue = false; return false; } /***/ }), /* 10 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, "a", function() { return /* reexport */ reactive; }); __webpack_require__.d(__webpack_exports__, "b", function() { return /* reexport */ watchEffect; }); // UNUSED EXPORTS: customRef, isProxy, isReactive, isReadonly, isRef, markRaw, proxyRefs, readonly, ref, shallowReactive, shallowReadonly, shallowRef, toRaw, toRef, toRefs, triggerRef, unref, camelize, capitalize, toDisplayString, BaseTransition, Comment, Fragment, KeepAlive, Static, Suspense, Teleport, Text, callWithAsyncErrorHandling, callWithErrorHandling, cloneVNode, computed, createBlock, createCommentVNode, createHydrationRenderer, createRenderer, createSlots, createStaticVNode, createTextVNode, createVNode, defineAsyncComponent, defineComponent, devtools, getCurrentInstance, getTransitionRawChildren, h, handleError, inject, isVNode, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onUnmounted, onUpdated, openBlock, popScopeId, provide, pushScopeId, queuePostFlushCb, registerRuntimeCompiler, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, ssrContextKey, ssrUtils, toHandlers, transformVNodeArgs, useSSRContext, useTransitionState, version, warn, watch, withCtx, withDirectives, withScopeId, Transition, TransitionGroup, createApp, createSSRApp, hydrate, render, useCssModule, useCssVars, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, withKeys, withModifiers, compile // EXTERNAL MODULE: ./node_modules/@vue/shared/dist/shared.esm-bundler.js var shared_esm_bundler = __webpack_require__(0); // CONCATENATED MODULE: ./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js const targetMap = new WeakMap(); const effectStack = []; let activeEffect; const ITERATE_KEY = Symbol(( false) ? undefined : ''); const MAP_KEY_ITERATE_KEY = Symbol(( false) ? undefined : ''); function isEffect(fn) { return fn && fn._isEffect === true; } function reactivity_esm_bundler_effect(fn, options = shared_esm_bundler["b" /* EMPTY_OBJ */]) { if (isEffect(fn)) { fn = fn.raw; } const effect = createReactiveEffect(fn, options); if (!options.lazy) { effect(); } return effect; } function stop(effect) { if (effect.active) { reactivity_esm_bundler_cleanup(effect); if (effect.options.onStop) { effect.options.onStop(); } effect.active = false; } } let uid = 0; function createReactiveEffect(fn, options) { const effect = function reactiveEffect() { if (!effect.active) { return options.scheduler ? undefined : fn(); } if (!effectStack.includes(effect)) { reactivity_esm_bundler_cleanup(effect); try { enableTracking(); effectStack.push(effect); activeEffect = effect; return fn(); } finally { effectStack.pop(); resetTracking(); activeEffect = effectStack[effectStack.length - 1]; } } }; effect.id = uid++; effect._isEffect = true; effect.active = true; effect.raw = fn; effect.deps = []; effect.options = options; return effect; } function reactivity_esm_bundler_cleanup(effect) { const { deps } = effect; if (deps.length) { for (let i = 0; i < deps.length; i++) { deps[i].delete(effect); } deps.length = 0; } } let shouldTrack = true; const trackStack = []; function pauseTracking() { trackStack.push(shouldTrack); shouldTrack = false; } function enableTracking() { trackStack.push(shouldTrack); shouldTrack = true; } function resetTracking() { const last = trackStack.pop(); shouldTrack = last === undefined ? true : last; } function track(target, type, key) { if (!shouldTrack || activeEffect === undefined) { return; } let depsMap = targetMap.get(target); if (!depsMap) { targetMap.set(target, (depsMap = new Map())); } let dep = depsMap.get(key); if (!dep) { depsMap.set(key, (dep = new Set())); } if (!dep.has(activeEffect)) { dep.add(activeEffect); activeEffect.deps.push(dep); if (false) {} } } function trigger(target, type, key, newValue, oldValue, oldTarget) { const depsMap = targetMap.get(target); if (!depsMap) { // never been tracked return; } const effects = new Set(); const add = (effectsToAdd) => { if (effectsToAdd) { effectsToAdd.forEach(effect => { if (effect !== activeEffect) { effects.add(effect); } }); } }; if (type === "clear" /* CLEAR */) { // collection being cleared // trigger all effects for target depsMap.forEach(add); } else if (key === 'length' && Object(shared_esm_bundler["n" /* isArray */])(target)) { depsMap.forEach((dep, key) => { if (key === 'length' || key >= newValue) { add(dep); } }); } else { // schedule runs for SET | ADD | DELETE if (key !== void 0) { add(depsMap.get(key)); } // also run for iteration key on ADD | DELETE | Map.SET const shouldTriggerIteration = (type === "add" /* ADD */ && (!Object(shared_esm_bundler["n" /* isArray */])(target) || Object(shared_esm_bundler["r" /* isIntegerKey */])(key))) || (type === "delete" /* DELETE */ && !Object(shared_esm_bundler["n" /* isArray */])(target)); if (shouldTriggerIteration || (type === "set" /* SET */ && target instanceof Map)) { add(depsMap.get(Object(shared_esm_bundler["n" /* isArray */])(target) ? 'length' : ITERATE_KEY)); } if (shouldTriggerIteration && target instanceof Map) { add(depsMap.get(MAP_KEY_ITERATE_KEY)); } } const run = (effect) => { if (false) {} if (effect.options.scheduler) { effect.options.scheduler(effect); } else { effect(); } }; effects.forEach(run); } const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol) .map(key => Symbol[key]) .filter(shared_esm_bundler["A" /* isSymbol */])); const reactivity_esm_bundler_get = /*#__PURE__*/ createGetter(); const shallowGet = /*#__PURE__*/ createGetter(false, true); const readonlyGet = /*#__PURE__*/ createGetter(true); const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); const arrayInstrumentations = {}; ['includes', 'indexOf', 'lastIndexOf'].forEach(key => { arrayInstrumentations[key] = function (...args) { const arr = toRaw(this); for (let i = 0, l = this.length; i < l; i++) { track(arr, "get" /* GET */, i + ''); } // we run the method using the original args first (which may be reactive) const res = arr[key](...args); if (res === -1 || res === false) { // if that didn't work, run it again using raw values. return arr[key](...args.map(toRaw)); } else { return res; } }; }); function createGetter(isReadonly = false, shallow = false) { return function get(target, key, receiver) { if (key === "__v_isReactive" /* IS_REACTIVE */) { return !isReadonly; } else if (key === "__v_isReadonly" /* IS_READONLY */) { return isReadonly; } else if (key === "__v_raw" /* RAW */ && receiver === (isReadonly ? readonlyMap : reactiveMap).get(target)) { return target; } const targetIsArray = Object(shared_esm_bundler["n" /* isArray */])(target); if (targetIsArray && Object(shared_esm_bundler["k" /* hasOwn */])(arrayInstrumentations, key)) { return Reflect.get(arrayInstrumentations, key, receiver); } const res = Reflect.get(target, key, receiver); const keyIsSymbol = Object(shared_esm_bundler["A" /* isSymbol */])(key); if (keyIsSymbol ? builtInSymbols.has(key) : key === `__proto__` || key === `__v_isRef`) { return res; } if (!isReadonly) { track(target, "get" /* GET */, key); } if (shallow) { return res; } if (isRef(res)) { // ref unwrapping - does not apply for Array + integer key. const shouldUnwrap = !targetIsArray || !Object(shared_esm_bundler["r" /* isIntegerKey */])(key); return shouldUnwrap ? res.value : res; } if (Object(shared_esm_bundler["t" /* isObject */])(res)) { // Convert returned value into a proxy as well. we do the isObject check // here to avoid invalid value warning. Also need to lazy access readonly // and reactive here to avoid circular dependency. return isReadonly ? readonly(res) : reactive(res); } return res; }; } const reactivity_esm_bundler_set = /*#__PURE__*/ createSetter(); const shallowSet = /*#__PURE__*/ createSetter(true); function createSetter(shallow = false) { return function set(target, key, value, receiver) { const oldValue = target[key]; if (!shallow) { value = toRaw(value); if (!Object(shared_esm_bundler["n" /* isArray */])(target) && isRef(oldValue) && !isRef(value)) { oldValue.value = value; return true; } } const hadKey = Object(shared_esm_bundler["n" /* isArray */])(target) && Object(shared_esm_bundler["r" /* isIntegerKey */])(key) ? Number(key) < target.length : Object(shared_esm_bundler["k" /* hasOwn */])(target, key); const result = Reflect.set(target, key, value, receiver); // don't trigger if target is something up in the prototype chain of original if (target === toRaw(receiver)) { if (!hadKey) { trigger(target, "add" /* ADD */, key, value); } else if (Object(shared_esm_bundler["j" /* hasChanged */])(value, oldValue)) { trigger(target, "set" /* SET */, key, value, oldValue); } } return result; }; } function deleteProperty(target, key) { const hadKey = Object(shared_esm_bundler["k" /* hasOwn */])(target, key); const oldValue = target[key]; const result = Reflect.deleteProperty(target, key); if (result && hadKey) { trigger(target, "delete" /* DELETE */, key, undefined, oldValue); } return result; } function reactivity_esm_bundler_has(target, key) { const result = Reflect.has(target, key); if (!Object(shared_esm_bundler["A" /* isSymbol */])(key) || !builtInSymbols.has(key)) { track(target, "has" /* HAS */, key); } return result; } function ownKeys(target) { track(target, "iterate" /* ITERATE */, ITERATE_KEY); return Reflect.ownKeys(target); } const mutableHandlers = { get: reactivity_esm_bundler_get, set: reactivity_esm_bundler_set, deleteProperty, has: reactivity_esm_bundler_has, ownKeys }; const readonlyHandlers = { get: readonlyGet, set(target, key) { if ((false)) {} return true; }, deleteProperty(target, key) { if ((false)) {} return true; } }; const shallowReactiveHandlers = Object(shared_esm_bundler["h" /* extend */])({}, mutableHandlers, { get: shallowGet, set: shallowSet }); // Props handlers are special in the sense that it should not unwrap top-level // refs (in order to allow refs to be explicitly passed down), but should // retain the reactivity of the normal readonly object. const shallowReadonlyHandlers = Object(shared_esm_bundler["h" /* extend */])({}, readonlyHandlers, { get: shallowReadonlyGet }); const toReactive = (value) => Object(shared_esm_bundler["t" /* isObject */])(value) ? reactive(value) : value; const toReadonly = (value) => Object(shared_esm_bundler["t" /* isObject */])(value) ? readonly(value) : value; const toShallow = (value) => value; const getProto = (v) => Reflect.getPrototypeOf(v); function get$1(target, key, isReadonly = false, isShallow = false) { // #1772: readonly(reactive(Map)) should return readonly + reactive version // of the value target = target["__v_raw" /* RAW */]; const rawTarget = toRaw(target); const rawKey = toRaw(key); if (key !== rawKey) { !isReadonly && track(rawTarget, "get" /* GET */, key); } !isReadonly && track(rawTarget, "get" /* GET */, rawKey); const { has } = getProto(rawTarget); const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; if (has.call(rawTarget, key)) { return wrap(target.get(key)); } else if (has.call(rawTarget, rawKey)) { return wrap(target.get(rawKey)); } } function has$1(key, isReadonly = false) { const target = this["__v_raw" /* RAW */]; const rawTarget = toRaw(target); const rawKey = toRaw(key); if (key !== rawKey) { !isReadonly && track(rawTarget, "has" /* HAS */, key); } !isReadonly && track(rawTarget, "has" /* HAS */, rawKey); return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); } function size(target, isReadonly = false) { target = target["__v_raw" /* RAW */]; !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY); return Reflect.get(target, 'size', target); } function reactivity_esm_bundler_add(value) { value = toRaw(value); const target = toRaw(this); const proto = getProto(target); const hadKey = proto.has.call(target, value); const result = proto.add.call(target, value); if (!hadKey) { trigger(target, "add" /* ADD */, value, value); } return result; } function set$1(key, value) { value = toRaw(value); const target = toRaw(this); const { has, get, set } = getProto(target); let hadKey = has.call(target, key); if (!hadKey) { key = toRaw(key); hadKey = has.call(target, key); } else if ((false)) {} const oldValue = get.call(target, key); const result = set.call(target, key, value); if (!hadKey) { trigger(target, "add" /* ADD */, key, value); } else if (Object(shared_esm_bundler["j" /* hasChanged */])(value, oldValue)) { trigger(target, "set" /* SET */, key, value, oldValue); } return result; } function deleteEntry(key) { const target = toRaw(this); const { has, get, delete: del } = getProto(target); let hadKey = has.call(target, key); if (!hadKey) { key = toRaw(key); hadKey = has.call(target, key); } else if ((false)) {} const oldValue = get ? get.call(target, key) : undefined; // forward the operation before queueing reactions const result = del.call(target, key); if (hadKey) { trigger(target, "delete" /* DELETE */, key, undefined, oldValue); } return result; } function clear() { const target = toRaw(this); const hadItems = target.size !== 0; const oldTarget = ( false) ? undefined : undefined; // forward the operation before queueing reactions const result = getProto(target).clear.call(target); if (hadItems) { trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget); } return result; } function createForEach(isReadonly, isShallow) { return function forEach(callback, thisArg) { const observed = this; const target = observed["__v_raw" /* RAW */]; const rawTarget = toRaw(target); const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY); return target.forEach((value, key) => { // important: make sure the callback is // 1. invoked with the reactive map as `this` and 3rd arg // 2. the value received should be a corresponding reactive/readonly. return callback.call(thisArg, wrap(value), wrap(key), observed); }); }; } function createIterableMethod(method, isReadonly, isShallow) { return function (...args) { const target = this["__v_raw" /* RAW */]; const rawTarget = toRaw(target); const isMap = rawTarget instanceof Map; const isPair = method === 'entries' || (method === Symbol.iterator && isMap); const isKeyOnly = method === 'keys' && isMap; const innerIterator = target[method](...args); const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive; !isReadonly && track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); // return a wrapped iterator which returns observed versions of the // values emitted from the real iterator return { // iterator protocol next() { const { value, done } = innerIterator.next(); return done ? { value, done } : { value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), done }; }, // iterable protocol [Symbol.iterator]() { return this; } }; }; } function createReadonlyMethod(type) { return function (...args) { if ((false)) {} return type === "delete" /* DELETE */ ? false : this; }; } const mutableInstrumentations = { get(key) { return get$1(this, key); }, get size() { return size(this); }, has: has$1, add: reactivity_esm_bundler_add, set: set$1, delete: deleteEntry, clear, forEach: createForEach(false, false) }; const shallowInstrumentations = { get(key) { return get$1(this, key, false, true); }, get size() { return size(this); }, has: has$1, add: reactivity_esm_bundler_add, set: set$1, delete: deleteEntry, clear, forEach: createForEach(false, true) }; const readonlyInstrumentations = { get(key) { return get$1(this, key, true); }, get size() { return size(this, true); }, has(key) { return has$1.call(this, key, true); }, add: createReadonlyMethod("add" /* ADD */), set: createReadonlyMethod("set" /* SET */), delete: createReadonlyMethod("delete" /* DELETE */), clear: createReadonlyMethod("clear" /* CLEAR */), forEach: createForEach(true, false) }; const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; iteratorMethods.forEach(method => { mutableInstrumentations[method] = createIterableMethod(method, false, false); readonlyInstrumentations[method] = createIterableMethod(method, true, false); shallowInstrumentations[method] = createIterableMethod(method, false, true); }); function createInstrumentationGetter(isReadonly, shallow) { const instrumentations = shallow ? shallowInstrumentations : isReadonly ? readonlyInstrumentations : mutableInstrumentations; return (target, key, receiver) => { if (key === "__v_isReactive" /* IS_REACTIVE */) { return !isReadonly; } else if (key === "__v_isReadonly" /* IS_READONLY */) { return isReadonly; } else if (key === "__v_raw" /* RAW */) { return target; } return Reflect.get(Object(shared_esm_bundler["k" /* hasOwn */])(instrumentations, key) && key in target ? instrumentations : target, key, receiver); }; } const mutableCollectionHandlers = { get: createInstrumentationGetter(false, false) }; const shallowCollectionHandlers = { get: createInstrumentationGetter(false, true) }; const readonlyCollectionHandlers = { get: createInstrumentationGetter(true, false) }; function checkIdentityKeys(target, has, key) { const rawKey = toRaw(key); if (rawKey !== key && has.call(target, rawKey)) { const type = Object(shared_esm_bundler["I" /* toRawType */])(target); console.warn(`Reactive ${type} contains both the raw and reactive ` + `versions of the same object${type === `Map` ? `as keys` : ``}, ` + `which can lead to inconsistencies. ` + `Avoid differentiating between the raw and reactive versions ` + `of an object and only use the reactive version if possible.`); } } const reactiveMap = new WeakMap(); const readonlyMap = new WeakMap(); function targetTypeMap(rawType) { switch (rawType) { case 'Object': case 'Array': return 1 /* COMMON */; case 'Map': case 'Set': case 'WeakMap': case 'WeakSet': return 2 /* COLLECTION */; default: return 0 /* INVALID */; } } function getTargetType(value) { return value["__v_skip" /* SKIP */] || !Object.isExtensible(value) ? 0 /* INVALID */ : targetTypeMap(Object(shared_esm_bundler["I" /* toRawType */])(value)); } function reactive(target) { // if trying to observe a readonly proxy, return the readonly version. if (target && target["__v_isReadonly" /* IS_READONLY */]) { return target; } return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers); } // Return a reactive-copy of the original object, where only the root level // properties are reactive, and does NOT unwrap refs nor recursively convert // returned properties. function shallowReactive(target) { return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers); } function readonly(target) { return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers); } // Return a reactive-copy of the original object, where only the root level // properties are readonly, and does NOT unwrap refs nor recursively convert // returned properties. // This is used for creating the props proxy object for stateful components. function shallowReadonly(target) { return createReactiveObject(target, true, shallowReadonlyHandlers, readonlyCollectionHandlers); } function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers) { if (!Object(shared_esm_bundler["t" /* isObject */])(target)) { if ((false)) {} return target; } // target is already a Proxy, return it. // exception: calling readonly() on a reactive object if (target["__v_raw" /* RAW */] && !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) { return target; } // target already has corresponding Proxy const proxyMap = isReadonly ? readonlyMap : reactiveMap; const existingProxy = proxyMap.get(target); if (existingProxy) { return existingProxy; } // only a whitelist of value types can be observed. const targetType = getTargetType(target); if (targetType === 0 /* INVALID */) { return target; } const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); proxyMap.set(target, proxy); return proxy; } function isReactive(value) { if (reactivity_esm_bundler_isReadonly(value)) { return isReactive(value["__v_raw" /* RAW */]); } return !!(value && value["__v_isReactive" /* IS_REACTIVE */]); } function reactivity_esm_bundler_isReadonly(value) { return !!(value && value["__v_isReadonly" /* IS_READONLY */]); } function isProxy(value) { return isReactive(value) || reactivity_esm_bundler_isReadonly(value); } function toRaw(observed) { return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed); } function markRaw(value) { Object(shared_esm_bundler["g" /* def */])(value, "__v_skip" /* SKIP */, true); return value; } const convert = (val) => Object(shared_esm_bundler["t" /* isObject */])(val) ? reactive(val) : val; function isRef(r) { return Boolean(r && r.__v_isRef === true); } function reactivity_esm_bundler_ref(value) { return createRef(value); } function shallowRef(value) { return createRef(value, true); } class reactivity_esm_bundler_RefImpl { constructor(_rawValue, _shallow = false) { this._rawValue = _rawValue; this._shallow = _shallow; this.__v_isRef = true; this._value = _shallow ? _rawValue : convert(_rawValue); } get value() { track(toRaw(this), "get" /* GET */, 'value'); return this._value; } set value(newVal) { if (Object(shared_esm_bundler["j" /* hasChanged */])(toRaw(newVal), this._rawValue)) { this._rawValue = newVal; this._value = this._shallow ? newVal : convert(newVal); trigger(toRaw(this), "set" /* SET */, 'value', newVal); } } } function createRef(rawValue, shallow = false) { if (isRef(rawValue)) { return rawValue; } return new reactivity_esm_bundler_RefImpl(rawValue, shallow); } function triggerRef(ref) { trigger(ref, "set" /* SET */, 'value', ( false) ? undefined : void 0); } function unref(ref) { return isRef(ref) ? ref.value : ref; } const shallowUnwrapHandlers = { get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), set: (target, key, value, receiver) => { const oldValue = target[key]; if (isRef(oldValue) && !isRef(value)) { oldValue.value = value; return true; } else { return Reflect.set(target, key, value, receiver); } } }; function proxyRefs(objectWithRefs) { return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); } class CustomRefImpl { constructor(factory) { this.__v_isRef = true; const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value')); this._get = get; this._set = set; } get value() { return this._get(); } set value(newVal) { this._set(newVal); } } function customRef(factory) { return new CustomRefImpl(factory); } function toRefs(object) { if (false) {} const ret = Object(shared_esm_bundler["n" /* isArray */])(object) ? new Array(object.length) : {}; for (const key in object) { ret[key] = toRef(object, key); } return ret; } class ObjectRefImpl { constructor(_object, _key) { this._object = _object; this._key = _key; this.__v_isRef = true; } get value() { return this._object[this._key]; } set value(newVal) { this._object[this._key] = newVal; } } function toRef(object, key) { return new ObjectRefImpl(object, key); } class ComputedRefImpl { constructor(getter, _setter, isReadonly) { this._setter = _setter; this._dirty = true; this.__v_isRef = true; this.effect = reactivity_esm_bundler_effect(getter, { lazy: true, scheduler: () => { if (!this._dirty) { this._dirty = true; trigger(toRaw(this), "set" /* SET */, 'value'); } } }); this["__v_isReadonly" /* IS_READONLY */] = isReadonly; } get value() { if (this._dirty) { this._value = this.effect(); this._dirty = false; } track(toRaw(this), "get" /* GET */, 'value'); return this._value; } set value(newValue) { this._setter(newValue); } } function computed(getterOrOptions) { let getter; let setter; if (Object(shared_esm_bundler["o" /* isFunction */])(getterOrOptions)) { getter = getterOrOptions; setter = ( false) ? undefined : shared_esm_bundler["d" /* NOOP */]; } else { getter = getterOrOptions.get; setter = getterOrOptions.set; } return new ComputedRefImpl(getter, setter, Object(shared_esm_bundler["o" /* isFunction */])(getterOrOptions) || !getterOrOptions.set); } // CONCATENATED MODULE: ./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js const stack = []; function pushWarningContext(vnode) { stack.push(vnode); } function popWarningContext() { stack.pop(); } function warn(msg, ...args) { // avoid props formatting or warn handler tracking deps that might be mutated // during patch, leading to infinite recursion. pauseTracking(); const instance = stack.length ? stack[stack.length - 1].component : null; const appWarnHandler = instance && instance.appContext.config.warnHandler; const trace = getComponentTrace(); if (appWarnHandler) { callWithErrorHandling(appWarnHandler, instance, 11 /* APP_WARN_HANDLER */, [ msg + args.join(''), instance && instance.proxy, trace .map(({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`) .join('\n'), trace ]); } else { const warnArgs = [`[Vue warn]: ${msg}`, ...args]; /* istanbul ignore if */ if (trace.length && // avoid spamming console during tests !false) { warnArgs.push(`\n`, ...formatTrace(trace)); } console.warn(...warnArgs); } resetTracking(); } function getComponentTrace() { let currentVNode = stack[stack.length - 1]; if (!currentVNode) { return []; } // we can't just use the stack because it will be incomplete during updates // that did not start from the root. Re-construct the parent chain using // instance parent pointers. const normalizedStack = []; while (currentVNode) { const last = normalizedStack[0]; if (last && last.vnode === currentVNode) { last.recurseCount++; } else { normalizedStack.push({ vnode: currentVNode, recurseCount: 0 }); } const parentInstance = currentVNode.component && currentVNode.component.parent; currentVNode = parentInstance && parentInstance.vnode; } return normalizedStack; } /* istanbul ignore next */ function formatTrace(trace) { const logs = []; trace.forEach((entry, i) => { logs.push(...(i === 0 ? [] : [`\n`]), ...formatTraceEntry(entry)); }); return logs; } function formatTraceEntry({ vnode, recurseCount }) { const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``; const isRoot = vnode.component ? vnode.component.parent == null : false; const open = ` at <${formatComponentName(vnode.component, vnode.type, isRoot)}`; const close = `>` + postfix; return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close]; } /* istanbul ignore next */ function formatProps(props) { const res = []; const keys = Object.keys(props); keys.slice(0, 3).forEach(key => { res.push(...formatProp(key, props[key])); }); if (keys.length > 3) { res.push(` ...`); } return res; } /* istanbul ignore next */ function formatProp(key, value, raw) { if (Object(shared_esm_bundler["z" /* isString */])(value)) { value = JSON.stringify(value); return raw ? value : [`${key}=${value}`]; } else if (typeof value === 'number' || typeof value === 'boolean' || value == null) { return raw ? value : [`${key}=${value}`]; } else if (isRef(value)) { value = formatProp(key, toRaw(value.value), true); return raw ? value : [`${key}=Ref<`, value, `>`]; } else if (Object(shared_esm_bundler["o" /* isFunction */])(value)) { return [`${key}=fn${value.name ? `<${value.name}>` : ``}`]; } else { value = toRaw(value); return raw ? value : [`${key}=`, value]; } } const ErrorTypeStrings = { ["bc" /* BEFORE_CREATE */]: 'beforeCreate hook', ["c" /* CREATED */]: 'created hook', ["bm" /* BEFORE_MOUNT */]: 'beforeMount hook', ["m" /* MOUNTED */]: 'mounted hook', ["bu" /* BEFORE_UPDATE */]: 'beforeUpdate hook', ["u" /* UPDATED */]: 'updated', ["bum" /* BEFORE_UNMOUNT */]: 'beforeUnmount hook', ["um" /* UNMOUNTED */]: 'unmounted hook', ["a" /* ACTIVATED */]: 'activated hook', ["da" /* DEACTIVATED */]: 'deactivated hook', ["ec" /* ERROR_CAPTURED */]: 'errorCaptured hook', ["rtc" /* RENDER_TRACKED */]: 'renderTracked hook', ["rtg" /* RENDER_TRIGGERED */]: 'renderTriggered hook', [0 /* SETUP_FUNCTION */]: 'setup function', [1 /* RENDER_FUNCTION */]: 'render function', [2 /* WATCH_GETTER */]: 'watcher getter', [3 /* WATCH_CALLBACK */]: 'watcher callback', [4 /* WATCH_CLEANUP */]: 'watcher cleanup function', [5 /* NATIVE_EVENT_HANDLER */]: 'native event handler', [6 /* COMPONENT_EVENT_HANDLER */]: 'component event handler', [7 /* VNODE_HOOK */]: 'vnode hook', [8 /* DIRECTIVE_HOOK */]: 'directive hook', [9 /* TRANSITION_HOOK */]: 'transition hook', [10 /* APP_ERROR_HANDLER */]: 'app errorHandler', [11 /* APP_WARN_HANDLER */]: 'app warnHandler', [12 /* FUNCTION_REF */]: 'ref function', [13 /* ASYNC_COMPONENT_LOADER */]: 'async component loader', [14 /* SCHEDULER */]: 'scheduler flush. This is likely a Vue internals bug. ' + 'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next' }; function callWithErrorHandling(fn, instance, type, args) { let res; try { res = args ? fn(...args) : fn(); } catch (err) { handleError(err, instance, type); } return res; } function callWithAsyncErrorHandling(fn, instance, type, args) { if (Object(shared_esm_bundler["o" /* isFunction */])(fn)) { const res = callWithErrorHandling(fn, instance, type, args); if (res && Object(shared_esm_bundler["v" /* isPromise */])(res)) { res.catch(err => { handleError(err, instance, type); }); } return res; } const values = []; for (let i = 0; i < fn.length; i++) { values.push(callWithAsyncErrorHandling(fn[i], instance, type, args)); } return values; } function handleError(err, instance, type) { const contextVNode = instance ? instance.vnode : null; if (instance) { let cur = instance.parent; // the exposed instance is the render proxy to keep it consistent with 2.x const exposedInstance = instance.proxy; // in production the hook receives only the error code const errorInfo = ( false) ? undefined : type; while (cur) { const errorCapturedHooks = cur.ec; if (errorCapturedHooks) { for (let i = 0; i < errorCapturedHooks.length; i++) { if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) { return; } } } cur = cur.parent; } // app-level handling const appErrorHandler = instance.appContext.config.errorHandler; if (appErrorHandler) { callWithErrorHandling(appErrorHandler, null, 10 /* APP_ERROR_HANDLER */, [err, exposedInstance, errorInfo]); return; } } logError(err, type, contextVNode); } function logError(err, type, contextVNode) { if ((false)) {} else { // recover in prod to reduce the impact on end-user console.error(err); } } let isFlushing = false; let isFlushPending = false; const queue = []; let flushIndex = 0; const pendingPreFlushCbs = []; let activePreFlushCbs = null; let preFlushIndex = 0; const pendingPostFlushCbs = []; let activePostFlushCbs = null; let postFlushIndex = 0; const resolvedPromise = Promise.resolve(); let currentFlushPromise = null; let currentPreFlushParentJob = null; const RECURSION_LIMIT = 100; function nextTick(fn) { const p = currentFlushPromise || resolvedPromise; return fn ? p.then(fn) : p; } function queueJob(job) { // the dedupe search uses the startIndex argument of Array.includes() // by default the search index includes the current job that is being run // so it cannot recursively trigger itself again. // if the job is a watch() callback, the search will start with a +1 index to // allow it recursively trigger itself - it is the user's responsibility to // ensure it doesn't end up in an infinite loop. if ((!queue.length || !queue.includes(job, isFlushing && job.allowRecurse ? flushIndex + 1 : flushIndex)) && job !== currentPreFlushParentJob) { queue.push(job); queueFlush(); } } function queueFlush() { if (!isFlushing && !isFlushPending) { isFlushPending = true; currentFlushPromise = resolvedPromise.then(flushJobs); } } function invalidateJob(job) { const i = queue.indexOf(job); if (i > -1) { queue[i] = null; } } function queueCb(cb, activeQueue, pendingQueue, index) { if (!Object(shared_esm_bundler["n" /* isArray */])(cb)) { if (!activeQueue || !activeQueue.includes(cb, cb.allowRecurse ? index + 1 : index)) { pendingQueue.push(cb); } } else { // if cb is an array, it is a component lifecycle hook which can only be // triggered by a job, which is already deduped in the main queue, so // we can skip duplicate check here to improve perf pendingQueue.push(...cb); } queueFlush(); } function queuePreFlushCb(cb) { queueCb(cb, activePreFlushCbs, pendingPreFlushCbs, preFlushIndex); } function queuePostFlushCb(cb) { queueCb(cb, activePostFlushCbs, pendingPostFlushCbs, postFlushIndex); } function flushPreFlushCbs(seen, parentJob = null) { if (pendingPreFlushCbs.length) { currentPreFlushParentJob = parentJob; activePreFlushCbs = [...new Set(pendingPreFlushCbs)]; pendingPreFlushCbs.length = 0; if ((false)) {} for (preFlushIndex = 0; preFlushIndex < activePreFlushCbs.length; preFlushIndex++) { if ((false)) {} activePreFlushCbs[preFlushIndex](); } activePreFlushCbs = null; preFlushIndex = 0; currentPreFlushParentJob = null; // recursively flush until it drains flushPreFlushCbs(seen, parentJob); } } function flushPostFlushCbs(seen) { if (pendingPostFlushCbs.length) { const deduped = [...new Set(pendingPostFlushCbs)]; pendingPostFlushCbs.length = 0; // #1947 already has active queue, nested flushPostFlushCbs call if (activePostFlushCbs) { activePostFlushCbs.push(...deduped); return; } activePostFlushCbs = deduped; if ((false)) {} activePostFlushCbs.sort((a, b) => getId(a) - getId(b)); for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) { if ((false)) {} activePostFlushCbs[postFlushIndex](); } activePostFlushCbs = null; postFlushIndex = 0; } } const getId = (job) => job.id == null ? Infinity : job.id; function flushJobs(seen) { isFlushPending = false; isFlushing = true; if ((false)) {} flushPreFlushCbs(seen); // Sort queue before flush. // This ensures that: // 1. Components are updated from parent to child. (because parent is always // created before the child so its render effect will have smaller // priority number) // 2. If a component is unmounted during a parent component's update, // its update can be skipped. // Jobs can never be null before flush starts, since they are only invalidated // during execution of another flushed job. queue.sort((a, b) => getId(a) - getId(b)); try { for (flushIndex = 0; flushIndex < queue.length; flushIndex++) { const job = queue[flushIndex]; if (job) { if ((false)) {} callWithErrorHandling(job, null, 14 /* SCHEDULER */); } } } finally { flushIndex = 0; queue.length = 0; flushPostFlushCbs(seen); isFlushing = false; currentFlushPromise = null; // some postFlushCb queued jobs! // keep flushing until it drains. if (queue.length || pendingPostFlushCbs.length) { flushJobs(seen); } } } function checkRecursiveUpdates(seen, fn) { if (!seen.has(fn)) { seen.set(fn, 1); } else { const count = seen.get(fn); if (count > RECURSION_LIMIT) { throw new Error(`Maximum recursive updates exceeded. ` + `This means you have a reactive effect that is mutating its own ` + `dependencies and thus recursively triggering itself. Possible sources ` + `include component template, render function, updated hook or ` + `watcher source function.`); } else { seen.set(fn, count + 1); } } } let isHmrUpdating = false; const hmrDirtyComponents = new Set(); // Expose the HMR runtime on the global object // This makes it entirely tree-shakable without polluting the exports and makes // it easier to be used in toolings like vue-loader // Note: for a component to be eligible for HMR it also needs the __hmrId option // to be set so that its instances can be registered / removed. if ((false)) {} const map = new Map(); function registerHMR(instance) { const id = instance.type.__hmrId; let record = map.get(id); if (!record) { createRecord(id); record = map.get(id); } record.add(instance); } function unregisterHMR(instance) { map.get(instance.type.__hmrId).delete(instance); } function createRecord(id) { if (map.has(id)) { return false; } map.set(id, new Set()); return true; } function rerender(id, newRender) { const record = map.get(id); if (!record) return; // Array.from creates a snapshot which avoids the set being mutated during // updates Array.from(record).forEach(instance => { if (newRender) { instance.render = newRender; } instance.renderCache = []; // this flag forces child components with slot content to update isHmrUpdating = true; instance.update(); isHmrUpdating = false; }); } function reload(id, newComp) { const record = map.get(id); if (!record) return; // Array.from creates a snapshot which avoids the set being mutated during // updates Array.from(record).forEach(instance => { const comp = instance.type; if (!hmrDirtyComponents.has(comp)) { // 1. Update existing comp definition to match new one Object(shared_esm_bundler["h" /* extend */])(comp, newComp); for (const key in comp) { if (!(key in newComp)) { delete comp[key]; } } // 2. Mark component dirty. This forces the renderer to replace the component // on patch. hmrDirtyComponents.add(comp); // 3. Make sure to unmark the component after the reload. queuePostFlushCb(() => { hmrDirtyComponents.delete(comp); }); } if (instance.parent) { // 4. Force the parent instance to re-render. This will cause all updated // components to be unmounted and re-mounted. Queue the update so that we // don't end up forcing the same parent to re-render multiple times. queueJob(instance.parent.update); } else if (instance.appContext.reload) { // root instance mounted via createApp() has a reload method instance.appContext.reload(); } else if (typeof window !== 'undefined') { // root instance inside tree created via raw render(). Force reload. window.location.reload(); } else { console.warn('[HMR] Root or manually mounted instance modified. Full reload required.'); } }); } function tryWrap(fn) { return (id, arg) => { try { return fn(id, arg); } catch (e) { console.error(e); console.warn(`[HMR] Something went wrong during Vue component hot-reload. ` + `Full reload required.`); } }; } // mark the current rendering instance for asset resolution (e.g. // resolveComponent, resolveDirective) during render let currentRenderingInstance = null; function setCurrentRenderingInstance(instance) { currentRenderingInstance = instance; } // dev only flag to track whether $attrs was used during render. // If $attrs was used during render then the warning for failed attrs // fallthrough can be suppressed. let accessedAttrs = false; function markAttrsAccessed() { accessedAttrs = true; } function renderComponentRoot(instance) { const { type: Component, vnode, proxy, withProxy, props, propsOptions: [propsOptions], slots, attrs, emit, render, renderCache, data, setupState, ctx } = instance; let result; currentRenderingInstance = instance; if ((false)) {} try { let fallthroughAttrs; if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { // withProxy is a proxy with a different `has` trap only for // runtime-compiled render functions using `with` block. const proxyToUse = withProxy || proxy; result = normalizeVNode(render.call(proxyToUse, proxyToUse, renderCache, props, setupState, data, ctx)); fallthroughAttrs = attrs; } else { // functional const render = Component; // in dev, mark attrs accessed if optional props (attrs === props) if (false) {} result = normalizeVNode(render.length > 1 ? render(props, ( false) ? undefined : { attrs, slots, emit }) : render(props, null /* we know it doesn't need it */)); fallthroughAttrs = Component.props ? attrs : getFunctionalFallthrough(attrs); } // attr merging // in dev mode, comments are preserved, and it's possible for a template // to have comments along side the root element which makes it a fragment let root = result; let setRoot = undefined; if ((false)) {} if (Component.inheritAttrs !== false && fallthroughAttrs) { const keys = Object.keys(fallthroughAttrs); const { shapeFlag } = root; if (keys.length) { if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 6 /* COMPONENT */) { if (propsOptions && keys.some(shared_esm_bundler["s" /* isModelListener */])) { // If a v-model listener (onUpdate:xxx) has a corresponding declared // prop, it indicates this component expects to handle v-model and // it should not fallthrough. // related: #1543, #1643, #1989 fallthroughAttrs = filterModelListeners(fallthroughAttrs, propsOptions); } root = cloneVNode(root, fallthroughAttrs); } else if (false) {} } } // inherit directives if (vnode.dirs) { if (false) {} root.dirs = vnode.dirs; } // inherit transition data if (vnode.transition) { if (false) {} root.transition = vnode.transition; } if (false) {} else { result = root; } } catch (err) { handleError(err, instance, 1 /* RENDER_FUNCTION */); result = createVNode(Comment); } currentRenderingInstance = null; return result; } /** * dev only */ const getChildRoot = (vnode) => { if (vnode.type !== Fragment) { return [vnode, undefined]; } const rawChildren = vnode.children; const dynamicChildren = vnode.dynamicChildren; const children = rawChildren.filter(child => { return !(isVNode(child) && child.type === Comment && child.children !== 'v-if'); }); if (children.length !== 1) { return [vnode, undefined]; } const childRoot = children[0]; const index = rawChildren.indexOf(childRoot); const dynamicIndex = dynamicChildren ? dynamicChildren.indexOf(childRoot) : -1; const setRoot = (updatedRoot) => { rawChildren[index] = updatedRoot; if (dynamicIndex > -1) { dynamicChildren[dynamicIndex] = updatedRoot; } else if (dynamicChildren && updatedRoot.patchFlag > 0) { dynamicChildren.push(updatedRoot); } }; return [normalizeVNode(childRoot), setRoot]; }; const getFunctionalFallthrough = (attrs) => { let res; for (const key in attrs) { if (key === 'class' || key === 'style' || Object(shared_esm_bundler["u" /* isOn */])(key)) { (res || (res = {}))[key] = attrs[key]; } } return res; }; const filterModelListeners = (attrs, props) => { const res = {}; for (const key in attrs) { if (!Object(shared_esm_bundler["s" /* isModelListener */])(key) || !(key.slice(9) in props)) { res[key] = attrs[key]; } } return res; }; const isElementRoot = (vnode) => { return (vnode.shapeFlag & 6 /* COMPONENT */ || vnode.shapeFlag & 1 /* ELEMENT */ || vnode.type === Comment // potential v-if branch switch ); }; function shouldUpdateComponent(prevVNode, nextVNode, optimized) { const { props: prevProps, children: prevChildren } = prevVNode; const { props: nextProps, children: nextChildren, patchFlag } = nextVNode; // Parent component's render function was hot-updated. Since this may have // caused the child component's slots content to have changed, we need to // force the child to update as well. if (false) {} // force child update for runtime directive or transition on component vnode. if (nextVNode.dirs || nextVNode.transition) { return true; } if (optimized && patchFlag > 0) { if (patchFlag & 1024 /* DYNAMIC_SLOTS */) { // slot content that references values that might have changed, // e.g. in a v-for return true; } if (patchFlag & 16 /* FULL_PROPS */) { if (!prevProps) { return !!nextProps; } // presence of this flag indicates props are always non-null return hasPropsChanged(prevProps, nextProps); } else if (patchFlag & 8 /* PROPS */) { const dynamicProps = nextVNode.dynamicProps; for (let i = 0; i < dynamicProps.length; i++) { const key = dynamicProps[i]; if (nextProps[key] !== prevProps[key]) { return true; } } } } else { // this path is only taken by manually written render functions // so presence of any children leads to a forced update if (prevChildren || nextChildren) { if (!nextChildren || !nextChildren.$stable) { return true; } } if (prevProps === nextProps) { return false; } if (!prevProps) { return !!nextProps; } if (!nextProps) { return true; } return hasPropsChanged(prevProps, nextProps); } return false; } function hasPropsChanged(prevProps, nextProps) { const nextKeys = Object.keys(nextProps); if (nextKeys.length !== Object.keys(prevProps).length) { return true; } for (let i = 0; i < nextKeys.length; i++) { const key = nextKeys[i]; if (nextProps[key] !== prevProps[key]) { return true; } } return false; } function updateHOCHostEl({ vnode, parent }, el // HostNode ) { while (parent && parent.subTree === vnode) { (vnode = parent.vnode).el = el; parent = parent.parent; } } const isSuspense = (type) => type.__isSuspense; // Suspense exposes a component-like API, and is treated like a component // in the compiler, but internally it's a special built-in type that hooks // directly into the renderer. const SuspenseImpl = { // In order to make Suspense tree-shakable, we need to avoid importing it // directly in the renderer. The renderer checks for the __isSuspense flag // on a vnode's type and calls the `process` method, passing in renderer // internals. __isSuspense: true, process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, // platform-specific impl passed from renderer rendererInternals) { if (n1 == null) { mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals); } else { patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, rendererInternals); } }, hydrate: hydrateSuspense }; // Force-casted public typing for h and TSX props inference const Suspense = ( SuspenseImpl ); function mountSuspense(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, rendererInternals) { const { p: patch, o: { createElement } } = rendererInternals; const hiddenContainer = createElement('div'); const suspense = (n2.suspense = createSuspenseBoundary(n2, parentSuspense, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals)); // start mounting the content subtree in an off-dom container patch(null, suspense.subTree, hiddenContainer, null, parentComponent, suspense, isSVG, optimized); // now check if we have encountered any async deps if (suspense.deps > 0) { // mount the fallback tree patch(null, suspense.fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, optimized); n2.el = suspense.fallbackTree.el; } else { // Suspense has no async deps. Just resolve. suspense.resolve(); } } function patchSuspense(n1, n2, container, anchor, parentComponent, isSVG, optimized, { p: patch }) { const suspense = (n2.suspense = n1.suspense); suspense.vnode = n2; const { content, fallback } = normalizeSuspenseChildren(n2); const oldSubTree = suspense.subTree; const oldFallbackTree = suspense.fallbackTree; if (!suspense.isResolved) { patch(oldSubTree, content, suspense.hiddenContainer, null, parentComponent, suspense, isSVG, optimized); if (suspense.deps > 0) { // still pending. patch the fallback tree. patch(oldFallbackTree, fallback, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, optimized); n2.el = fallback.el; } // If deps somehow becomes 0 after the patch it means the patch caused an // async dep component to unmount and removed its dep. It will cause the // suspense to resolve and we don't need to do anything here. } else { // just normal patch inner content as a fragment patch(oldSubTree, content, container, anchor, parentComponent, suspense, isSVG, optimized); n2.el = content.el; } suspense.subTree = content; suspense.fallbackTree = fallback; } let hasWarned = false; function createSuspenseBoundary(vnode, parent, parentComponent, container, hiddenContainer, anchor, isSVG, optimized, rendererInternals, isHydrating = false) { /* istanbul ignore if */ if (false) {} const { p: patch, m: move, um: unmount, n: next, o: { parentNode } } = rendererInternals; const getCurrentTree = () => suspense.isResolved || suspense.isHydrating ? suspense.subTree : suspense.fallbackTree; const { content, fallback } = normalizeSuspenseChildren(vnode); const suspense = { vnode, parent, parentComponent, isSVG, optimized, container, hiddenContainer, anchor, deps: 0, subTree: content, fallbackTree: fallback, isHydrating, isResolved: false, isUnmounted: false, effects: [], resolve() { if ((false)) {} const { vnode, subTree, fallbackTree, effects, parentComponent, container } = suspense; if (suspense.isHydrating) { suspense.isHydrating = false; } else { // this is initial anchor on mount let { anchor } = suspense; // unmount fallback tree if (fallbackTree.el) { // if the fallback tree was mounted, it may have been moved // as part of a parent suspense. get the latest anchor for insertion anchor = next(fallbackTree); unmount(fallbackTree, parentComponent, suspense, true); } // move content from off-dom container to actual container move(subTree, container, anchor, 0 /* ENTER */); } const el = (vnode.el = subTree.el); // suspense as the root node of a component... if (parentComponent && parentComponent.subTree === vnode) { parentComponent.vnode.el = el; updateHOCHostEl(parentComponent, el); } // check if there is a pending parent suspense let parent = suspense.parent; let hasUnresolvedAncestor = false; while (parent) { if (!parent.isResolved) { // found a pending parent suspense, merge buffered post jobs // into that parent parent.effects.push(...effects); hasUnresolvedAncestor = true; break; } parent = parent.parent; } // no pending parent suspense, flush all jobs if (!hasUnresolvedAncestor) { queuePostFlushCb(effects); } suspense.isResolved = true; suspense.effects = []; // invoke @resolve event const onResolve = vnode.props && vnode.props.onResolve; if (Object(shared_esm_bundler["o" /* isFunction */])(onResolve)) { onResolve(); } }, recede() { suspense.isResolved = false; const { vnode, subTree, fallbackTree, parentComponent, container, hiddenContainer, isSVG, optimized } = suspense; // move content tree back to the off-dom container const anchor = next(subTree); move(subTree, hiddenContainer, null, 1 /* LEAVE */); // remount the fallback tree patch(null, fallbackTree, container, anchor, parentComponent, null, // fallback tree will not have suspense context isSVG, optimized); const el = (vnode.el = fallbackTree.el); // suspense as the root node of a component... if (parentComponent && parentComponent.subTree === vnode) { parentComponent.vnode.el = el; updateHOCHostEl(parentComponent, el); } // invoke @recede event const onRecede = vnode.props && vnode.props.onRecede; if (Object(shared_esm_bundler["o" /* isFunction */])(onRecede)) { onRecede(); } }, move(container, anchor, type) { move(getCurrentTree(), container, anchor, type); suspense.container = container; }, next() { return next(getCurrentTree()); }, registerDep(instance, setupRenderEffect) { // suspense is already resolved, need to recede. // use queueJob so it's handled synchronously after patching the current // suspense tree if (suspense.isResolved) { queueJob(() => { suspense.recede(); }); } const hydratedEl = instance.vnode.el; suspense.deps++; instance .asyncDep.catch(err => { handleError(err, instance, 0 /* SETUP_FUNCTION */); }) .then(asyncSetupResult => { // retry when the setup() promise resolves. // component may have been unmounted before resolve. if (instance.isUnmounted || suspense.isUnmounted) { return; } suspense.deps--; // retry from this component instance.asyncResolved = true; const { vnode } = instance; if ((false)) {} handleSetupResult(instance, asyncSetupResult); if (hydratedEl) { // vnode may have been replaced if an update happened before the // async dep is resolved. vnode.el = hydratedEl; } setupRenderEffect(instance, vnode, // component may have been moved before resolve. // if this is not a hydration, instance.subTree will be the comment // placeholder. hydratedEl ? parentNode(hydratedEl) : parentNode(instance.subTree.el), // anchor will not be used if this is hydration, so only need to // consider the comment placeholder case. hydratedEl ? null : next(instance.subTree), suspense, isSVG, optimized); updateHOCHostEl(instance, vnode.el); if ((false)) {} if (suspense.deps === 0) { suspense.resolve(); } }); }, unmount(parentSuspense, doRemove) { suspense.isUnmounted = true; unmount(suspense.subTree, parentComponent, parentSuspense, doRemove); if (!suspense.isResolved) { unmount(suspense.fallbackTree, parentComponent, parentSuspense, doRemove); } } }; return suspense; } function hydrateSuspense(node, vnode, parentComponent, parentSuspense, isSVG, optimized, rendererInternals, hydrateNode) { /* eslint-disable no-restricted-globals */ const suspense = (vnode.suspense = createSuspenseBoundary(vnode, parentSuspense, parentComponent, node.parentNode, document.createElement('div'), null, isSVG, optimized, rendererInternals, true /* hydrating */)); // there are two possible scenarios for server-rendered suspense: // - success: ssr content should be fully resolved // - failure: ssr content should be the fallback branch. // however, on the client we don't really know if it has failed or not // attempt to hydrate the DOM assuming it has succeeded, but we still // need to construct a suspense boundary first const result = hydrateNode(node, suspense.subTree, parentComponent, suspense, optimized); if (suspense.deps === 0) { suspense.resolve(); } return result; /* eslint-enable no-restricted-globals */ } function normalizeSuspenseChildren(vnode) { const { shapeFlag, children } = vnode; if (shapeFlag & 32 /* SLOTS_CHILDREN */) { const { default: d, fallback } = children; return { content: normalizeVNode(Object(shared_esm_bundler["o" /* isFunction */])(d) ? d() : d), fallback: normalizeVNode(Object(shared_esm_bundler["o" /* isFunction */])(fallback) ? fallback() : fallback) }; } else { return { content: normalizeVNode(children), fallback: normalizeVNode(null) }; } } function queueEffectWithSuspense(fn, suspense) { if (suspense && !suspense.isResolved) { if (Object(shared_esm_bundler["n" /* isArray */])(fn)) { suspense.effects.push(...fn); } else { suspense.effects.push(fn); } } else { queuePostFlushCb(fn); } } let isRenderingCompiledSlot = 0; const setCompiledSlotRendering = (n) => (isRenderingCompiledSlot += n); /** * Compiler runtime helper for rendering `` * @private */ function renderSlot(slots, name, props = {}, // this is not a user-facing function, so the fallback is always generated by // the compiler and guaranteed to be a function returning an array fallback) { let slot = slots[name]; if (false) {} // a compiled slot disables block tracking by default to avoid manual // invocation interfering with template-based block tracking, but in // `renderSlot` we can be sure that it's template-based so we can force // enable it. isRenderingCompiledSlot++; const rendered = (openBlock(), createBlock(Fragment, { key: props.key }, slot ? slot(props) : fallback ? fallback() : [], slots._ === 1 /* STABLE */ ? 64 /* STABLE_FRAGMENT */ : -2 /* BAIL */)); isRenderingCompiledSlot--; return rendered; } /** * Wrap a slot function to memoize current rendering instance * @private */ function withCtx(fn, ctx = currentRenderingInstance) { if (!ctx) return fn; const renderFnWithContext = (...args) => { // If a user calls a compiled slot inside a template expression (#1745), it // can mess up block tracking, so by default we need to push a null block to // avoid that. This isn't necessary if rendering a compiled ``. if (!isRenderingCompiledSlot) { openBlock(true /* null block that disables tracking */); } const owner = currentRenderingInstance; setCurrentRenderingInstance(ctx); const res = fn(...args); setCurrentRenderingInstance(owner); if (!isRenderingCompiledSlot) { closeBlock(); } return res; }; renderFnWithContext._c = true; return renderFnWithContext; } // SFC scoped style ID management. let currentScopeId = null; const scopeIdStack = []; /** * @private */ function pushScopeId(id) { scopeIdStack.push((currentScopeId = id)); } /** * @private */ function popScopeId() { scopeIdStack.pop(); currentScopeId = scopeIdStack[scopeIdStack.length - 1] || null; } /** * @private */ function withScopeId(id) { return ((fn) => withCtx(function () { pushScopeId(id); const res = fn.apply(this, arguments); popScopeId(); return res; })); } const isTeleport = (type) => type.__isTeleport; const isTeleportDisabled = (props) => props && (props.disabled || props.disabled === ''); const resolveTarget = (props, select) => { const targetSelector = props && props.to; if (Object(shared_esm_bundler["z" /* isString */])(targetSelector)) { if (!select) { ( false) && false; return null; } else { const target = select(targetSelector); if (!target) { ( false) && false; } return target; } } else { if (false) {} return targetSelector; } }; const TeleportImpl = { __isTeleport: true, process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals) { const { mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, o: { insert, querySelector, createText, createComment } } = internals; const disabled = isTeleportDisabled(n2.props); const { shapeFlag, children } = n2; if (n1 == null) { // insert anchors in the main view const placeholder = (n2.el = ( false) ? undefined : createText('')); const mainAnchor = (n2.anchor = ( false) ? undefined : createText('')); insert(placeholder, container, anchor); insert(mainAnchor, container, anchor); const target = (n2.target = resolveTarget(n2.props, querySelector)); const targetAnchor = (n2.targetAnchor = createText('')); if (target) { insert(targetAnchor, target); } else if (false) {} const mount = (container, anchor) => { // Teleport *always* has Array children. This is enforced in both the // compiler and vnode children normalization. if (shapeFlag & 16 /* ARRAY_CHILDREN */) { mountChildren(children, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } }; if (disabled) { mount(container, mainAnchor); } else if (target) { mount(target, targetAnchor); } } else { // update content n2.el = n1.el; const mainAnchor = (n2.anchor = n1.anchor); const target = (n2.target = n1.target); const targetAnchor = (n2.targetAnchor = n1.targetAnchor); const wasDisabled = isTeleportDisabled(n1.props); const currentContainer = wasDisabled ? container : target; const currentAnchor = wasDisabled ? mainAnchor : targetAnchor; if (n2.dynamicChildren) { // fast path when the teleport happens to be a block root patchBlockChildren(n1.dynamicChildren, n2.dynamicChildren, currentContainer, parentComponent, parentSuspense, isSVG); // even in block tree mode we need to make sure all root-level nodes // in the teleport inherit previous DOM references so that they can // be moved in future patches. if (n2.shapeFlag & 16 /* ARRAY_CHILDREN */) { const oldChildren = n1.children; const children = n2.children; for (let i = 0; i < children.length; i++) { // only inherit for non-patched nodes (i.e. static ones) if (!children[i].el) { children[i].el = oldChildren[i].el; } } } } else if (!optimized) { patchChildren(n1, n2, currentContainer, currentAnchor, parentComponent, parentSuspense, isSVG); } if (disabled) { if (!wasDisabled) { // enabled -> disabled // move into main container moveTeleport(n2, container, mainAnchor, internals, 1 /* TOGGLE */); } } else { // target changed if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) { const nextTarget = (n2.target = resolveTarget(n2.props, querySelector)); if (nextTarget) { moveTeleport(n2, nextTarget, null, internals, 0 /* TARGET_CHANGE */); } else if ((false)) {} } else if (wasDisabled) { // disabled -> enabled // move into teleport target moveTeleport(n2, target, targetAnchor, internals, 1 /* TOGGLE */); } } } }, remove(vnode, { r: remove, o: { remove: hostRemove } }) { const { shapeFlag, children, anchor } = vnode; hostRemove(anchor); if (shapeFlag & 16 /* ARRAY_CHILDREN */) { for (let i = 0; i < children.length; i++) { remove(children[i]); } } }, move: moveTeleport, hydrate: hydrateTeleport }; function moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2 /* REORDER */) { // move target anchor if this is a target change. if (moveType === 0 /* TARGET_CHANGE */) { insert(vnode.targetAnchor, container, parentAnchor); } const { el, anchor, shapeFlag, children, props } = vnode; const isReorder = moveType === 2 /* REORDER */; // move main view anchor if this is a re-order. if (isReorder) { insert(el, container, parentAnchor); } // if this is a re-order and teleport is enabled (content is in target) // do not move children. So the opposite is: only move children if this // is not a reorder, or the teleport is disabled if (!isReorder || isTeleportDisabled(props)) { // Teleport has either Array children or no children. if (shapeFlag & 16 /* ARRAY_CHILDREN */) { for (let i = 0; i < children.length; i++) { move(children[i], container, parentAnchor, 2 /* REORDER */); } } } // move main view anchor if this is a re-order. if (isReorder) { insert(anchor, container, parentAnchor); } } function hydrateTeleport(node, vnode, parentComponent, parentSuspense, optimized, { o: { nextSibling, parentNode, querySelector } }, hydrateChildren) { const target = (vnode.target = resolveTarget(vnode.props, querySelector)); if (target) { // if multiple teleports rendered to the same target element, we need to // pick up from where the last teleport finished instead of the first node const targetNode = target._lpa || target.firstChild; if (vnode.shapeFlag & 16 /* ARRAY_CHILDREN */) { if (isTeleportDisabled(vnode.props)) { vnode.anchor = hydrateChildren(nextSibling(node), vnode, parentNode(node), parentComponent, parentSuspense, optimized); vnode.targetAnchor = targetNode; } else { vnode.anchor = nextSibling(node); vnode.targetAnchor = hydrateChildren(targetNode, vnode, target, parentComponent, parentSuspense, optimized); } target._lpa = vnode.targetAnchor && nextSibling(vnode.targetAnchor); } } return vnode.anchor && nextSibling(vnode.anchor); } // Force-casted public typing for h and TSX props inference const Teleport = TeleportImpl; const COMPONENTS = 'components'; const DIRECTIVES = 'directives'; /** * @private */ function resolveComponent(name) { return resolveAsset(COMPONENTS, name) || name; } const NULL_DYNAMIC_COMPONENT = Symbol(); /** * @private */ function resolveDynamicComponent(component) { if (Object(shared_esm_bundler["z" /* isString */])(component)) { return resolveAsset(COMPONENTS, component, false) || component; } else { // invalid types will fallthrough to createVNode and raise warning return (component || NULL_DYNAMIC_COMPONENT); } } /** * @private */ function resolveDirective(name) { return resolveAsset(DIRECTIVES, name); } // implementation function resolveAsset(type, name, warnMissing = true) { const instance = currentRenderingInstance || currentInstance; if (instance) { const Component = instance.type; // self name has highest priority if (type === COMPONENTS) { const selfName = Component.displayName || Component.name; if (selfName && (selfName === name || selfName === Object(shared_esm_bundler["e" /* camelize */])(name) || selfName === Object(shared_esm_bundler["f" /* capitalize */])(Object(shared_esm_bundler["e" /* camelize */])(name)))) { return Component; } } const res = // local registration // check instance[type] first for components with mixin or extends. resolve(instance[type] || Component[type], name) || // global registration resolve(instance.appContext[type], name); if (false) {} return res; } else if ((false)) {} } function resolve(registry, name) { return (registry && (registry[name] || registry[Object(shared_esm_bundler["e" /* camelize */])(name)] || registry[Object(shared_esm_bundler["f" /* capitalize */])(Object(shared_esm_bundler["e" /* camelize */])(name))])); } const Fragment = Symbol(( false) ? undefined : undefined); const Text = Symbol(( false) ? undefined : undefined); const Comment = Symbol(( false) ? undefined : undefined); const Static = Symbol(( false) ? undefined : undefined); // Since v-if and v-for are the two possible ways node structure can dynamically // change, once we consider v-if branches and each v-for fragment a block, we // can divide a template into nested blocks, and within each block the node // structure would be stable. This allows us to skip most children diffing // and only worry about the dynamic nodes (indicated by patch flags). const blockStack = []; let currentBlock = null; /** * Open a block. * This must be called before `createBlock`. It cannot be part of `createBlock` * because the children of the block are evaluated before `createBlock` itself * is called. The generated code typically looks like this: * * ```js * function render() { * return (openBlock(),createBlock('div', null, [...])) * } * ``` * disableTracking is true when creating a v-for fragment block, since a v-for * fragment always diffs its children. * * @private */ function openBlock(disableTracking = false) { blockStack.push((currentBlock = disableTracking ? null : [])); } function closeBlock() { blockStack.pop(); currentBlock = blockStack[blockStack.length - 1] || null; } // Whether we should be tracking dynamic child nodes inside a block. // Only tracks when this value is > 0 // We are not using a simple boolean because this value may need to be // incremented/decremented by nested usage of v-once (see below) let runtime_core_esm_bundler_shouldTrack = 1; /** * Block tracking sometimes needs to be disabled, for example during the * creation of a tree that needs to be cached by v-once. The compiler generates * code like this: * * ``` js * _cache[1] || ( * setBlockTracking(-1), * _cache[1] = createVNode(...), * setBlockTracking(1), * _cache[1] * ) * ``` * * @private */ function setBlockTracking(value) { runtime_core_esm_bundler_shouldTrack += value; } /** * Create a block root vnode. Takes the same exact arguments as `createVNode`. * A block root keeps track of dynamic nodes within the block in the * `dynamicChildren` array. * * @private */ function createBlock(type, props, children, patchFlag, dynamicProps) { const vnode = createVNode(type, props, children, patchFlag, dynamicProps, true /* isBlock: prevent a block from tracking itself */); // save current block children on the block vnode vnode.dynamicChildren = currentBlock || shared_esm_bundler["a" /* EMPTY_ARR */]; // close block closeBlock(); // a block is always going to be patched, so track it as a child of its // parent block if (runtime_core_esm_bundler_shouldTrack > 0 && currentBlock) { currentBlock.push(vnode); } return vnode; } function isVNode(value) { return value ? value.__v_isVNode === true : false; } function isSameVNodeType(n1, n2) { if (false) {} return n1.type === n2.type && n1.key === n2.key; } let vnodeArgsTransformer; /** * Internal API for registering an arguments transform for createVNode * used for creating stubs in the test-utils * It is *internal* but needs to be exposed for test-utils to pick up proper * typings */ function transformVNodeArgs(transformer) { vnodeArgsTransformer = transformer; } const createVNodeWithArgsTransform = (...args) => { return _createVNode(...(vnodeArgsTransformer ? vnodeArgsTransformer(args, currentRenderingInstance) : args)); }; const InternalObjectKey = `__vInternal`; const normalizeKey = ({ key }) => key != null ? key : null; const normalizeRef = ({ ref }) => { return (ref != null ? Object(shared_esm_bundler["n" /* isArray */])(ref) ? ref : [currentRenderingInstance, ref] : null); }; const createVNode = (( false) ? undefined : _createVNode); function _createVNode(type, props = null, children = null, patchFlag = 0, dynamicProps = null, isBlockNode = false) { if (!type || type === NULL_DYNAMIC_COMPONENT) { if (false) {} type = Comment; } if (isVNode(type)) { const cloned = cloneVNode(type, props); if (children) { normalizeChildren(cloned, children); } return cloned; } // class component normalization. if (Object(shared_esm_bundler["o" /* isFunction */])(type) && '__vccOpts' in type) { type = type.__vccOpts; } // class & style normalization. if (props) { // for reactive or proxy objects, we need to clone it to enable mutation. if (isProxy(props) || InternalObjectKey in props) { props = Object(shared_esm_bundler["h" /* extend */])({}, props); } let { class: klass, style } = props; if (klass && !Object(shared_esm_bundler["z" /* isString */])(klass)) { props.class = Object(shared_esm_bundler["E" /* normalizeClass */])(klass); } if (Object(shared_esm_bundler["t" /* isObject */])(style)) { // reactive state objects need to be cloned since they are likely to be // mutated if (isProxy(style) && !Object(shared_esm_bundler["n" /* isArray */])(style)) { style = Object(shared_esm_bundler["h" /* extend */])({}, style); } props.style = Object(shared_esm_bundler["F" /* normalizeStyle */])(style); } } // encode the vnode type information into a bitmap const shapeFlag = Object(shared_esm_bundler["z" /* isString */])(type) ? 1 /* ELEMENT */ : isSuspense(type) ? 128 /* SUSPENSE */ : isTeleport(type) ? 64 /* TELEPORT */ : Object(shared_esm_bundler["t" /* isObject */])(type) ? 4 /* STATEFUL_COMPONENT */ : Object(shared_esm_bundler["o" /* isFunction */])(type) ? 2 /* FUNCTIONAL_COMPONENT */ : 0; if (false) {} const vnode = { __v_isVNode: true, ["__v_skip" /* SKIP */]: true, type, props, key: props && normalizeKey(props), ref: props && normalizeRef(props), scopeId: currentScopeId, children: null, component: null, suspense: null, dirs: null, transition: null, el: null, anchor: null, target: null, targetAnchor: null, staticCount: 0, shapeFlag, patchFlag, dynamicProps, dynamicChildren: null, appContext: null }; // validate key if (false) {} normalizeChildren(vnode, children); if (runtime_core_esm_bundler_shouldTrack > 0 && // avoid a block node from tracking itself !isBlockNode && // has current parent block currentBlock && // presence of a patch flag indicates this node needs patching on updates. // component nodes also should always be patched, because even if the // component doesn't need to update, it needs to persist the instance on to // the next vnode so that it can be properly unmounted later. (patchFlag > 0 || shapeFlag & 6 /* COMPONENT */) && // the EVENTS flag is only for hydration and if it is the only flag, the // vnode should not be considered dynamic due to handler caching. patchFlag !== 32 /* HYDRATE_EVENTS */) { currentBlock.push(vnode); } return vnode; } function cloneVNode(vnode, extraProps) { // This is intentionally NOT using spread or extend to avoid the runtime // key enumeration cost. const { props, patchFlag } = vnode; const mergedProps = extraProps ? mergeProps(props || {}, extraProps) : props; return { __v_isVNode: true, ["__v_skip" /* SKIP */]: true, type: vnode.type, props: mergedProps, key: mergedProps && normalizeKey(mergedProps), ref: extraProps && extraProps.ref ? normalizeRef(extraProps) : vnode.ref, scopeId: vnode.scopeId, children: vnode.children, target: vnode.target, targetAnchor: vnode.targetAnchor, staticCount: vnode.staticCount, shapeFlag: vnode.shapeFlag, // if the vnode is cloned with extra props, we can no longer assume its // existing patch flag to be reliable and need to add the FULL_PROPS flag. // note: perserve flag for fragments since they use the flag for children // fast paths only. patchFlag: extraProps && vnode.type !== Fragment ? patchFlag === -1 // hoisted node ? 16 /* FULL_PROPS */ : patchFlag | 16 /* FULL_PROPS */ : patchFlag, dynamicProps: vnode.dynamicProps, dynamicChildren: vnode.dynamicChildren, appContext: vnode.appContext, dirs: vnode.dirs, transition: vnode.transition, // These should technically only be non-null on mounted VNodes. However, // they *should* be copied for kept-alive vnodes. So we just always copy // them since them being non-null during a mount doesn't affect the logic as // they will simply be overwritten. component: vnode.component, suspense: vnode.suspense, el: vnode.el, anchor: vnode.anchor }; } /** * @private */ function createTextVNode(text = ' ', flag = 0) { return createVNode(Text, null, text, flag); } /** * @private */ function createStaticVNode(content, numberOfNodes) { // A static vnode can contain multiple stringified elements, and the number // of elements is necessary for hydration. const vnode = createVNode(Static, null, content); vnode.staticCount = numberOfNodes; return vnode; } /** * @private */ function createCommentVNode(text = '', // when used as the v-else branch, the comment node must be created as a // block to ensure correct updates. asBlock = false) { return asBlock ? (openBlock(), createBlock(Comment, null, text)) : createVNode(Comment, null, text); } function normalizeVNode(child) { if (child == null || typeof child === 'boolean') { // empty placeholder return createVNode(Comment); } else if (Object(shared_esm_bundler["n" /* isArray */])(child)) { // fragment return createVNode(Fragment, null, child); } else if (typeof child === 'object') { // already vnode, this should be the most common since compiled templates // always produce all-vnode children arrays return child.el === null ? child : cloneVNode(child); } else { // strings and numbers return createVNode(Text, null, String(child)); } } // optimized normalization for template-compiled render fns function cloneIfMounted(child) { return child.el === null ? child : cloneVNode(child); } function normalizeChildren(vnode, children) { let type = 0; const { shapeFlag } = vnode; if (children == null) { children = null; } else if (Object(shared_esm_bundler["n" /* isArray */])(children)) { type = 16 /* ARRAY_CHILDREN */; } else if (typeof children === 'object') { if (shapeFlag & 1 /* ELEMENT */ || shapeFlag & 64 /* TELEPORT */) { // Normalize slot to plain children for plain element and Teleport const slot = children.default; if (slot) { // _c marker is added by withCtx() indicating this is a compiled slot slot._c && setCompiledSlotRendering(1); normalizeChildren(vnode, slot()); slot._c && setCompiledSlotRendering(-1); } return; } else { type = 32 /* SLOTS_CHILDREN */; const slotFlag = children._; if (!slotFlag && !(InternalObjectKey in children)) { children._ctx = currentRenderingInstance; } else if (slotFlag === 3 /* FORWARDED */ && currentRenderingInstance) { // a child component receives forwarded slots from the parent. // its slot type is determined by its parent's slot type. if (currentRenderingInstance.vnode.patchFlag & 1024 /* DYNAMIC_SLOTS */) { children._ = 2 /* DYNAMIC */; vnode.patchFlag |= 1024 /* DYNAMIC_SLOTS */; } else { children._ = 1 /* STABLE */; } } } } else if (Object(shared_esm_bundler["o" /* isFunction */])(children)) { children = { default: children, _ctx: currentRenderingInstance }; type = 32 /* SLOTS_CHILDREN */; } else { children = String(children); // force teleport children to array so it can be moved around if (shapeFlag & 64 /* TELEPORT */) { type = 16 /* ARRAY_CHILDREN */; children = [createTextVNode(children)]; } else { type = 8 /* TEXT_CHILDREN */; } } vnode.children = children; vnode.shapeFlag |= type; } function mergeProps(...args) { const ret = Object(shared_esm_bundler["h" /* extend */])({}, args[0]); for (let i = 1; i < args.length; i++) { const toMerge = args[i]; for (const key in toMerge) { if (key === 'class') { if (ret.class !== toMerge.class) { ret.class = Object(shared_esm_bundler["E" /* normalizeClass */])([ret.class, toMerge.class]); } } else if (key === 'style') { ret.style = Object(shared_esm_bundler["F" /* normalizeStyle */])([ret.style, toMerge.style]); } else if (Object(shared_esm_bundler["u" /* isOn */])(key)) { const existing = ret[key]; const incoming = toMerge[key]; if (existing !== incoming) { ret[key] = existing ? [].concat(existing, toMerge[key]) : incoming; } } else { ret[key] = toMerge[key]; } } } return ret; } let devtools; function setDevtoolsHook(hook) { devtools = hook; } function devtoolsInitApp(app, version) { // TODO queue if devtools is undefined if (!devtools) return; devtools.emit("app:init" /* APP_INIT */, app, version, { Fragment, Text, Comment, Static }); } function devtoolsUnmountApp(app) { if (!devtools) return; devtools.emit("app:unmount" /* APP_UNMOUNT */, app); } const devtoolsComponentAdded = /*#__PURE__*/ createDevtoolsComponentHook("component:added" /* COMPONENT_ADDED */); const devtoolsComponentUpdated = /*#__PURE__*/ createDevtoolsComponentHook("component:updated" /* COMPONENT_UPDATED */); const devtoolsComponentRemoved = /*#__PURE__*/ createDevtoolsComponentHook("component:removed" /* COMPONENT_REMOVED */); function createDevtoolsComponentHook(hook) { return (component) => { if (!devtools) return; devtools.emit(hook, component.appContext.app, component.uid, component.parent ? component.parent.uid : undefined); }; } function devtoolsComponentEmit(component, event, params) { if (!devtools) return; devtools.emit("component:emit" /* COMPONENT_EMIT */, component.appContext.app, component, event, params); } function runtime_core_esm_bundler_emit(instance, event, ...args) { const props = instance.vnode.props || shared_esm_bundler["b" /* EMPTY_OBJ */]; if ((false)) {} if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentEmit(instance, event, args); } let handlerName = `on${Object(shared_esm_bundler["f" /* capitalize */])(event)}`; let handler = props[handlerName]; // for v-model update:xxx events, also trigger kebab-case equivalent // for props passed via kebab-case if (!handler && event.startsWith('update:')) { handlerName = `on${Object(shared_esm_bundler["f" /* capitalize */])(Object(shared_esm_bundler["l" /* hyphenate */])(event))}`; handler = props[handlerName]; } if (!handler) { handler = props[handlerName + `Once`]; if (!instance.emitted) { (instance.emitted = {})[handlerName] = true; } else if (instance.emitted[handlerName]) { return; } } if (handler) { callWithAsyncErrorHandling(handler, instance, 6 /* COMPONENT_EVENT_HANDLER */, args); } } function normalizeEmitsOptions(comp, appContext, asMixin = false) { const appId = appContext.app ? appContext.app._uid : -1; const cache = comp.__emits || (comp.__emits = {}); const cached = cache[appId]; if (cached !== undefined) { return cached; } const raw = comp.emits; let normalized = {}; // apply mixin/extends props let hasExtends = false; if (__VUE_OPTIONS_API__ && !Object(shared_esm_bundler["o" /* isFunction */])(comp)) { const extendEmits = (raw) => { hasExtends = true; Object(shared_esm_bundler["h" /* extend */])(normalized, normalizeEmitsOptions(raw, appContext, true)); }; if (!asMixin && appContext.mixins.length) { appContext.mixins.forEach(extendEmits); } if (comp.extends) { extendEmits(comp.extends); } if (comp.mixins) { comp.mixins.forEach(extendEmits); } } if (!raw && !hasExtends) { return (cache[appId] = null); } if (Object(shared_esm_bundler["n" /* isArray */])(raw)) { raw.forEach(key => (normalized[key] = null)); } else { Object(shared_esm_bundler["h" /* extend */])(normalized, raw); } return (cache[appId] = normalized); } // Check if an incoming prop key is a declared emit event listener. // e.g. With `emits: { click: null }`, props named `onClick` and `onclick` are // both considered matched listeners. function isEmitListener(options, key) { if (!options || !Object(shared_esm_bundler["u" /* isOn */])(key)) { return false; } key = key.replace(/Once$/, ''); return (Object(shared_esm_bundler["k" /* hasOwn */])(options, key[2].toLowerCase() + key.slice(3)) || Object(shared_esm_bundler["k" /* hasOwn */])(options, key.slice(2))); } function initProps(instance, rawProps, isStateful, // result of bitwise flag comparison isSSR = false) { const props = {}; const attrs = {}; Object(shared_esm_bundler["g" /* def */])(attrs, InternalObjectKey, 1); setFullProps(instance, rawProps, props, attrs); // validation if ((false)) {} if (isStateful) { // stateful instance.props = isSSR ? props : shallowReactive(props); } else { if (!instance.type.props) { // functional w/ optional props, props === attrs instance.props = attrs; } else { // functional w/ declared props instance.props = props; } } instance.attrs = attrs; } function updateProps(instance, rawProps, rawPrevProps, optimized) { const { props, attrs, vnode: { patchFlag } } = instance; const rawCurrentProps = toRaw(props); const [options] = instance.propsOptions; if ( // always force full diff if hmr is enabled true && (optimized || patchFlag > 0) && !(patchFlag & 16 /* FULL_PROPS */)) { if (patchFlag & 8 /* PROPS */) { // Compiler-generated props & no keys change, just set the updated // the props. const propsToUpdate = instance.vnode.dynamicProps; for (let i = 0; i < propsToUpdate.length; i++) { const key = propsToUpdate[i]; // PROPS flag guarantees rawProps to be non-null const value = rawProps[key]; if (options) { // attr / props separation was done on init and will be consistent // in this code path, so just check if attrs have it. if (Object(shared_esm_bundler["k" /* hasOwn */])(attrs, key)) { attrs[key] = value; } else { const camelizedKey = Object(shared_esm_bundler["e" /* camelize */])(key); props[camelizedKey] = resolvePropValue(options, rawCurrentProps, camelizedKey, value); } } else { attrs[key] = value; } } } } else { // full props update. setFullProps(instance, rawProps, props, attrs); // in case of dynamic props, check if we need to delete keys from // the props object let kebabKey; for (const key in rawCurrentProps) { if (!rawProps || // for camelCase (!Object(shared_esm_bundler["k" /* hasOwn */])(rawProps, key) && // it's possible the original props was passed in as kebab-case // and converted to camelCase (#955) ((kebabKey = Object(shared_esm_bundler["l" /* hyphenate */])(key)) === key || !Object(shared_esm_bundler["k" /* hasOwn */])(rawProps, kebabKey)))) { if (options) { if (rawPrevProps && // for camelCase (rawPrevProps[key] !== undefined || // for kebab-case rawPrevProps[kebabKey] !== undefined)) { props[key] = resolvePropValue(options, rawProps || shared_esm_bundler["b" /* EMPTY_OBJ */], key, undefined); } } else { delete props[key]; } } } // in the case of functional component w/o props declaration, props and // attrs point to the same object so it should already have been updated. if (attrs !== rawCurrentProps) { for (const key in attrs) { if (!rawProps || !Object(shared_esm_bundler["k" /* hasOwn */])(rawProps, key)) { delete attrs[key]; } } } } // trigger updates for $attrs in case it's used in component slots trigger(instance, "set" /* SET */, '$attrs'); if (false) {} } function setFullProps(instance, rawProps, props, attrs) { const [options, needCastKeys] = instance.propsOptions; if (rawProps) { for (const key in rawProps) { const value = rawProps[key]; // key, ref are reserved and never passed down if (Object(shared_esm_bundler["w" /* isReservedProp */])(key)) { continue; } // prop option names are camelized during normalization, so to support // kebab -> camel conversion here we need to camelize the key. let camelKey; if (options && Object(shared_esm_bundler["k" /* hasOwn */])(options, (camelKey = Object(shared_esm_bundler["e" /* camelize */])(key)))) { props[camelKey] = value; } else if (!isEmitListener(instance.emitsOptions, key)) { // Any non-declared (either as a prop or an emitted event) props are put // into a separate `attrs` object for spreading. Make sure to preserve // original key casing attrs[key] = value; } } } if (needCastKeys) { const rawCurrentProps = toRaw(props); for (let i = 0; i < needCastKeys.length; i++) { const key = needCastKeys[i]; props[key] = resolvePropValue(options, rawCurrentProps, key, rawCurrentProps[key]); } } } function resolvePropValue(options, props, key, value) { const opt = options[key]; if (opt != null) { const hasDefault = Object(shared_esm_bundler["k" /* hasOwn */])(opt, 'default'); // default values if (hasDefault && value === undefined) { const defaultValue = opt.default; value = opt.type !== Function && Object(shared_esm_bundler["o" /* isFunction */])(defaultValue) ? defaultValue(props) : defaultValue; } // boolean casting if (opt[0 /* shouldCast */]) { if (!Object(shared_esm_bundler["k" /* hasOwn */])(props, key) && !hasDefault) { value = false; } else if (opt[1 /* shouldCastTrue */] && (value === '' || value === Object(shared_esm_bundler["l" /* hyphenate */])(key))) { value = true; } } } return value; } function normalizePropsOptions(comp, appContext, asMixin = false) { const appId = appContext.app ? appContext.app._uid : -1; const cache = comp.__props || (comp.__props = {}); const cached = cache[appId]; if (cached) { return cached; } const raw = comp.props; const normalized = {}; const needCastKeys = []; // apply mixin/extends props let hasExtends = false; if (__VUE_OPTIONS_API__ && !Object(shared_esm_bundler["o" /* isFunction */])(comp)) { const extendProps = (raw) => { hasExtends = true; const [props, keys] = normalizePropsOptions(raw, appContext, true); Object(shared_esm_bundler["h" /* extend */])(normalized, props); if (keys) needCastKeys.push(...keys); }; if (!asMixin && appContext.mixins.length) { appContext.mixins.forEach(extendProps); } if (comp.extends) { extendProps(comp.extends); } if (comp.mixins) { comp.mixins.forEach(extendProps); } } if (!raw && !hasExtends) { return (cache[appId] = shared_esm_bundler["a" /* EMPTY_ARR */]); } if (Object(shared_esm_bundler["n" /* isArray */])(raw)) { for (let i = 0; i < raw.length; i++) { if (false) {} const normalizedKey = Object(shared_esm_bundler["e" /* camelize */])(raw[i]); if (validatePropName(normalizedKey)) { normalized[normalizedKey] = shared_esm_bundler["b" /* EMPTY_OBJ */]; } } } else if (raw) { if (false) {} for (const key in raw) { const normalizedKey = Object(shared_esm_bundler["e" /* camelize */])(key); if (validatePropName(normalizedKey)) { const opt = raw[key]; const prop = (normalized[normalizedKey] = Object(shared_esm_bundler["n" /* isArray */])(opt) || Object(shared_esm_bundler["o" /* isFunction */])(opt) ? { type: opt } : opt); if (prop) { const booleanIndex = getTypeIndex(Boolean, prop.type); const stringIndex = getTypeIndex(String, prop.type); prop[0 /* shouldCast */] = booleanIndex > -1; prop[1 /* shouldCastTrue */] = stringIndex < 0 || booleanIndex < stringIndex; // if the prop needs boolean casting or default value if (booleanIndex > -1 || Object(shared_esm_bundler["k" /* hasOwn */])(prop, 'default')) { needCastKeys.push(normalizedKey); } } } } } return (cache[appId] = [normalized, needCastKeys]); } // use function string name to check type constructors // so that it works across vms / iframes. function getType(ctor) { const match = ctor && ctor.toString().match(/^\s*function (\w+)/); return match ? match[1] : ''; } function isSameType(a, b) { return getType(a) === getType(b); } function getTypeIndex(type, expectedTypes) { if (Object(shared_esm_bundler["n" /* isArray */])(expectedTypes)) { for (let i = 0, len = expectedTypes.length; i < len; i++) { if (isSameType(expectedTypes[i], type)) { return i; } } } else if (Object(shared_esm_bundler["o" /* isFunction */])(expectedTypes)) { return isSameType(expectedTypes, type) ? 0 : -1; } return -1; } /** * dev only */ function validateProps(props, instance) { const rawValues = toRaw(props); const options = instance.propsOptions[0]; for (const key in options) { let opt = options[key]; if (opt == null) continue; validateProp(key, rawValues[key], opt, !Object(shared_esm_bundler["k" /* hasOwn */])(rawValues, key)); } } /** * dev only */ function validatePropName(key) { if (key[0] !== '$') { return true; } else if ((false)) {} return false; } /** * dev only */ function validateProp(name, value, prop, isAbsent) { const { type, required, validator } = prop; // required! if (required && isAbsent) { warn('Missing required prop: "' + name + '"'); return; } // missing but optional if (value == null && !prop.required) { return; } // type check if (type != null && type !== true) { let isValid = false; const types = Object(shared_esm_bundler["n" /* isArray */])(type) ? type : [type]; const expectedTypes = []; // value is valid as long as one of the specified types match for (let i = 0; i < types.length && !isValid; i++) { const { valid, expectedType } = assertType(value, types[i]); expectedTypes.push(expectedType || ''); isValid = valid; } if (!isValid) { warn(getInvalidTypeMessage(name, value, expectedTypes)); return; } } // custom validator if (validator && !validator(value)) { warn('Invalid prop: custom validator check failed for prop "' + name + '".'); } } const isSimpleType = /*#__PURE__*/ Object(shared_esm_bundler["D" /* makeMap */])('String,Number,Boolean,Function,Symbol'); /** * dev only */ function assertType(value, type) { let valid; const expectedType = getType(type); if (isSimpleType(expectedType)) { const t = typeof value; valid = t === expectedType.toLowerCase(); // for primitive wrapper objects if (!valid && t === 'object') { valid = value instanceof type; } } else if (expectedType === 'Object') { valid = Object(shared_esm_bundler["t" /* isObject */])(value); } else if (expectedType === 'Array') { valid = Object(shared_esm_bundler["n" /* isArray */])(value); } else { valid = value instanceof type; } return { valid, expectedType }; } /** * dev only */ function getInvalidTypeMessage(name, value, expectedTypes) { let message = `Invalid prop: type check failed for prop "${name}".` + ` Expected ${expectedTypes.map(shared_esm_bundler["f" /* capitalize */]).join(', ')}`; const expectedType = expectedTypes[0]; const receivedType = Object(shared_esm_bundler["I" /* toRawType */])(value); const expectedValue = styleValue(value, expectedType); const receivedValue = styleValue(value, receivedType); // check if we need to specify expected value if (expectedTypes.length === 1 && isExplicable(expectedType) && !runtime_core_esm_bundler_isBoolean(expectedType, receivedType)) { message += ` with value ${expectedValue}`; } message += `, got ${receivedType} `; // check if we need to specify received value if (isExplicable(receivedType)) { message += `with value ${receivedValue}.`; } return message; } /** * dev only */ function styleValue(value, type) { if (type === 'String') { return `"${value}"`; } else if (type === 'Number') { return `${Number(value)}`; } else { return `${value}`; } } /** * dev only */ function isExplicable(type) { const explicitTypes = ['string', 'number', 'boolean']; return explicitTypes.some(elem => type.toLowerCase() === elem); } /** * dev only */ function runtime_core_esm_bundler_isBoolean(...args) { return args.some(elem => elem.toLowerCase() === 'boolean'); } function injectHook(type, hook, target = currentInstance, prepend = false) { if (target) { const hooks = target[type] || (target[type] = []); // cache the error handling wrapper for injected hooks so the same hook // can be properly deduped by the scheduler. "__weh" stands for "with error // handling". const wrappedHook = hook.__weh || (hook.__weh = (...args) => { if (target.isUnmounted) { return; } // disable tracking inside all lifecycle hooks // since they can potentially be called inside effects. pauseTracking(); // Set currentInstance during hook invocation. // This assumes the hook does not synchronously trigger other hooks, which // can only be false when the user does something really funky. setCurrentInstance(target); const res = callWithAsyncErrorHandling(hook, target, type, args); setCurrentInstance(null); resetTracking(); return res; }); if (prepend) { hooks.unshift(wrappedHook); } else { hooks.push(wrappedHook); } return wrappedHook; } else if ((false)) {} } const createHook = (lifecycle) => (hook, target = currentInstance) => // post-create lifecycle registrations are noops during SSR !isInSSRComponentSetup && injectHook(lifecycle, hook, target); const onBeforeMount = createHook("bm" /* BEFORE_MOUNT */); const onMounted = createHook("m" /* MOUNTED */); const onBeforeUpdate = createHook("bu" /* BEFORE_UPDATE */); const onUpdated = createHook("u" /* UPDATED */); const onBeforeUnmount = createHook("bum" /* BEFORE_UNMOUNT */); const onUnmounted = createHook("um" /* UNMOUNTED */); const onRenderTriggered = createHook("rtg" /* RENDER_TRIGGERED */); const onRenderTracked = createHook("rtc" /* RENDER_TRACKED */); const onErrorCaptured = (hook, target = currentInstance) => { injectHook("ec" /* ERROR_CAPTURED */, hook, target); }; function useTransitionState() { const state = { isMounted: false, isLeaving: false, isUnmounting: false, leavingVNodes: new Map() }; onMounted(() => { state.isMounted = true; }); onBeforeUnmount(() => { state.isUnmounting = true; }); return state; } const TransitionHookValidator = [Function, Array]; const BaseTransitionImpl = { name: `BaseTransition`, props: { mode: String, appear: Boolean, persisted: Boolean, // enter onBeforeEnter: TransitionHookValidator, onEnter: TransitionHookValidator, onAfterEnter: TransitionHookValidator, onEnterCancelled: TransitionHookValidator, // leave onBeforeLeave: TransitionHookValidator, onLeave: TransitionHookValidator, onAfterLeave: TransitionHookValidator, onLeaveCancelled: TransitionHookValidator, // appear onBeforeAppear: TransitionHookValidator, onAppear: TransitionHookValidator, onAfterAppear: TransitionHookValidator, onAppearCancelled: TransitionHookValidator }, setup(props, { slots }) { const instance = getCurrentInstance(); const state = useTransitionState(); let prevTransitionKey; return () => { const children = slots.default && getTransitionRawChildren(slots.default(), true); if (!children || !children.length) { return; } // warn multiple elements if (false) {} // there's no need to track reactivity for these props so use the raw // props for a bit better perf const rawProps = toRaw(props); const { mode } = rawProps; // check mode if (false) {} // at this point children has a guaranteed length of 1. const child = children[0]; if (state.isLeaving) { return emptyPlaceholder(child); } // in the case of , we need to // compare the type of the kept-alive children. const innerChild = getKeepAliveChild(child); if (!innerChild) { return emptyPlaceholder(child); } const enterHooks = (innerChild.transition = resolveTransitionHooks(innerChild, rawProps, state, instance)); const oldChild = instance.subTree; const oldInnerChild = oldChild && getKeepAliveChild(oldChild); let transitionKeyChanged = false; const { getTransitionKey } = innerChild.type; if (getTransitionKey) { const key = getTransitionKey(); if (prevTransitionKey === undefined) { prevTransitionKey = key; } else if (key !== prevTransitionKey) { prevTransitionKey = key; transitionKeyChanged = true; } } // handle mode if (oldInnerChild && oldInnerChild.type !== Comment && (!isSameVNodeType(innerChild, oldInnerChild) || transitionKeyChanged)) { const leavingHooks = resolveTransitionHooks(oldInnerChild, rawProps, state, instance); // update old tree's hooks in case of dynamic transition setTransitionHooks(oldInnerChild, leavingHooks); // switching between different views if (mode === 'out-in') { state.isLeaving = true; // return placeholder node and queue update when leave finishes leavingHooks.afterLeave = () => { state.isLeaving = false; instance.update(); }; return emptyPlaceholder(child); } else if (mode === 'in-out') { leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => { const leavingVNodesCache = getLeavingNodesForType(state, oldInnerChild); leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild; // early removal callback el._leaveCb = () => { earlyRemove(); el._leaveCb = undefined; delete enterHooks.delayedLeave; }; enterHooks.delayedLeave = delayedLeave; }; } } return child; }; } }; // export the public type for h/tsx inference // also to avoid inline import() in generated d.ts files const BaseTransition = BaseTransitionImpl; function getLeavingNodesForType(state, vnode) { const { leavingVNodes } = state; let leavingVNodesCache = leavingVNodes.get(vnode.type); if (!leavingVNodesCache) { leavingVNodesCache = Object.create(null); leavingVNodes.set(vnode.type, leavingVNodesCache); } return leavingVNodesCache; } // The transition hooks are attached to the vnode as vnode.transition // and will be called at appropriate timing in the renderer. function resolveTransitionHooks(vnode, { appear, persisted = false, onBeforeEnter, onEnter, onAfterEnter, onEnterCancelled, onBeforeLeave, onLeave, onAfterLeave, onLeaveCancelled, onBeforeAppear, onAppear, onAfterAppear, onAppearCancelled }, state, instance) { const key = String(vnode.key); const leavingVNodesCache = getLeavingNodesForType(state, vnode); const callHook = (hook, args) => { hook && callWithAsyncErrorHandling(hook, instance, 9 /* TRANSITION_HOOK */, args); }; const hooks = { persisted, beforeEnter(el) { let hook = onBeforeEnter; if (!state.isMounted) { if (appear) { hook = onBeforeAppear || onBeforeEnter; } else { return; } } // for same element (v-show) if (el._leaveCb) { el._leaveCb(true /* cancelled */); } // for toggled element with same key (v-if) const leavingVNode = leavingVNodesCache[key]; if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el._leaveCb) { // force early removal (not cancelled) leavingVNode.el._leaveCb(); } callHook(hook, [el]); }, enter(el) { let hook = onEnter; let afterHook = onAfterEnter; let cancelHook = onEnterCancelled; if (!state.isMounted) { if (appear) { hook = onAppear || onEnter; afterHook = onAfterAppear || onAfterEnter; cancelHook = onAppearCancelled || onEnterCancelled; } else { return; } } let called = false; const done = (el._enterCb = (cancelled) => { if (called) return; called = true; if (cancelled) { callHook(cancelHook, [el]); } else { callHook(afterHook, [el]); } if (hooks.delayedLeave) { hooks.delayedLeave(); } el._enterCb = undefined; }); if (hook) { hook(el, done); if (hook.length <= 1) { done(); } } else { done(); } }, leave(el, remove) { const key = String(vnode.key); if (el._enterCb) { el._enterCb(true /* cancelled */); } if (state.isUnmounting) { return remove(); } callHook(onBeforeLeave, [el]); let called = false; const done = (el._leaveCb = (cancelled) => { if (called) return; called = true; remove(); if (cancelled) { callHook(onLeaveCancelled, [el]); } else { callHook(onAfterLeave, [el]); } el._leaveCb = undefined; if (leavingVNodesCache[key] === vnode) { delete leavingVNodesCache[key]; } }); leavingVNodesCache[key] = vnode; if (onLeave) { onLeave(el, done); if (onLeave.length <= 1) { done(); } } else { done(); } } }; return hooks; } // the placeholder really only handles one special case: KeepAlive // in the case of a KeepAlive in a leave phase we need to return a KeepAlive // placeholder with empty content to avoid the KeepAlive instance from being // unmounted. function emptyPlaceholder(vnode) { if (isKeepAlive(vnode)) { vnode = cloneVNode(vnode); vnode.children = null; return vnode; } } function getKeepAliveChild(vnode) { return isKeepAlive(vnode) ? vnode.children ? vnode.children[0] : undefined : vnode; } function setTransitionHooks(vnode, hooks) { if (vnode.shapeFlag & 6 /* COMPONENT */ && vnode.component) { setTransitionHooks(vnode.component.subTree, hooks); } else { vnode.transition = hooks; } } function getTransitionRawChildren(children, keepComment = false) { let ret = []; let keyedFragmentCount = 0; for (let i = 0; i < children.length; i++) { const child = children[i]; // handle fragment children case, e.g. v-for if (child.type === Fragment) { if (child.patchFlag & 128 /* KEYED_FRAGMENT */) keyedFragmentCount++; ret = ret.concat(getTransitionRawChildren(child.children, keepComment)); } // comment placeholders should be skipped, e.g. v-if else if (keepComment || child.type !== Comment) { ret.push(child); } } // #1126 if a transition children list contains multiple sub fragments, these // fragments will be merged into a flat children array. Since each v-for // fragment may contain different static bindings inside, we need to de-top // these children to force full diffs to ensure correct behavior. if (keyedFragmentCount > 1) { for (let i = 0; i < ret.length; i++) { ret[i].patchFlag = -2 /* BAIL */; } } return ret; } const isKeepAlive = (vnode) => vnode.type.__isKeepAlive; const KeepAliveImpl = { name: `KeepAlive`, // Marker for special handling inside the renderer. We are not using a === // check directly on KeepAlive in the renderer, because importing it directly // would prevent it from being tree-shaken. __isKeepAlive: true, inheritRef: true, props: { include: [String, RegExp, Array], exclude: [String, RegExp, Array], max: [String, Number] }, setup(props, { slots }) { const cache = new Map(); const keys = new Set(); let current = null; const instance = getCurrentInstance(); const parentSuspense = instance.suspense; // KeepAlive communicates with the instantiated renderer via the // ctx where the renderer passes in its internals, // and the KeepAlive instance exposes activate/deactivate implementations. // The whole point of this is to avoid importing KeepAlive directly in the // renderer to facilitate tree-shaking. const sharedContext = instance.ctx; const { renderer: { p: patch, m: move, um: _unmount, o: { createElement } } } = sharedContext; const storageContainer = createElement('div'); sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => { const instance = vnode.component; move(vnode, container, anchor, 0 /* ENTER */, parentSuspense); // in case props have changed patch(instance.vnode, vnode, container, anchor, instance, parentSuspense, isSVG, optimized); queuePostRenderEffect(() => { instance.isDeactivated = false; if (instance.a) { Object(shared_esm_bundler["m" /* invokeArrayFns */])(instance.a); } const vnodeHook = vnode.props && vnode.props.onVnodeMounted; if (vnodeHook) { invokeVNodeHook(vnodeHook, instance.parent, vnode); } }, parentSuspense); }; sharedContext.deactivate = (vnode) => { const instance = vnode.component; move(vnode, storageContainer, null, 1 /* LEAVE */, parentSuspense); queuePostRenderEffect(() => { if (instance.da) { Object(shared_esm_bundler["m" /* invokeArrayFns */])(instance.da); } const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted; if (vnodeHook) { invokeVNodeHook(vnodeHook, instance.parent, vnode); } instance.isDeactivated = true; }, parentSuspense); }; function unmount(vnode) { // reset the shapeFlag so it can be properly unmounted resetShapeFlag(vnode); _unmount(vnode, instance, parentSuspense); } function pruneCache(filter) { cache.forEach((vnode, key) => { const name = getName(vnode.type); if (name && (!filter || !filter(name))) { pruneCacheEntry(key); } }); } function pruneCacheEntry(key) { const cached = cache.get(key); if (!current || cached.type !== current.type) { unmount(cached); } else if (current) { // current active instance should no longer be kept-alive. // we can't unmount it now but it might be later, so reset its flag now. resetShapeFlag(current); } cache.delete(key); keys.delete(key); } watch(() => [props.include, props.exclude], ([include, exclude]) => { include && pruneCache(name => matches(include, name)); exclude && pruneCache(name => matches(exclude, name)); }); // cache sub tree in beforeMount/Update (i.e. right after the render) let pendingCacheKey = null; const cacheSubtree = () => { // fix #1621, the pendingCacheKey could be 0 if (pendingCacheKey != null) { cache.set(pendingCacheKey, instance.subTree); } }; onBeforeMount(cacheSubtree); onBeforeUpdate(cacheSubtree); onBeforeUnmount(() => { cache.forEach(cached => { const { subTree, suspense } = instance; if (cached.type === subTree.type) { // current instance will be unmounted as part of keep-alive's unmount resetShapeFlag(subTree); // but invoke its deactivated hook here const da = subTree.component.da; da && queuePostRenderEffect(da, suspense); return; } unmount(cached); }); }); return () => { pendingCacheKey = null; if (!slots.default) { return null; } const children = slots.default(); let vnode = children[0]; if (children.length > 1) { if ((false)) {} current = null; return children; } else if (!isVNode(vnode) || !(vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */)) { current = null; return vnode; } const comp = vnode.type; const name = getName(comp); const { include, exclude, max } = props; if ((include && (!name || !matches(include, name))) || (exclude && name && matches(exclude, name))) { return (current = vnode); } const key = vnode.key == null ? comp : vnode.key; const cachedVNode = cache.get(key); // clone vnode if it's reused because we are going to mutate it if (vnode.el) { vnode = cloneVNode(vnode); } // #1513 it's possible for the returned vnode to be cloned due to attr // fallthrough or scopeId, so the vnode here may not be the final vnode // that is mounted. Instead of caching it directly, we store the pending // key and cache `instance.subTree` (the normalized vnode) in // beforeMount/beforeUpdate hooks. pendingCacheKey = key; if (cachedVNode) { // copy over mounted state vnode.el = cachedVNode.el; vnode.component = cachedVNode.component; if (vnode.transition) { // recursively update transition hooks on subTree setTransitionHooks(vnode, vnode.transition); } // avoid vnode being mounted as fresh vnode.shapeFlag |= 512 /* COMPONENT_KEPT_ALIVE */; // make this key the freshest keys.delete(key); keys.add(key); } else { keys.add(key); // prune oldest entry if (max && keys.size > parseInt(max, 10)) { pruneCacheEntry(keys.values().next().value); } } // avoid vnode being unmounted vnode.shapeFlag |= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; current = vnode; return vnode; }; } }; // export the public type for h/tsx inference // also to avoid inline import() in generated d.ts files const KeepAlive = KeepAliveImpl; function getName(comp) { return comp.displayName || comp.name; } function matches(pattern, name) { if (Object(shared_esm_bundler["n" /* isArray */])(pattern)) { return pattern.some((p) => matches(p, name)); } else if (Object(shared_esm_bundler["z" /* isString */])(pattern)) { return pattern.split(',').indexOf(name) > -1; } else if (pattern.test) { return pattern.test(name); } /* istanbul ignore next */ return false; } function onActivated(hook, target) { registerKeepAliveHook(hook, "a" /* ACTIVATED */, target); } function onDeactivated(hook, target) { registerKeepAliveHook(hook, "da" /* DEACTIVATED */, target); } function registerKeepAliveHook(hook, type, target = currentInstance) { // cache the deactivate branch check wrapper for injected hooks so the same // hook can be properly deduped by the scheduler. "__wdc" stands for "with // deactivation check". const wrappedHook = hook.__wdc || (hook.__wdc = () => { // only fire the hook if the target instance is NOT in a deactivated branch. let current = target; while (current) { if (current.isDeactivated) { return; } current = current.parent; } hook(); }); injectHook(type, wrappedHook, target); // In addition to registering it on the target instance, we walk up the parent // chain and register it on all ancestor instances that are keep-alive roots. // This avoids the need to walk the entire component tree when invoking these // hooks, and more importantly, avoids the need to track child components in // arrays. if (target) { let current = target.parent; while (current && current.parent) { if (isKeepAlive(current.parent.vnode)) { injectToKeepAliveRoot(wrappedHook, type, target, current); } current = current.parent; } } } function injectToKeepAliveRoot(hook, type, target, keepAliveRoot) { // injectHook wraps the original for error handling, so make sure to remove // the wrapped version. const injected = injectHook(type, hook, keepAliveRoot, true /* prepend */); onUnmounted(() => { Object(shared_esm_bundler["G" /* remove */])(keepAliveRoot[type], injected); }, target); } function resetShapeFlag(vnode) { let shapeFlag = vnode.shapeFlag; if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { shapeFlag -= 256 /* COMPONENT_SHOULD_KEEP_ALIVE */; } if (shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { shapeFlag -= 512 /* COMPONENT_KEPT_ALIVE */; } vnode.shapeFlag = shapeFlag; } const isInternalKey = (key) => key[0] === '_' || key === '$stable'; const normalizeSlotValue = (value) => Object(shared_esm_bundler["n" /* isArray */])(value) ? value.map(normalizeVNode) : [normalizeVNode(value)]; const normalizeSlot = (key, rawSlot, ctx) => withCtx((props) => { if (false) {} return normalizeSlotValue(rawSlot(props)); }, ctx); const normalizeObjectSlots = (rawSlots, slots) => { const ctx = rawSlots._ctx; for (const key in rawSlots) { if (isInternalKey(key)) continue; const value = rawSlots[key]; if (Object(shared_esm_bundler["o" /* isFunction */])(value)) { slots[key] = normalizeSlot(key, value, ctx); } else if (value != null) { if ((false)) {} const normalized = normalizeSlotValue(value); slots[key] = () => normalized; } } }; const normalizeVNodeSlots = (instance, children) => { if (false) {} const normalized = normalizeSlotValue(children); instance.slots.default = () => normalized; }; const initSlots = (instance, children) => { if (instance.vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { const type = children._; if (type) { instance.slots = children; // make compiler marker non-enumerable Object(shared_esm_bundler["g" /* def */])(children, '_', type); } else { normalizeObjectSlots(children, (instance.slots = {})); } } else { instance.slots = {}; if (children) { normalizeVNodeSlots(instance, children); } } Object(shared_esm_bundler["g" /* def */])(instance.slots, InternalObjectKey, 1); }; const updateSlots = (instance, children) => { const { vnode, slots } = instance; let needDeletionCheck = true; let deletionComparisonTarget = shared_esm_bundler["b" /* EMPTY_OBJ */]; if (vnode.shapeFlag & 32 /* SLOTS_CHILDREN */) { const type = children._; if (type) { // compiled slots. if (false) {} else if (type === 1 /* STABLE */) { // compiled AND stable. // no need to update, and skip stale slots removal. needDeletionCheck = false; } else { // compiled but dynamic (v-if/v-for on slots) - update slots, but skip // normalization. Object(shared_esm_bundler["h" /* extend */])(slots, children); } } else { needDeletionCheck = !children.$stable; normalizeObjectSlots(children, slots); } deletionComparisonTarget = children; } else if (children) { // non slot object children (direct value) passed to a component normalizeVNodeSlots(instance, children); deletionComparisonTarget = { default: 1 }; } // delete stale slots if (needDeletionCheck) { for (const key in slots) { if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { delete slots[key]; } } } }; /** Runtime helper for applying directives to a vnode. Example usage: const comp = resolveComponent('comp') const foo = resolveDirective('foo') const bar = resolveDirective('bar') return withDirectives(h(comp), [ [foo, this.x], [bar, this.y] ]) */ const isBuiltInDirective = /*#__PURE__*/ Object(shared_esm_bundler["D" /* makeMap */])('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text'); function validateDirectiveName(name) { if (isBuiltInDirective(name)) { warn('Do not use built-in directive ids as custom directive id: ' + name); } } /** * Adds directives to a VNode. */ function withDirectives(vnode, directives) { const internalInstance = currentRenderingInstance; if (internalInstance === null) { ( false) && false; return vnode; } const instance = internalInstance.proxy; const bindings = vnode.dirs || (vnode.dirs = []); for (let i = 0; i < directives.length; i++) { let [dir, value, arg, modifiers = shared_esm_bundler["b" /* EMPTY_OBJ */]] = directives[i]; if (Object(shared_esm_bundler["o" /* isFunction */])(dir)) { dir = { mounted: dir, updated: dir }; } bindings.push({ dir, instance, value, oldValue: void 0, arg, modifiers }); } return vnode; } function invokeDirectiveHook(vnode, prevVNode, instance, name) { const bindings = vnode.dirs; const oldBindings = prevVNode && prevVNode.dirs; for (let i = 0; i < bindings.length; i++) { const binding = bindings[i]; if (oldBindings) { binding.oldValue = oldBindings[i].value; } const hook = binding.dir[name]; if (hook) { callWithAsyncErrorHandling(hook, instance, 8 /* DIRECTIVE_HOOK */, [ vnode.el, binding, vnode, prevVNode ]); } } } function createAppContext() { return { app: null, config: { isNativeTag: shared_esm_bundler["c" /* NO */], performance: false, globalProperties: {}, optionMergeStrategies: {}, isCustomElement: shared_esm_bundler["c" /* NO */], errorHandler: undefined, warnHandler: undefined }, mixins: [], components: {}, directives: {}, provides: Object.create(null) }; } let runtime_core_esm_bundler_uid = 0; function createAppAPI(render, hydrate) { return function createApp(rootComponent, rootProps = null) { if (rootProps != null && !Object(shared_esm_bundler["t" /* isObject */])(rootProps)) { ( false) && false; rootProps = null; } const context = createAppContext(); const installedPlugins = new Set(); let isMounted = false; const app = (context.app = { _uid: runtime_core_esm_bundler_uid++, _component: rootComponent, _props: rootProps, _container: null, _context: context, version, get config() { return context.config; }, set config(v) { if ((false)) {} }, use(plugin, ...options) { if (installedPlugins.has(plugin)) { ( false) && false; } else if (plugin && Object(shared_esm_bundler["o" /* isFunction */])(plugin.install)) { installedPlugins.add(plugin); plugin.install(app, ...options); } else if (Object(shared_esm_bundler["o" /* isFunction */])(plugin)) { installedPlugins.add(plugin); plugin(app, ...options); } else if ((false)) {} return app; }, mixin(mixin) { if (__VUE_OPTIONS_API__) { if (!context.mixins.includes(mixin)) { context.mixins.push(mixin); } else if ((false)) {} } else if ((false)) {} return app; }, component(name, component) { if ((false)) {} if (!component) { return context.components[name]; } if (false) {} context.components[name] = component; return app; }, directive(name, directive) { if ((false)) {} if (!directive) { return context.directives[name]; } if (false) {} context.directives[name] = directive; return app; }, mount(rootContainer, isHydrate) { if (!isMounted) { const vnode = createVNode(rootComponent, rootProps); // store app context on the root VNode. // this will be set on the root instance on initial mount. vnode.appContext = context; // HMR root reload if ((false)) {} if (isHydrate && hydrate) { hydrate(vnode, rootContainer); } else { render(vnode, rootContainer); } isMounted = true; app._container = rootContainer; rootContainer.__vue_app__ = app; if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsInitApp(app, version); } return vnode.component.proxy; } else if ((false)) {} }, unmount() { if (isMounted) { render(null, app._container); if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsUnmountApp(app); } } else if ((false)) {} }, provide(key, value) { if (false) {} // TypeScript doesn't allow symbols as index type // https://github.com/Microsoft/TypeScript/issues/24587 context.provides[key] = value; return app; } }); return app; }; } let hasMismatch = false; const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject'; const isComment = (node) => node.nodeType === 8 /* COMMENT */; // Note: hydration is DOM-specific // But we have to place it in core due to tight coupling with core - splitting // it out creates a ton of unnecessary complexity. // Hydration also depends on some renderer internal logic which needs to be // passed in via arguments. function createHydrationFunctions(rendererInternals) { const { mt: mountComponent, p: patch, o: { patchProp, nextSibling, parentNode, remove, insert, createComment } } = rendererInternals; const hydrate = (vnode, container) => { if (false) {} hasMismatch = false; hydrateNode(container.firstChild, vnode, null, null); flushPostFlushCbs(); if (hasMismatch && !false) { // this error should show up in production console.error(`Hydration completed but contains mismatches.`); } }; const hydrateNode = (node, vnode, parentComponent, parentSuspense, optimized = false) => { const isFragmentStart = isComment(node) && node.data === '['; const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, isFragmentStart); const { type, ref, shapeFlag } = vnode; const domType = node.nodeType; vnode.el = node; let nextNode = null; switch (type) { case Text: if (domType !== 3 /* TEXT */) { nextNode = onMismatch(); } else { if (node.data !== vnode.children) { hasMismatch = true; ( false) && false; node.data = vnode.children; } nextNode = nextSibling(node); } break; case Comment: if (domType !== 8 /* COMMENT */ || isFragmentStart) { nextNode = onMismatch(); } else { nextNode = nextSibling(node); } break; case Static: if (domType !== 1 /* ELEMENT */) { nextNode = onMismatch(); } else { // determine anchor, adopt content nextNode = node; // if the static vnode has its content stripped during build, // adopt it from the server-rendered HTML. const needToAdoptContent = !vnode.children.length; for (let i = 0; i < vnode.staticCount; i++) { if (needToAdoptContent) vnode.children += nextNode.outerHTML; if (i === vnode.staticCount - 1) { vnode.anchor = nextNode; } nextNode = nextSibling(nextNode); } return nextNode; } break; case Fragment: if (!isFragmentStart) { nextNode = onMismatch(); } else { nextNode = hydrateFragment(node, vnode, parentComponent, parentSuspense, optimized); } break; default: if (shapeFlag & 1 /* ELEMENT */) { if (domType !== 1 /* ELEMENT */ || vnode.type !== node.tagName.toLowerCase()) { nextNode = onMismatch(); } else { nextNode = hydrateElement(node, vnode, parentComponent, parentSuspense, optimized); } } else if (shapeFlag & 6 /* COMPONENT */) { // when setting up the render effect, if the initial vnode already // has .el set, the component will perform hydration instead of mount // on its sub-tree. const container = parentNode(node); const hydrateComponent = () => { mountComponent(vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container), optimized); }; // async component const loadAsync = vnode.type.__asyncLoader; if (loadAsync) { loadAsync().then(hydrateComponent); } else { hydrateComponent(); } // component may be async, so in the case of fragments we cannot rely // on component's rendered output to determine the end of the fragment // instead, we do a lookahead to find the end anchor node. nextNode = isFragmentStart ? locateClosingAsyncAnchor(node) : nextSibling(node); } else if (shapeFlag & 64 /* TELEPORT */) { if (domType !== 8 /* COMMENT */) { nextNode = onMismatch(); } else { nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, optimized, rendererInternals, hydrateChildren); } } else if ( shapeFlag & 128 /* SUSPENSE */) { nextNode = vnode.type.hydrate(node, vnode, parentComponent, parentSuspense, isSVGContainer(parentNode(node)), optimized, rendererInternals, hydrateNode); } else if ((false)) {} } if (ref != null && parentComponent) { setRef(ref, null, parentComponent, parentSuspense, vnode); } return nextNode; }; const hydrateElement = (el, vnode, parentComponent, parentSuspense, optimized) => { optimized = optimized || !!vnode.dynamicChildren; const { props, patchFlag, shapeFlag, dirs } = vnode; // skip props & children if this is hoisted static nodes if (patchFlag !== -1 /* HOISTED */) { if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'created'); } // props if (props) { if (!optimized || (patchFlag & 16 /* FULL_PROPS */ || patchFlag & 32 /* HYDRATE_EVENTS */)) { for (const key in props) { if (!Object(shared_esm_bundler["w" /* isReservedProp */])(key) && Object(shared_esm_bundler["u" /* isOn */])(key)) { patchProp(el, key, null, props[key]); } } } else if (props.onClick) { // Fast path for click listeners (which is most often) to avoid // iterating through props. patchProp(el, 'onClick', null, props.onClick); } } // vnode / directive hooks let vnodeHooks; if ((vnodeHooks = props && props.onVnodeBeforeMount)) { invokeVNodeHook(vnodeHooks, parentComponent, vnode); } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); } if ((vnodeHooks = props && props.onVnodeMounted) || dirs) { queueEffectWithSuspense(() => { vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode); dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); }, parentSuspense); } // children if (shapeFlag & 16 /* ARRAY_CHILDREN */ && // skip if element has innerHTML / textContent !(props && (props.innerHTML || props.textContent))) { let next = hydrateChildren(el.firstChild, vnode, el, parentComponent, parentSuspense, optimized); let hasWarned = false; while (next) { hasMismatch = true; if (false) {} // The SSRed DOM contains more nodes than it should. Remove them. const cur = next; next = next.nextSibling; remove(cur); } } else if (shapeFlag & 8 /* TEXT_CHILDREN */) { if (el.textContent !== vnode.children) { hasMismatch = true; ( false) && false; el.textContent = vnode.children; } } } return el.nextSibling; }; const hydrateChildren = (node, vnode, container, parentComponent, parentSuspense, optimized) => { optimized = optimized || !!vnode.dynamicChildren; const children = vnode.children; const l = children.length; let hasWarned = false; for (let i = 0; i < l; i++) { const vnode = optimized ? children[i] : (children[i] = normalizeVNode(children[i])); if (node) { node = hydrateNode(node, vnode, parentComponent, parentSuspense, optimized); } else { hasMismatch = true; if (false) {} // the SSRed DOM didn't contain enough nodes. Mount the missing ones. patch(null, vnode, container, null, parentComponent, parentSuspense, isSVGContainer(container)); } } return node; }; const hydrateFragment = (node, vnode, parentComponent, parentSuspense, optimized) => { const container = parentNode(node); const next = hydrateChildren(nextSibling(node), vnode, container, parentComponent, parentSuspense, optimized); if (next && isComment(next) && next.data === ']') { return nextSibling((vnode.anchor = next)); } else { // fragment didn't hydrate successfully, since we didn't get a end anchor // back. This should have led to node/children mismatch warnings. hasMismatch = true; // since the anchor is missing, we need to create one and insert it insert((vnode.anchor = createComment(`]`)), container, next); return next; } }; const handleMismatch = (node, vnode, parentComponent, parentSuspense, isFragment) => { hasMismatch = true; ( false) && false; vnode.el = null; if (isFragment) { // remove excessive fragment nodes const end = locateClosingAsyncAnchor(node); while (true) { const next = nextSibling(node); if (next && next !== end) { remove(next); } else { break; } } } const next = nextSibling(node); const container = parentNode(node); remove(node); patch(null, vnode, container, next, parentComponent, parentSuspense, isSVGContainer(container)); return next; }; const locateClosingAsyncAnchor = (node) => { let match = 0; while (node) { node = nextSibling(node); if (node && isComment(node)) { if (node.data === '[') match++; if (node.data === ']') { if (match === 0) { return nextSibling(node); } else { match--; } } } } return node; }; return [hydrate, hydrateNode]; } let supported; let perf; function startMeasure(instance, type) { if (instance.appContext.config.performance && isSupported()) { perf.mark(`vue-${type}-${instance.uid}`); } } function endMeasure(instance, type) { if (instance.appContext.config.performance && isSupported()) { const startTag = `vue-${type}-${instance.uid}`; const endTag = startTag + `:end`; perf.mark(endTag); perf.measure(`<${formatComponentName(instance, instance.type)}> ${type}`, startTag, endTag); perf.clearMarks(startTag); perf.clearMarks(endTag); } } function isSupported() { if (supported !== undefined) { return supported; } /* eslint-disable no-restricted-globals */ if (typeof window !== 'undefined' && window.performance) { supported = true; perf = window.performance; } else { supported = false; } /* eslint-enable no-restricted-globals */ return supported; } /** * This is only called in esm-bundler builds. * It is called when a renderer is created, in `baseCreateRenderer` so that * importing runtime-core is side-effects free. * * istanbul-ignore-next */ function initFeatureFlags() { let needWarn = false; if (typeof __VUE_OPTIONS_API__ !== 'boolean') { needWarn = true; Object(shared_esm_bundler["i" /* getGlobalThis */])().__VUE_OPTIONS_API__ = true; } if (typeof __VUE_PROD_DEVTOOLS__ !== 'boolean') { needWarn = true; Object(shared_esm_bundler["i" /* getGlobalThis */])().__VUE_PROD_DEVTOOLS__ = false; } if (false) {} } const prodEffectOptions = { scheduler: queueJob }; function createDevEffectOptions(instance) { return { scheduler: queueJob, onTrack: instance.rtc ? e => Object(shared_esm_bundler["m" /* invokeArrayFns */])(instance.rtc, e) : void 0, onTrigger: instance.rtg ? e => Object(shared_esm_bundler["m" /* invokeArrayFns */])(instance.rtg, e) : void 0 }; } const queuePostRenderEffect = queueEffectWithSuspense ; const setRef = (rawRef, oldRawRef, parentComponent, parentSuspense, vnode) => { let value; if (!vnode) { value = null; } else { if (vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */) { value = vnode.component.proxy; } else { value = vnode.el; } } const [owner, ref] = rawRef; if (false) {} const oldRef = oldRawRef && oldRawRef[1]; const refs = owner.refs === shared_esm_bundler["b" /* EMPTY_OBJ */] ? (owner.refs = {}) : owner.refs; const setupState = owner.setupState; // unset old ref if (oldRef != null && oldRef !== ref) { if (Object(shared_esm_bundler["z" /* isString */])(oldRef)) { refs[oldRef] = null; if (Object(shared_esm_bundler["k" /* hasOwn */])(setupState, oldRef)) { setupState[oldRef] = null; } } else if (isRef(oldRef)) { oldRef.value = null; } } if (Object(shared_esm_bundler["z" /* isString */])(ref)) { const doSet = () => { refs[ref] = value; if (Object(shared_esm_bundler["k" /* hasOwn */])(setupState, ref)) { setupState[ref] = value; } }; // #1789: for non-null values, set them after render // null values means this is unmount and it should not overwrite another // ref with the same key if (value) { doSet.id = -1; queuePostRenderEffect(doSet, parentSuspense); } else { doSet(); } } else if (isRef(ref)) { const doSet = () => { ref.value = value; }; if (value) { doSet.id = -1; queuePostRenderEffect(doSet, parentSuspense); } else { doSet(); } } else if (Object(shared_esm_bundler["o" /* isFunction */])(ref)) { callWithErrorHandling(ref, parentComponent, 12 /* FUNCTION_REF */, [ value, refs ]); } else if ((false)) {} }; /** * The createRenderer function accepts two generic arguments: * HostNode and HostElement, corresponding to Node and Element types in the * host environment. For example, for runtime-dom, HostNode would be the DOM * `Node` interface and HostElement would be the DOM `Element` interface. * * Custom renderers can pass in the platform specific types like this: * * ``` js * const { render, createApp } = createRenderer({ * patchProp, * ...nodeOps * }) * ``` */ function createRenderer(options) { return baseCreateRenderer(options); } // Separate API for creating hydration-enabled renderer. // Hydration logic is only used when calling this function, making it // tree-shakable. function createHydrationRenderer(options) { return baseCreateRenderer(options, createHydrationFunctions); } // implementation function baseCreateRenderer(options, createHydrationFns) { // compile-time feature flags check { initFeatureFlags(); } const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, forcePatchProp: hostForcePatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = shared_esm_bundler["d" /* NOOP */], cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options; // Note: functions inside this closure should use `const xxx = () => {}` // style in order to prevent being inlined by minifiers. const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, optimized = false) => { // patching & not same type, unmount old tree if (n1 && !isSameVNodeType(n1, n2)) { anchor = getNextHostNode(n1); unmount(n1, parentComponent, parentSuspense, true); n1 = null; } if (n2.patchFlag === -2 /* BAIL */) { optimized = false; n2.dynamicChildren = null; } const { type, ref, shapeFlag } = n2; switch (type) { case Text: processText(n1, n2, container, anchor); break; case Comment: processCommentNode(n1, n2, container, anchor); break; case Static: if (n1 == null) { mountStaticNode(n2, container, anchor, isSVG); } else if ((false)) {} break; case Fragment: processFragment(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); break; default: if (shapeFlag & 1 /* ELEMENT */) { processElement(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } else if (shapeFlag & 6 /* COMPONENT */) { processComponent(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } else if (shapeFlag & 64 /* TELEPORT */) { type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals); } else if ( shapeFlag & 128 /* SUSPENSE */) { type.process(n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, internals); } else if ((false)) {} } // set ref if (ref != null && parentComponent) { setRef(ref, n1 && n1.ref, parentComponent, parentSuspense, n2); } }; const processText = (n1, n2, container, anchor) => { if (n1 == null) { hostInsert((n2.el = hostCreateText(n2.children)), container, anchor); } else { const el = (n2.el = n1.el); if (n2.children !== n1.children) { hostSetText(el, n2.children); } } }; const processCommentNode = (n1, n2, container, anchor) => { if (n1 == null) { hostInsert((n2.el = hostCreateComment(n2.children || '')), container, anchor); } else { // there's no support for dynamic comments n2.el = n1.el; } }; const mountStaticNode = (n2, container, anchor, isSVG) => { [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); }; /** * Dev / HMR only */ const patchStaticNode = (n1, n2, container, isSVG) => { // static nodes are only patched during dev for HMR if (n2.children !== n1.children) { const anchor = hostNextSibling(n1.anchor); // remove existing removeStaticNode(n1); [n2.el, n2.anchor] = hostInsertStaticContent(n2.children, container, anchor, isSVG); } else { n2.el = n1.el; n2.anchor = n1.anchor; } }; /** * Dev / HMR only */ const moveStaticNode = (vnode, container, anchor) => { let cur = vnode.el; const end = vnode.anchor; while (cur && cur !== end) { const next = hostNextSibling(cur); hostInsert(cur, container, anchor); cur = next; } hostInsert(end, container, anchor); }; /** * Dev / HMR only */ const removeStaticNode = (vnode) => { let cur = vnode.el; while (cur && cur !== vnode.anchor) { const next = hostNextSibling(cur); hostRemove(cur); cur = next; } hostRemove(vnode.anchor); }; const processElement = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { isSVG = isSVG || n2.type === 'svg'; if (n1 == null) { mountElement(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } else { patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized); } }; const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { let el; let vnodeHook; const { type, props, shapeFlag, transition, scopeId, patchFlag, dirs } = vnode; if ( true && vnode.el && hostCloneNode !== undefined && patchFlag === -1 /* HOISTED */) { // If a vnode has non-null el, it means it's being reused. // Only static vnodes can be reused, so its mounted DOM nodes should be // exactly the same, and we can simply do a clone here. // only do this in production since cloned trees cannot be HMR updated. el = vnode.el = hostCloneNode(vnode.el); } else { el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is); // mount children first, since some props may rely on child content // being already rendered, e.g. `` if (shapeFlag & 8 /* TEXT_CHILDREN */) { hostSetElementText(el, vnode.children); } else if (shapeFlag & 16 /* ARRAY_CHILDREN */) { mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', optimized || !!vnode.dynamicChildren); } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'created'); } // props if (props) { for (const key in props) { if (!Object(shared_esm_bundler["w" /* isReservedProp */])(key)) { hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); } } if ((vnodeHook = props.onVnodeBeforeMount)) { invokeVNodeHook(vnodeHook, parentComponent, vnode); } } // scopeId setScopeId(el, scopeId, vnode, parentComponent); // if (scopeId) { // hostSetScopeId(el, scopeId) // } // if (parentComponent) { // const treeOwnerId = parentComponent.type.__scopeId // // vnode's own scopeId and the current patched component's scopeId is // // different - this is a slot content node. // if (treeOwnerId && treeOwnerId !== scopeId) { // hostSetScopeId(el, treeOwnerId + '-s') // } // const parentScopeId = // vnode === parentComponent.subTree && parentComponent.vnode.scopeId // if (parentScopeId) { // hostSetScopeId(el, parentScopeId) // if (parentComponent.parent) { // const treeOwnerId = parentComponent.parent.type.__scopeId // // vnode's own scopeId and the current patched component's scopeId is // // different - this is a slot content node. // if (treeOwnerId && treeOwnerId !== parentScopeId) { // hostSetScopeId(el, treeOwnerId + '-s') // } // } // } // } } if (( false) || __VUE_PROD_DEVTOOLS__) { Object.defineProperty(el, '__vnode', { value: vnode, enumerable: false }); Object.defineProperty(el, '__vueParentComponent', { value: parentComponent, enumerable: false }); } if (dirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount'); } // #1583 For inside suspense + suspense not resolved case, enter hook should call when suspense resolved // #1689 For inside suspense + suspense resolved case, just call it const needCallTransitionHooks = (!parentSuspense || (parentSuspense && parentSuspense.isResolved)) && transition && !transition.persisted; if (needCallTransitionHooks) { transition.beforeEnter(el); } hostInsert(el, container, anchor); if ((vnodeHook = props && props.onVnodeMounted) || needCallTransitionHooks || dirs) { queuePostRenderEffect(() => { vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode); needCallTransitionHooks && transition.enter(el); dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted'); }, parentSuspense); } }; const setScopeId = (el, scopeId, vnode, parentComponent) => { if (scopeId) { hostSetScopeId(el, scopeId); } if (parentComponent) { const treeOwnerId = parentComponent.type.__scopeId; // vnode's own scopeId and the current patched component's scopeId is // different - this is a slot content node. if (treeOwnerId && treeOwnerId !== scopeId) { hostSetScopeId(el, treeOwnerId + '-s'); } if (vnode === parentComponent.subTree) { setScopeId(el, parentComponent.vnode.scopeId, parentComponent.vnode, parentComponent.parent); } } }; const mountChildren = (children, container, anchor, parentComponent, parentSuspense, isSVG, optimized, start = 0) => { for (let i = start; i < children.length; i++) { const child = (children[i] = optimized ? cloneIfMounted(children[i]) : normalizeVNode(children[i])); patch(null, child, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } }; const patchElement = (n1, n2, parentComponent, parentSuspense, isSVG, optimized) => { const el = (n2.el = n1.el); let { patchFlag, dynamicChildren, dirs } = n2; // #1426 take the old vnode's patch flag into account since user may clone a // compiler-generated vnode, which de-opts to FULL_PROPS patchFlag |= n1.patchFlag & 16 /* FULL_PROPS */; const oldProps = n1.props || shared_esm_bundler["b" /* EMPTY_OBJ */]; const newProps = n2.props || shared_esm_bundler["b" /* EMPTY_OBJ */]; let vnodeHook; if ((vnodeHook = newProps.onVnodeBeforeUpdate)) { invokeVNodeHook(vnodeHook, parentComponent, n2, n1); } if (dirs) { invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate'); } if (false) {} if (patchFlag > 0) { // the presence of a patchFlag means this element's render code was // generated by the compiler and can take the fast path. // in this path old node and new node are guaranteed to have the same shape // (i.e. at the exact same position in the source template) if (patchFlag & 16 /* FULL_PROPS */) { // element props contain dynamic keys, full diff needed patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG); } else { // class // this flag is matched when the element has dynamic class bindings. if (patchFlag & 2 /* CLASS */) { if (oldProps.class !== newProps.class) { hostPatchProp(el, 'class', null, newProps.class, isSVG); } } // style // this flag is matched when the element has dynamic style bindings if (patchFlag & 4 /* STYLE */) { hostPatchProp(el, 'style', oldProps.style, newProps.style, isSVG); } // props // This flag is matched when the element has dynamic prop/attr bindings // other than class and style. The keys of dynamic prop/attrs are saved for // faster iteration. // Note dynamic keys like :[foo]="bar" will cause this optimization to // bail out and go through a full diff because we need to unset the old key if (patchFlag & 8 /* PROPS */) { // if the flag is present then dynamicProps must be non-null const propsToUpdate = n2.dynamicProps; for (let i = 0; i < propsToUpdate.length; i++) { const key = propsToUpdate[i]; const prev = oldProps[key]; const next = newProps[key]; if (next !== prev || (hostForcePatchProp && hostForcePatchProp(el, key))) { hostPatchProp(el, key, prev, next, isSVG, n1.children, parentComponent, parentSuspense, unmountChildren); } } } } // text // This flag is matched when the element has only dynamic text children. if (patchFlag & 1 /* TEXT */) { if (n1.children !== n2.children) { hostSetElementText(el, n2.children); } } } else if (!optimized && dynamicChildren == null) { // unoptimized, full diff patchProps(el, n2, oldProps, newProps, parentComponent, parentSuspense, isSVG); } const areChildrenSVG = isSVG && n2.type !== 'foreignObject'; if (dynamicChildren) { patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG); if (false) {} } else if (!optimized) { // full diff patchChildren(n1, n2, el, null, parentComponent, parentSuspense, areChildrenSVG); } if ((vnodeHook = newProps.onVnodeUpdated) || dirs) { queuePostRenderEffect(() => { vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1); dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated'); }, parentSuspense); } }; // The fast path for blocks. const patchBlockChildren = (oldChildren, newChildren, fallbackContainer, parentComponent, parentSuspense, isSVG) => { for (let i = 0; i < newChildren.length; i++) { const oldVNode = oldChildren[i]; const newVNode = newChildren[i]; // Determine the container (parent element) for the patch. const container = // - In the case of a Fragment, we need to provide the actual parent // of the Fragment itself so it can move its children. oldVNode.type === Fragment || // - In the case of different nodes, there is going to be a replacement // which also requires the correct parent container !isSameVNodeType(oldVNode, newVNode) || // - In the case of a component, it could contain anything. oldVNode.shapeFlag & 6 /* COMPONENT */ || oldVNode.shapeFlag & 64 /* TELEPORT */ ? hostParentNode(oldVNode.el) : // In other cases, the parent container is not actually used so we // just pass the block element here to avoid a DOM parentNode call. fallbackContainer; patch(oldVNode, newVNode, container, null, parentComponent, parentSuspense, isSVG, true); } }; const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => { if (oldProps !== newProps) { for (const key in newProps) { if (Object(shared_esm_bundler["w" /* isReservedProp */])(key)) continue; const next = newProps[key]; const prev = oldProps[key]; if (next !== prev || (hostForcePatchProp && hostForcePatchProp(el, key))) { hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); } } if (oldProps !== shared_esm_bundler["b" /* EMPTY_OBJ */]) { for (const key in oldProps) { if (!Object(shared_esm_bundler["w" /* isReservedProp */])(key) && !(key in newProps)) { hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren); } } } } }; const processFragment = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { const fragmentStartAnchor = (n2.el = n1 ? n1.el : hostCreateText('')); const fragmentEndAnchor = (n2.anchor = n1 ? n1.anchor : hostCreateText('')); let { patchFlag, dynamicChildren } = n2; if (patchFlag > 0) { optimized = true; } if (false) {} if (n1 == null) { hostInsert(fragmentStartAnchor, container, anchor); hostInsert(fragmentEndAnchor, container, anchor); // a fragment can only have array children // since they are either generated by the compiler, or implicitly created // from arrays. mountChildren(n2.children, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized); } else { if (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */ && dynamicChildren) { // a stable fragment (template root or ) doesn't need to // patch children order, but it may contain dynamicChildren. patchBlockChildren(n1.dynamicChildren, dynamicChildren, container, parentComponent, parentSuspense, isSVG); if (false) {} } else { // keyed / unkeyed, or manual fragments. // for keyed & unkeyed, since they are compiler generated from v-for, // each child is guaranteed to be a block so the fragment will never // have dynamicChildren. patchChildren(n1, n2, container, fragmentEndAnchor, parentComponent, parentSuspense, isSVG, optimized); } } }; const processComponent = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { if (n1 == null) { if (n2.shapeFlag & 512 /* COMPONENT_KEPT_ALIVE */) { parentComponent.ctx.activate(n2, container, anchor, isSVG, optimized); } else { mountComponent(n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } } else { updateComponent(n1, n2, optimized); } }; const mountComponent = (initialVNode, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { const instance = (initialVNode.component = createComponentInstance(initialVNode, parentComponent, parentSuspense)); if (false) {} if ((false)) {} // inject renderer internals for keepAlive if (isKeepAlive(initialVNode)) { instance.ctx.renderer = internals; } // resolve props and slots for setup context if ((false)) {} setupComponent(instance); if ((false)) {} // setup() is async. This component relies on async logic to be resolved // before proceeding if ( instance.asyncDep) { if (!parentSuspense) { if ((false)) {} return; } parentSuspense.registerDep(instance, setupRenderEffect); // Give it a placeholder if this is not hydration if (!initialVNode.el) { const placeholder = (instance.subTree = createVNode(Comment)); processCommentNode(null, placeholder, container, anchor); } return; } setupRenderEffect(instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized); if ((false)) {} }; const updateComponent = (n1, n2, optimized) => { const instance = (n2.component = n1.component); if (shouldUpdateComponent(n1, n2, optimized)) { if ( instance.asyncDep && !instance.asyncResolved) { // async & still pending - just update props and slots // since the component's reactive effect for render isn't set-up yet if ((false)) {} updateComponentPreRender(instance, n2, optimized); if ((false)) {} return; } else { // normal update instance.next = n2; // in case the child component is also queued, remove it to avoid // double updating the same child component in the same flush. invalidateJob(instance.update); // instance.update is the reactive effect runner. instance.update(); } } else { // no update needed. just copy over properties n2.component = n1.component; n2.el = n1.el; instance.vnode = n2; } }; const setupRenderEffect = (instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized) => { // create reactive effect for rendering instance.update = reactivity_esm_bundler_effect(function componentEffect() { if (!instance.isMounted) { let vnodeHook; const { el, props } = initialVNode; const { bm, m, parent } = instance; // beforeMount hook if (bm) { Object(shared_esm_bundler["m" /* invokeArrayFns */])(bm); } // onVnodeBeforeMount if ((vnodeHook = props && props.onVnodeBeforeMount)) { invokeVNodeHook(vnodeHook, parent, initialVNode); } // render if ((false)) {} const subTree = (instance.subTree = renderComponentRoot(instance)); if ((false)) {} if (el && hydrateNode) { if ((false)) {} // vnode has adopted host node - perform hydration instead of mount. hydrateNode(initialVNode.el, subTree, instance, parentSuspense); if ((false)) {} } else { if ((false)) {} patch(null, subTree, container, anchor, instance, parentSuspense, isSVG); if ((false)) {} initialVNode.el = subTree.el; } // mounted hook if (m) { queuePostRenderEffect(m, parentSuspense); } // onVnodeMounted if ((vnodeHook = props && props.onVnodeMounted)) { queuePostRenderEffect(() => { invokeVNodeHook(vnodeHook, parent, initialVNode); }, parentSuspense); } // activated hook for keep-alive roots. // #1742 activated hook must be accessed after first render // since the hook may be injected by a child keep-alive const { a } = instance; if (a && initialVNode.shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { queuePostRenderEffect(a, parentSuspense); } instance.isMounted = true; } else { // updateComponent // This is triggered by mutation of component's own state (next: null) // OR parent calling processComponent (next: VNode) let { next, bu, u, parent, vnode } = instance; let originNext = next; let vnodeHook; if ((false)) {} if (next) { updateComponentPreRender(instance, next, optimized); } else { next = vnode; } next.el = vnode.el; // beforeUpdate hook if (bu) { Object(shared_esm_bundler["m" /* invokeArrayFns */])(bu); } // onVnodeBeforeUpdate if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) { invokeVNodeHook(vnodeHook, parent, next, vnode); } // render if ((false)) {} const nextTree = renderComponentRoot(instance); if ((false)) {} const prevTree = instance.subTree; instance.subTree = nextTree; // reset refs // only needed if previous patch had refs if (instance.refs !== shared_esm_bundler["b" /* EMPTY_OBJ */]) { instance.refs = {}; } if ((false)) {} patch(prevTree, nextTree, // parent may have changed if it's in a teleport hostParentNode(prevTree.el), // anchor may have changed if it's in a fragment getNextHostNode(prevTree), instance, parentSuspense, isSVG); if ((false)) {} next.el = nextTree.el; if (originNext === null) { // self-triggered update. In case of HOC, update parent component // vnode el. HOC is indicated by parent instance's subTree pointing // to child component's vnode updateHOCHostEl(instance, nextTree.el); } // updated hook if (u) { queuePostRenderEffect(u, parentSuspense); } // onVnodeUpdated if ((vnodeHook = next.props && next.props.onVnodeUpdated)) { queuePostRenderEffect(() => { invokeVNodeHook(vnodeHook, parent, next, vnode); }, parentSuspense); } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentUpdated(instance); } if ((false)) {} } }, ( false) ? undefined : prodEffectOptions); instance.update.allowRecurse = true; }; const updateComponentPreRender = (instance, nextVNode, optimized) => { nextVNode.component = instance; const prevProps = instance.vnode.props; instance.vnode = nextVNode; instance.next = null; updateProps(instance, nextVNode.props, prevProps, optimized); updateSlots(instance, nextVNode.children); // props update may have triggered pre-flush watchers. // flush them before the render update. flushPreFlushCbs(undefined, instance.update); }; const patchChildren = (n1, n2, container, anchor, parentComponent, parentSuspense, isSVG, optimized = false) => { const c1 = n1 && n1.children; const prevShapeFlag = n1 ? n1.shapeFlag : 0; const c2 = n2.children; const { patchFlag, shapeFlag } = n2; // fast path if (patchFlag > 0) { if (patchFlag & 128 /* KEYED_FRAGMENT */) { // this could be either fully-keyed or mixed (some keyed some not) // presence of patchFlag means children are guaranteed to be arrays patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); return; } else if (patchFlag & 256 /* UNKEYED_FRAGMENT */) { // unkeyed patchUnkeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); return; } } // children has 3 possibilities: text, array or no children. if (shapeFlag & 8 /* TEXT_CHILDREN */) { // text children fast path if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) { unmountChildren(c1, parentComponent, parentSuspense); } if (c2 !== c1) { hostSetElementText(container, c2); } } else { if (prevShapeFlag & 16 /* ARRAY_CHILDREN */) { // prev children was array if (shapeFlag & 16 /* ARRAY_CHILDREN */) { // two arrays, cannot assume anything, do full diff patchKeyedChildren(c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } else { // no new children, just unmount old unmountChildren(c1, parentComponent, parentSuspense, true); } } else { // prev children was text OR null // new children is array OR null if (prevShapeFlag & 8 /* TEXT_CHILDREN */) { hostSetElementText(container, ''); } // mount new if array if (shapeFlag & 16 /* ARRAY_CHILDREN */) { mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized); } } } }; const patchUnkeyedChildren = (c1, c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized) => { c1 = c1 || shared_esm_bundler["a" /* EMPTY_ARR */]; c2 = c2 || shared_esm_bundler["a" /* EMPTY_ARR */]; const oldLength = c1.length; const newLength = c2.length; const commonLength = Math.min(oldLength, newLength); let i; for (i = 0; i < commonLength; i++) { const nextChild = (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])); patch(c1[i], nextChild, container, null, parentComponent, parentSuspense, isSVG, optimized); } if (oldLength > newLength) { // remove old unmountChildren(c1, parentComponent, parentSuspense, true, commonLength); } else { // mount new mountChildren(c2, container, anchor, parentComponent, parentSuspense, isSVG, optimized, commonLength); } }; // can be all-keyed or mixed const patchKeyedChildren = (c1, c2, container, parentAnchor, parentComponent, parentSuspense, isSVG, optimized) => { let i = 0; const l2 = c2.length; let e1 = c1.length - 1; // prev ending index let e2 = l2 - 1; // next ending index // 1. sync from start // (a b) c // (a b) d e while (i <= e1 && i <= e2) { const n1 = c1[i]; const n2 = (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])); if (isSameVNodeType(n1, n2)) { patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized); } else { break; } i++; } // 2. sync from end // a (b c) // d e (b c) while (i <= e1 && i <= e2) { const n1 = c1[e1]; const n2 = (c2[e2] = optimized ? cloneIfMounted(c2[e2]) : normalizeVNode(c2[e2])); if (isSameVNodeType(n1, n2)) { patch(n1, n2, container, null, parentComponent, parentSuspense, isSVG, optimized); } else { break; } e1--; e2--; } // 3. common sequence + mount // (a b) // (a b) c // i = 2, e1 = 1, e2 = 2 // (a b) // c (a b) // i = 0, e1 = -1, e2 = 0 if (i > e1) { if (i <= e2) { const nextPos = e2 + 1; const anchor = nextPos < l2 ? c2[nextPos].el : parentAnchor; while (i <= e2) { patch(null, (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])), container, anchor, parentComponent, parentSuspense, isSVG); i++; } } } // 4. common sequence + unmount // (a b) c // (a b) // i = 2, e1 = 2, e2 = 1 // a (b c) // (b c) // i = 0, e1 = 0, e2 = -1 else if (i > e2) { while (i <= e1) { unmount(c1[i], parentComponent, parentSuspense, true); i++; } } // 5. unknown sequence // [i ... e1 + 1]: a b [c d e] f g // [i ... e2 + 1]: a b [e d c h] f g // i = 2, e1 = 4, e2 = 5 else { const s1 = i; // prev starting index const s2 = i; // next starting index // 5.1 build key:index map for newChildren const keyToNewIndexMap = new Map(); for (i = s2; i <= e2; i++) { const nextChild = (c2[i] = optimized ? cloneIfMounted(c2[i]) : normalizeVNode(c2[i])); if (nextChild.key != null) { if (false) {} keyToNewIndexMap.set(nextChild.key, i); } } // 5.2 loop through old children left to be patched and try to patch // matching nodes & remove nodes that are no longer present let j; let patched = 0; const toBePatched = e2 - s2 + 1; let moved = false; // used to track whether any node has moved let maxNewIndexSoFar = 0; // works as Map // Note that oldIndex is offset by +1 // and oldIndex = 0 is a special value indicating the new node has // no corresponding old node. // used for determining longest stable subsequence const newIndexToOldIndexMap = new Array(toBePatched); for (i = 0; i < toBePatched; i++) newIndexToOldIndexMap[i] = 0; for (i = s1; i <= e1; i++) { const prevChild = c1[i]; if (patched >= toBePatched) { // all new children have been patched so this can only be a removal unmount(prevChild, parentComponent, parentSuspense, true); continue; } let newIndex; if (prevChild.key != null) { newIndex = keyToNewIndexMap.get(prevChild.key); } else { // key-less node, try to locate a key-less node of the same type for (j = s2; j <= e2; j++) { if (newIndexToOldIndexMap[j - s2] === 0 && isSameVNodeType(prevChild, c2[j])) { newIndex = j; break; } } } if (newIndex === undefined) { unmount(prevChild, parentComponent, parentSuspense, true); } else { newIndexToOldIndexMap[newIndex - s2] = i + 1; if (newIndex >= maxNewIndexSoFar) { maxNewIndexSoFar = newIndex; } else { moved = true; } patch(prevChild, c2[newIndex], container, null, parentComponent, parentSuspense, isSVG, optimized); patched++; } } // 5.3 move and mount // generate longest stable subsequence only when nodes have moved const increasingNewIndexSequence = moved ? getSequence(newIndexToOldIndexMap) : shared_esm_bundler["a" /* EMPTY_ARR */]; j = increasingNewIndexSequence.length - 1; // looping backwards so that we can use last patched node as anchor for (i = toBePatched - 1; i >= 0; i--) { const nextIndex = s2 + i; const nextChild = c2[nextIndex]; const anchor = nextIndex + 1 < l2 ? c2[nextIndex + 1].el : parentAnchor; if (newIndexToOldIndexMap[i] === 0) { // mount new patch(null, nextChild, container, anchor, parentComponent, parentSuspense, isSVG); } else if (moved) { // move if: // There is no stable subsequence (e.g. a reverse) // OR current node is not among the stable sequence if (j < 0 || i !== increasingNewIndexSequence[j]) { move(nextChild, container, anchor, 2 /* REORDER */); } else { j--; } } } } }; const move = (vnode, container, anchor, moveType, parentSuspense = null) => { const { el, type, transition, children, shapeFlag } = vnode; if (shapeFlag & 6 /* COMPONENT */) { move(vnode.component.subTree, container, anchor, moveType); return; } if ( shapeFlag & 128 /* SUSPENSE */) { vnode.suspense.move(container, anchor, moveType); return; } if (shapeFlag & 64 /* TELEPORT */) { type.move(vnode, container, anchor, internals); return; } if (type === Fragment) { hostInsert(el, container, anchor); for (let i = 0; i < children.length; i++) { move(children[i], container, anchor, moveType); } hostInsert(vnode.anchor, container, anchor); return; } // static node move can only happen when force updating HMR if (false) {} // single nodes const needTransition = moveType !== 2 /* REORDER */ && shapeFlag & 1 /* ELEMENT */ && transition; if (needTransition) { if (moveType === 0 /* ENTER */) { transition.beforeEnter(el); hostInsert(el, container, anchor); queuePostRenderEffect(() => transition.enter(el), parentSuspense); } else { const { leave, delayLeave, afterLeave } = transition; const remove = () => hostInsert(el, container, anchor); const performLeave = () => { leave(el, () => { remove(); afterLeave && afterLeave(); }); }; if (delayLeave) { delayLeave(el, remove, performLeave); } else { performLeave(); } } } else { hostInsert(el, container, anchor); } }; const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => { const { type, props, ref, children, dynamicChildren, shapeFlag, patchFlag, dirs } = vnode; // unset ref if (ref != null && parentComponent) { setRef(ref, null, parentComponent, parentSuspense, null); } if (shapeFlag & 256 /* COMPONENT_SHOULD_KEEP_ALIVE */) { parentComponent.ctx.deactivate(vnode); return; } const shouldInvokeDirs = shapeFlag & 1 /* ELEMENT */ && dirs; let vnodeHook; if ((vnodeHook = props && props.onVnodeBeforeUnmount)) { invokeVNodeHook(vnodeHook, parentComponent, vnode); } if (shapeFlag & 6 /* COMPONENT */) { unmountComponent(vnode.component, parentSuspense, doRemove); } else { if ( shapeFlag & 128 /* SUSPENSE */) { vnode.suspense.unmount(parentSuspense, doRemove); return; } if (shouldInvokeDirs) { invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount'); } if (dynamicChildren && // #1153: fast path should not be taken for non-stable (v-for) fragments (type !== Fragment || (patchFlag > 0 && patchFlag & 64 /* STABLE_FRAGMENT */))) { // fast path for block nodes: only need to unmount dynamic children. unmountChildren(dynamicChildren, parentComponent, parentSuspense); } else if (shapeFlag & 16 /* ARRAY_CHILDREN */) { unmountChildren(children, parentComponent, parentSuspense); } // an unmounted teleport should always remove its children if (shapeFlag & 64 /* TELEPORT */) { vnode.type.remove(vnode, internals); } if (doRemove) { remove(vnode); } } if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) { queuePostRenderEffect(() => { vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode); shouldInvokeDirs && invokeDirectiveHook(vnode, null, parentComponent, 'unmounted'); }, parentSuspense); } }; const remove = vnode => { const { type, el, anchor, transition } = vnode; if (type === Fragment) { removeFragment(el, anchor); return; } if (false) {} const performRemove = () => { hostRemove(el); if (transition && !transition.persisted && transition.afterLeave) { transition.afterLeave(); } }; if (vnode.shapeFlag & 1 /* ELEMENT */ && transition && !transition.persisted) { const { leave, delayLeave } = transition; const performLeave = () => leave(el, performRemove); if (delayLeave) { delayLeave(vnode.el, performRemove, performLeave); } else { performLeave(); } } else { performRemove(); } }; const removeFragment = (cur, end) => { // For fragments, directly remove all contained DOM nodes. // (fragment child nodes cannot have transition) let next; while (cur !== end) { next = hostNextSibling(cur); hostRemove(cur); cur = next; } hostRemove(end); }; const unmountComponent = (instance, parentSuspense, doRemove) => { if (false) {} const { bum, effects, update, subTree, um } = instance; // beforeUnmount hook if (bum) { Object(shared_esm_bundler["m" /* invokeArrayFns */])(bum); } if (effects) { for (let i = 0; i < effects.length; i++) { stop(effects[i]); } } // update may be null if a component is unmounted before its async // setup has resolved. if (update) { stop(update); unmount(subTree, instance, parentSuspense, doRemove); } // unmounted hook if (um) { queuePostRenderEffect(um, parentSuspense); } queuePostRenderEffect(() => { instance.isUnmounted = true; }, parentSuspense); // A component with async dep inside a pending suspense is unmounted before // its async dep resolves. This should remove the dep from the suspense, and // cause the suspense to resolve immediately if that was the last dep. if ( parentSuspense && !parentSuspense.isResolved && !parentSuspense.isUnmounted && instance.asyncDep && !instance.asyncResolved) { parentSuspense.deps--; if (parentSuspense.deps === 0) { parentSuspense.resolve(); } } if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentRemoved(instance); } }; const unmountChildren = (children, parentComponent, parentSuspense, doRemove = false, start = 0) => { for (let i = start; i < children.length; i++) { unmount(children[i], parentComponent, parentSuspense, doRemove); } }; const getNextHostNode = vnode => { if (vnode.shapeFlag & 6 /* COMPONENT */) { return getNextHostNode(vnode.component.subTree); } if ( vnode.shapeFlag & 128 /* SUSPENSE */) { return vnode.suspense.next(); } return hostNextSibling((vnode.anchor || vnode.el)); }; /** * #1156 * When a component is HMR-enabled, we need to make sure that all static nodes * inside a block also inherit the DOM element from the previous tree so that * HMR updates (which are full updates) can retrieve the element for patching. * * Dev only. */ const traverseStaticChildren = (n1, n2) => { const ch1 = n1.children; const ch2 = n2.children; if (Object(shared_esm_bundler["n" /* isArray */])(ch1) && Object(shared_esm_bundler["n" /* isArray */])(ch2)) { for (let i = 0; i < ch1.length; i++) { // this is only called in the optimized path so array children are // guaranteed to be vnodes const c1 = ch1[i]; const c2 = (ch2[i] = cloneIfMounted(ch2[i])); if (c2.shapeFlag & 1 /* ELEMENT */ && !c2.dynamicChildren) { if (c2.patchFlag <= 0 || c2.patchFlag === 32 /* HYDRATE_EVENTS */) { c2.el = c1.el; } traverseStaticChildren(c1, c2); } } } }; const render = (vnode, container) => { if (vnode == null) { if (container._vnode) { unmount(container._vnode, null, null, true); } } else { patch(container._vnode || null, vnode, container); } flushPostFlushCbs(); container._vnode = vnode; }; const internals = { p: patch, um: unmount, m: move, r: remove, mt: mountComponent, mc: mountChildren, pc: patchChildren, pbc: patchBlockChildren, n: getNextHostNode, o: options }; let hydrate; let hydrateNode; if (createHydrationFns) { [hydrate, hydrateNode] = createHydrationFns(internals); } return { render, hydrate, createApp: createAppAPI(render, hydrate) }; } function invokeVNodeHook(hook, instance, vnode, prevVNode = null) { callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [ vnode, prevVNode ]); } // https://en.wikipedia.org/wiki/Longest_increasing_subsequence function getSequence(arr) { const p = arr.slice(); const result = [0]; let i, j, u, v, c; const len = arr.length; for (i = 0; i < len; i++) { const arrI = arr[i]; if (arrI !== 0) { j = result[result.length - 1]; if (arr[j] < arrI) { p[i] = j; result.push(i); continue; } u = 0; v = result.length - 1; while (u < v) { c = ((u + v) / 2) | 0; if (arr[result[c]] < arrI) { u = c + 1; } else { v = c; } } if (arrI < arr[result[u]]) { if (u > 0) { p[i] = result[u - 1]; } result[u] = i; } } } u = result.length; v = result[u - 1]; while (u-- > 0) { result[u] = v; v = p[v]; } return result; } // Simple effect. function watchEffect(effect, options) { return doWatch(effect, null, options); } // initial value for watchers to trigger on undefined initial values const INITIAL_WATCHER_VALUE = {}; // implementation function watch(source, cb, options) { if (false) {} return doWatch(source, cb, options); } function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = shared_esm_bundler["b" /* EMPTY_OBJ */], instance = currentInstance) { if (false) {} const warnInvalidSource = (s) => { warn(`Invalid watch source: `, s, `A watch source can only be a getter/effect function, a ref, ` + `a reactive object, or an array of these types.`); }; let getter; const isRefSource = isRef(source); if (isRefSource) { getter = () => source.value; } else if (isReactive(source)) { getter = () => source; deep = true; } else if (Object(shared_esm_bundler["n" /* isArray */])(source)) { getter = () => source.map(s => { if (isRef(s)) { return s.value; } else if (isReactive(s)) { return traverse(s); } else if (Object(shared_esm_bundler["o" /* isFunction */])(s)) { return callWithErrorHandling(s, instance, 2 /* WATCH_GETTER */); } else { ( false) && false; } }); } else if (Object(shared_esm_bundler["o" /* isFunction */])(source)) { if (cb) { // getter with cb getter = () => callWithErrorHandling(source, instance, 2 /* WATCH_GETTER */); } else { // no cb -> simple effect getter = () => { if (instance && instance.isUnmounted) { return; } if (cleanup) { cleanup(); } return callWithErrorHandling(source, instance, 3 /* WATCH_CALLBACK */, [onInvalidate]); }; } } else { getter = shared_esm_bundler["d" /* NOOP */]; ( false) && false; } if (cb && deep) { const baseGetter = getter; getter = () => traverse(baseGetter()); } let cleanup; const onInvalidate = (fn) => { cleanup = runner.options.onStop = () => { callWithErrorHandling(fn, instance, 4 /* WATCH_CLEANUP */); }; }; let oldValue = Object(shared_esm_bundler["n" /* isArray */])(source) ? [] : INITIAL_WATCHER_VALUE; const job = () => { if (!runner.active) { return; } if (cb) { // watch(source, cb) const newValue = runner(); if (deep || isRefSource || Object(shared_esm_bundler["j" /* hasChanged */])(newValue, oldValue)) { // cleanup before running cb again if (cleanup) { cleanup(); } callWithAsyncErrorHandling(cb, instance, 3 /* WATCH_CALLBACK */, [ newValue, // pass undefined as the old value when it's changed for the first time oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue, onInvalidate ]); oldValue = newValue; } } else { // watchEffect runner(); } }; // important: mark the job as a watcher callback so that scheduler knows it // it is allowed to self-trigger (#1727) job.allowRecurse = !!cb; let scheduler; if (flush === 'sync') { scheduler = job; } else if (flush === 'pre') { // ensure it's queued before component updates (which have positive ids) job.id = -1; scheduler = () => { if (!instance || instance.isMounted) { queuePreFlushCb(job); } else { // with 'pre' option, the first call must happen before // the component is mounted so it is called synchronously. job(); } }; } else { scheduler = () => queuePostRenderEffect(job, instance && instance.suspense); } const runner = reactivity_esm_bundler_effect(getter, { lazy: true, onTrack, onTrigger, scheduler }); recordInstanceBoundEffect(runner); // initial run if (cb) { if (immediate) { job(); } else { oldValue = runner(); } } else { runner(); } return () => { stop(runner); if (instance) { Object(shared_esm_bundler["G" /* remove */])(instance.effects, runner); } }; } // this.$watch function instanceWatch(source, cb, options) { const publicThis = this.proxy; const getter = Object(shared_esm_bundler["z" /* isString */])(source) ? () => publicThis[source] : source.bind(publicThis); return doWatch(getter, cb.bind(publicThis), options, this); } function traverse(value, seen = new Set()) { if (!Object(shared_esm_bundler["t" /* isObject */])(value) || seen.has(value)) { return value; } seen.add(value); if (isRef(value)) { traverse(value.value, seen); } else if (Object(shared_esm_bundler["n" /* isArray */])(value)) { for (let i = 0; i < value.length; i++) { traverse(value[i], seen); } } else if (value instanceof Map) { value.forEach((v, key) => { // to register mutation dep for existing keys traverse(value.get(key), seen); }); } else if (value instanceof Set) { value.forEach(v => { traverse(v, seen); }); } else { for (const key in value) { traverse(value[key], seen); } } return value; } function provide(key, value) { if (!currentInstance) { if ((false)) {} } else { let provides = currentInstance.provides; // by default an instance inherits its parent's provides object // but when it needs to provide values of its own, it creates its // own provides object using parent provides object as prototype. // this way in `inject` we can simply look up injections from direct // parent and let the prototype chain do the work. const parentProvides = currentInstance.parent && currentInstance.parent.provides; if (parentProvides === provides) { provides = currentInstance.provides = Object.create(parentProvides); } // TS doesn't allow symbol as index type provides[key] = value; } } function inject(key, defaultValue) { // fallback to `currentRenderingInstance` so that this can be called in // a functional component const instance = currentInstance || currentRenderingInstance; if (instance) { const provides = instance.provides; if (key in provides) { // TS doesn't allow symbol as index type return provides[key]; } else if (arguments.length > 1) { return defaultValue; } else if ((false)) {} } else if ((false)) {} } function createDuplicateChecker() { const cache = Object.create(null); return (type, key) => { if (cache[key]) { warn(`${type} property "${key}" is already defined in ${cache[key]}.`); } else { cache[key] = type; } }; } let isInBeforeCreate = false; function applyOptions(instance, options, deferredData = [], deferredWatch = [], asMixin = false) { const { // composition mixins, extends: extendsOptions, // state data: dataOptions, computed: computedOptions, methods, watch: watchOptions, provide: provideOptions, inject: injectOptions, // assets components, directives, // lifecycle beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeUnmount, unmounted, render, renderTracked, renderTriggered, errorCaptured } = options; const publicThis = instance.proxy; const ctx = instance.ctx; const globalMixins = instance.appContext.mixins; if (asMixin && render && instance.render === shared_esm_bundler["d" /* NOOP */]) { instance.render = render; } // applyOptions is called non-as-mixin once per instance if (!asMixin) { isInBeforeCreate = true; callSyncHook('beforeCreate', options, publicThis, globalMixins); isInBeforeCreate = false; // global mixins are applied first applyMixins(instance, globalMixins, deferredData, deferredWatch); } // extending a base component... if (extendsOptions) { applyOptions(instance, extendsOptions, deferredData, deferredWatch, true); } // local mixins if (mixins) { applyMixins(instance, mixins, deferredData, deferredWatch); } const checkDuplicateProperties = ( false) ? undefined : null; if ((false)) {} // options initialization order (to be consistent with Vue 2): // - props (already done outside of this function) // - inject // - methods // - data (deferred since it relies on `this` access) // - computed // - watch (deferred since it relies on `this` access) if (injectOptions) { if (Object(shared_esm_bundler["n" /* isArray */])(injectOptions)) { for (let i = 0; i < injectOptions.length; i++) { const key = injectOptions[i]; ctx[key] = inject(key); if ((false)) {} } } else { for (const key in injectOptions) { const opt = injectOptions[key]; if (Object(shared_esm_bundler["t" /* isObject */])(opt)) { ctx[key] = inject(opt.from, opt.default); } else { ctx[key] = inject(opt); } if ((false)) {} } } } if (methods) { for (const key in methods) { const methodHandler = methods[key]; if (Object(shared_esm_bundler["o" /* isFunction */])(methodHandler)) { ctx[key] = methodHandler.bind(publicThis); if ((false)) {} } else if ((false)) {} } } if (!asMixin) { if (deferredData.length) { deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis)); } if (dataOptions) { resolveData(instance, dataOptions, publicThis); } if ((false)) {} } else if (dataOptions) { deferredData.push(dataOptions); } if (computedOptions) { for (const key in computedOptions) { const opt = computedOptions[key]; const get = Object(shared_esm_bundler["o" /* isFunction */])(opt) ? opt.bind(publicThis, publicThis) : Object(shared_esm_bundler["o" /* isFunction */])(opt.get) ? opt.get.bind(publicThis, publicThis) : shared_esm_bundler["d" /* NOOP */]; if (false) {} const set = !Object(shared_esm_bundler["o" /* isFunction */])(opt) && Object(shared_esm_bundler["o" /* isFunction */])(opt.set) ? opt.set.bind(publicThis) : ( false) ? undefined : shared_esm_bundler["d" /* NOOP */]; const c = runtime_core_esm_bundler_computed({ get, set }); Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => c.value, set: v => (c.value = v) }); if ((false)) {} } } if (watchOptions) { deferredWatch.push(watchOptions); } if (!asMixin && deferredWatch.length) { deferredWatch.forEach(watchOptions => { for (const key in watchOptions) { createWatcher(watchOptions[key], ctx, publicThis, key); } }); } if (provideOptions) { const provides = Object(shared_esm_bundler["o" /* isFunction */])(provideOptions) ? provideOptions.call(publicThis) : provideOptions; for (const key in provides) { provide(key, provides[key]); } } // asset options. // To reduce memory usage, only components with mixins or extends will have // resolved asset registry attached to instance. if (asMixin) { if (components) { Object(shared_esm_bundler["h" /* extend */])(instance.components || (instance.components = Object(shared_esm_bundler["h" /* extend */])({}, instance.type.components)), components); } if (directives) { Object(shared_esm_bundler["h" /* extend */])(instance.directives || (instance.directives = Object(shared_esm_bundler["h" /* extend */])({}, instance.type.directives)), directives); } } // lifecycle options if (!asMixin) { callSyncHook('created', options, publicThis, globalMixins); } if (beforeMount) { onBeforeMount(beforeMount.bind(publicThis)); } if (mounted) { onMounted(mounted.bind(publicThis)); } if (beforeUpdate) { onBeforeUpdate(beforeUpdate.bind(publicThis)); } if (updated) { onUpdated(updated.bind(publicThis)); } if (activated) { onActivated(activated.bind(publicThis)); } if (deactivated) { onDeactivated(deactivated.bind(publicThis)); } if (errorCaptured) { onErrorCaptured(errorCaptured.bind(publicThis)); } if (renderTracked) { onRenderTracked(renderTracked.bind(publicThis)); } if (renderTriggered) { onRenderTriggered(renderTriggered.bind(publicThis)); } if (beforeUnmount) { onBeforeUnmount(beforeUnmount.bind(publicThis)); } if (unmounted) { onUnmounted(unmounted.bind(publicThis)); } } function callSyncHook(name, options, ctx, globalMixins) { callHookFromMixins(name, globalMixins, ctx); const { extends: base, mixins } = options; if (base) { callHookFromExtends(name, base, ctx); } if (mixins) { callHookFromMixins(name, mixins, ctx); } const selfHook = options[name]; if (selfHook) { selfHook.call(ctx); } } function callHookFromExtends(name, base, ctx) { if (base.extends) { callHookFromExtends(name, base.extends, ctx); } const baseHook = base[name]; if (baseHook) { baseHook.call(ctx); } } function callHookFromMixins(name, mixins, ctx) { for (let i = 0; i < mixins.length; i++) { const chainedMixins = mixins[i].mixins; if (chainedMixins) { callHookFromMixins(name, chainedMixins, ctx); } const fn = mixins[i][name]; if (fn) { fn.call(ctx); } } } function applyMixins(instance, mixins, deferredData, deferredWatch) { for (let i = 0; i < mixins.length; i++) { applyOptions(instance, mixins[i], deferredData, deferredWatch, true); } } function resolveData(instance, dataFn, publicThis) { if (false) {} const data = dataFn.call(publicThis, publicThis); if (false) {} if (!Object(shared_esm_bundler["t" /* isObject */])(data)) { ( false) && false; } else if (instance.data === shared_esm_bundler["b" /* EMPTY_OBJ */]) { instance.data = reactive(data); } else { // existing data: this is a mixin or extends. Object(shared_esm_bundler["h" /* extend */])(instance.data, data); } } function createWatcher(raw, ctx, publicThis, key) { const getter = () => publicThis[key]; if (Object(shared_esm_bundler["z" /* isString */])(raw)) { const handler = ctx[raw]; if (Object(shared_esm_bundler["o" /* isFunction */])(handler)) { watch(getter, handler); } else if ((false)) {} } else if (Object(shared_esm_bundler["o" /* isFunction */])(raw)) { watch(getter, raw.bind(publicThis)); } else if (Object(shared_esm_bundler["t" /* isObject */])(raw)) { if (Object(shared_esm_bundler["n" /* isArray */])(raw)) { raw.forEach(r => createWatcher(r, ctx, publicThis, key)); } else { const handler = Object(shared_esm_bundler["o" /* isFunction */])(raw.handler) ? raw.handler.bind(publicThis) : ctx[raw.handler]; if (Object(shared_esm_bundler["o" /* isFunction */])(handler)) { watch(getter, handler, raw); } else if ((false)) {} } } else if ((false)) {} } function resolveMergedOptions(instance) { const raw = instance.type; const { __merged, mixins, extends: extendsOptions } = raw; if (__merged) return __merged; const globalMixins = instance.appContext.mixins; if (!globalMixins.length && !mixins && !extendsOptions) return raw; const options = {}; mergeOptions(options, raw, instance); globalMixins.forEach(m => mergeOptions(options, m, instance)); return (raw.__merged = options); } function mergeOptions(to, from, instance) { const strats = instance.appContext.config.optionMergeStrategies; for (const key in from) { if (strats && Object(shared_esm_bundler["k" /* hasOwn */])(strats, key)) { to[key] = strats[key](to[key], from[key], instance.proxy, key); } else if (!Object(shared_esm_bundler["k" /* hasOwn */])(to, key)) { to[key] = from[key]; } } const { mixins, extends: extendsOptions } = from; extendsOptions && mergeOptions(to, extendsOptions, instance); mixins && mixins.forEach((m) => mergeOptions(to, m, instance)); } const publicPropertiesMap = Object(shared_esm_bundler["h" /* extend */])(Object.create(null), { $: i => i, $el: i => i.vnode.el, $data: i => i.data, $props: i => (( false) ? undefined : i.props), $attrs: i => (( false) ? undefined : i.attrs), $slots: i => (( false) ? undefined : i.slots), $refs: i => (( false) ? undefined : i.refs), $parent: i => i.parent && i.parent.proxy, $root: i => i.root && i.root.proxy, $emit: i => i.emit, $options: i => (__VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type), $forceUpdate: i => () => queueJob(i.update), $nextTick: () => nextTick, $watch: i => (__VUE_OPTIONS_API__ ? instanceWatch.bind(i) : shared_esm_bundler["d" /* NOOP */]) }); const PublicInstanceProxyHandlers = { get({ _: instance }, key) { const { ctx, setupState, data, props, accessCache, type, appContext } = instance; // let @vue/reactivity know it should never observe Vue public instances. if (key === "__v_skip" /* SKIP */) { return true; } // data / props / ctx // This getter gets called for every property access on the render context // during render and is a major hotspot. The most expensive part of this // is the multiple hasOwn() calls. It's much faster to do a simple property // access on a plain object, so we use an accessCache object (with null // prototype) to memoize what access type a key corresponds to. let normalizedProps; if (key[0] !== '$') { const n = accessCache[key]; if (n !== undefined) { switch (n) { case 0 /* SETUP */: return setupState[key]; case 1 /* DATA */: return data[key]; case 3 /* CONTEXT */: return ctx[key]; case 2 /* PROPS */: return props[key]; // default: just fallthrough } } else if (setupState !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(setupState, key)) { accessCache[key] = 0 /* SETUP */; return setupState[key]; } else if (data !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(data, key)) { accessCache[key] = 1 /* DATA */; return data[key]; } else if ( // only cache other properties when instance has declared (thus stable) // props (normalizedProps = instance.propsOptions[0]) && Object(shared_esm_bundler["k" /* hasOwn */])(normalizedProps, key)) { accessCache[key] = 2 /* PROPS */; return props[key]; } else if (ctx !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(ctx, key)) { accessCache[key] = 3 /* CONTEXT */; return ctx[key]; } else if (!__VUE_OPTIONS_API__ || !isInBeforeCreate) { accessCache[key] = 4 /* OTHER */; } } const publicGetter = publicPropertiesMap[key]; let cssModule, globalProperties; // public $xxx properties if (publicGetter) { if (key === '$attrs') { track(instance, "get" /* GET */, key); ( false) && false; } return publicGetter(instance); } else if ( // css module (injected by vue-loader) (cssModule = type.__cssModules) && (cssModule = cssModule[key])) { return cssModule; } else if (ctx !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(ctx, key)) { // user may set custom properties to `this` that start with `$` accessCache[key] = 3 /* CONTEXT */; return ctx[key]; } else if ( // global properties ((globalProperties = appContext.config.globalProperties), Object(shared_esm_bundler["k" /* hasOwn */])(globalProperties, key))) { return globalProperties[key]; } else if (false) {} }, set({ _: instance }, key, value) { const { data, setupState, ctx } = instance; if (setupState !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(setupState, key)) { setupState[key] = value; } else if (data !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(data, key)) { data[key] = value; } else if (key in instance.props) { ( false) && false; return false; } if (key[0] === '$' && key.slice(1) in instance) { ( false) && false; return false; } else { if (false) {} else { ctx[key] = value; } } return true; }, has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) { let normalizedProps; return (accessCache[key] !== undefined || (data !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(data, key)) || (setupState !== shared_esm_bundler["b" /* EMPTY_OBJ */] && Object(shared_esm_bundler["k" /* hasOwn */])(setupState, key)) || ((normalizedProps = propsOptions[0]) && Object(shared_esm_bundler["k" /* hasOwn */])(normalizedProps, key)) || Object(shared_esm_bundler["k" /* hasOwn */])(ctx, key) || Object(shared_esm_bundler["k" /* hasOwn */])(publicPropertiesMap, key) || Object(shared_esm_bundler["k" /* hasOwn */])(appContext.config.globalProperties, key)); } }; if (false) {} const RuntimeCompiledPublicInstanceProxyHandlers = Object(shared_esm_bundler["h" /* extend */])({}, PublicInstanceProxyHandlers, { get(target, key) { // fast path for unscopables when using `with` block if (key === Symbol.unscopables) { return; } return PublicInstanceProxyHandlers.get(target, key, target); }, has(_, key) { const has = key[0] !== '_' && !Object(shared_esm_bundler["p" /* isGloballyWhitelisted */])(key); if (false) {} return has; } }); // In dev mode, the proxy target exposes the same properties as seen on `this` // for easier console inspection. In prod mode it will be an empty object so // these properties definitions can be skipped. function createRenderContext(instance) { const target = {}; // expose internal instance for proxy handlers Object.defineProperty(target, `_`, { configurable: true, enumerable: false, get: () => instance }); // expose public properties Object.keys(publicPropertiesMap).forEach(key => { Object.defineProperty(target, key, { configurable: true, enumerable: false, get: () => publicPropertiesMap[key](instance), // intercepted by the proxy so no need for implementation, // but needed to prevent set errors set: shared_esm_bundler["d" /* NOOP */] }); }); // expose global properties const { globalProperties } = instance.appContext.config; Object.keys(globalProperties).forEach(key => { Object.defineProperty(target, key, { configurable: true, enumerable: false, get: () => globalProperties[key], set: shared_esm_bundler["d" /* NOOP */] }); }); return target; } // dev only function exposePropsOnRenderContext(instance) { const { ctx, propsOptions: [propsOptions] } = instance; if (propsOptions) { Object.keys(propsOptions).forEach(key => { Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => instance.props[key], set: shared_esm_bundler["d" /* NOOP */] }); }); } } // dev only function exposeSetupStateOnRenderContext(instance) { const { ctx, setupState } = instance; Object.keys(toRaw(setupState)).forEach(key => { Object.defineProperty(ctx, key, { enumerable: true, configurable: true, get: () => setupState[key], set: shared_esm_bundler["d" /* NOOP */] }); }); } const emptyAppContext = createAppContext(); let uid$1 = 0; function createComponentInstance(vnode, parent, suspense) { const type = vnode.type; // inherit parent app context - or - if root, adopt from root vnode const appContext = (parent ? parent.appContext : vnode.appContext) || emptyAppContext; const instance = { uid: uid$1++, vnode, type, parent, appContext, root: null, next: null, subTree: null, update: null, render: null, proxy: null, withProxy: null, effects: null, provides: parent ? parent.provides : Object.create(appContext.provides), accessCache: null, renderCache: [], // local resovled assets components: null, directives: null, // resolved props and emits options propsOptions: normalizePropsOptions(type, appContext), emitsOptions: normalizeEmitsOptions(type, appContext), // emit emit: null, emitted: null, // state ctx: shared_esm_bundler["b" /* EMPTY_OBJ */], data: shared_esm_bundler["b" /* EMPTY_OBJ */], props: shared_esm_bundler["b" /* EMPTY_OBJ */], attrs: shared_esm_bundler["b" /* EMPTY_OBJ */], slots: shared_esm_bundler["b" /* EMPTY_OBJ */], refs: shared_esm_bundler["b" /* EMPTY_OBJ */], setupState: shared_esm_bundler["b" /* EMPTY_OBJ */], setupContext: null, // suspense related suspense, asyncDep: null, asyncResolved: false, // lifecycle hooks // not using enums here because it results in computed properties isMounted: false, isUnmounted: false, isDeactivated: false, bc: null, c: null, bm: null, m: null, bu: null, u: null, um: null, bum: null, da: null, a: null, rtg: null, rtc: null, ec: null }; if ((false)) {} else { instance.ctx = { _: instance }; } instance.root = parent ? parent.root : instance; instance.emit = runtime_core_esm_bundler_emit.bind(null, instance); if (( false) || __VUE_PROD_DEVTOOLS__) { devtoolsComponentAdded(instance); } return instance; } let currentInstance = null; const getCurrentInstance = () => currentInstance || currentRenderingInstance; const setCurrentInstance = (instance) => { currentInstance = instance; }; const isBuiltInTag = /*#__PURE__*/ Object(shared_esm_bundler["D" /* makeMap */])('slot,component'); function validateComponentName(name, config) { const appIsNativeTag = config.isNativeTag || shared_esm_bundler["c" /* NO */]; if (isBuiltInTag(name) || appIsNativeTag(name)) { warn('Do not use built-in or reserved HTML elements as component id: ' + name); } } let isInSSRComponentSetup = false; function setupComponent(instance, isSSR = false) { isInSSRComponentSetup = isSSR; const { props, children, shapeFlag } = instance.vnode; const isStateful = shapeFlag & 4 /* STATEFUL_COMPONENT */; initProps(instance, props, isStateful, isSSR); initSlots(instance, children); const setupResult = isStateful ? setupStatefulComponent(instance, isSSR) : undefined; isInSSRComponentSetup = false; return setupResult; } function setupStatefulComponent(instance, isSSR) { const Component = instance.type; if ((false)) {} // 0. create render proxy property access cache instance.accessCache = {}; // 1. create public instance / render proxy // also mark it raw so it's never observed instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers); if ((false)) {} // 2. call setup() const { setup } = Component; if (setup) { const setupContext = (instance.setupContext = setup.length > 1 ? createSetupContext(instance) : null); currentInstance = instance; pauseTracking(); const setupResult = callWithErrorHandling(setup, instance, 0 /* SETUP_FUNCTION */, [( false) ? undefined : instance.props, setupContext]); resetTracking(); currentInstance = null; if (Object(shared_esm_bundler["v" /* isPromise */])(setupResult)) { if (isSSR) { // return the promise so server-renderer can wait on it return setupResult.then((resolvedResult) => { handleSetupResult(instance, resolvedResult); }); } else { // async setup returned Promise. // bail here and wait for re-entry. instance.asyncDep = setupResult; } } else { handleSetupResult(instance, setupResult); } } else { finishComponentSetup(instance); } } function handleSetupResult(instance, setupResult, isSSR) { if (Object(shared_esm_bundler["o" /* isFunction */])(setupResult)) { // setup returned an inline render function instance.render = setupResult; } else if (Object(shared_esm_bundler["t" /* isObject */])(setupResult)) { if (false) {} // setup returned bindings. // assuming a render function compiled from template is present. if (( false) || __VUE_PROD_DEVTOOLS__) { instance.devtoolsRawSetupState = setupResult; } instance.setupState = proxyRefs(setupResult); if ((false)) {} } else if (false) {} finishComponentSetup(instance); } let compile; /** * For runtime-dom to register the compiler. * Note the exported method uses any to avoid d.ts relying on the compiler types. */ function registerRuntimeCompiler(_compile) { compile = _compile; } function finishComponentSetup(instance, isSSR) { const Component = instance.type; // template / render function normalization if (!instance.render) { // could be set from setup() if (compile && Component.template && !Component.render) { if ((false)) {} Component.render = compile(Component.template, { isCustomElement: instance.appContext.config.isCustomElement, delimiters: Component.delimiters }); if ((false)) {} } instance.render = (Component.render || shared_esm_bundler["d" /* NOOP */]); // for runtime-compiled render functions using `with` blocks, the render // proxy used needs a different `has` handler which is more performant and // also only allows a whitelist of globals to fallthrough. if (instance.render._rc) { instance.withProxy = new Proxy(instance.ctx, RuntimeCompiledPublicInstanceProxyHandlers); } } // support for 2.x options if (__VUE_OPTIONS_API__) { currentInstance = instance; applyOptions(instance, Component); currentInstance = null; } // warn missing template/render if (false) {} } const attrHandlers = { get: (target, key) => { if ((false)) {} return target[key]; }, set: () => { warn(`setupContext.attrs is readonly.`); return false; }, deleteProperty: () => { warn(`setupContext.attrs is readonly.`); return false; } }; function createSetupContext(instance) { if ((false)) {} else { return { attrs: instance.attrs, slots: instance.slots, emit: instance.emit }; } } // record effects created during a component's setup() so that they can be // stopped when the component unmounts function recordInstanceBoundEffect(effect) { if (currentInstance) { (currentInstance.effects || (currentInstance.effects = [])).push(effect); } } const classifyRE = /(?:^|[-_])(\w)/g; const classify = (str) => str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, ''); /* istanbul ignore next */ function formatComponentName(instance, Component, isRoot = false) { let name = Object(shared_esm_bundler["o" /* isFunction */])(Component) ? Component.displayName || Component.name : Component.name; if (!name && Component.__file) { const match = Component.__file.match(/([^/\\]+)\.vue$/); if (match) { name = match[1]; } } if (!name && instance && instance.parent) { // try to infer the name based on reverse resolution const inferFromRegistry = (registry) => { for (const key in registry) { if (registry[key] === Component) { return key; } } }; name = inferFromRegistry(instance.components || instance.parent.type.components) || inferFromRegistry(instance.appContext.components); } return name ? classify(name) : isRoot ? `App` : `Anonymous`; } function runtime_core_esm_bundler_computed(getterOrOptions) { const c = computed(getterOrOptions); recordInstanceBoundEffect(c.effect); return c; } // implementation, close to no-op function defineComponent(options) { return Object(shared_esm_bundler["o" /* isFunction */])(options) ? { setup: options, name: options.name } : options; } function defineAsyncComponent(source) { if (Object(shared_esm_bundler["o" /* isFunction */])(source)) { source = { loader: source }; } const { loader, loadingComponent: loadingComponent, errorComponent: errorComponent, delay = 200, timeout, // undefined = never times out suspensible = true, onError: userOnError } = source; let pendingRequest = null; let resolvedComp; let retries = 0; const retry = () => { retries++; pendingRequest = null; return load(); }; const load = () => { let thisRequest; return (pendingRequest || (thisRequest = pendingRequest = loader() .catch(err => { err = err instanceof Error ? err : new Error(String(err)); if (userOnError) { return new Promise((resolve, reject) => { const userRetry = () => resolve(retry()); const userFail = () => reject(err); userOnError(err, userRetry, userFail, retries + 1); }); } else { throw err; } }) .then((comp) => { if (thisRequest !== pendingRequest && pendingRequest) { return pendingRequest; } if (false) {} // interop module default if (comp && (comp.__esModule || comp[Symbol.toStringTag] === 'Module')) { comp = comp.default; } if (false) {} resolvedComp = comp; return comp; }))); }; return defineComponent({ __asyncLoader: load, name: 'AsyncComponentWrapper', setup() { const instance = currentInstance; // already resolved if (resolvedComp) { return () => createInnerComp(resolvedComp, instance); } const onError = (err) => { pendingRequest = null; handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */); }; // suspense-controlled or SSR. if (( suspensible && instance.suspense) || (false )) { return load() .then(comp => { return () => createInnerComp(comp, instance); }) .catch(err => { onError(err); return () => errorComponent ? createVNode(errorComponent, { error: err }) : null; }); } const loaded = reactivity_esm_bundler_ref(false); const error = reactivity_esm_bundler_ref(); const delayed = reactivity_esm_bundler_ref(!!delay); if (delay) { setTimeout(() => { delayed.value = false; }, delay); } if (timeout != null) { setTimeout(() => { if (!loaded.value) { const err = new Error(`Async component timed out after ${timeout}ms.`); onError(err); error.value = err; } }, timeout); } load() .then(() => { loaded.value = true; }) .catch(err => { onError(err); error.value = err; }); return () => { if (loaded.value && resolvedComp) { return createInnerComp(resolvedComp, instance); } else if (error.value && errorComponent) { return createVNode(errorComponent, { error: error.value }); } else if (loadingComponent && !delayed.value) { return createVNode(loadingComponent); } }; } }); } function createInnerComp(comp, { vnode: { props, children } }) { return createVNode(comp, props, children); } // Actual implementation function h(type, propsOrChildren, children) { const l = arguments.length; if (l === 2) { if (Object(shared_esm_bundler["t" /* isObject */])(propsOrChildren) && !Object(shared_esm_bundler["n" /* isArray */])(propsOrChildren)) { // single vnode without props if (isVNode(propsOrChildren)) { return createVNode(type, null, [propsOrChildren]); } // props without children return createVNode(type, propsOrChildren); } else { // omit props return createVNode(type, null, propsOrChildren); } } else { if (l > 3) { children = Array.prototype.slice.call(arguments, 2); } else if (l === 3 && isVNode(children)) { children = [children]; } return createVNode(type, propsOrChildren, children); } } const ssrContextKey = Symbol(( false) ? undefined : ``); const useSSRContext = () => { { const ctx = inject(ssrContextKey); if (!ctx) { warn(`Server rendering context not provided. Make sure to only call ` + `useSsrContext() conditionally in the server build.`); } return ctx; } }; /** * Actual implementation */ function renderList(source, renderItem) { let ret; if (Object(shared_esm_bundler["n" /* isArray */])(source) || Object(shared_esm_bundler["z" /* isString */])(source)) { ret = new Array(source.length); for (let i = 0, l = source.length; i < l; i++) { ret[i] = renderItem(source[i], i); } } else if (typeof source === 'number') { ret = new Array(source); for (let i = 0; i < source; i++) { ret[i] = renderItem(i + 1, i); } } else if (Object(shared_esm_bundler["t" /* isObject */])(source)) { if (source[Symbol.iterator]) { ret = Array.from(source, renderItem); } else { const keys = Object.keys(source); ret = new Array(keys.length); for (let i = 0, l = keys.length; i < l; i++) { const key = keys[i]; ret[i] = renderItem(source[key], key, i); } } } else { ret = []; } return ret; } /** * For prefixing keys in v-on="obj" with "on" * @private */ function toHandlers(obj) { const ret = {}; if (false) {} for (const key in obj) { ret[`on${Object(shared_esm_bundler["f" /* capitalize */])(key)}`] = obj[key]; } return ret; } /** * Compiler runtime helper for creating dynamic slots object * @private */ function createSlots(slots, dynamicSlots) { for (let i = 0; i < dynamicSlots.length; i++) { const slot = dynamicSlots[i]; // array of dynamic slot generated by if (Object(shared_esm_bundler["n" /* isArray */])(slot)) { for (let j = 0; j < slot.length; j++) { slots[slot[j].name] = slot[j].fn; } } else if (slot) { // conditional single slot generated by slots[slot.name] = slot.fn; } } return slots; } // Core API ------------------------------------------------------------------ const version = "3.0.0-rc.10"; /** * SSR utils for \@vue/server-renderer. Only exposed in cjs builds. * @internal */ const ssrUtils = ( null); // CONCATENATED MODULE: ./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js const svgNS = 'http://www.w3.org/2000/svg'; const doc = (typeof document !== 'undefined' ? document : null); let tempContainer; let tempSVGContainer; const nodeOps = { insert: (child, parent, anchor) => { parent.insertBefore(child, anchor || null); }, remove: child => { const parent = child.parentNode; if (parent) { parent.removeChild(child); } }, createElement: (tag, isSVG, is) => isSVG ? doc.createElementNS(svgNS, tag) : doc.createElement(tag, is ? { is } : undefined), createText: text => doc.createTextNode(text), createComment: text => doc.createComment(text), setText: (node, text) => { node.nodeValue = text; }, setElementText: (el, text) => { el.textContent = text; }, parentNode: node => node.parentNode, nextSibling: node => node.nextSibling, querySelector: selector => doc.querySelector(selector), setScopeId(el, id) { el.setAttribute(id, ''); }, cloneNode(el) { return el.cloneNode(true); }, // __UNSAFE__ // Reason: innerHTML. // Static content here can only come from compiled templates. // As long as the user only uses trusted templates, this is safe. insertStaticContent(content, parent, anchor, isSVG) { const temp = isSVG ? tempSVGContainer || (tempSVGContainer = doc.createElementNS(svgNS, 'svg')) : tempContainer || (tempContainer = doc.createElement('div')); temp.innerHTML = content; const first = temp.firstChild; let node = first; let last = node; while (node) { last = node; nodeOps.insert(node, parent, anchor); node = temp.firstChild; } return [first, last]; } }; // compiler should normalize class + :class bindings on the same element // into a single binding ['staticClass', dynamic] function patchClass(el, value, isSVG) { if (value == null) { value = ''; } if (isSVG) { el.setAttribute('class', value); } else { // directly setting className should be faster than setAttribute in theory // if this is an element during a transition, take the temporary transition // classes into account. const transitionClasses = el._vtc; if (transitionClasses) { value = (value ? [value, ...transitionClasses] : [...transitionClasses]).join(' '); } el.className = value; } } function patchStyle(el, prev, next) { const style = el.style; if (!next) { el.removeAttribute('style'); } else if (Object(shared_esm_bundler["z" /* isString */])(next)) { if (prev !== next) { style.cssText = next; } } else { for (const key in next) { setStyle(style, key, next[key]); } if (prev && !Object(shared_esm_bundler["z" /* isString */])(prev)) { for (const key in prev) { if (next[key] == null) { setStyle(style, key, ''); } } } } } const importantRE = /\s*!important$/; function setStyle(style, name, val) { if (Object(shared_esm_bundler["n" /* isArray */])(val)) { val.forEach(v => setStyle(style, name, v)); } else { if (name.startsWith('--')) { // custom property definition style.setProperty(name, val); } else { const prefixed = autoPrefix(style, name); if (importantRE.test(val)) { // !important style.setProperty(Object(shared_esm_bundler["l" /* hyphenate */])(prefixed), val.replace(importantRE, ''), 'important'); } else { style[prefixed] = val; } } } } const prefixes = ['Webkit', 'Moz', 'ms']; const prefixCache = {}; function autoPrefix(style, rawName) { const cached = prefixCache[rawName]; if (cached) { return cached; } let name = Object(shared_esm_bundler["e" /* camelize */])(rawName); if (name !== 'filter' && name in style) { return (prefixCache[rawName] = name); } name = Object(shared_esm_bundler["f" /* capitalize */])(name); for (let i = 0; i < prefixes.length; i++) { const prefixed = prefixes[i] + name; if (prefixed in style) { return (prefixCache[rawName] = prefixed); } } return rawName; } const xlinkNS = 'http://www.w3.org/1999/xlink'; function patchAttr(el, key, value, isSVG) { if (isSVG && key.startsWith('xlink:')) { if (value == null) { el.removeAttributeNS(xlinkNS, key.slice(6, key.length)); } else { el.setAttributeNS(xlinkNS, key, value); } } else { // note we are only checking boolean attributes that don't have a // corresponding dom prop of the same name here. const isBoolean = Object(shared_esm_bundler["y" /* isSpecialBooleanAttr */])(key); if (value == null || (isBoolean && value === false)) { el.removeAttribute(key); } else { el.setAttribute(key, isBoolean ? '' : value); } } } // __UNSAFE__ // functions. The user is responsible for using them with only trusted content. function patchDOMProp(el, key, value, // the following args are passed only due to potential innerHTML/textContent // overriding existing VNodes, in which case the old tree must be properly // unmounted. prevChildren, parentComponent, parentSuspense, unmountChildren) { if (key === 'innerHTML' || key === 'textContent') { if (prevChildren) { unmountChildren(prevChildren, parentComponent, parentSuspense); } el[key] = value == null ? '' : value; return; } if (key === 'value' && el.tagName !== 'PROGRESS') { // store value as _value as well since // non-string values will be stringified. el._value = value; const newValue = value == null ? '' : value; if (el.value !== newValue) { el.value = newValue; } return; } if (value === '' && typeof el[key] === 'boolean') { // e.g. compiles to { multiple: '' } el[key] = true; } else if (value == null && typeof el[key] === 'string') { // e.g. el[key] = ''; el.removeAttribute(key); } else { // some properties perform value validation and throw try { el[key] = value; } catch (e) { if ((false)) {} } } } // Async edge case fix requires storing an event listener's attach timestamp. let _getNow = Date.now; // Determine what event timestamp the browser is using. Annoyingly, the // timestamp can either be hi-res (relative to page load) or low-res // (relative to UNIX epoch), so in order to compare time we have to use the // same timestamp type when saving the flush timestamp. if (typeof document !== 'undefined' && _getNow() > document.createEvent('Event').timeStamp) { // if the low-res timestamp which is bigger than the event timestamp // (which is evaluated AFTER) it means the event is using a hi-res timestamp, // and we need to use the hi-res version for event listeners as well. _getNow = () => performance.now(); } // To avoid the overhead of repeatedly calling performance.now(), we cache // and use the same timestamp for all event listeners attached in the same tick. let cachedNow = 0; const p = Promise.resolve(); const runtime_dom_esm_bundler_reset = () => { cachedNow = 0; }; const getNow = () => cachedNow || (p.then(runtime_dom_esm_bundler_reset), (cachedNow = _getNow())); function addEventListener(el, event, handler, options) { el.addEventListener(event, handler, options); } function removeEventListener(el, event, handler, options) { el.removeEventListener(event, handler, options); } function patchEvent(el, rawName, prevValue, nextValue, instance = null) { // vei = vue event invokers const invokers = el._vei || (el._vei = {}); const existingInvoker = invokers[rawName]; if (nextValue && existingInvoker) { // patch existingInvoker.value = nextValue; } else { const [name, options] = parseName(rawName); if (nextValue) { // add const invoker = (invokers[rawName] = createInvoker(nextValue, instance)); addEventListener(el, name, invoker, options); } else if (existingInvoker) { // remove removeEventListener(el, name, existingInvoker, options); invokers[rawName] = undefined; } } } const optionsModifierRE = /(?:Once|Passive|Capture)$/; function parseName(name) { let options; if (optionsModifierRE.test(name)) { options = {}; let m; while ((m = name.match(optionsModifierRE))) { name = name.slice(0, name.length - m[0].length); options[m[0].toLowerCase()] = true; } } return [name.slice(2).toLowerCase(), options]; } function createInvoker(initialValue, instance) { const invoker = (e) => { // async edge case #6566: inner click event triggers patch, event handler // attached to outer element during patch, and triggered again. This // happens because browsers fire microtask ticks between event propagation. // the solution is simple: we save the timestamp when a handler is attached, // and the handler would only fire if the event passed to it was fired // AFTER it was attached. const timeStamp = e.timeStamp || _getNow(); if (timeStamp >= invoker.attached - 1) { callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]); } }; invoker.value = initialValue; invoker.attached = getNow(); return invoker; } function patchStopImmediatePropagation(e, value) { if (Object(shared_esm_bundler["n" /* isArray */])(value)) { const originalStop = e.stopImmediatePropagation; e.stopImmediatePropagation = () => { originalStop.call(e); e._stopped = true; }; return value.map(fn => (e) => !e._stopped && fn(e)); } else { return value; } } const nativeOnRE = /^on[a-z]/; const forcePatchProp = (_, key) => key === 'value'; const runtime_dom_esm_bundler_patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => { switch (key) { // special case 'class': patchClass(el, nextValue, isSVG); break; case 'style': patchStyle(el, prevValue, nextValue); break; default: if (Object(shared_esm_bundler["u" /* isOn */])(key)) { // ignore v-model listeners if (!Object(shared_esm_bundler["s" /* isModelListener */])(key)) { patchEvent(el, key, prevValue, nextValue, parentComponent); } } else if (shouldSetAsProp(el, key, nextValue, isSVG)) { patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren); } else { // special case for with // :true-value & :false-value // store value as dom properties since non-string values will be // stringified. if (key === 'true-value') { el._trueValue = nextValue; } else if (key === 'false-value') { el._falseValue = nextValue; } patchAttr(el, key, nextValue, isSVG); } break; } }; function shouldSetAsProp(el, key, value, isSVG) { if (isSVG) { // most keys must be set as attribute on svg elements to work // ...except innerHTML if (key === 'innerHTML') { return true; } // or native onclick with function values if (key in el && nativeOnRE.test(key) && Object(shared_esm_bundler["o" /* isFunction */])(value)) { return true; } return false; } // spellcheck and draggable are numerated attrs, however their // corresponding DOM properties are actually booleans - this leads to // setting it with a string "false" value leading it to be coerced to // `true`, so we need to always treat them as attributes. // Note that `contentEditable` doesn't have this problem: its DOM // property is also enumerated string values. if (key === 'spellcheck' || key === 'draggable') { return false; } // #1787 form as an attribute must be a string, while it accepts an Element as // a prop if (key === 'form' && typeof value === 'string') { return false; } // #1526 must be set as attribute if (key === 'list' && el.tagName === 'INPUT') { return false; } // native onclick with string value, must be set as attribute if (nativeOnRE.test(key) && Object(shared_esm_bundler["z" /* isString */])(value)) { return false; } return key in el; } function useCssModule(name = '$style') { /* istanbul ignore else */ { const instance = getCurrentInstance(); if (!instance) { ( false) && false; return shared_esm_bundler["b" /* EMPTY_OBJ */]; } const modules = instance.type.__cssModules; if (!modules) { ( false) && false; return shared_esm_bundler["b" /* EMPTY_OBJ */]; } const mod = modules[name]; if (!mod) { ( false) && false; return shared_esm_bundler["b" /* EMPTY_OBJ */]; } return mod; } } function useCssVars(getter, scoped = false) { const instance = getCurrentInstance(); /* istanbul ignore next */ if (!instance) { ( false) && false; return; } const prefix = scoped && instance.type.__scopeId ? `${instance.type.__scopeId.replace(/^data-v-/, '')}-` : ``; onMounted(() => { watchEffect(() => { setVarsOnVNode(instance.subTree, getter(instance.proxy), prefix); }); }); } function setVarsOnVNode(vnode, vars, prefix) { if ( vnode.shapeFlag & 128 /* SUSPENSE */) { const { isResolved, isHydrating, fallbackTree, subTree } = vnode.suspense; if (isResolved || isHydrating) { vnode = subTree; } else { vnode.suspense.effects.push(() => { setVarsOnVNode(subTree, vars, prefix); }); vnode = fallbackTree; } } // drill down HOCs until it's a non-component vnode while (vnode.component) { vnode = vnode.component.subTree; } if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) { const style = vnode.el.style; for (const key in vars) { style.setProperty(`--${prefix}${key}`, unref(vars[key])); } } else if (vnode.type === Fragment) { vnode.children.forEach(c => setVarsOnVNode(c, vars, prefix)); } } const TRANSITION = 'transition'; const ANIMATION = 'animation'; // DOM Transition is a higher-order-component based on the platform-agnostic // base Transition component, with DOM-specific logic. const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots); Transition.displayName = 'Transition'; const DOMTransitionPropsValidators = { name: String, type: String, css: { type: Boolean, default: true }, duration: [String, Number, Object], enterFromClass: String, enterActiveClass: String, enterToClass: String, appearFromClass: String, appearActiveClass: String, appearToClass: String, leaveFromClass: String, leaveActiveClass: String, leaveToClass: String }; const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ Object(shared_esm_bundler["h" /* extend */])({}, BaseTransition.props, DOMTransitionPropsValidators)); function resolveTransitionProps(rawProps) { let { name = 'v', type, css = true, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps; const baseProps = {}; for (const key in rawProps) { if (!(key in DOMTransitionPropsValidators)) { baseProps[key] = rawProps[key]; } } if (!css) { return baseProps; } const durations = normalizeDuration(duration); const enterDuration = durations && durations[0]; const leaveDuration = durations && durations[1]; const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps; const finishEnter = (el, isAppear, done) => { removeTransitionClass(el, isAppear ? appearToClass : enterToClass); removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass); done && done(); }; const finishLeave = (el, done) => { removeTransitionClass(el, leaveToClass); removeTransitionClass(el, leaveActiveClass); done && done(); }; const makeEnterHook = (isAppear) => { return (el, done) => { const hook = isAppear ? onAppear : onEnter; const resolve = () => finishEnter(el, isAppear, done); hook && hook(el, resolve); nextFrame(() => { removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass); addTransitionClass(el, isAppear ? appearToClass : enterToClass); if (!(hook && hook.length > 1)) { if (enterDuration) { setTimeout(resolve, enterDuration); } else { whenTransitionEnds(el, type, resolve); } } }); }; }; return Object(shared_esm_bundler["h" /* extend */])(baseProps, { onBeforeEnter(el) { onBeforeEnter && onBeforeEnter(el); addTransitionClass(el, enterActiveClass); addTransitionClass(el, enterFromClass); }, onBeforeAppear(el) { onBeforeAppear && onBeforeAppear(el); addTransitionClass(el, appearActiveClass); addTransitionClass(el, appearFromClass); }, onEnter: makeEnterHook(false), onAppear: makeEnterHook(true), onLeave(el, done) { const resolve = () => finishLeave(el, done); addTransitionClass(el, leaveActiveClass); addTransitionClass(el, leaveFromClass); nextFrame(() => { removeTransitionClass(el, leaveFromClass); addTransitionClass(el, leaveToClass); if (!(onLeave && onLeave.length > 1)) { if (leaveDuration) { setTimeout(resolve, leaveDuration); } else { whenTransitionEnds(el, type, resolve); } } }); onLeave && onLeave(el, resolve); }, onEnterCancelled(el) { finishEnter(el, false); onEnterCancelled && onEnterCancelled(el); }, onAppearCancelled(el) { finishEnter(el, true); onAppearCancelled && onAppearCancelled(el); }, onLeaveCancelled(el) { finishLeave(el); onLeaveCancelled && onLeaveCancelled(el); } }); } function normalizeDuration(duration) { if (duration == null) { return null; } else if (Object(shared_esm_bundler["t" /* isObject */])(duration)) { return [NumberOf(duration.enter), NumberOf(duration.leave)]; } else { const n = NumberOf(duration); return [n, n]; } } function NumberOf(val) { const res = Object(shared_esm_bundler["H" /* toNumber */])(val); if ((false)) {} return res; } function validateDuration(val) { if (typeof val !== 'number') { warn(` explicit duration is not a valid number - ` + `got ${JSON.stringify(val)}.`); } else if (isNaN(val)) { warn(` explicit duration is NaN - ` + 'the duration expression might be incorrect.'); } } function addTransitionClass(el, cls) { cls.split(/\s+/).forEach(c => c && el.classList.add(c)); (el._vtc || (el._vtc = new Set())).add(cls); } function removeTransitionClass(el, cls) { cls.split(/\s+/).forEach(c => c && el.classList.remove(c)); const { _vtc } = el; if (_vtc) { _vtc.delete(cls); if (!_vtc.size) { el._vtc = undefined; } } } function nextFrame(cb) { requestAnimationFrame(() => { requestAnimationFrame(cb); }); } function whenTransitionEnds(el, expectedType, cb) { const { type, timeout, propCount } = getTransitionInfo(el, expectedType); if (!type) { return cb(); } const endEvent = type + 'end'; let ended = 0; const end = () => { el.removeEventListener(endEvent, onEnd); cb(); }; const onEnd = (e) => { if (e.target === el) { if (++ended >= propCount) { end(); } } }; setTimeout(() => { if (ended < propCount) { end(); } }, timeout + 1); el.addEventListener(endEvent, onEnd); } function getTransitionInfo(el, expectedType) { const styles = window.getComputedStyle(el); // JSDOM may return undefined for transition properties const getStyleProperties = (key) => (styles[key] || '').split(', '); const transitionDelays = getStyleProperties(TRANSITION + 'Delay'); const transitionDurations = getStyleProperties(TRANSITION + 'Duration'); const transitionTimeout = getTimeout(transitionDelays, transitionDurations); const animationDelays = getStyleProperties(ANIMATION + 'Delay'); const animationDurations = getStyleProperties(ANIMATION + 'Duration'); const animationTimeout = getTimeout(animationDelays, animationDurations); let type = null; let timeout = 0; let propCount = 0; /* istanbul ignore if */ if (expectedType === TRANSITION) { if (transitionTimeout > 0) { type = TRANSITION; timeout = transitionTimeout; propCount = transitionDurations.length; } } else if (expectedType === ANIMATION) { if (animationTimeout > 0) { type = ANIMATION; timeout = animationTimeout; propCount = animationDurations.length; } } else { timeout = Math.max(transitionTimeout, animationTimeout); type = timeout > 0 ? transitionTimeout > animationTimeout ? TRANSITION : ANIMATION : null; propCount = type ? type === TRANSITION ? transitionDurations.length : animationDurations.length : 0; } const hasTransform = type === TRANSITION && /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']); return { type, timeout, propCount, hasTransform }; } function getTimeout(delays, durations) { while (delays.length < durations.length) { delays = delays.concat(delays); } return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i]))); } // Old versions of Chromium (below 61.0.3163.100) formats floating pointer // numbers in a locale-dependent way, using a comma instead of a dot. // If comma is not replaced with a dot, the input will be rounded down // (i.e. acting as a floor function) causing unexpected behaviors function toMs(s) { return Number(s.slice(0, -1).replace(',', '.')) * 1000; } function runtime_dom_esm_bundler_toRaw(observed) { return ((observed && runtime_dom_esm_bundler_toRaw(observed["__v_raw" /* RAW */])) || observed); } const positionMap = new WeakMap(); const newPositionMap = new WeakMap(); const TransitionGroupImpl = { name: 'TransitionGroup', props: /*#__PURE__*/ Object(shared_esm_bundler["h" /* extend */])({}, TransitionPropsValidators, { tag: String, moveClass: String }), setup(props, { slots }) { const instance = getCurrentInstance(); const state = useTransitionState(); let prevChildren; let children; onUpdated(() => { // children is guaranteed to exist after initial render if (!prevChildren.length) { return; } const moveClass = props.moveClass || `${props.name || 'v'}-move`; if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) { return; } // we divide the work into three loops to avoid mixing DOM reads and writes // in each iteration - which helps prevent layout thrashing. prevChildren.forEach(callPendingCbs); prevChildren.forEach(recordPosition); const movedChildren = prevChildren.filter(applyTranslation); // force reflow to put everything in position forceReflow(); movedChildren.forEach(c => { const el = c.el; const style = el.style; addTransitionClass(el, moveClass); style.transform = style.webkitTransform = style.transitionDuration = ''; const cb = (el._moveCb = (e) => { if (e && e.target !== el) { return; } if (!e || /transform$/.test(e.propertyName)) { el.removeEventListener('transitionend', cb); el._moveCb = null; removeTransitionClass(el, moveClass); } }); el.addEventListener('transitionend', cb); }); }); return () => { const rawProps = runtime_dom_esm_bundler_toRaw(props); const cssTransitionProps = resolveTransitionProps(rawProps); const tag = rawProps.tag || Fragment; prevChildren = children; children = slots.default ? getTransitionRawChildren(slots.default()) : []; for (let i = 0; i < children.length; i++) { const child = children[i]; if (child.key != null) { setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance)); } else if ((false)) {} } if (prevChildren) { for (let i = 0; i < prevChildren.length; i++) { const child = prevChildren[i]; setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance)); positionMap.set(child, child.el.getBoundingClientRect()); } } return createVNode(tag, null, children); }; } }; const TransitionGroup = TransitionGroupImpl; function callPendingCbs(c) { const el = c.el; if (el._moveCb) { el._moveCb(); } if (el._enterCb) { el._enterCb(); } } function recordPosition(c) { newPositionMap.set(c, c.el.getBoundingClientRect()); } function applyTranslation(c) { const oldPos = positionMap.get(c); const newPos = newPositionMap.get(c); const dx = oldPos.left - newPos.left; const dy = oldPos.top - newPos.top; if (dx || dy) { const s = c.el.style; s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`; s.transitionDuration = '0s'; return c; } } // this is put in a dedicated function to avoid the line from being treeshaken function forceReflow() { return document.body.offsetHeight; } function hasCSSTransform(el, root, moveClass) { // Detect whether an element with the move class applied has // CSS transitions. Since the element may be inside an entering // transition at this very moment, we make a clone of it and remove // all other transition classes applied to ensure only the move class // is applied. const clone = el.cloneNode(); if (el._vtc) { el._vtc.forEach(cls => { cls.split(/\s+/).forEach(c => c && clone.classList.remove(c)); }); } moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c)); clone.style.display = 'none'; const container = (root.nodeType === 1 ? root : root.parentNode); container.appendChild(clone); const { hasTransform } = getTransitionInfo(clone); container.removeChild(clone); return hasTransform; } const getModelAssigner = (vnode) => { const fn = vnode.props['onUpdate:modelValue']; return Object(shared_esm_bundler["n" /* isArray */])(fn) ? value => Object(shared_esm_bundler["m" /* invokeArrayFns */])(fn, value) : fn; }; function onCompositionStart(e) { e.target.composing = true; } function onCompositionEnd(e) { const target = e.target; if (target.composing) { target.composing = false; runtime_dom_esm_bundler_trigger(target, 'input'); } } function runtime_dom_esm_bundler_trigger(el, type) { const e = document.createEvent('HTMLEvents'); e.initEvent(type, true, true); el.dispatchEvent(e); } // We are exporting the v-model runtime directly as vnode hooks so that it can // be tree-shaken in case v-model is never used. const vModelText = { created(el, { value, modifiers: { lazy, trim, number } }, vnode) { el.value = value == null ? '' : value; el._assign = getModelAssigner(vnode); const castToNumber = number || el.type === 'number'; addEventListener(el, lazy ? 'change' : 'input', e => { if (e.target.composing) return; let domValue = el.value; if (trim) { domValue = domValue.trim(); } else if (castToNumber) { domValue = Object(shared_esm_bundler["H" /* toNumber */])(domValue); } el._assign(domValue); }); if (trim) { addEventListener(el, 'change', () => { el.value = el.value.trim(); }); } if (!lazy) { addEventListener(el, 'compositionstart', onCompositionStart); addEventListener(el, 'compositionend', onCompositionEnd); // Safari < 10.2 & UIWebView doesn't fire compositionend when // switching focus before confirming composition choice // this also fixes the issue where some browsers e.g. iOS Chrome // fires "change" instead of "input" on autocomplete. addEventListener(el, 'change', onCompositionEnd); } }, beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) { el._assign = getModelAssigner(vnode); if (document.activeElement === el) { if (trim && el.value.trim() === value) { return; } if ((number || el.type === 'number') && Object(shared_esm_bundler["H" /* toNumber */])(el.value) === value) { return; } } const newValue = value == null ? '' : value; if (el.value !== newValue) { el.value = newValue; } } }; const vModelCheckbox = { created(el, binding, vnode) { setChecked(el, binding, vnode); el._assign = getModelAssigner(vnode); addEventListener(el, 'change', () => { const modelValue = el._modelValue; const elementValue = getValue(el); const checked = el.checked; const assign = el._assign; if (Object(shared_esm_bundler["n" /* isArray */])(modelValue)) { const index = Object(shared_esm_bundler["C" /* looseIndexOf */])(modelValue, elementValue); const found = index !== -1; if (checked && !found) { assign(modelValue.concat(elementValue)); } else if (!checked && found) { const filtered = [...modelValue]; filtered.splice(index, 1); assign(filtered); } } else { assign(getCheckboxValue(el, checked)); } }); }, beforeUpdate(el, binding, vnode) { el._assign = getModelAssigner(vnode); setChecked(el, binding, vnode); } }; function setChecked(el, { value, oldValue }, vnode) { el._modelValue = value; if (Object(shared_esm_bundler["n" /* isArray */])(value)) { el.checked = Object(shared_esm_bundler["C" /* looseIndexOf */])(value, vnode.props.value) > -1; } else if (value !== oldValue) { el.checked = Object(shared_esm_bundler["B" /* looseEqual */])(value, getCheckboxValue(el, true)); } } const vModelRadio = { created(el, { value }, vnode) { el.checked = Object(shared_esm_bundler["B" /* looseEqual */])(value, vnode.props.value); el._assign = getModelAssigner(vnode); addEventListener(el, 'change', () => { el._assign(getValue(el)); }); }, beforeUpdate(el, { value, oldValue }, vnode) { el._assign = getModelAssigner(vnode); if (value !== oldValue) { el.checked = Object(shared_esm_bundler["B" /* looseEqual */])(value, vnode.props.value); } } }; const vModelSelect = { created(el, binding, vnode) { addEventListener(el, 'change', () => { const selectedVal = Array.prototype.filter .call(el.options, (o) => o.selected) .map(getValue); el._assign(el.multiple ? selectedVal : selectedVal[0]); }); el._assign = getModelAssigner(vnode); }, // set value in mounted & updated because relies on its children // s. mounted(el, { value }) { setSelected(el, value); }, beforeUpdate(el, _binding, vnode) { el._assign = getModelAssigner(vnode); }, updated(el, { value }) { setSelected(el, value); } }; function setSelected(el, value) { const isMultiple = el.multiple; if (isMultiple && !Object(shared_esm_bundler["n" /* isArray */])(value)) { ( false) && false; return; } for (let i = 0, l = el.options.length; i < l; i++) { const option = el.options[i]; const optionValue = getValue(option); if (isMultiple) { option.selected = Object(shared_esm_bundler["C" /* looseIndexOf */])(value, optionValue) > -1; } else { if (Object(shared_esm_bundler["B" /* looseEqual */])(getValue(option), value)) { el.selectedIndex = i; return; } } } if (!isMultiple) { el.selectedIndex = -1; } } // retrieve raw value set via :value bindings function getValue(el) { return '_value' in el ? el._value : el.value; } // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings function getCheckboxValue(el, checked) { const key = checked ? '_trueValue' : '_falseValue'; return key in el ? el[key] : checked; } const vModelDynamic = { created(el, binding, vnode) { callModelHook(el, binding, vnode, null, 'created'); }, mounted(el, binding, vnode) { callModelHook(el, binding, vnode, null, 'mounted'); }, beforeUpdate(el, binding, vnode, prevVNode) { callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate'); }, updated(el, binding, vnode, prevVNode) { callModelHook(el, binding, vnode, prevVNode, 'updated'); } }; function callModelHook(el, binding, vnode, prevVNode, hook) { let modelToUse; switch (el.tagName) { case 'SELECT': modelToUse = vModelSelect; break; case 'TEXTAREA': modelToUse = vModelText; break; default: switch (vnode.props && vnode.props.type) { case 'checkbox': modelToUse = vModelCheckbox; break; case 'radio': modelToUse = vModelRadio; break; default: modelToUse = vModelText; } } const fn = modelToUse[hook]; fn && fn(el, binding, vnode, prevVNode); } const systemModifiers = ['ctrl', 'shift', 'alt', 'meta']; const modifierGuards = { stop: e => e.stopPropagation(), prevent: e => e.preventDefault(), self: e => e.target !== e.currentTarget, ctrl: e => !e.ctrlKey, shift: e => !e.shiftKey, alt: e => !e.altKey, meta: e => !e.metaKey, left: e => 'button' in e && e.button !== 0, middle: e => 'button' in e && e.button !== 1, right: e => 'button' in e && e.button !== 2, exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m)) }; /** * @private */ const withModifiers = (fn, modifiers) => { return (event, ...args) => { for (let i = 0; i < modifiers.length; i++) { const guard = modifierGuards[modifiers[i]]; if (guard && guard(event, modifiers)) return; } return fn(event, ...args); }; }; // Kept for 2.x compat. // Note: IE11 compat for `spacebar` and `del` is removed for now. const keyNames = { esc: 'escape', space: ' ', up: 'arrow-up', left: 'arrow-left', right: 'arrow-right', down: 'arrow-down', delete: 'backspace' }; /** * @private */ const withKeys = (fn, modifiers) => { return (event) => { if (!('key' in event)) return; const eventKey = Object(shared_esm_bundler["l" /* hyphenate */])(event.key); if ( // None of the provided key modifiers match the current event key !modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) { return; } return fn(event); }; }; const vShow = { beforeMount(el, { value }, { transition }) { el._vod = el.style.display === 'none' ? '' : el.style.display; if (transition && value) { transition.beforeEnter(el); } else { setDisplay(el, value); } }, mounted(el, { value }, { transition }) { if (transition && value) { transition.enter(el); } }, updated(el, { value, oldValue }, { transition }) { if (!value === !oldValue) return; if (transition) { if (value) { transition.beforeEnter(el); setDisplay(el, true); transition.enter(el); } else { transition.leave(el, () => { setDisplay(el, false); }); } } else { setDisplay(el, value); } }, beforeUnmount(el, { value }) { setDisplay(el, value); } }; function setDisplay(el, value) { el.style.display = value ? el._vod : 'none'; } const rendererOptions = Object(shared_esm_bundler["h" /* extend */])({ patchProp: runtime_dom_esm_bundler_patchProp, forcePatchProp }, nodeOps); // lazy create the renderer - this makes core renderer logic tree-shakable // in case the user only imports reactivity utilities from Vue. let renderer; let enabledHydration = false; function ensureRenderer() { return renderer || (renderer = createRenderer(rendererOptions)); } function ensureHydrationRenderer() { renderer = enabledHydration ? renderer : createHydrationRenderer(rendererOptions); enabledHydration = true; return renderer; } // use explicit type casts here to avoid import() calls in rolled-up d.ts const runtime_dom_esm_bundler_render = ((...args) => { ensureRenderer().render(...args); }); const runtime_dom_esm_bundler_hydrate = ((...args) => { ensureHydrationRenderer().hydrate(...args); }); const runtime_dom_esm_bundler_createApp = ((...args) => { const app = ensureRenderer().createApp(...args); if ((false)) {} const { mount } = app; app.mount = (containerOrSelector) => { const container = normalizeContainer(containerOrSelector); if (!container) return; const component = app._component; if (!Object(shared_esm_bundler["o" /* isFunction */])(component) && !component.render && !component.template) { component.template = container.innerHTML; } // clear content before mounting container.innerHTML = ''; const proxy = mount(container); container.removeAttribute('v-cloak'); container.setAttribute('data-v-app', ''); return proxy; }; return app; }); const createSSRApp = ((...args) => { const app = ensureHydrationRenderer().createApp(...args); if ((false)) {} const { mount } = app; app.mount = (containerOrSelector) => { const container = normalizeContainer(containerOrSelector); if (container) { return mount(container, true); } }; return app; }); function injectNativeTagCheck(app) { // Inject `isNativeTag` // this is used for component name validation (dev only) Object.defineProperty(app.config, 'isNativeTag', { value: (tag) => Object(shared_esm_bundler["q" /* isHTMLTag */])(tag) || Object(shared_esm_bundler["x" /* isSVGTag */])(tag), writable: false }); } function normalizeContainer(container) { if (Object(shared_esm_bundler["z" /* isString */])(container)) { const res = document.querySelector(container); if (false) {} return res; } return container; } // CONCATENATED MODULE: ./node_modules/vue/dist/vue.runtime.esm-bundler.js function initDev() { const target = Object(shared_esm_bundler["i" /* getGlobalThis */])(); target.__VUE__ = true; setDevtoolsHook(target.__VUE_DEVTOOLS_GLOBAL_HOOK__); { console.info(`You are running a development build of Vue.\n` + `Make sure to use the production build (*.prod.js) when deploying for production.`); } } // This entry exports the runtime only, and is built as ( false) && false; const vue_runtime_esm_bundler_compile = () => { if ((false)) {} }; /***/ }), /* 11 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return note_list_store; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return settingStore; }); /* harmony import */ var svelte_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); /* harmony import */ var _lib_store__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8); /** 用来显示笔记的地方 */ const note_list_store = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* writable */ "c"])([]); const defaultSetting = { a: 3, swatches: { textColor: { default: "#333", list: ["#EB5757", "#F2C94C", "#9B51E0", "#E0E0E0", "#2F80ED", "#2F80ED", "#828282", "#27AE60", "#27AE60", "#EB5757", "#56CCF2", "#F2994A", "#4F4F4F", "#219653", "#BB6BD9", "#F2F2F2", "#2D9CDB", "#2D9CDB", "#BDBDBD", "#6FCF97", "#6FCF97"] }, bgColor: { default: "#EB5757", list: ["#EB5757", "#F2C94C", "#9B51E0", "#E0E0E0", "#2F80ED", "#2F80ED", "#828282", "#27AE60", "#27AE60", "#EB5757", "#56CCF2", "#F2994A", "#4F4F4F", "#219653", "#BB6BD9", "#F2F2F2", "#2D9CDB", "#2D9CDB", "#BDBDBD", "#6FCF97", "#6FCF97"] }, underlineColor: { default: "#EB5757", list: ["#EB5757", "#F2C94C", "#9B51E0", "#E0E0E0", "#2F80ED", "#2F80ED", "#828282", "#27AE60", "#27AE60", "#EB5757", "#56CCF2", "#F2994A", "#4F4F4F", "#219653", "#BB6BD9", "#F2F2F2", "#2D9CDB", "#2D9CDB", "#BDBDBD", "#6FCF97", "#6FCF97"] } } }; class PageNotesStore { constructor(storePath) { this.storePath = storePath; this.store = {}; this._writable = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* writable */ "c"])({}); this.initializing = Object(_lib_store__WEBPACK_IMPORTED_MODULE_1__[/* getLocalItem */ "b"])(storePath, JSON.stringify(defaultSetting)).then(r => { this.store = JSON.parse(r); this._writable.set(this.store); this._writable.subscribe(r => { this.store = r; this.save(r); }); return; }); } async getStore() { await this.initializing; return this.store; } save(r) { Object(_lib_store__WEBPACK_IMPORTED_MODULE_1__[/* setLocalItem */ "c"])(this.storePath, JSON.stringify(r)); } getWritable() { return this._writable; } async get(k) { return (await this.getStore())[k]; } async set(k, value) { const s = await this.getStore(); s[k] = value; this._writable.set(s); this.save(s); } } /** 设置相关的存储 */ const settingStore = new PageNotesStore("__setting__"); /***/ }), /* 12 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return styleList; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return styleText; }); /* harmony import */ var svelte_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); const styleList = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* writable */ "c"])([]); /** 根据 styleList 计算出来的 css 片段 */ const styleText = Object(svelte_store__WEBPACK_IMPORTED_MODULE_0__[/* derived */ "a"])(styleList, $styleList => { return ``; }); /***/ }), /* 13 */ /***/ (function(module, exports) { var g; // This works in non-strict mode g = (function() { return this; })(); try { // This works if eval is allowed (see CSP) g = g || new Function("return this")(); } catch (e) { // This works if the window reference is available if (typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /* 14 */, /* 15 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, "我来md导出", function() { return /* binding */ 我来md导出; }); // CONCATENATED MODULE: ./node_modules/ajax-hook/src/xhr-hook.js /* * author: wendux * email: 824783146@qq.com * source code: https://github.com/wendux/Ajax-hook */ // Save original XMLHttpRequest as _rxhr var realXhr = "_rxhr" function configEvent(event, xhrProxy) { var e = {}; for (var attr in event) e[attr] = event[attr]; // xhrProxy instead e.target = e.currentTarget = xhrProxy return e; } function hook(proxy) { // Avoid double hookAjax window[realXhr] = window[realXhr] || XMLHttpRequest XMLHttpRequest = function () { var xhr = new window[realXhr]; // We shouldn't hookAjax XMLHttpRequest.prototype because we can't // guarantee that all attributes are on the prototype。 // Instead, hooking XMLHttpRequest instance can avoid this problem. for (var attr in xhr) { var type = ""; try { type = typeof xhr[attr] // May cause exception on some browser } catch (e) { } if (type === "function") { // hookAjax methods of xhr, such as `open`、`send` ... this[attr] = hookFunction(attr); } else { Object.defineProperty(this, attr, { get: getterFactory(attr), set: setterFactory(attr), enumerable: true }) } } var that = this; xhr.getProxy = function () { return that } this.xhr = xhr; } // Generate getter for attributes of xhr function getterFactory(attr) { return function () { var v = this.hasOwnProperty(attr + "_") ? this[attr + "_"] : this.xhr[attr]; var attrGetterHook = (proxy[attr] || {})["getter"] return attrGetterHook && attrGetterHook(v, this) || v } } // Generate setter for attributes of xhr; by this we have an opportunity // to hookAjax event callbacks (eg: `onload`) of xhr; function setterFactory(attr) { return function (v) { var xhr = this.xhr; var that = this; var hook = proxy[attr]; // hookAjax event callbacks such as `onload`、`onreadystatechange`... if (attr.substring(0, 2) === 'on') { that[attr + "_"] = v; xhr[attr] = function (e) { e = configEvent(e, that) var ret = proxy[attr] && proxy[attr].call(that, xhr, e) ret || v.call(that, e); } } else { //If the attribute isn't writable, generate proxy attribute var attrSetterHook = (hook || {})["setter"]; v = attrSetterHook && attrSetterHook(v, that) || v this[attr + "_"] = v; try { // Not all attributes of xhr are writable(setter may undefined). xhr[attr] = v; } catch (e) { } } } } // Hook methods of xhr. function hookFunction(fun) { return function () { var args = [].slice.call(arguments) if (proxy[fun]) { var ret = proxy[fun].call(this, args, this.xhr) // If the proxy return value exists, return it directly, // otherwise call the function of xhr. if (ret) return ret; } return this.xhr[fun].apply(this.xhr, args); } } // Return the real XMLHttpRequest return window[realXhr]; } function unHook() { if (window[realXhr]) XMLHttpRequest = window[realXhr]; window[realXhr] = undefined; } // CONCATENATED MODULE: ./node_modules/ajax-hook/src/xhr-proxy.js /* * author: wendux * email: 824783146@qq.com * source code: https://github.com/wendux/Ajax-hook */ var events = ['load', 'loadend', 'timeout', 'error', 'readystatechange', 'abort']; var eventLoad = events[0], eventLoadEnd = events[1], eventTimeout = events[2], eventError = events[3], eventReadyStateChange = events[4], eventAbort = events[5]; var singleton, xhr_proxy_prototype = 'prototype'; function xhr_proxy_proxy(proxy) { if (singleton) throw "Proxy already exists"; return singleton = new Proxy(proxy); } function unProxy() { singleton = null unHook() } function trim(str) { return str.replace(/^\s+|\s+$/g, ''); } function getEventTarget(xhr) { return xhr.watcher || (xhr.watcher = document.createElement('a')); } function triggerListener(xhr, name) { var xhrProxy = xhr.getProxy(); var callback = 'on' + name + '_'; var event = configEvent({type: name}, xhrProxy); xhrProxy[callback] && xhrProxy[callback](event); var evt; if(typeof(Event) === 'function') { evt = new Event(name,{bubbles: false}); } else { // https://stackoverflow.com/questions/27176983/dispatchevent-not-working-in-ie11 evt = document.createEvent('Event'); evt.initEvent(name, false, true); } getEventTarget(xhr).dispatchEvent(evt); } function Handler(xhr) { this.xhr = xhr; this.xhrProxy = xhr.getProxy(); } Handler[xhr_proxy_prototype] = Object.create({ resolve: function resolve(response) { var xhrProxy = this.xhrProxy; var xhr = this.xhr; xhrProxy.readyState = 4; xhr.resHeader = response.headers; xhrProxy.response = xhrProxy.responseText = response.response; xhrProxy.statusText = response.statusText; xhrProxy.status = response.status; triggerListener(xhr, eventReadyStateChange); triggerListener(xhr, eventLoad); triggerListener(xhr, eventLoadEnd); }, reject: function reject(error) { this.xhrProxy.status = 0; triggerListener(this.xhr, error.type); triggerListener(this.xhr, eventLoadEnd); } }); function makeHandler(next) { function sub(xhr) { Handler.call(this, xhr); } sub[xhr_proxy_prototype] = Object.create(Handler[xhr_proxy_prototype]); sub[xhr_proxy_prototype].next = next; return sub; } var RequestHandler = makeHandler(function (rq) { var xhr = this.xhr; rq = rq || xhr.config; xhr.withCredentials = rq.withCredentials; xhr.open(rq.method, rq.url, rq.async !== false, rq.user, rq.password); for (var key in rq.headers) { xhr.setRequestHeader(key, rq.headers[key]); } xhr.send(rq.body); }); var ResponseHandler = makeHandler(function (response) { this.resolve(response); }); var ErrorHandler = makeHandler(function (error) { this.reject(error); }); function Proxy(proxy) { var onRequest = proxy.onRequest, onResponse = proxy.onResponse, onError = proxy.onError; function handleResponse(xhr, xhrProxy) { var handler = new ResponseHandler(xhr); if (!onResponse) return handler.resolve(); var ret = { response: xhrProxy.response, status: xhrProxy.status, statusText: xhrProxy.statusText, config: xhr.config, headers: xhr.resHeader || xhr.getAllResponseHeaders().split('\r\n').reduce(function (ob, str) { if (str === "") return ob; var m = str.split(":"); ob[m.shift()] = trim(m.join(':')); return ob; }, {}) }; onResponse(ret, handler); } function onerror(xhr, xhrProxy, e) { var handler = new ErrorHandler(xhr); var error = {config: xhr.config, error: e}; if (onError) { onError(error, handler); } else { handler.next(error); } } function preventXhrProxyCallback() { return true; } function errorCallback(xhr, e) { onerror(xhr, this, e); return true; } function stateChangeCallback(xhr, xhrProxy) { if (xhr.readyState === 4 && xhr.status !== 0) { handleResponse(xhr, xhrProxy); } else if (xhr.readyState !== 4) { triggerListener(xhr, eventReadyStateChange); } return true; } return hook({ onload: preventXhrProxyCallback, onloadend: preventXhrProxyCallback, onerror: errorCallback, ontimeout: errorCallback, onabort: errorCallback, onreadystatechange: function (xhr) { return stateChangeCallback(xhr, this); }, open: function open(args, xhr) { var _this = this; var config = xhr.config = {headers: {}}; config.method = args[0]; config.url = args[1]; config.async = args[2]; config.user = args[3]; config.password = args[4]; config.xhr = xhr; var evName = 'on' + eventReadyStateChange; if (!xhr[evName]) { xhr[evName] = function () { return stateChangeCallback(xhr, _this); }; } var defaultErrorHandler = function defaultErrorHandler(e) { onerror(xhr, _this, configEvent(e, _this)); }; [eventError, eventTimeout, eventAbort].forEach(function (e) { var event = 'on' + e; if (!xhr[event]) xhr[event] = defaultErrorHandler; }); // 如果有请求拦截器,则在调用onRequest后再打开链接。因为onRequest最佳调用时机是在send前, // 所以我们在send拦截函数中再手动调用open,因此返回true阻止xhr.open调用。 // // 如果没有请求拦截器,则不用阻断xhr.open调用 if (onRequest) return true; }, send: function (args, xhr) { var config = xhr.config config.withCredentials=xhr.withCredentials config.body = args[0]; if (onRequest) { // In 'onRequest', we may call XHR's event handler, such as `xhr.onload`. // However, XHR's event handler may not be set until xhr.send is called in // the user's code, so we use `setTimeout` to avoid this situation var req = function () { onRequest(config, new RequestHandler(xhr)); } config.async === false ? req() : setTimeout(req) return true; } }, setRequestHeader: function (args, xhr) { // Collect request headers xhr.config.headers[args[0].toLowerCase()] = args[1]; return true; }, addEventListener: function (args, xhr) { var _this = this; if (events.indexOf(args[0]) !== -1) { var handler = args[1]; getEventTarget(xhr).addEventListener(args[0], function (e) { var event = configEvent(e, _this); event.type = args[0]; event.isTrusted = true; handler.call(_this, event); }); return true; } }, getAllResponseHeaders: function (_, xhr) { var headers = xhr.resHeader if (headers) { var header = ""; for (var key in headers) { header += key + ': ' + headers[key] + '\r\n'; } return header; } }, getResponseHeader: function (args, xhr) { var headers = xhr.resHeader if (headers) { return headers[(args[0] || '').toLowerCase()]; } } }); } // CONCATENATED MODULE: ./node_modules/ajax-hook/index.js /* * author: wendux * email: 824783146@qq.com * source code: https://github.com/wendux/Ajax-hook **/ // EXTERNAL MODULE: ./网页笔记/util.ts var util = __webpack_require__(4); // CONCATENATED MODULE: ./util/dom/element.ts function 检测元素状态(selector, 出现 = () => {}, 变化 = () => {}, 消失 = () => {}) { let status = false; let html = ""; setInterval(() => { const el = document.querySelector(selector); if (status && el && el.innerHTML !== html) { html = el.innerHTML; 变化(el); } if (el && !status) { status = true; 出现(el); } else if (!el && status) { status = false; 消失(); } }, 100); } // CONCATENATED MODULE: ./util/dom/剪贴板.ts const copy = str => { // 第一种 return navigator.clipboard.writeText(str); }; // CONCATENATED MODULE: ./更好的我来导出/index.user.ts // ==UserScript== // @name 更好的我来导出 // @namespace https://shenzilong.cn/ // @version 1.0.0 // @description 从我来导出markdown 文档 // @author 崮生 admin@shenzilong.cn // @include https://www.wolai.com/* // @grant unsafeWindow // @grant GM.setValue // @grant GM.getValue // @grant GM.xmlHttpRequest // ==/UserScript== const _n = "\n\n"; // const _n = "\n"; var 我来md导出; (function (我来md导出) { async function toMarkdown(p) { let mdText = ""; const blocks = Object.keys(p.data.block).map(k => p.data.block[k]).map(el => el.value); console.log("[blocks]", blocks); const page = findPage(blocks); if (!page) { throw "没有寻找到page块"; } mdText += await nodeToMarkdown(page, p); return mdText; } 我来md导出.toMarkdown = toMarkdown; function findPage(p) { return p.find(el => el.type === "page"); } /** 存储所有节点解析器 */ const nodeParers = []; /** 对 子节点和父节点的关系 进行处理,因为不同父子节点的组织方式可能不一样 */ const sub_nodeParers = []; function registerNodeParer(...parers) { nodeParers.push(...parers); } 我来md导出.registerNodeParer = registerNodeParer; function registerSubNodeParer(...parers) { sub_nodeParers.push(...parers); } 我来md导出.registerSubNodeParer = registerSubNodeParer; async function nodeToMarkdown(p, pageChunkRes) { const parer = nodeParers.find(el => el.check(p, pageChunkRes)); if (parer) { const md_str = await parer.parer(p, pageChunkRes); if (p.sub_nodes.length) { const sub_node_parer = sub_nodeParers.find(el => el.check(p, pageChunkRes)); if (sub_node_parer) { return await sub_node_parer.parer(md_str, p, pageChunkRes); } else { console.log(`[没有对应的结构解析器 ${p.type}]`, p); } } return md_str; } else { console.log(`[没有对应的解析器 ${p.type}]`, p); return `--- 没有对应的解析器 -> ${p.type} ---`; } } 我来md导出.nodeToMarkdown = nodeToMarkdown; /** 对块的title属性进行解析 */ function NodeTitleToMarkdown(p) { if (!p) { return ""; } return p.map(el => { const text = el[0]; if (el.length === 1) { return text; } else { const 修饰 = el[1]; if (修饰.length === 0) { /** 无修饰啥也不做 */ } let _text = text; for (const mode of 修饰) { if (mode[0] === "Link") { _text = `[${_text}](${mode[1]})`; } else if (mode[0] === "BiLink" /** 我来内部链接 */ ) { const workspace_url = getWorkUrl(); _text = `[${_text}](${workspace_url}${mode[2]})`; } else if (mode[0] === "<>" /** 行内代码块 */ ) { _text = `\`${_text}\``; } else if (mode[0] === "B" /** 粗体 */ ) { _text = `**${_text}**`; } else if (mode[0] === "h" /** 字体以及背景颜色 */ ) { /** 这里在某些选项下可以选择开启转换 */ _text = _text; } else if (mode[0] === "i" /** 斜体 */ ) { _text = `*${_text}*`; } else if (mode[0] === "U" /** 下划线 */ ) { /** 这里在某些选项下可以选择开启转换 */ _text = `${_text}`; } else if (mode[0] === "S" /** 删除线 */ ) { _text = `~~${_text}~~`; } else if (mode[0] === "Equation" /** 公式 */ ) { _text = `$${_text}$`; } else { /** 这里mode的类型应当始终为 never */ mode; _text = `<未知类型 ${mode[0]}>`; console.log(`<未知类型 ${mode[0]}>`, mode, 修饰, el); } } return _text; } }).join(""); } 我来md导出.NodeTitleToMarkdown = NodeTitleToMarkdown; /** 当前打开页面的工作空间链接 */ function getWorkUrl() { return location.href.match(/.*?wolai\.com\/.*?\//)[0]; } 我来md导出.getWorkUrl = getWorkUrl; })(我来md导出 || (我来md导出 = {})); const NodeTitleToMarkdown = 我来md导出.NodeTitleToMarkdown; 我来md导出.registerNodeParer({ check: p => p.type === "quote", async parer(p) { return `> ${NodeTitleToMarkdown(p.attributes.title)}`; } }, /** 对各级标题进行处理 * 对bullList节点进行处理 */ (() => { const header = { bullList: "-", header: "#", midHeader: "##", subHeader: "###", tinyHeader: "####" }; return { check: p => header.hasOwnProperty(p.type), async parer(p) { const t = header[p.type]; return `${t} ${NodeTitleToMarkdown(p.attributes.title)}`; } }; })(), /** 数字列表的解析 */ { check: p => p.type === "enumList", async parer(p, pageChunkRes) { let l = 0; const brothers = sub_nodeToNode(pageChunkRes.data.block[p.parent_id].value, pageChunkRes); let i = brothers.findIndex(el => el.id === p.id); while (i >= 0 && brothers[i].type === "enumList") { i -= 1; l += 1; } // const l = pageChunkRes.data.block[p.parent_id].value.sub_nodes.findIndex((id) => id === p.id) + 1; return `${l}. ${NodeTitleToMarkdown(p.attributes.title)}`; } }, /** 折叠列表的解析 */ { check: p => p.type === "toggleList", async parer(p, pageChunkRes) { return NodeTitleToMarkdown(p.attributes.title); } }, /** 对书签的解析, **这里到时候应该要调成可控的** */ { check: p => p.type === "bookmark", async parer(p) { var _rich$thumbnail; const rich = p.attributes.rich_media[0]; const description = rich.description || ""; const thumbnail = /** 和我来一样有描述信息才显示缩略图 */ description && (rich === null || rich === void 0 ? void 0 : (_rich$thumbnail = rich.thumbnail) === null || _rich$thumbnail === void 0 ? void 0 : _rich$thumbnail.length) ? `{:height="60px" width="60px"}` : ""; return `> [{:height="30px" width="30px"} 崮生 一些随笔](${p.attributes.source} "${description}") ${description} ${thumbnail}`; } }, /** 对嵌入内容的解析, **这里到时候应该要调成可控的** */ { check: p => ["embed", "bilibiliVideo", "tencentVideo", "youkuVideo", "youtubeVideo"].includes(p.type), async parer(p) { return ``; } }, /** 对着重文字的解析 */ { check: p => ["callout"].includes(p.type), async parer(p) { return `${我来md导出.NodeTitleToMarkdown(p.attributes.title)}`; } }, /** 分割线 */ { check: p => ["divider"].includes(p.type), async parer(p) { return `---`; } }, /** 文件 */ { check: p => ["file"].includes(p.type), async parer(p) { /** TODO 这里需要获取签名才能访问 */ const src = `https://secure-static.wolai.com/${encodeURIComponent(p.attributes.file[0])}`; return `[file:${p.attributes.alias[0]}](${src}})`; } }, /** 公式 */ { check: p => ["blockEquation"].includes(p.type), async parer(p) { return `$$\n${p.attributes.title.join("\n")}\n$$`; } }, /** 模板按钮 */ { check: p => ["templateButton"].includes(p.type), async parer(p) { /** TODO 暂不解析模板按钮 */ return ``; } }, /** 表格解析器 */ { check: p => ["simpleTable"].includes(p.type), async parer(p) { /** TODO 暂不解析模板按钮 */ const cells = JSON.parse(p.attributes.cells); let md_str = ""; /** 遍历行 */ for (let i = 0; i < cells[0].column.length; i++) { if (i === 1) { /** 标题栏的分隔 */ md_str += "|" + cells.map(el => "-").join("|") + "|\n"; } md_str += "|"; /** 遍历列 */ for (let j = 0; j < cells.length; j++) { /** 当前遍历到的元素 */ const cur = cells[j].column[i]; md_str += 我来md导出.NodeTitleToMarkdown(cur.attributes.title) + "|"; } md_str += "\n"; } return md_str; } }, { check: p => p.type === "text", async parer(p) { return `${NodeTitleToMarkdown(p.attributes.title)}`; } }, { check: p => p.type === "row" || p.type === "column", async parer(p, pageChunkRes) { const sub_nodes = p.sub_nodes.map(id => pageChunkRes.data.block[id]); let mdText = ``; for (const el of sub_nodes) { mdText += (await 我来md导出.nodeToMarkdown(el.value, pageChunkRes)) + _n; } return mdText; } }, { check: p => p.type === "code", async parer(p, pageChunkRes) { return `\`\`\`${p.attributes.language}\n${NodeTitleToMarkdown(p.attributes.title)}\n\`\`\``; } }, { check: p => p.type === "image", async parer(p, pageChunkRes) { /** 此处需要在浏览器内才能正常运行 */ const src = document.querySelector(`#id-${p.id} img`).getAttribute("src"); return ``; // TODO 描述应该要去获取到 } }, { check: p => p.type === "page", async parer(p, pageChunkRes) { const workspace_url = 我来md导出.getWorkUrl(); if (p.id === Object.keys(pageChunkRes.data.block)[0]) { /** 顶层块 也就是当前页面块 */ return `# [${NodeTitleToMarkdown(p.attributes.title)}](${workspace_url}${p.id})`; } else { /** 页面内引用其他页面的块 */ return `[${NodeTitleToMarkdown(p.attributes.title)}](${workspace_url}${p.id})`; } } }, { check: p => p.type === "todoList", async parer(p, pageChunkRes) { return `[${p.attributes.checked === "yes" ? "x" : " "}] ${NodeTitleToMarkdown(p.attributes.title)}`; } }); function sub_nodeToNode(p, pageChunkRes) { return p.sub_nodes.map(id => pageChunkRes.data.block[id].value); } 我来md导出.registerSubNodeParer( /** 对页面下面的一级节点进行处理 */ { check: p => p.type === "page", async parer(md_str, p, pageChunkRes) { return md_str + "\n\n" + (await Promise.all(sub_nodeToNode(p, pageChunkRes).map(p => 我来md导出.nodeToMarkdown(p, pageChunkRes)))).join("\n\n"); } }, /** 对列表类的层级进行处理 */ { check: p => ["bullList", "enumList", "todoList"].includes(p.type), async parer(md_str, p, pageChunkRes) { /** 获取一个节点有多少父级 */ function getNodeNumberOfLayers(p, pageChunkRes) { let l = 0; let cur = p; while ((_cur = cur) === null || _cur === void 0 ? void 0 : _cur.parent_id) { var _cur, _pageChunkRes$data$bl, _cur2; l++; cur = (_pageChunkRes$data$bl = pageChunkRes.data.block[cur.parent_id]) === null || _pageChunkRes$data$bl === void 0 ? void 0 : _pageChunkRes$data$bl.value; if (((_cur2 = cur) === null || _cur2 === void 0 ? void 0 : _cur2.type) === "toggleList") { /** 不是相同的结构了,层级关系算到这里位置,更外层的层级关系交给该结构自行处理 */ l++; /** 因为上面算了页面,这里将 toggleList 当做和页面一样看待 */ break; } } /** 不算页面这一级 */ return l - 1; } const l = getNodeNumberOfLayers(p, pageChunkRes) - 1; // console.log(l,p,md_str); const md_str_List = (await Promise.all(sub_nodeToNode(p, pageChunkRes).map(p => 我来md导出.nodeToMarkdown(p, pageChunkRes)))).map(md_str => `${"".padEnd( /** 列表内的是当前节点的子节点而l是当前节点的层级,所以这里要+1 */ l + 1, "\t")}${md_str}`); return `${md_str}${md_str_List.length ? "\n" + md_str_List.join("\n") : ""}`; } }, /** 对折叠列表类的层级进行处理 */ { check: p => ["toggleList"].includes(p.type), async parer(md_str, p, pageChunkRes) { const md_str_List = await Promise.all(sub_nodeToNode(p, pageChunkRes).map(p => 我来md导出.nodeToMarkdown(p, pageChunkRes))); return ` ${md_str} ${md_str_List.join(_n)} `; } }); let curData = null; xhr_proxy_proxy({ //请求发起前进入 onRequest: (config, handler) => { // console.log("[💚开始请求]", config.url); // config.url = urlHandler(config.url); /** 关闭 withCredentials 避免触发跨域 */ // config.withCredentials = false; handler.next(config); }, //请求发生错误时进入,比如超时;注意,不包括http状态码错误,如404仍然会认为请求成功 onError: (err, handler) => { handler.next(err); }, //请求成功后进入 onResponse: (response, handler) => { handler.next(response); if (response.config.url.endsWith("transaction/getPageChunks")) { curData = response.response; } } }); 检测元素状态('[data-growing-title="复制页面引用链接-头部栏"]', el => { console.log("[ el]", el); const btn = el.nextElementSibling; const newBtn = btn.cloneNode(true); btn.parentElement.appendChild(newBtn); newBtn.querySelectorAll("span")[1].textContent = `[✨] 导出Markdown`; newBtn.addEventListener("click", async () => { if (curData === null) { return alert("没有获取到当前页面数据,您可以尝试刷新重试。"); } const res = JSON.parse(curData); const md = await 我来md导出.toMarkdown(res); const blob = new Blob([md], { type: "text/plain;charset=utf-8" }); const downloadUrl = URL.createObjectURL(blob); console.log(`[markdown:${downloadUrl}]\n----\n`, md); console.log("[copy(md)]", copy(md)); alert("复制成功"); }); }); var 附加按钮; (function (附加按钮) { 附加按钮.已附加 = false; })(附加按钮 || (附加按钮 = {})); /** 替换 windows 上的 xml 对象 */ //@ts-ignore unsafeWindow.XMLHttpRequest = XMLHttpRequest; /***/ }) /******/ ]); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0B2dWUvc2hhcmVkL2Rpc3Qvc2hhcmVkLmVzbS1idW5kbGVyLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zdmVsdGUvaW50ZXJuYWwvaW5kZXgubWpzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC9jb25maWcudHMiLCJ3ZWJwYWNrOi8vLy4v572R6aG156yU6K6wL2Z1bi9jb21tYW5kLnRzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC91dGlsLnRzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC9zdGF0ZS9yZW1vdGUuc3RhdGUudHMiLCJ3ZWJwYWNrOi8vLy4v572R6aG156yU6K6wL3N0YXRlL2luZGV4LnRzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9zdmVsdGUvc3RvcmUvaW5kZXgubWpzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC91aS9tZXNzYWdlLnRzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC9saWIvc3RvcmUudHMiLCJ3ZWJwYWNrOi8vLy4v572R6aG156yU6K6wL2Z1bi9hamF4LnRzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC91aS9zdHlsZS50cyIsIndlYnBhY2s6Ly8vLi/nvZHpobXnrJTorrAvdWkvd2FybmluZy50cyIsIndlYnBhY2s6Ly8vLi/nvZHpobXnrJTorrAvZnVuL2Z1bi50cyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQHZ1ZS9yZWFjdGl2aXR5L2Rpc3QvcmVhY3Rpdml0eS5lc20tYnVuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQHZ1ZS9ydW50aW1lLWNvcmUvZGlzdC9ydW50aW1lLWNvcmUuZXNtLWJ1bmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL0B2dWUvcnVudGltZS1kb20vZGlzdC9ydW50aW1lLWRvbS5lc20tYnVuZGxlci5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdnVlL2Rpc3QvdnVlLnJ1bnRpbWUuZXNtLWJ1bmRsZXIuanMiLCJ3ZWJwYWNrOi8vLy4v572R6aG156yU6K6wL3N0YXRlL3N0b3JlLnRzIiwid2VicGFjazovLy8uL+e9kemhteeslOiusC9zdGF0ZS9oaWdobGlnaHRlZF9zdHlsZS50cyIsIndlYnBhY2s6Ly8vKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9hamF4LWhvb2svc3JjL3hoci1ob29rLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9hamF4LWhvb2svc3JjL3hoci1wcm94eS5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYWpheC1ob29rL2luZGV4LmpzIiwid2VicGFjazovLy8uL3V0aWwvZG9tL2VsZW1lbnQudHMiLCJ3ZWJwYWNrOi8vLy4vdXRpbC9kb20v5Ymq6LS05p2/LnRzIiwid2VicGFjazovLy8uL+abtOWlveeahOaIkeadpeWvvOWHui9pbmRleC51c2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O1FBQUE7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7OztRQUdBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwwQ0FBMEMsZ0NBQWdDO1FBQzFFO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0Esd0RBQXdELGtCQUFrQjtRQUMxRTtRQUNBLGlEQUFpRCxjQUFjO1FBQy9EOztRQUVBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQSx5Q0FBeUMsaUNBQWlDO1FBQzFFLGdIQUFnSCxtQkFBbUIsRUFBRTtRQUNySTtRQUNBOztRQUVBO1FBQ0E7UUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQWdCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQzs7QUFFeXNCOzs7Ozs7Ozs7QUNoZXpzQjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLEtBQUs7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsU0FBUztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLDBCQUEwQjtBQUN4RCxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix1QkFBdUI7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QyxLQUFLO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxvQkFBb0IsNkNBQTZDO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGtCQUFrQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixtQkFBbUI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixrQkFBa0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMkJBQTJCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMkJBQTJCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQsb0JBQW9CLFFBQVEsU0FBUyxhQUFhLGNBQWM7QUFDakgsMEJBQTBCLFdBQVcsWUFBWSxzQkFBc0IsWUFBWSxTQUFTO0FBQzVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsMEJBQTBCO0FBQzNGO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLG1CQUFtQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLG1CQUFtQixRQUFRO0FBQzNCO0FBQ0Esa0NBQWtDLEVBQUUsY0FBYztBQUNsRDtBQUNBLG9DQUFvQyxFQUFFLGNBQWMsR0FBRztBQUN2RCw2QkFBNkIsV0FBVyxHQUFHLElBQUk7QUFDL0M7QUFDQTtBQUNBO0FBQ0Esd0VBQXdFO0FBQ3hFO0FBQ0E7QUFDQSw0Q0FBNEMsS0FBSyxHQUFHLEtBQUs7QUFDekQ7QUFDQTtBQUNBLDhCQUE4QixlQUFlLFVBQVUsU0FBUyxFQUFFLEtBQUssR0FBRyxTQUFTLFlBQVksTUFBTTtBQUNyRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBLG1EQUFtRCxhQUFhLFdBQVc7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBZ0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFVBQVUsYUFBYSxnQkFBZ0IsTUFBTSxjQUFjO0FBQzdGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw2QkFBNkI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw2QkFBNkI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyw4QkFBOEIsRUFBRSxLQUFLO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpRUFBaUU7QUFDaEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpRUFBaUU7QUFDaEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUVBQWlFO0FBQ2hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUFDLEVBQUQsQ0FBVCxFQUFlO0FBQUUsVUFBSSxFQUFFO0FBQVIsS0FBZixDQUFiO0FBQ0EsVUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLGVBQUosQ0FBb0IsSUFBcEIsQ0FBcEI7QUFDQSxXQUFPLENBQUMsR0FBUixDQUFZLGFBQWEsV0FBVyxXQUFwQyxFQUFpRCxFQUFqRDtBQUNBLFdBQU8sQ0FBQyxHQUFSLENBQVksWUFBWixFQUEwQixJQUFJLENBQUMsRUFBRCxDQUE5QjtBQUNBLFNBQUssQ0FBQyxNQUFELENBQUw7QUFDRCxHQVhEO0FBWUQsQ0FuQkssQ0FBTjtBQXFCQSxJQUFVLElBQVY7O0FBQUEsV0FBVSxJQUFWLEVBQWM7QUFDRCxhQUFNLEtBQU47QUFDWixDQUZELEVBQVUsSUFBSSxLQUFKLElBQUksTUFBZDtBQUdBO0FBQ0E7OztBQUNBLFlBQVksQ0FBQyxjQUFiLEdBQThCLGNBQTlCLEMiLCJmaWxlIjoi5pu05aW955qE5oiR5p2l5a+85Ye6LnVzZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMTUpO1xuIiwiLyoqXHJcbiAqIE1ha2UgYSBtYXAgYW5kIHJldHVybiBhIGZ1bmN0aW9uIGZvciBjaGVja2luZyBpZiBhIGtleVxyXG4gKiBpcyBpbiB0aGF0IG1hcC5cclxuICogSU1QT1JUQU5UOiBhbGwgY2FsbHMgb2YgdGhpcyBmdW5jdGlvbiBtdXN0IGJlIHByZWZpeGVkIHdpdGhcclxuICogXFwvXFwqI1xcX1xcX1BVUkVcXF9cXF9cXCpcXC9cclxuICogU28gdGhhdCByb2xsdXAgY2FuIHRyZWUtc2hha2UgdGhlbSBpZiBuZWNlc3NhcnkuXHJcbiAqL1xyXG5mdW5jdGlvbiBtYWtlTWFwKHN0ciwgZXhwZWN0c0xvd2VyQ2FzZSkge1xyXG4gICAgY29uc3QgbWFwID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcclxuICAgIGNvbnN0IGxpc3QgPSBzdHIuc3BsaXQoJywnKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIG1hcFtsaXN0W2ldXSA9IHRydWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZXhwZWN0c0xvd2VyQ2FzZSA/IHZhbCA9PiAhIW1hcFt2YWwudG9Mb3dlckNhc2UoKV0gOiB2YWwgPT4gISFtYXBbdmFsXTtcclxufVxuXG4vLyBQYXRjaCBmbGFncyBhcmUgb3B0aW1pemF0aW9uIGhpbnRzIGdlbmVyYXRlZCBieSB0aGUgY29tcGlsZXIuXHJcbi8vIHdoZW4gYSBibG9jayB3aXRoIGR5bmFtaWNDaGlsZHJlbiBpcyBlbmNvdW50ZXJlZCBkdXJpbmcgZGlmZiwgdGhlIGFsZ29yaXRobVxyXG4vLyBlbnRlcnMgXCJvcHRpbWl6ZWQgbW9kZVwiLiBJbiB0aGlzIG1vZGUsIHdlIGtub3cgdGhhdCB0aGUgdmRvbSBpcyBwcm9kdWNlZCBieVxyXG4vLyBhIHJlbmRlciBmdW5jdGlvbiBnZW5lcmF0ZWQgYnkgdGhlIGNvbXBpbGVyLCBzbyB0aGUgYWxnb3JpdGhtIG9ubHkgbmVlZHMgdG9cclxuLy8gaGFuZGxlIHVwZGF0ZXMgZXhwbGljaXRseSBtYXJrZWQgYnkgdGhlc2UgcGF0Y2ggZmxhZ3MuXHJcbi8vIGRldiBvbmx5IGZsYWcgLT4gbmFtZSBtYXBwaW5nXHJcbmNvbnN0IFBhdGNoRmxhZ05hbWVzID0ge1xyXG4gICAgWzEgLyogVEVYVCAqL106IGBURVhUYCxcclxuICAgIFsyIC8qIENMQVNTICovXTogYENMQVNTYCxcclxuICAgIFs0IC8qIFNUWUxFICovXTogYFNUWUxFYCxcclxuICAgIFs4IC8qIFBST1BTICovXTogYFBST1BTYCxcclxuICAgIFsxNiAvKiBGVUxMX1BST1BTICovXTogYEZVTExfUFJPUFNgLFxyXG4gICAgWzMyIC8qIEhZRFJBVEVfRVZFTlRTICovXTogYEhZRFJBVEVfRVZFTlRTYCxcclxuICAgIFs2NCAvKiBTVEFCTEVfRlJBR01FTlQgKi9dOiBgU1RBQkxFX0ZSQUdNRU5UYCxcclxuICAgIFsxMjggLyogS0VZRURfRlJBR01FTlQgKi9dOiBgS0VZRURfRlJBR01FTlRgLFxyXG4gICAgWzI1NiAvKiBVTktFWUVEX0ZSQUdNRU5UICovXTogYFVOS0VZRURfRlJBR01FTlRgLFxyXG4gICAgWzEwMjQgLyogRFlOQU1JQ19TTE9UUyAqL106IGBEWU5BTUlDX1NMT1RTYCxcclxuICAgIFs1MTIgLyogTkVFRF9QQVRDSCAqL106IGBORUVEX1BBVENIYCxcclxuICAgIFstMSAvKiBIT0lTVEVEICovXTogYEhPSVNURURgLFxyXG4gICAgWy0yIC8qIEJBSUwgKi9dOiBgQkFJTGBcclxufTtcblxuY29uc3QgR0xPQkFMU19XSElURV9MSVNURUQgPSAnSW5maW5pdHksdW5kZWZpbmVkLE5hTixpc0Zpbml0ZSxpc05hTixwYXJzZUZsb2F0LHBhcnNlSW50LGRlY29kZVVSSSwnICtcclxuICAgICdkZWNvZGVVUklDb21wb25lbnQsZW5jb2RlVVJJLGVuY29kZVVSSUNvbXBvbmVudCxNYXRoLE51bWJlcixEYXRlLEFycmF5LCcgK1xyXG4gICAgJ09iamVjdCxCb29sZWFuLFN0cmluZyxSZWdFeHAsTWFwLFNldCxKU09OLEludGwnO1xyXG5jb25zdCBpc0dsb2JhbGx5V2hpdGVsaXN0ZWQgPSAvKiNfX1BVUkVfXyovIG1ha2VNYXAoR0xPQkFMU19XSElURV9MSVNURUQpO1xuXG5jb25zdCByYW5nZSA9IDI7XHJcbmZ1bmN0aW9uIGdlbmVyYXRlQ29kZUZyYW1lKHNvdXJjZSwgc3RhcnQgPSAwLCBlbmQgPSBzb3VyY2UubGVuZ3RoKSB7XHJcbiAgICBjb25zdCBsaW5lcyA9IHNvdXJjZS5zcGxpdCgvXFxyP1xcbi8pO1xyXG4gICAgbGV0IGNvdW50ID0gMDtcclxuICAgIGNvbnN0IHJlcyA9IFtdO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvdW50ICs9IGxpbmVzW2ldLmxlbmd0aCArIDE7XHJcbiAgICAgICAgaWYgKGNvdW50ID49IHN0YXJ0KSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBpIC0gcmFuZ2U7IGogPD0gaSArIHJhbmdlIHx8IGVuZCA+IGNvdW50OyBqKyspIHtcclxuICAgICAgICAgICAgICAgIGlmIChqIDwgMCB8fCBqID49IGxpbmVzLmxlbmd0aClcclxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmUgPSBqICsgMTtcclxuICAgICAgICAgICAgICAgIHJlcy5wdXNoKGAke2xpbmV9JHsnICcucmVwZWF0KE1hdGgubWF4KDMgLSBTdHJpbmcobGluZSkubGVuZ3RoLCAwKSl9fCAgJHtsaW5lc1tqXX1gKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmVMZW5ndGggPSBsaW5lc1tqXS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBpZiAoaiA9PT0gaSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHB1c2ggdW5kZXJsaW5lXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFkID0gc3RhcnQgLSAoY291bnQgLSBsaW5lTGVuZ3RoKSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5tYXgoMSwgZW5kID4gY291bnQgPyBsaW5lTGVuZ3RoIC0gcGFkIDogZW5kIC0gc3RhcnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlcy5wdXNoKGAgICB8ICBgICsgJyAnLnJlcGVhdChwYWQpICsgJ14nLnJlcGVhdChsZW5ndGgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGogPiBpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVuZCA+IGNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWF4KE1hdGgubWluKGVuZCAtIGNvdW50LCBsaW5lTGVuZ3RoKSwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5wdXNoKGAgICB8ICBgICsgJ14nLnJlcGVhdChsZW5ndGgpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gbGluZUxlbmd0aCArIDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlcy5qb2luKCdcXG4nKTtcclxufVxuXG4vKipcclxuICogT24gdGhlIGNsaWVudCB3ZSBvbmx5IG5lZWQgdG8gb2ZmZXIgc3BlY2lhbCBjYXNlcyBmb3IgYm9vbGVhbiBhdHRyaWJ1dGVzIHRoYXRcclxuICogaGF2ZSBkaWZmZXJlbnQgbmFtZXMgZnJvbSB0aGVpciBjb3JyZXNwb25kaW5nIGRvbSBwcm9wZXJ0aWVzOlxyXG4gKiAtIGl0ZW1zY29wZSAtPiBOL0FcclxuICogLSBhbGxvd2Z1bGxzY3JlZW4gLT4gYWxsb3dGdWxsc2NyZWVuXHJcbiAqIC0gZm9ybW5vdmFsaWRhdGUgLT4gZm9ybU5vVmFsaWRhdGVcclxuICogLSBpc21hcCAtPiBpc01hcFxyXG4gKiAtIG5vbW9kdWxlIC0+IG5vTW9kdWxlXHJcbiAqIC0gbm92YWxpZGF0ZSAtPiBub1ZhbGlkYXRlXHJcbiAqIC0gcmVhZG9ubHkgLT4gcmVhZE9ubHlcclxuICovXHJcbmNvbnN0IHNwZWNpYWxCb29sZWFuQXR0cnMgPSBgaXRlbXNjb3BlLGFsbG93ZnVsbHNjcmVlbixmb3Jtbm92YWxpZGF0ZSxpc21hcCxub21vZHVsZSxub3ZhbGlkYXRlLHJlYWRvbmx5YDtcclxuY29uc3QgaXNTcGVjaWFsQm9vbGVhbkF0dHIgPSAvKiNfX1BVUkVfXyovIG1ha2VNYXAoc3BlY2lhbEJvb2xlYW5BdHRycyk7XHJcbi8qKlxyXG4gKiBUaGUgZnVsbCBsaXN0IGlzIG5lZWRlZCBkdXJpbmcgU1NSIHRvIHByb2R1Y2UgdGhlIGNvcnJlY3QgaW5pdGlhbCBtYXJrdXAuXHJcbiAqL1xyXG5jb25zdCBpc0Jvb2xlYW5BdHRyID0gLyojX19QVVJFX18qLyBtYWtlTWFwKHNwZWNpYWxCb29sZWFuQXR0cnMgK1xyXG4gICAgYCxhc3luYyxhdXRvZm9jdXMsYXV0b3BsYXksY29udHJvbHMsZGVmYXVsdCxkZWZlcixkaXNhYmxlZCxoaWRkZW4sYCArXHJcbiAgICBgbG9vcCxvcGVuLHJlcXVpcmVkLHJldmVyc2VkLHNjb3BlZCxzZWFtbGVzcyxgICtcclxuICAgIGBjaGVja2VkLG11dGVkLG11bHRpcGxlLHNlbGVjdGVkYCk7XHJcbmNvbnN0IHVuc2FmZUF0dHJDaGFyUkUgPSAvWz4vPVwiJ1xcdTAwMDlcXHUwMDBhXFx1MDAwY1xcdTAwMjBdLztcclxuY29uc3QgYXR0clZhbGlkYXRpb25DYWNoZSA9IHt9O1xyXG5mdW5jdGlvbiBpc1NTUlNhZmVBdHRyTmFtZShuYW1lKSB7XHJcbiAgICBpZiAoYXR0clZhbGlkYXRpb25DYWNoZS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xyXG4gICAgICAgIHJldHVybiBhdHRyVmFsaWRhdGlvbkNhY2hlW25hbWVdO1xyXG4gICAgfVxyXG4gICAgY29uc3QgaXNVbnNhZmUgPSB1bnNhZmVBdHRyQ2hhclJFLnRlc3QobmFtZSk7XHJcbiAgICBpZiAoaXNVbnNhZmUpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKGB1bnNhZmUgYXR0cmlidXRlIG5hbWU6ICR7bmFtZX1gKTtcclxuICAgIH1cclxuICAgIHJldHVybiAoYXR0clZhbGlkYXRpb25DYWNoZVtuYW1lXSA9ICFpc1Vuc2FmZSk7XHJcbn1cclxuY29uc3QgcHJvcHNUb0F0dHJNYXAgPSB7XHJcbiAgICBhY2NlcHRDaGFyc2V0OiAnYWNjZXB0LWNoYXJzZXQnLFxyXG4gICAgY2xhc3NOYW1lOiAnY2xhc3MnLFxyXG4gICAgaHRtbEZvcjogJ2ZvcicsXHJcbiAgICBodHRwRXF1aXY6ICdodHRwLWVxdWl2J1xyXG59O1xyXG4vKipcclxuICogQ1NTIHByb3BlcnRpZXMgdGhhdCBhY2NlcHQgcGxhaW4gbnVtYmVyc1xyXG4gKi9cclxuY29uc3QgaXNOb1VuaXROdW1lcmljU3R5bGVQcm9wID0gLyojX19QVVJFX18qLyBtYWtlTWFwKGBhbmltYXRpb24taXRlcmF0aW9uLWNvdW50LGJvcmRlci1pbWFnZS1vdXRzZXQsYm9yZGVyLWltYWdlLXNsaWNlLGAgK1xyXG4gICAgYGJvcmRlci1pbWFnZS13aWR0aCxib3gtZmxleCxib3gtZmxleC1ncm91cCxib3gtb3JkaW5hbC1ncm91cCxjb2x1bW4tY291bnQsYCArXHJcbiAgICBgY29sdW1ucyxmbGV4LGZsZXgtZ3JvdyxmbGV4LXBvc2l0aXZlLGZsZXgtc2hyaW5rLGZsZXgtbmVnYXRpdmUsZmxleC1vcmRlcixgICtcclxuICAgIGBncmlkLXJvdyxncmlkLXJvdy1lbmQsZ3JpZC1yb3ctc3BhbixncmlkLXJvdy1zdGFydCxncmlkLWNvbHVtbixgICtcclxuICAgIGBncmlkLWNvbHVtbi1lbmQsZ3JpZC1jb2x1bW4tc3BhbixncmlkLWNvbHVtbi1zdGFydCxmb250LXdlaWdodCxsaW5lLWNsYW1wLGAgK1xyXG4gICAgYGxpbmUtaGVpZ2h0LG9wYWNpdHksb3JkZXIsb3JwaGFucyx0YWItc2l6ZSx3aWRvd3Msei1pbmRleCx6b29tLGAgK1xyXG4gICAgLy8gU1ZHXHJcbiAgICBgZmlsbC1vcGFjaXR5LGZsb29kLW9wYWNpdHksc3RvcC1vcGFjaXR5LHN0cm9rZS1kYXNoYXJyYXksc3Ryb2tlLWRhc2hvZmZzZXQsYCArXHJcbiAgICBgc3Ryb2tlLW1pdGVybGltaXQsc3Ryb2tlLW9wYWNpdHksc3Ryb2tlLXdpZHRoYCk7XHJcbi8qKlxyXG4gKiBLbm93biBhdHRyaWJ1dGVzLCB0aGlzIGlzIHVzZWQgZm9yIHN0cmluZ2lmaWNhdGlvbiBvZiBydW50aW1lIHN0YXRpYyBub2Rlc1xyXG4gKiBzbyB0aGF0IHdlIGRvbid0IHN0cmluZ2lmeSBiaW5kaW5ncyB0aGF0IGNhbm5vdCBiZSBzZXQgZnJvbSBIVE1MLlxyXG4gKiBEb24ndCBhbHNvIGZvcmdldCB0byBhbGxvdyBgZGF0YS0qYCBhbmQgYGFyaWEtKmAhXHJcbiAqIEdlbmVyYXRlZCBmcm9tIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvQXR0cmlidXRlc1xyXG4gKi9cclxuY29uc3QgaXNLbm93bkF0dHIgPSAvKiNfX1BVUkVfXyovIG1ha2VNYXAoYGFjY2VwdCxhY2NlcHQtY2hhcnNldCxhY2Nlc3NrZXksYWN0aW9uLGFsaWduLGFsbG93LGFsdCxhc3luYyxgICtcclxuICAgIGBhdXRvY2FwaXRhbGl6ZSxhdXRvY29tcGxldGUsYXV0b2ZvY3VzLGF1dG9wbGF5LGJhY2tncm91bmQsYmdjb2xvcixgICtcclxuICAgIGBib3JkZXIsYnVmZmVyZWQsY2FwdHVyZSxjaGFsbGVuZ2UsY2hhcnNldCxjaGVja2VkLGNpdGUsY2xhc3MsY29kZSxgICtcclxuICAgIGBjb2RlYmFzZSxjb2xvcixjb2xzLGNvbHNwYW4sY29udGVudCxjb250ZW50ZWRpdGFibGUsY29udGV4dG1lbnUsY29udHJvbHMsYCArXHJcbiAgICBgY29vcmRzLGNyb3Nzb3JpZ2luLGNzcCxkYXRhLGRhdGV0aW1lLGRlY29kaW5nLGRlZmF1bHQsZGVmZXIsZGlyLGRpcm5hbWUsYCArXHJcbiAgICBgZGlzYWJsZWQsZG93bmxvYWQsZHJhZ2dhYmxlLGRyb3B6b25lLGVuY3R5cGUsZW50ZXJrZXloaW50LGZvcixmb3JtLGAgK1xyXG4gICAgYGZvcm1hY3Rpb24sZm9ybWVuY3R5cGUsZm9ybW1ldGhvZCxmb3Jtbm92YWxpZGF0ZSxmb3JtdGFyZ2V0LGhlYWRlcnMsYCArXHJcbiAgICBgaGVpZ2h0LGhpZGRlbixoaWdoLGhyZWYsaHJlZmxhbmcsaHR0cC1lcXVpdixpY29uLGlkLGltcG9ydGFuY2UsaW50ZWdyaXR5LGAgK1xyXG4gICAgYGlzbWFwLGl0ZW1wcm9wLGtleXR5cGUsa2luZCxsYWJlbCxsYW5nLGxhbmd1YWdlLGxvYWRpbmcsbGlzdCxsb29wLGxvdyxgICtcclxuICAgIGBtYW5pZmVzdCxtYXgsbWF4bGVuZ3RoLG1pbmxlbmd0aCxtZWRpYSxtaW4sbXVsdGlwbGUsbXV0ZWQsbmFtZSxub3ZhbGlkYXRlLGAgK1xyXG4gICAgYG9wZW4sb3B0aW11bSxwYXR0ZXJuLHBpbmcscGxhY2Vob2xkZXIscG9zdGVyLHByZWxvYWQscmFkaW9ncm91cCxyZWFkb25seSxgICtcclxuICAgIGByZWZlcnJlcnBvbGljeSxyZWwscmVxdWlyZWQscmV2ZXJzZWQscm93cyxyb3dzcGFuLHNhbmRib3gsc2NvcGUsc2NvcGVkLGAgK1xyXG4gICAgYHNlbGVjdGVkLHNoYXBlLHNpemUsc2l6ZXMsc2xvdCxzcGFuLHNwZWxsY2hlY2ssc3JjLHNyY2RvYyxzcmNsYW5nLHNyY3NldCxgICtcclxuICAgIGBzdGFydCxzdGVwLHN0eWxlLHN1bW1hcnksdGFiaW5kZXgsdGFyZ2V0LHRpdGxlLHRyYW5zbGF0ZSx0eXBlLHVzZW1hcCxgICtcclxuICAgIGB2YWx1ZSx3aWR0aCx3cmFwYCk7XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVN0eWxlKHZhbHVlKSB7XHJcbiAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcclxuICAgICAgICBjb25zdCByZXMgPSB7fTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSB2YWx1ZVtpXTtcclxuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVN0eWxlKGlzU3RyaW5nKGl0ZW0pID8gcGFyc2VTdHJpbmdTdHlsZShpdGVtKSA6IGl0ZW0pO1xyXG4gICAgICAgICAgICBpZiAobm9ybWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbm9ybWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc1trZXldID0gbm9ybWFsaXplZFtrZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcbn1cclxuY29uc3QgbGlzdERlbGltaXRlclJFID0gLzsoPyFbXihdKlxcKSkvZztcclxuY29uc3QgcHJvcGVydHlEZWxpbWl0ZXJSRSA9IC86KC4rKS87XHJcbmZ1bmN0aW9uIHBhcnNlU3RyaW5nU3R5bGUoY3NzVGV4dCkge1xyXG4gICAgY29uc3QgcmV0ID0ge307XHJcbiAgICBjc3NUZXh0LnNwbGl0KGxpc3REZWxpbWl0ZXJSRSkuZm9yRWFjaChpdGVtID0+IHtcclxuICAgICAgICBpZiAoaXRlbSkge1xyXG4gICAgICAgICAgICBjb25zdCB0bXAgPSBpdGVtLnNwbGl0KHByb3BlcnR5RGVsaW1pdGVyUkUpO1xyXG4gICAgICAgICAgICB0bXAubGVuZ3RoID4gMSAmJiAocmV0W3RtcFswXS50cmltKCldID0gdG1wWzFdLnRyaW0oKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcmV0O1xyXG59XHJcbmZ1bmN0aW9uIHN0cmluZ2lmeVN0eWxlKHN0eWxlcykge1xyXG4gICAgbGV0IHJldCA9ICcnO1xyXG4gICAgaWYgKCFzdHlsZXMpIHtcclxuICAgICAgICByZXR1cm4gcmV0O1xyXG4gICAgfVxyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gc3R5bGVzKSB7XHJcbiAgICAgICAgY29uc3QgdmFsdWUgPSBzdHlsZXNba2V5XTtcclxuICAgICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0ga2V5LnN0YXJ0c1dpdGgoYC0tYCkgPyBrZXkgOiBoeXBoZW5hdGUoa2V5KTtcclxuICAgICAgICBpZiAoaXNTdHJpbmcodmFsdWUpIHx8XHJcbiAgICAgICAgICAgICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIGlzTm9Vbml0TnVtZXJpY1N0eWxlUHJvcChub3JtYWxpemVkS2V5KSkpIHtcclxuICAgICAgICAgICAgLy8gb25seSByZW5kZXIgdmFsaWQgdmFsdWVzXHJcbiAgICAgICAgICAgIHJldCArPSBgJHtub3JtYWxpemVkS2V5fToke3ZhbHVlfTtgO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXQ7XHJcbn1cclxuZnVuY3Rpb24gbm9ybWFsaXplQ2xhc3ModmFsdWUpIHtcclxuICAgIGxldCByZXMgPSAnJztcclxuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcclxuICAgICAgICByZXMgPSB2YWx1ZTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICByZXMgKz0gbm9ybWFsaXplQ2xhc3ModmFsdWVbaV0pICsgJyAnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xyXG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiB2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAodmFsdWVbbmFtZV0pIHtcclxuICAgICAgICAgICAgICAgIHJlcyArPSBuYW1lICsgJyAnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlcy50cmltKCk7XHJcbn1cblxuLy8gVGhlc2UgdGFnIGNvbmZpZ3MgYXJlIHNoYXJlZCBiZXR3ZWVuIGNvbXBpbGVyLWRvbSBhbmQgcnVudGltZS1kb20sIHNvIHRoZXlcclxuLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50XHJcbmNvbnN0IEhUTUxfVEFHUyA9ICdodG1sLGJvZHksYmFzZSxoZWFkLGxpbmssbWV0YSxzdHlsZSx0aXRsZSxhZGRyZXNzLGFydGljbGUsYXNpZGUsZm9vdGVyLCcgK1xyXG4gICAgJ2hlYWRlcixoMSxoMixoMyxoNCxoNSxoNixoZ3JvdXAsbmF2LHNlY3Rpb24sZGl2LGRkLGRsLGR0LGZpZ2NhcHRpb24sJyArXHJcbiAgICAnZmlndXJlLHBpY3R1cmUsaHIsaW1nLGxpLG1haW4sb2wscCxwcmUsdWwsYSxiLGFiYnIsYmRpLGJkbyxicixjaXRlLGNvZGUsJyArXHJcbiAgICAnZGF0YSxkZm4sZW0saSxrYmQsbWFyayxxLHJwLHJ0LHJ0YyxydWJ5LHMsc2FtcCxzbWFsbCxzcGFuLHN0cm9uZyxzdWIsc3VwLCcgK1xyXG4gICAgJ3RpbWUsdSx2YXIsd2JyLGFyZWEsYXVkaW8sbWFwLHRyYWNrLHZpZGVvLGVtYmVkLG9iamVjdCxwYXJhbSxzb3VyY2UsJyArXHJcbiAgICAnY2FudmFzLHNjcmlwdCxub3NjcmlwdCxkZWwsaW5zLGNhcHRpb24sY29sLGNvbGdyb3VwLHRhYmxlLHRoZWFkLHRib2R5LHRkLCcgK1xyXG4gICAgJ3RoLHRyLGJ1dHRvbixkYXRhbGlzdCxmaWVsZHNldCxmb3JtLGlucHV0LGxhYmVsLGxlZ2VuZCxtZXRlcixvcHRncm91cCwnICtcclxuICAgICdvcHRpb24sb3V0cHV0LHByb2dyZXNzLHNlbGVjdCx0ZXh0YXJlYSxkZXRhaWxzLGRpYWxvZyxtZW51LCcgK1xyXG4gICAgJ3N1bW1hcnksdGVtcGxhdGUsYmxvY2txdW90ZSxpZnJhbWUsdGZvb3QnO1xyXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9TVkcvRWxlbWVudFxyXG5jb25zdCBTVkdfVEFHUyA9ICdzdmcsYW5pbWF0ZSxhbmltYXRlTW90aW9uLGFuaW1hdGVUcmFuc2Zvcm0sY2lyY2xlLGNsaXBQYXRoLGNvbG9yLXByb2ZpbGUsJyArXHJcbiAgICAnZGVmcyxkZXNjLGRpc2NhcmQsZWxsaXBzZSxmZUJsZW5kLGZlQ29sb3JNYXRyaXgsZmVDb21wb25lbnRUcmFuc2ZlciwnICtcclxuICAgICdmZUNvbXBvc2l0ZSxmZUNvbnZvbHZlTWF0cml4LGZlRGlmZnVzZUxpZ2h0aW5nLGZlRGlzcGxhY2VtZW50TWFwLCcgK1xyXG4gICAgJ2ZlRGlzdGFuY2VMaWdodCxmZURyb3BTaGFkb3csZmVGbG9vZCxmZUZ1bmNBLGZlRnVuY0IsZmVGdW5jRyxmZUZ1bmNSLCcgK1xyXG4gICAgJ2ZlR2F1c3NpYW5CbHVyLGZlSW1hZ2UsZmVNZXJnZSxmZU1lcmdlTm9kZSxmZU1vcnBob2xvZ3ksZmVPZmZzZXQsJyArXHJcbiAgICAnZmVQb2ludExpZ2h0LGZlU3BlY3VsYXJMaWdodGluZyxmZVNwb3RMaWdodCxmZVRpbGUsZmVUdXJidWxlbmNlLGZpbHRlciwnICtcclxuICAgICdmb3JlaWduT2JqZWN0LGcsaGF0Y2gsaGF0Y2hwYXRoLGltYWdlLGxpbmUsbGluZWFyR3JhZGllbnQsbWFya2VyLG1hc2ssJyArXHJcbiAgICAnbWVzaCxtZXNoZ3JhZGllbnQsbWVzaHBhdGNoLG1lc2hyb3csbWV0YWRhdGEsbXBhdGgscGF0aCxwYXR0ZXJuLCcgK1xyXG4gICAgJ3BvbHlnb24scG9seWxpbmUscmFkaWFsR3JhZGllbnQscmVjdCxzZXQsc29saWRjb2xvcixzdG9wLHN3aXRjaCxzeW1ib2wsJyArXHJcbiAgICAndGV4dCx0ZXh0UGF0aCx0aXRsZSx0c3Bhbix1bmtub3duLHVzZSx2aWV3JztcclxuY29uc3QgVk9JRF9UQUdTID0gJ2FyZWEsYmFzZSxicixjb2wsZW1iZWQsaHIsaW1nLGlucHV0LGxpbmssbWV0YSxwYXJhbSxzb3VyY2UsdHJhY2ssd2JyJztcclxuY29uc3QgaXNIVE1MVGFnID0gLyojX19QVVJFX18qLyBtYWtlTWFwKEhUTUxfVEFHUyk7XHJcbmNvbnN0IGlzU1ZHVGFnID0gLyojX19QVVJFX18qLyBtYWtlTWFwKFNWR19UQUdTKTtcclxuY29uc3QgaXNWb2lkVGFnID0gLyojX19QVVJFX18qLyBtYWtlTWFwKFZPSURfVEFHUyk7XG5cbmNvbnN0IGVzY2FwZVJFID0gL1tcIicmPD5dLztcclxuZnVuY3Rpb24gZXNjYXBlSHRtbChzdHJpbmcpIHtcclxuICAgIGNvbnN0IHN0ciA9ICcnICsgc3RyaW5nO1xyXG4gICAgY29uc3QgbWF0Y2ggPSBlc2NhcGVSRS5leGVjKHN0cik7XHJcbiAgICBpZiAoIW1hdGNoKSB7XHJcbiAgICAgICAgcmV0dXJuIHN0cjtcclxuICAgIH1cclxuICAgIGxldCBodG1sID0gJyc7XHJcbiAgICBsZXQgZXNjYXBlZDtcclxuICAgIGxldCBpbmRleDtcclxuICAgIGxldCBsYXN0SW5kZXggPSAwO1xyXG4gICAgZm9yIChpbmRleCA9IG1hdGNoLmluZGV4OyBpbmRleCA8IHN0ci5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICBzd2l0Y2ggKHN0ci5jaGFyQ29kZUF0KGluZGV4KSkge1xyXG4gICAgICAgICAgICBjYXNlIDM0OiAvLyBcIlxyXG4gICAgICAgICAgICAgICAgZXNjYXBlZCA9ICcmcXVvdDsnO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzg6IC8vICZcclxuICAgICAgICAgICAgICAgIGVzY2FwZWQgPSAnJmFtcDsnO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzk6IC8vICdcclxuICAgICAgICAgICAgICAgIGVzY2FwZWQgPSAnJiMzOTsnO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgNjA6IC8vIDxcclxuICAgICAgICAgICAgICAgIGVzY2FwZWQgPSAnJmx0Oyc7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSA2MjogLy8gPlxyXG4gICAgICAgICAgICAgICAgZXNjYXBlZCA9ICcmZ3Q7JztcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsYXN0SW5kZXggIT09IGluZGV4KSB7XHJcbiAgICAgICAgICAgIGh0bWwgKz0gc3RyLnN1YnN0cmluZyhsYXN0SW5kZXgsIGluZGV4KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGFzdEluZGV4ID0gaW5kZXggKyAxO1xyXG4gICAgICAgIGh0bWwgKz0gZXNjYXBlZDtcclxuICAgIH1cclxuICAgIHJldHVybiBsYXN0SW5kZXggIT09IGluZGV4ID8gaHRtbCArIHN0ci5zdWJzdHJpbmcobGFzdEluZGV4LCBpbmRleCkgOiBodG1sO1xyXG59XHJcbi8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9odG1sNTIvc3ludGF4Lmh0bWwjY29tbWVudHNcclxuY29uc3QgY29tbWVudFN0cmlwUkUgPSAvXi0/Pnw8IS0tfC0tPnwtLSE+fDwhLSQvZztcclxuZnVuY3Rpb24gZXNjYXBlSHRtbENvbW1lbnQoc3JjKSB7XHJcbiAgICByZXR1cm4gc3JjLnJlcGxhY2UoY29tbWVudFN0cmlwUkUsICcnKTtcclxufVxuXG5mdW5jdGlvbiBsb29zZUNvbXBhcmVBcnJheXMoYSwgYikge1xyXG4gICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aClcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICBsZXQgZXF1YWwgPSB0cnVlO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGVxdWFsICYmIGkgPCBhLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgZXF1YWwgPSBsb29zZUVxdWFsKGFbaV0sIGJbaV0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVxdWFsO1xyXG59XHJcbmZ1bmN0aW9uIGxvb3NlRXF1YWwoYSwgYikge1xyXG4gICAgaWYgKGEgPT09IGIpXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICBsZXQgYVZhbGlkVHlwZSA9IGlzRGF0ZShhKTtcclxuICAgIGxldCBiVmFsaWRUeXBlID0gaXNEYXRlKGIpO1xyXG4gICAgaWYgKGFWYWxpZFR5cGUgfHwgYlZhbGlkVHlwZSkge1xyXG4gICAgICAgIHJldHVybiBhVmFsaWRUeXBlICYmIGJWYWxpZFR5cGUgPyBhLmdldFRpbWUoKSA9PT0gYi5nZXRUaW1lKCkgOiBmYWxzZTtcclxuICAgIH1cclxuICAgIGFWYWxpZFR5cGUgPSBpc0FycmF5KGEpO1xyXG4gICAgYlZhbGlkVHlwZSA9IGlzQXJyYXkoYik7XHJcbiAgICBpZiAoYVZhbGlkVHlwZSB8fCBiVmFsaWRUeXBlKSB7XHJcbiAgICAgICAgcmV0dXJuIGFWYWxpZFR5cGUgJiYgYlZhbGlkVHlwZSA/IGxvb3NlQ29tcGFyZUFycmF5cyhhLCBiKSA6IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgYVZhbGlkVHlwZSA9IGlzT2JqZWN0KGEpO1xyXG4gICAgYlZhbGlkVHlwZSA9IGlzT2JqZWN0KGIpO1xyXG4gICAgaWYgKGFWYWxpZFR5cGUgfHwgYlZhbGlkVHlwZSkge1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZjogdGhpcyBpZiB3aWxsIHByb2JhYmx5IG5ldmVyIGJlIGNhbGxlZCAqL1xyXG4gICAgICAgIGlmICghYVZhbGlkVHlwZSB8fCAhYlZhbGlkVHlwZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGFLZXlzQ291bnQgPSBPYmplY3Qua2V5cyhhKS5sZW5ndGg7XHJcbiAgICAgICAgY29uc3QgYktleXNDb3VudCA9IE9iamVjdC5rZXlzKGIpLmxlbmd0aDtcclxuICAgICAgICBpZiAoYUtleXNDb3VudCAhPT0gYktleXNDb3VudCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGEpIHtcclxuICAgICAgICAgICAgY29uc3QgYUhhc0tleSA9IGEuaGFzT3duUHJvcGVydHkoa2V5KTtcclxuICAgICAgICAgICAgY29uc3QgYkhhc0tleSA9IGIuaGFzT3duUHJvcGVydHkoa2V5KTtcclxuICAgICAgICAgICAgaWYgKChhSGFzS2V5ICYmICFiSGFzS2V5KSB8fFxyXG4gICAgICAgICAgICAgICAgKCFhSGFzS2V5ICYmIGJIYXNLZXkpIHx8XHJcbiAgICAgICAgICAgICAgICAhbG9vc2VFcXVhbChhW2tleV0sIGJba2V5XSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBTdHJpbmcoYSkgPT09IFN0cmluZyhiKTtcclxufVxyXG5mdW5jdGlvbiBsb29zZUluZGV4T2YoYXJyLCB2YWwpIHtcclxuICAgIHJldHVybiBhcnIuZmluZEluZGV4KGl0ZW0gPT4gbG9vc2VFcXVhbChpdGVtLCB2YWwpKTtcclxufVxuXG4vKipcclxuICogRm9yIGNvbnZlcnRpbmcge3sgaW50ZXJwb2xhdGlvbiB9fSB2YWx1ZXMgdG8gZGlzcGxheWVkIHN0cmluZ3MuXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb25zdCB0b0Rpc3BsYXlTdHJpbmcgPSAodmFsKSA9PiB7XHJcbiAgICByZXR1cm4gdmFsID09IG51bGxcclxuICAgICAgICA/ICcnXHJcbiAgICAgICAgOiBpc09iamVjdCh2YWwpXHJcbiAgICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkodmFsLCByZXBsYWNlciwgMilcclxuICAgICAgICAgICAgOiBTdHJpbmcodmFsKTtcclxufTtcclxuY29uc3QgcmVwbGFjZXIgPSAoX2tleSwgdmFsKSA9PiB7XHJcbiAgICBpZiAodmFsIGluc3RhbmNlb2YgTWFwKSB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgW2BNYXAoJHt2YWwuc2l6ZX0pYF06IFsuLi52YWwuZW50cmllcygpXS5yZWR1Y2UoKGVudHJpZXMsIFtrZXksIHZhbF0pID0+IHtcclxuICAgICAgICAgICAgICAgIGVudHJpZXNbYCR7a2V5fSA9PmBdID0gdmFsO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGVudHJpZXM7XHJcbiAgICAgICAgICAgIH0sIHt9KVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh2YWwgaW5zdGFuY2VvZiBTZXQpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBbYFNldCgke3ZhbC5zaXplfSlgXTogWy4uLnZhbC52YWx1ZXMoKV1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNPYmplY3QodmFsKSAmJiAhaXNBcnJheSh2YWwpICYmICFpc1BsYWluT2JqZWN0KHZhbCkpIHtcclxuICAgICAgICByZXR1cm4gU3RyaW5nKHZhbCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsO1xyXG59O1xuXG4vKipcclxuICogTGlzdCBvZiBAYmFiZWwvcGFyc2VyIHBsdWdpbnMgdGhhdCBhcmUgdXNlZCBmb3IgdGVtcGxhdGUgZXhwcmVzc2lvblxyXG4gKiB0cmFuc2Zvcm1zIGFuZCBTRkMgc2NyaXB0IHRyYW5zZm9ybXMuIEJ5IGRlZmF1bHQgd2UgZW5hYmxlIHByb3Bvc2FscyBzbGF0ZWRcclxuICogZm9yIEVTMjAyMC4gVGhpcyB3aWxsIG5lZWQgdG8gYmUgdXBkYXRlZCBhcyB0aGUgc3BlYyBtb3ZlcyBmb3J3YXJkLlxyXG4gKiBGdWxsIGxpc3QgYXQgaHR0cHM6Ly9iYWJlbGpzLmlvL2RvY3MvZW4vbmV4dC9iYWJlbC1wYXJzZXIjcGx1Z2luc1xyXG4gKi9cclxuY29uc3QgYmFiZWxQYXJzZXJEZWZhdWx0UGx1Z2lucyA9IFtcclxuICAgICdiaWdJbnQnLFxyXG4gICAgJ29wdGlvbmFsQ2hhaW5pbmcnLFxyXG4gICAgJ251bGxpc2hDb2FsZXNjaW5nT3BlcmF0b3InXHJcbl07XHJcbmNvbnN0IEVNUFRZX09CSiA9IChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKVxyXG4gICAgPyBPYmplY3QuZnJlZXplKHt9KVxyXG4gICAgOiB7fTtcclxuY29uc3QgRU1QVFlfQVJSID0gW107XHJcbmNvbnN0IE5PT1AgPSAoKSA9PiB7IH07XHJcbi8qKlxyXG4gKiBBbHdheXMgcmV0dXJuIGZhbHNlLlxyXG4gKi9cclxuY29uc3QgTk8gPSAoKSA9PiBmYWxzZTtcclxuY29uc3Qgb25SRSA9IC9eb25bXmEtel0vO1xyXG5jb25zdCBpc09uID0gKGtleSkgPT4gb25SRS50ZXN0KGtleSk7XHJcbmNvbnN0IGlzTW9kZWxMaXN0ZW5lciA9IChrZXkpID0+IGtleS5zdGFydHNXaXRoKCdvblVwZGF0ZTonKTtcclxuY29uc3QgZXh0ZW5kID0gT2JqZWN0LmFzc2lnbjtcclxuY29uc3QgcmVtb3ZlID0gKGFyciwgZWwpID0+IHtcclxuICAgIGNvbnN0IGkgPSBhcnIuaW5kZXhPZihlbCk7XHJcbiAgICBpZiAoaSA+IC0xKSB7XHJcbiAgICAgICAgYXJyLnNwbGljZShpLCAxKTtcclxuICAgIH1cclxufTtcclxuY29uc3QgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xyXG5jb25zdCBoYXNPd24gPSAodmFsLCBrZXkpID0+IGhhc093blByb3BlcnR5LmNhbGwodmFsLCBrZXkpO1xyXG5jb25zdCBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcclxuY29uc3QgaXNEYXRlID0gKHZhbCkgPT4gdmFsIGluc3RhbmNlb2YgRGF0ZTtcclxuY29uc3QgaXNGdW5jdGlvbiA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbic7XHJcbmNvbnN0IGlzU3RyaW5nID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZyc7XHJcbmNvbnN0IGlzU3ltYm9sID0gKHZhbCkgPT4gdHlwZW9mIHZhbCA9PT0gJ3N5bWJvbCc7XHJcbmNvbnN0IGlzT2JqZWN0ID0gKHZhbCkgPT4gdmFsICE9PSBudWxsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnO1xyXG5jb25zdCBpc1Byb21pc2UgPSAodmFsKSA9PiB7XHJcbiAgICByZXR1cm4gaXNPYmplY3QodmFsKSAmJiBpc0Z1bmN0aW9uKHZhbC50aGVuKSAmJiBpc0Z1bmN0aW9uKHZhbC5jYXRjaCk7XHJcbn07XHJcbmNvbnN0IG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcclxuY29uc3QgdG9UeXBlU3RyaW5nID0gKHZhbHVlKSA9PiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcclxuY29uc3QgdG9SYXdUeXBlID0gKHZhbHVlKSA9PiB7XHJcbiAgICByZXR1cm4gdG9UeXBlU3RyaW5nKHZhbHVlKS5zbGljZSg4LCAtMSk7XHJcbn07XHJcbmNvbnN0IGlzUGxhaW5PYmplY3QgPSAodmFsKSA9PiB0b1R5cGVTdHJpbmcodmFsKSA9PT0gJ1tvYmplY3QgT2JqZWN0XSc7XHJcbmNvbnN0IGlzSW50ZWdlcktleSA9IChrZXkpID0+IGlzU3RyaW5nKGtleSkgJiYga2V5WzBdICE9PSAnLScgJiYgJycgKyBwYXJzZUludChrZXksIDEwKSA9PT0ga2V5O1xyXG5jb25zdCBpc1Jlc2VydmVkUHJvcCA9IC8qI19fUFVSRV9fKi8gbWFrZU1hcCgna2V5LHJlZiwnICtcclxuICAgICdvblZub2RlQmVmb3JlTW91bnQsb25Wbm9kZU1vdW50ZWQsJyArXHJcbiAgICAnb25Wbm9kZUJlZm9yZVVwZGF0ZSxvblZub2RlVXBkYXRlZCwnICtcclxuICAgICdvblZub2RlQmVmb3JlVW5tb3VudCxvblZub2RlVW5tb3VudGVkJyk7XHJcbmNvbnN0IGNhY2hlU3RyaW5nRnVuY3Rpb24gPSAoZm4pID0+IHtcclxuICAgIGNvbnN0IGNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcclxuICAgIHJldHVybiAoKHN0cikgPT4ge1xyXG4gICAgICAgIGNvbnN0IGhpdCA9IGNhY2hlW3N0cl07XHJcbiAgICAgICAgcmV0dXJuIGhpdCB8fCAoY2FjaGVbc3RyXSA9IGZuKHN0cikpO1xyXG4gICAgfSk7XHJcbn07XHJcbmNvbnN0IGNhbWVsaXplUkUgPSAvLShcXHcpL2c7XHJcbi8qKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY29uc3QgY2FtZWxpemUgPSBjYWNoZVN0cmluZ0Z1bmN0aW9uKChzdHIpID0+IHtcclxuICAgIHJldHVybiBzdHIucmVwbGFjZShjYW1lbGl6ZVJFLCAoXywgYykgPT4gKGMgPyBjLnRvVXBwZXJDYXNlKCkgOiAnJykpO1xyXG59KTtcclxuY29uc3QgaHlwaGVuYXRlUkUgPSAvXFxCKFtBLVpdKS9nO1xyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmNvbnN0IGh5cGhlbmF0ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cikgPT4ge1xyXG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKGh5cGhlbmF0ZVJFLCAnLSQxJykudG9Mb3dlckNhc2UoKTtcclxufSk7XHJcbi8qKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY29uc3QgY2FwaXRhbGl6ZSA9IGNhY2hlU3RyaW5nRnVuY3Rpb24oKHN0cikgPT4ge1xyXG4gICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKTtcclxufSk7XHJcbi8vIGNvbXBhcmUgd2hldGhlciBhIHZhbHVlIGhhcyBjaGFuZ2VkLCBhY2NvdW50aW5nIGZvciBOYU4uXHJcbmNvbnN0IGhhc0NoYW5nZWQgPSAodmFsdWUsIG9sZFZhbHVlKSA9PiB2YWx1ZSAhPT0gb2xkVmFsdWUgJiYgKHZhbHVlID09PSB2YWx1ZSB8fCBvbGRWYWx1ZSA9PT0gb2xkVmFsdWUpO1xyXG5jb25zdCBpbnZva2VBcnJheUZucyA9IChmbnMsIGFyZykgPT4ge1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBmbnNbaV0oYXJnKTtcclxuICAgIH1cclxufTtcclxuY29uc3QgZGVmID0gKG9iaiwga2V5LCB2YWx1ZSkgPT4ge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxyXG4gICAgICAgIHZhbHVlXHJcbiAgICB9KTtcclxufTtcclxuY29uc3QgdG9OdW1iZXIgPSAodmFsKSA9PiB7XHJcbiAgICBjb25zdCBuID0gcGFyc2VGbG9hdCh2YWwpO1xyXG4gICAgcmV0dXJuIGlzTmFOKG4pID8gdmFsIDogbjtcclxufTtcclxubGV0IF9nbG9iYWxUaGlzO1xyXG5jb25zdCBnZXRHbG9iYWxUaGlzID0gKCkgPT4ge1xyXG4gICAgcmV0dXJuIChfZ2xvYmFsVGhpcyB8fFxyXG4gICAgICAgIChfZ2xvYmFsVGhpcyA9XHJcbiAgICAgICAgICAgIHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICAgICAgICAgICAgPyBnbG9iYWxUaGlzXHJcbiAgICAgICAgICAgICAgICA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICAgICAgICAgICAgICAgID8gc2VsZlxyXG4gICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyB3aW5kb3dcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBnbG9iYWxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDoge30pKTtcclxufTtcblxuZXhwb3J0IHsgRU1QVFlfQVJSLCBFTVBUWV9PQkosIE5PLCBOT09QLCBQYXRjaEZsYWdOYW1lcywgYmFiZWxQYXJzZXJEZWZhdWx0UGx1Z2lucywgY2FtZWxpemUsIGNhcGl0YWxpemUsIGRlZiwgZXNjYXBlSHRtbCwgZXNjYXBlSHRtbENvbW1lbnQsIGV4dGVuZCwgZ2VuZXJhdGVDb2RlRnJhbWUsIGdldEdsb2JhbFRoaXMsIGhhc0NoYW5nZWQsIGhhc093biwgaHlwaGVuYXRlLCBpbnZva2VBcnJheUZucywgaXNBcnJheSwgaXNCb29sZWFuQXR0ciwgaXNEYXRlLCBpc0Z1bmN0aW9uLCBpc0dsb2JhbGx5V2hpdGVsaXN0ZWQsIGlzSFRNTFRhZywgaXNJbnRlZ2VyS2V5LCBpc0tub3duQXR0ciwgaXNNb2RlbExpc3RlbmVyLCBpc05vVW5pdE51bWVyaWNTdHlsZVByb3AsIGlzT2JqZWN0LCBpc09uLCBpc1BsYWluT2JqZWN0LCBpc1Byb21pc2UsIGlzUmVzZXJ2ZWRQcm9wLCBpc1NTUlNhZmVBdHRyTmFtZSwgaXNTVkdUYWcsIGlzU3BlY2lhbEJvb2xlYW5BdHRyLCBpc1N0cmluZywgaXNTeW1ib2wsIGlzVm9pZFRhZywgbG9vc2VFcXVhbCwgbG9vc2VJbmRleE9mLCBtYWtlTWFwLCBub3JtYWxpemVDbGFzcywgbm9ybWFsaXplU3R5bGUsIG9iamVjdFRvU3RyaW5nLCBwYXJzZVN0cmluZ1N0eWxlLCBwcm9wc1RvQXR0ck1hcCwgcmVtb3ZlLCBzdHJpbmdpZnlTdHlsZSwgdG9EaXNwbGF5U3RyaW5nLCB0b051bWJlciwgdG9SYXdUeXBlLCB0b1R5cGVTdHJpbmcgfTtcbiIsImZ1bmN0aW9uIG5vb3AoKSB7IH1cbmNvbnN0IGlkZW50aXR5ID0geCA9PiB4O1xuZnVuY3Rpb24gYXNzaWduKHRhciwgc3JjKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGZvciAoY29uc3QgayBpbiBzcmMpXG4gICAgICAgIHRhcltrXSA9IHNyY1trXTtcbiAgICByZXR1cm4gdGFyO1xufVxuZnVuY3Rpb24gaXNfcHJvbWlzZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWx1ZS50aGVuID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gYWRkX2xvY2F0aW9uKGVsZW1lbnQsIGZpbGUsIGxpbmUsIGNvbHVtbiwgY2hhcikge1xuICAgIGVsZW1lbnQuX19zdmVsdGVfbWV0YSA9IHtcbiAgICAgICAgbG9jOiB7IGZpbGUsIGxpbmUsIGNvbHVtbiwgY2hhciB9XG4gICAgfTtcbn1cbmZ1bmN0aW9uIHJ1bihmbikge1xuICAgIHJldHVybiBmbigpO1xufVxuZnVuY3Rpb24gYmxhbmtfb2JqZWN0KCkge1xuICAgIHJldHVybiBPYmplY3QuY3JlYXRlKG51bGwpO1xufVxuZnVuY3Rpb24gcnVuX2FsbChmbnMpIHtcbiAgICBmbnMuZm9yRWFjaChydW4pO1xufVxuZnVuY3Rpb24gaXNfZnVuY3Rpb24odGhpbmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaW5nID09PSAnZnVuY3Rpb24nO1xufVxuZnVuY3Rpb24gc2FmZV9ub3RfZXF1YWwoYSwgYikge1xuICAgIHJldHVybiBhICE9IGEgPyBiID09IGIgOiBhICE9PSBiIHx8ICgoYSAmJiB0eXBlb2YgYSA9PT0gJ29iamVjdCcpIHx8IHR5cGVvZiBhID09PSAnZnVuY3Rpb24nKTtcbn1cbmZ1bmN0aW9uIG5vdF9lcXVhbChhLCBiKSB7XG4gICAgcmV0dXJuIGEgIT0gYSA/IGIgPT0gYiA6IGEgIT09IGI7XG59XG5mdW5jdGlvbiBpc19lbXB0eShvYmopIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPT09IDA7XG59XG5mdW5jdGlvbiB2YWxpZGF0ZV9zdG9yZShzdG9yZSwgbmFtZSkge1xuICAgIGlmIChzdG9yZSAhPSBudWxsICYmIHR5cGVvZiBzdG9yZS5zdWJzY3JpYmUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAnJHtuYW1lfScgaXMgbm90IGEgc3RvcmUgd2l0aCBhICdzdWJzY3JpYmUnIG1ldGhvZGApO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHN1YnNjcmliZShzdG9yZSwgLi4uY2FsbGJhY2tzKSB7XG4gICAgaWYgKHN0b3JlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG5vb3A7XG4gICAgfVxuICAgIGNvbnN0IHVuc3ViID0gc3RvcmUuc3Vic2NyaWJlKC4uLmNhbGxiYWNrcyk7XG4gICAgcmV0dXJuIHVuc3ViLnVuc3Vic2NyaWJlID8gKCkgPT4gdW5zdWIudW5zdWJzY3JpYmUoKSA6IHVuc3ViO1xufVxuZnVuY3Rpb24gZ2V0X3N0b3JlX3ZhbHVlKHN0b3JlKSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIHN1YnNjcmliZShzdG9yZSwgXyA9PiB2YWx1ZSA9IF8pKCk7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuZnVuY3Rpb24gY29tcG9uZW50X3N1YnNjcmliZShjb21wb25lbnQsIHN0b3JlLCBjYWxsYmFjaykge1xuICAgIGNvbXBvbmVudC4kJC5vbl9kZXN0cm95LnB1c2goc3Vic2NyaWJlKHN0b3JlLCBjYWxsYmFjaykpO1xufVxuZnVuY3Rpb24gY3JlYXRlX3Nsb3QoZGVmaW5pdGlvbiwgY3R4LCAkJHNjb3BlLCBmbikge1xuICAgIGlmIChkZWZpbml0aW9uKSB7XG4gICAgICAgIGNvbnN0IHNsb3RfY3R4ID0gZ2V0X3Nsb3RfY29udGV4dChkZWZpbml0aW9uLCBjdHgsICQkc2NvcGUsIGZuKTtcbiAgICAgICAgcmV0dXJuIGRlZmluaXRpb25bMF0oc2xvdF9jdHgpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldF9zbG90X2NvbnRleHQoZGVmaW5pdGlvbiwgY3R4LCAkJHNjb3BlLCBmbikge1xuICAgIHJldHVybiBkZWZpbml0aW9uWzFdICYmIGZuXG4gICAgICAgID8gYXNzaWduKCQkc2NvcGUuY3R4LnNsaWNlKCksIGRlZmluaXRpb25bMV0oZm4oY3R4KSkpXG4gICAgICAgIDogJCRzY29wZS5jdHg7XG59XG5mdW5jdGlvbiBnZXRfc2xvdF9jaGFuZ2VzKGRlZmluaXRpb24sICQkc2NvcGUsIGRpcnR5LCBmbikge1xuICAgIGlmIChkZWZpbml0aW9uWzJdICYmIGZuKSB7XG4gICAgICAgIGNvbnN0IGxldHMgPSBkZWZpbml0aW9uWzJdKGZuKGRpcnR5KSk7XG4gICAgICAgIGlmICgkJHNjb3BlLmRpcnR5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBsZXRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbGV0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZCA9IFtdO1xuICAgICAgICAgICAgY29uc3QgbGVuID0gTWF0aC5tYXgoJCRzY29wZS5kaXJ0eS5sZW5ndGgsIGxldHMubGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBtZXJnZWRbaV0gPSAkJHNjb3BlLmRpcnR5W2ldIHwgbGV0c1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXJnZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICQkc2NvcGUuZGlydHkgfCBsZXRzO1xuICAgIH1cbiAgICByZXR1cm4gJCRzY29wZS5kaXJ0eTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZV9zbG90KHNsb3QsIHNsb3RfZGVmaW5pdGlvbiwgY3R4LCAkJHNjb3BlLCBkaXJ0eSwgZ2V0X3Nsb3RfY2hhbmdlc19mbiwgZ2V0X3Nsb3RfY29udGV4dF9mbikge1xuICAgIGNvbnN0IHNsb3RfY2hhbmdlcyA9IGdldF9zbG90X2NoYW5nZXMoc2xvdF9kZWZpbml0aW9uLCAkJHNjb3BlLCBkaXJ0eSwgZ2V0X3Nsb3RfY2hhbmdlc19mbik7XG4gICAgaWYgKHNsb3RfY2hhbmdlcykge1xuICAgICAgICBjb25zdCBzbG90X2NvbnRleHQgPSBnZXRfc2xvdF9jb250ZXh0KHNsb3RfZGVmaW5pdGlvbiwgY3R4LCAkJHNjb3BlLCBnZXRfc2xvdF9jb250ZXh0X2ZuKTtcbiAgICAgICAgc2xvdC5wKHNsb3RfY29udGV4dCwgc2xvdF9jaGFuZ2VzKTtcbiAgICB9XG59XG5mdW5jdGlvbiBleGNsdWRlX2ludGVybmFsX3Byb3BzKHByb3BzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgZm9yIChjb25zdCBrIGluIHByb3BzKVxuICAgICAgICBpZiAoa1swXSAhPT0gJyQnKVxuICAgICAgICAgICAgcmVzdWx0W2tdID0gcHJvcHNba107XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVfcmVzdF9wcm9wcyhwcm9wcywga2V5cykge1xuICAgIGNvbnN0IHJlc3QgPSB7fTtcbiAgICBrZXlzID0gbmV3IFNldChrZXlzKTtcbiAgICBmb3IgKGNvbnN0IGsgaW4gcHJvcHMpXG4gICAgICAgIGlmICgha2V5cy5oYXMoaykgJiYga1swXSAhPT0gJyQnKVxuICAgICAgICAgICAgcmVzdFtrXSA9IHByb3BzW2tdO1xuICAgIHJldHVybiByZXN0O1xufVxuZnVuY3Rpb24gY29tcHV0ZV9zbG90cyhzbG90cykge1xuICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IGluIHNsb3RzKSB7XG4gICAgICAgIHJlc3VsdFtrZXldID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG9uY2UoZm4pIHtcbiAgICBsZXQgcmFuID0gZmFsc2U7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmIChyYW4pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHJhbiA9IHRydWU7XG4gICAgICAgIGZuLmNhbGwodGhpcywgLi4uYXJncyk7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIG51bGxfdG9fZW1wdHkodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogdmFsdWU7XG59XG5mdW5jdGlvbiBzZXRfc3RvcmVfdmFsdWUoc3RvcmUsIHJldCwgdmFsdWUgPSByZXQpIHtcbiAgICBzdG9yZS5zZXQodmFsdWUpO1xuICAgIHJldHVybiByZXQ7XG59XG5jb25zdCBoYXNfcHJvcCA9IChvYmosIHByb3ApID0+IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xuZnVuY3Rpb24gYWN0aW9uX2Rlc3Ryb3llcihhY3Rpb25fcmVzdWx0KSB7XG4gICAgcmV0dXJuIGFjdGlvbl9yZXN1bHQgJiYgaXNfZnVuY3Rpb24oYWN0aW9uX3Jlc3VsdC5kZXN0cm95KSA/IGFjdGlvbl9yZXN1bHQuZGVzdHJveSA6IG5vb3A7XG59XG5cbmNvbnN0IGlzX2NsaWVudCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnO1xubGV0IG5vdyA9IGlzX2NsaWVudFxuICAgID8gKCkgPT4gd2luZG93LnBlcmZvcm1hbmNlLm5vdygpXG4gICAgOiAoKSA9PiBEYXRlLm5vdygpO1xubGV0IHJhZiA9IGlzX2NsaWVudCA/IGNiID0+IHJlcXVlc3RBbmltYXRpb25GcmFtZShjYikgOiBub29wO1xuLy8gdXNlZCBpbnRlcm5hbGx5IGZvciB0ZXN0aW5nXG5mdW5jdGlvbiBzZXRfbm93KGZuKSB7XG4gICAgbm93ID0gZm47XG59XG5mdW5jdGlvbiBzZXRfcmFmKGZuKSB7XG4gICAgcmFmID0gZm47XG59XG5cbmNvbnN0IHRhc2tzID0gbmV3IFNldCgpO1xuZnVuY3Rpb24gcnVuX3Rhc2tzKG5vdykge1xuICAgIHRhc2tzLmZvckVhY2godGFzayA9PiB7XG4gICAgICAgIGlmICghdGFzay5jKG5vdykpIHtcbiAgICAgICAgICAgIHRhc2tzLmRlbGV0ZSh0YXNrKTtcbiAgICAgICAgICAgIHRhc2suZigpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHRhc2tzLnNpemUgIT09IDApXG4gICAgICAgIHJhZihydW5fdGFza3MpO1xufVxuLyoqXG4gKiBGb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5IVxuICovXG5mdW5jdGlvbiBjbGVhcl9sb29wcygpIHtcbiAgICB0YXNrcy5jbGVhcigpO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHRhc2sgdGhhdCBydW5zIG9uIGVhY2ggcmFmIGZyYW1lXG4gKiB1bnRpbCBpdCByZXR1cm5zIGEgZmFsc3kgdmFsdWUgb3IgaXMgYWJvcnRlZFxuICovXG5mdW5jdGlvbiBsb29wKGNhbGxiYWNrKSB7XG4gICAgbGV0IHRhc2s7XG4gICAgaWYgKHRhc2tzLnNpemUgPT09IDApXG4gICAgICAgIHJhZihydW5fdGFza3MpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHByb21pc2U6IG5ldyBQcm9taXNlKGZ1bGZpbGwgPT4ge1xuICAgICAgICAgICAgdGFza3MuYWRkKHRhc2sgPSB7IGM6IGNhbGxiYWNrLCBmOiBmdWxmaWxsIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgYWJvcnQoKSB7XG4gICAgICAgICAgICB0YXNrcy5kZWxldGUodGFzayk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiBhcHBlbmQodGFyZ2V0LCBub2RlKSB7XG4gICAgdGFyZ2V0LmFwcGVuZENoaWxkKG5vZGUpO1xufVxuZnVuY3Rpb24gaW5zZXJ0KHRhcmdldCwgbm9kZSwgYW5jaG9yKSB7XG4gICAgdGFyZ2V0Lmluc2VydEJlZm9yZShub2RlLCBhbmNob3IgfHwgbnVsbCk7XG59XG5mdW5jdGlvbiBkZXRhY2gobm9kZSkge1xuICAgIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbn1cbmZ1bmN0aW9uIGRlc3Ryb3lfZWFjaChpdGVyYXRpb25zLCBkZXRhY2hpbmcpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZXJhdGlvbnMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgaWYgKGl0ZXJhdGlvbnNbaV0pXG4gICAgICAgICAgICBpdGVyYXRpb25zW2ldLmQoZGV0YWNoaW5nKTtcbiAgICB9XG59XG5mdW5jdGlvbiBlbGVtZW50KG5hbWUpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChuYW1lKTtcbn1cbmZ1bmN0aW9uIGVsZW1lbnRfaXMobmFtZSwgaXMpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChuYW1lLCB7IGlzIH0pO1xufVxuZnVuY3Rpb24gb2JqZWN0X3dpdGhvdXRfcHJvcGVydGllcyhvYmosIGV4Y2x1ZGUpIHtcbiAgICBjb25zdCB0YXJnZXQgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGsgaW4gb2JqKSB7XG4gICAgICAgIGlmIChoYXNfcHJvcChvYmosIGspXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAmJiBleGNsdWRlLmluZGV4T2YoaykgPT09IC0xKSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB0YXJnZXRba10gPSBvYmpba107XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cbmZ1bmN0aW9uIHN2Z19lbGVtZW50KG5hbWUpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsIG5hbWUpO1xufVxuZnVuY3Rpb24gdGV4dChkYXRhKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGRhdGEpO1xufVxuZnVuY3Rpb24gc3BhY2UoKSB7XG4gICAgcmV0dXJuIHRleHQoJyAnKTtcbn1cbmZ1bmN0aW9uIGVtcHR5KCkge1xuICAgIHJldHVybiB0ZXh0KCcnKTtcbn1cbmZ1bmN0aW9uIGxpc3Rlbihub2RlLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykge1xuICAgIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgb3B0aW9ucyk7XG4gICAgcmV0dXJuICgpID0+IG5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgb3B0aW9ucyk7XG59XG5mdW5jdGlvbiBwcmV2ZW50X2RlZmF1bHQoZm4pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgZXZlbnQpO1xuICAgIH07XG59XG5mdW5jdGlvbiBzdG9wX3Byb3BhZ2F0aW9uKGZuKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBldmVudCk7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIHNlbGYoZm4pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gdGhpcylcbiAgICAgICAgICAgIGZuLmNhbGwodGhpcywgZXZlbnQpO1xuICAgIH07XG59XG5mdW5jdGlvbiBhdHRyKG5vZGUsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbClcbiAgICAgICAgbm9kZS5yZW1vdmVBdHRyaWJ1dGUoYXR0cmlidXRlKTtcbiAgICBlbHNlIGlmIChub2RlLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGUpICE9PSB2YWx1ZSlcbiAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSk7XG59XG5mdW5jdGlvbiBzZXRfYXR0cmlidXRlcyhub2RlLCBhdHRyaWJ1dGVzKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGRlc2NyaXB0b3JzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMobm9kZS5fX3Byb3RvX18pO1xuICAgIGZvciAoY29uc3Qga2V5IGluIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgaWYgKGF0dHJpYnV0ZXNba2V5XSA9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGtleSA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgICAgbm9kZS5zdHlsZS5jc3NUZXh0ID0gYXR0cmlidXRlc1trZXldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGtleSA9PT0gJ19fdmFsdWUnKSB7XG4gICAgICAgICAgICBub2RlLnZhbHVlID0gbm9kZVtrZXldID0gYXR0cmlidXRlc1trZXldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRlc2NyaXB0b3JzW2tleV0gJiYgZGVzY3JpcHRvcnNba2V5XS5zZXQpIHtcbiAgICAgICAgICAgIG5vZGVba2V5XSA9IGF0dHJpYnV0ZXNba2V5XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGF0dHIobm9kZSwga2V5LCBhdHRyaWJ1dGVzW2tleV0pO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gc2V0X3N2Z19hdHRyaWJ1dGVzKG5vZGUsIGF0dHJpYnV0ZXMpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBhdHRyaWJ1dGVzKSB7XG4gICAgICAgIGF0dHIobm9kZSwga2V5LCBhdHRyaWJ1dGVzW2tleV0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHNldF9jdXN0b21fZWxlbWVudF9kYXRhKG5vZGUsIHByb3AsIHZhbHVlKSB7XG4gICAgaWYgKHByb3AgaW4gbm9kZSkge1xuICAgICAgICBub2RlW3Byb3BdID0gdmFsdWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBhdHRyKG5vZGUsIHByb3AsIHZhbHVlKTtcbiAgICB9XG59XG5mdW5jdGlvbiB4bGlua19hdHRyKG5vZGUsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgICBub2RlLnNldEF0dHJpYnV0ZU5TKCdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJywgYXR0cmlidXRlLCB2YWx1ZSk7XG59XG5mdW5jdGlvbiBnZXRfYmluZGluZ19ncm91cF92YWx1ZShncm91cCwgX192YWx1ZSwgY2hlY2tlZCkge1xuICAgIGNvbnN0IHZhbHVlID0gbmV3IFNldCgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ3JvdXAubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgaWYgKGdyb3VwW2ldLmNoZWNrZWQpXG4gICAgICAgICAgICB2YWx1ZS5hZGQoZ3JvdXBbaV0uX192YWx1ZSk7XG4gICAgfVxuICAgIGlmICghY2hlY2tlZCkge1xuICAgICAgICB2YWx1ZS5kZWxldGUoX192YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKHZhbHVlKTtcbn1cbmZ1bmN0aW9uIHRvX251bWJlcih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gJycgPyBudWxsIDogK3ZhbHVlO1xufVxuZnVuY3Rpb24gdGltZV9yYW5nZXNfdG9fYXJyYXkocmFuZ2VzKSB7XG4gICAgY29uc3QgYXJyYXkgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBhcnJheS5wdXNoKHsgc3RhcnQ6IHJhbmdlcy5zdGFydChpKSwgZW5kOiByYW5nZXMuZW5kKGkpIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG59XG5mdW5jdGlvbiBjaGlsZHJlbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oZWxlbWVudC5jaGlsZE5vZGVzKTtcbn1cbmZ1bmN0aW9uIGNsYWltX2VsZW1lbnQobm9kZXMsIG5hbWUsIGF0dHJpYnV0ZXMsIHN2Zykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAobm9kZS5ub2RlTmFtZSA9PT0gbmFtZSkge1xuICAgICAgICAgICAgbGV0IGogPSAwO1xuICAgICAgICAgICAgY29uc3QgcmVtb3ZlID0gW107XG4gICAgICAgICAgICB3aGlsZSAoaiA8IG5vZGUuYXR0cmlidXRlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGUgPSBub2RlLmF0dHJpYnV0ZXNbaisrXTtcbiAgICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZXNbYXR0cmlidXRlLm5hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZS5wdXNoKGF0dHJpYnV0ZS5uYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHJlbW92ZS5sZW5ndGg7IGsrKykge1xuICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlQXR0cmlidXRlKHJlbW92ZVtrXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbm9kZXMuc3BsaWNlKGksIDEpWzBdO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdmcgPyBzdmdfZWxlbWVudChuYW1lKSA6IGVsZW1lbnQobmFtZSk7XG59XG5mdW5jdGlvbiBjbGFpbV90ZXh0KG5vZGVzLCBkYXRhKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBub2RlID0gbm9kZXNbaV07XG4gICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSAzKSB7XG4gICAgICAgICAgICBub2RlLmRhdGEgPSAnJyArIGRhdGE7XG4gICAgICAgICAgICByZXR1cm4gbm9kZXMuc3BsaWNlKGksIDEpWzBdO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0ZXh0KGRhdGEpO1xufVxuZnVuY3Rpb24gY2xhaW1fc3BhY2Uobm9kZXMpIHtcbiAgICByZXR1cm4gY2xhaW1fdGV4dChub2RlcywgJyAnKTtcbn1cbmZ1bmN0aW9uIHNldF9kYXRhKHRleHQsIGRhdGEpIHtcbiAgICBkYXRhID0gJycgKyBkYXRhO1xuICAgIGlmICh0ZXh0Lndob2xlVGV4dCAhPT0gZGF0YSlcbiAgICAgICAgdGV4dC5kYXRhID0gZGF0YTtcbn1cbmZ1bmN0aW9uIHNldF9pbnB1dF92YWx1ZShpbnB1dCwgdmFsdWUpIHtcbiAgICBpbnB1dC52YWx1ZSA9IHZhbHVlID09IG51bGwgPyAnJyA6IHZhbHVlO1xufVxuZnVuY3Rpb24gc2V0X2lucHV0X3R5cGUoaW5wdXQsIHR5cGUpIHtcbiAgICB0cnkge1xuICAgICAgICBpbnB1dC50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gZG8gbm90aGluZ1xuICAgIH1cbn1cbmZ1bmN0aW9uIHNldF9zdHlsZShub2RlLCBrZXksIHZhbHVlLCBpbXBvcnRhbnQpIHtcbiAgICBub2RlLnN0eWxlLnNldFByb3BlcnR5KGtleSwgdmFsdWUsIGltcG9ydGFudCA/ICdpbXBvcnRhbnQnIDogJycpO1xufVxuZnVuY3Rpb24gc2VsZWN0X29wdGlvbihzZWxlY3QsIHZhbHVlKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Qub3B0aW9ucy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBvcHRpb24gPSBzZWxlY3Qub3B0aW9uc1tpXTtcbiAgICAgICAgaWYgKG9wdGlvbi5fX3ZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgb3B0aW9uLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHNlbGVjdF9vcHRpb25zKHNlbGVjdCwgdmFsdWUpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdC5vcHRpb25zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHNlbGVjdC5vcHRpb25zW2ldO1xuICAgICAgICBvcHRpb24uc2VsZWN0ZWQgPSB+dmFsdWUuaW5kZXhPZihvcHRpb24uX192YWx1ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gc2VsZWN0X3ZhbHVlKHNlbGVjdCkge1xuICAgIGNvbnN0IHNlbGVjdGVkX29wdGlvbiA9IHNlbGVjdC5xdWVyeVNlbGVjdG9yKCc6Y2hlY2tlZCcpIHx8IHNlbGVjdC5vcHRpb25zWzBdO1xuICAgIHJldHVybiBzZWxlY3RlZF9vcHRpb24gJiYgc2VsZWN0ZWRfb3B0aW9uLl9fdmFsdWU7XG59XG5mdW5jdGlvbiBzZWxlY3RfbXVsdGlwbGVfdmFsdWUoc2VsZWN0KSB7XG4gICAgcmV0dXJuIFtdLm1hcC5jYWxsKHNlbGVjdC5xdWVyeVNlbGVjdG9yQWxsKCc6Y2hlY2tlZCcpLCBvcHRpb24gPT4gb3B0aW9uLl9fdmFsdWUpO1xufVxuLy8gdW5mb3J0dW5hdGVseSB0aGlzIGNhbid0IGJlIGEgY29uc3RhbnQgYXMgdGhhdCB3b3VsZG4ndCBiZSB0cmVlLXNoYWtlYWJsZVxuLy8gc28gd2UgY2FjaGUgdGhlIHJlc3VsdCBpbnN0ZWFkXG5sZXQgY3Jvc3NvcmlnaW47XG5mdW5jdGlvbiBpc19jcm9zc29yaWdpbigpIHtcbiAgICBpZiAoY3Jvc3NvcmlnaW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjcm9zc29yaWdpbiA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICB2b2lkIHdpbmRvdy5wYXJlbnQuZG9jdW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjcm9zc29yaWdpbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNyb3Nzb3JpZ2luO1xufVxuZnVuY3Rpb24gYWRkX3Jlc2l6ZV9saXN0ZW5lcihub2RlLCBmbikge1xuICAgIGNvbnN0IGNvbXB1dGVkX3N0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShub2RlKTtcbiAgICBjb25zdCB6X2luZGV4ID0gKHBhcnNlSW50KGNvbXB1dGVkX3N0eWxlLnpJbmRleCkgfHwgMCkgLSAxO1xuICAgIGlmIChjb21wdXRlZF9zdHlsZS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpIHtcbiAgICAgICAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgfVxuICAgIGNvbnN0IGlmcmFtZSA9IGVsZW1lbnQoJ2lmcmFtZScpO1xuICAgIGlmcmFtZS5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYGRpc3BsYXk6IGJsb2NrOyBwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogMDsgbGVmdDogMDsgd2lkdGg6IDEwMCU7IGhlaWdodDogMTAwJTsgYCArXG4gICAgICAgIGBvdmVyZmxvdzogaGlkZGVuOyBib3JkZXI6IDA7IG9wYWNpdHk6IDA7IHBvaW50ZXItZXZlbnRzOiBub25lOyB6LWluZGV4OiAke3pfaW5kZXh9O2ApO1xuICAgIGlmcmFtZS5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICBpZnJhbWUudGFiSW5kZXggPSAtMTtcbiAgICBjb25zdCBjcm9zc29yaWdpbiA9IGlzX2Nyb3Nzb3JpZ2luKCk7XG4gICAgbGV0IHVuc3Vic2NyaWJlO1xuICAgIGlmIChjcm9zc29yaWdpbikge1xuICAgICAgICBpZnJhbWUuc3JjID0gYGRhdGE6dGV4dC9odG1sLDxzY3JpcHQ+b25yZXNpemU9ZnVuY3Rpb24oKXtwYXJlbnQucG9zdE1lc3NhZ2UoMCwnKicpfTwvc2NyaXB0PmA7XG4gICAgICAgIHVuc3Vic2NyaWJlID0gbGlzdGVuKHdpbmRvdywgJ21lc3NhZ2UnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5zb3VyY2UgPT09IGlmcmFtZS5jb250ZW50V2luZG93KVxuICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWZyYW1lLnNyYyA9ICdhYm91dDpibGFuayc7XG4gICAgICAgIGlmcmFtZS5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZSA9IGxpc3RlbihpZnJhbWUuY29udGVudFdpbmRvdywgJ3Jlc2l6ZScsIGZuKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgYXBwZW5kKG5vZGUsIGlmcmFtZSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKGNyb3Nzb3JpZ2luKSB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHVuc3Vic2NyaWJlICYmIGlmcmFtZS5jb250ZW50V2luZG93KSB7XG4gICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIGRldGFjaChpZnJhbWUpO1xuICAgIH07XG59XG5mdW5jdGlvbiB0b2dnbGVfY2xhc3MoZWxlbWVudCwgbmFtZSwgdG9nZ2xlKSB7XG4gICAgZWxlbWVudC5jbGFzc0xpc3RbdG9nZ2xlID8gJ2FkZCcgOiAncmVtb3ZlJ10obmFtZSk7XG59XG5mdW5jdGlvbiBjdXN0b21fZXZlbnQodHlwZSwgZGV0YWlsKSB7XG4gICAgY29uc3QgZSA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdDdXN0b21FdmVudCcpO1xuICAgIGUuaW5pdEN1c3RvbUV2ZW50KHR5cGUsIGZhbHNlLCBmYWxzZSwgZGV0YWlsKTtcbiAgICByZXR1cm4gZTtcbn1cbmZ1bmN0aW9uIHF1ZXJ5X3NlbGVjdG9yX2FsbChzZWxlY3RvciwgcGFyZW50ID0gZG9jdW1lbnQuYm9keSkge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHBhcmVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG59XG5jbGFzcyBIdG1sVGFnIHtcbiAgICBjb25zdHJ1Y3RvcihhbmNob3IgPSBudWxsKSB7XG4gICAgICAgIHRoaXMuYSA9IGFuY2hvcjtcbiAgICAgICAgdGhpcy5lID0gdGhpcy5uID0gbnVsbDtcbiAgICB9XG4gICAgbShodG1sLCB0YXJnZXQsIGFuY2hvciA9IG51bGwpIHtcbiAgICAgICAgaWYgKCF0aGlzLmUpIHtcbiAgICAgICAgICAgIHRoaXMuZSA9IGVsZW1lbnQodGFyZ2V0Lm5vZGVOYW1lKTtcbiAgICAgICAgICAgIHRoaXMudCA9IHRhcmdldDtcbiAgICAgICAgICAgIHRoaXMuaChodG1sKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmkoYW5jaG9yKTtcbiAgICB9XG4gICAgaChodG1sKSB7XG4gICAgICAgIHRoaXMuZS5pbm5lckhUTUwgPSBodG1sO1xuICAgICAgICB0aGlzLm4gPSBBcnJheS5mcm9tKHRoaXMuZS5jaGlsZE5vZGVzKTtcbiAgICB9XG4gICAgaShhbmNob3IpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm4ubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGluc2VydCh0aGlzLnQsIHRoaXMubltpXSwgYW5jaG9yKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwKGh0bWwpIHtcbiAgICAgICAgdGhpcy5kKCk7XG4gICAgICAgIHRoaXMuaChodG1sKTtcbiAgICAgICAgdGhpcy5pKHRoaXMuYSk7XG4gICAgfVxuICAgIGQoKSB7XG4gICAgICAgIHRoaXMubi5mb3JFYWNoKGRldGFjaCk7XG4gICAgfVxufVxuXG5jb25zdCBhY3RpdmVfZG9jcyA9IG5ldyBTZXQoKTtcbmxldCBhY3RpdmUgPSAwO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Rhcmtza3lhcHAvc3RyaW5nLWhhc2gvYmxvYi9tYXN0ZXIvaW5kZXguanNcbmZ1bmN0aW9uIGhhc2goc3RyKSB7XG4gICAgbGV0IGhhc2ggPSA1MzgxO1xuICAgIGxldCBpID0gc3RyLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKVxuICAgICAgICBoYXNoID0gKChoYXNoIDw8IDUpIC0gaGFzaCkgXiBzdHIuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gaGFzaCA+Pj4gMDtcbn1cbmZ1bmN0aW9uIGNyZWF0ZV9ydWxlKG5vZGUsIGEsIGIsIGR1cmF0aW9uLCBkZWxheSwgZWFzZSwgZm4sIHVpZCA9IDApIHtcbiAgICBjb25zdCBzdGVwID0gMTYuNjY2IC8gZHVyYXRpb247XG4gICAgbGV0IGtleWZyYW1lcyA9ICd7XFxuJztcbiAgICBmb3IgKGxldCBwID0gMDsgcCA8PSAxOyBwICs9IHN0ZXApIHtcbiAgICAgICAgY29uc3QgdCA9IGEgKyAoYiAtIGEpICogZWFzZShwKTtcbiAgICAgICAga2V5ZnJhbWVzICs9IHAgKiAxMDAgKyBgJXske2ZuKHQsIDEgLSB0KX19XFxuYDtcbiAgICB9XG4gICAgY29uc3QgcnVsZSA9IGtleWZyYW1lcyArIGAxMDAlIHske2ZuKGIsIDEgLSBiKX19XFxufWA7XG4gICAgY29uc3QgbmFtZSA9IGBfX3N2ZWx0ZV8ke2hhc2gocnVsZSl9XyR7dWlkfWA7XG4gICAgY29uc3QgZG9jID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIGFjdGl2ZV9kb2NzLmFkZChkb2MpO1xuICAgIGNvbnN0IHN0eWxlc2hlZXQgPSBkb2MuX19zdmVsdGVfc3R5bGVzaGVldCB8fCAoZG9jLl9fc3ZlbHRlX3N0eWxlc2hlZXQgPSBkb2MuaGVhZC5hcHBlbmRDaGlsZChlbGVtZW50KCdzdHlsZScpKS5zaGVldCk7XG4gICAgY29uc3QgY3VycmVudF9ydWxlcyA9IGRvYy5fX3N2ZWx0ZV9ydWxlcyB8fCAoZG9jLl9fc3ZlbHRlX3J1bGVzID0ge30pO1xuICAgIGlmICghY3VycmVudF9ydWxlc1tuYW1lXSkge1xuICAgICAgICBjdXJyZW50X3J1bGVzW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgc3R5bGVzaGVldC5pbnNlcnRSdWxlKGBAa2V5ZnJhbWVzICR7bmFtZX0gJHtydWxlfWAsIHN0eWxlc2hlZXQuY3NzUnVsZXMubGVuZ3RoKTtcbiAgICB9XG4gICAgY29uc3QgYW5pbWF0aW9uID0gbm9kZS5zdHlsZS5hbmltYXRpb24gfHwgJyc7XG4gICAgbm9kZS5zdHlsZS5hbmltYXRpb24gPSBgJHthbmltYXRpb24gPyBgJHthbmltYXRpb259LCBgIDogYGB9JHtuYW1lfSAke2R1cmF0aW9ufW1zIGxpbmVhciAke2RlbGF5fW1zIDEgYm90aGA7XG4gICAgYWN0aXZlICs9IDE7XG4gICAgcmV0dXJuIG5hbWU7XG59XG5mdW5jdGlvbiBkZWxldGVfcnVsZShub2RlLCBuYW1lKSB7XG4gICAgY29uc3QgcHJldmlvdXMgPSAobm9kZS5zdHlsZS5hbmltYXRpb24gfHwgJycpLnNwbGl0KCcsICcpO1xuICAgIGNvbnN0IG5leHQgPSBwcmV2aW91cy5maWx0ZXIobmFtZVxuICAgICAgICA/IGFuaW0gPT4gYW5pbS5pbmRleE9mKG5hbWUpIDwgMCAvLyByZW1vdmUgc3BlY2lmaWMgYW5pbWF0aW9uXG4gICAgICAgIDogYW5pbSA9PiBhbmltLmluZGV4T2YoJ19fc3ZlbHRlJykgPT09IC0xIC8vIHJlbW92ZSBhbGwgU3ZlbHRlIGFuaW1hdGlvbnNcbiAgICApO1xuICAgIGNvbnN0IGRlbGV0ZWQgPSBwcmV2aW91cy5sZW5ndGggLSBuZXh0Lmxlbmd0aDtcbiAgICBpZiAoZGVsZXRlZCkge1xuICAgICAgICBub2RlLnN0eWxlLmFuaW1hdGlvbiA9IG5leHQuam9pbignLCAnKTtcbiAgICAgICAgYWN0aXZlIC09IGRlbGV0ZWQ7XG4gICAgICAgIGlmICghYWN0aXZlKVxuICAgICAgICAgICAgY2xlYXJfcnVsZXMoKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjbGVhcl9ydWxlcygpIHtcbiAgICByYWYoKCkgPT4ge1xuICAgICAgICBpZiAoYWN0aXZlKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBhY3RpdmVfZG9jcy5mb3JFYWNoKGRvYyA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHlsZXNoZWV0ID0gZG9jLl9fc3ZlbHRlX3N0eWxlc2hlZXQ7XG4gICAgICAgICAgICBsZXQgaSA9IHN0eWxlc2hlZXQuY3NzUnVsZXMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSlcbiAgICAgICAgICAgICAgICBzdHlsZXNoZWV0LmRlbGV0ZVJ1bGUoaSk7XG4gICAgICAgICAgICBkb2MuX19zdmVsdGVfcnVsZXMgPSB7fTtcbiAgICAgICAgfSk7XG4gICAgICAgIGFjdGl2ZV9kb2NzLmNsZWFyKCk7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZV9hbmltYXRpb24obm9kZSwgZnJvbSwgZm4sIHBhcmFtcykge1xuICAgIGlmICghZnJvbSlcbiAgICAgICAgcmV0dXJuIG5vb3A7XG4gICAgY29uc3QgdG8gPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmIChmcm9tLmxlZnQgPT09IHRvLmxlZnQgJiYgZnJvbS5yaWdodCA9PT0gdG8ucmlnaHQgJiYgZnJvbS50b3AgPT09IHRvLnRvcCAmJiBmcm9tLmJvdHRvbSA9PT0gdG8uYm90dG9tKVxuICAgICAgICByZXR1cm4gbm9vcDtcbiAgICBjb25zdCB7IGRlbGF5ID0gMCwgZHVyYXRpb24gPSAzMDAsIGVhc2luZyA9IGlkZW50aXR5LCBcbiAgICAvLyBAdHMtaWdub3JlIHRvZG86IHNob3VsZCB0aGlzIGJlIHNlcGFyYXRlZCBmcm9tIGRlc3RydWN0dXJpbmc/IE9yIHN0YXJ0L2VuZCBhZGRlZCB0byBwdWJsaWMgYXBpIGFuZCBkb2N1bWVudGF0aW9uP1xuICAgIHN0YXJ0OiBzdGFydF90aW1lID0gbm93KCkgKyBkZWxheSwgXG4gICAgLy8gQHRzLWlnbm9yZSB0b2RvOlxuICAgIGVuZCA9IHN0YXJ0X3RpbWUgKyBkdXJhdGlvbiwgdGljayA9IG5vb3AsIGNzcyB9ID0gZm4obm9kZSwgeyBmcm9tLCB0byB9LCBwYXJhbXMpO1xuICAgIGxldCBydW5uaW5nID0gdHJ1ZTtcbiAgICBsZXQgc3RhcnRlZCA9IGZhbHNlO1xuICAgIGxldCBuYW1lO1xuICAgIGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgICAgICBpZiAoY3NzKSB7XG4gICAgICAgICAgICBuYW1lID0gY3JlYXRlX3J1bGUobm9kZSwgMCwgMSwgZHVyYXRpb24sIGRlbGF5LCBlYXNpbmcsIGNzcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFkZWxheSkge1xuICAgICAgICAgICAgc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZnVuY3Rpb24gc3RvcCgpIHtcbiAgICAgICAgaWYgKGNzcylcbiAgICAgICAgICAgIGRlbGV0ZV9ydWxlKG5vZGUsIG5hbWUpO1xuICAgICAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIGxvb3Aobm93ID0+IHtcbiAgICAgICAgaWYgKCFzdGFydGVkICYmIG5vdyA+PSBzdGFydF90aW1lKSB7XG4gICAgICAgICAgICBzdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhcnRlZCAmJiBub3cgPj0gZW5kKSB7XG4gICAgICAgICAgICB0aWNrKDEsIDApO1xuICAgICAgICAgICAgc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcnVubmluZykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGFydGVkKSB7XG4gICAgICAgICAgICBjb25zdCBwID0gbm93IC0gc3RhcnRfdGltZTtcbiAgICAgICAgICAgIGNvbnN0IHQgPSAwICsgMSAqIGVhc2luZyhwIC8gZHVyYXRpb24pO1xuICAgICAgICAgICAgdGljayh0LCAxIC0gdCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG4gICAgc3RhcnQoKTtcbiAgICB0aWNrKDAsIDEpO1xuICAgIHJldHVybiBzdG9wO1xufVxuZnVuY3Rpb24gZml4X3Bvc2l0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUobm9kZSk7XG4gICAgaWYgKHN0eWxlLnBvc2l0aW9uICE9PSAnYWJzb2x1dGUnICYmIHN0eWxlLnBvc2l0aW9uICE9PSAnZml4ZWQnKSB7XG4gICAgICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gc3R5bGU7XG4gICAgICAgIGNvbnN0IGEgPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBub2RlLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgbm9kZS5zdHlsZS53aWR0aCA9IHdpZHRoO1xuICAgICAgICBub2RlLnN0eWxlLmhlaWdodCA9IGhlaWdodDtcbiAgICAgICAgYWRkX3RyYW5zZm9ybShub2RlLCBhKTtcbiAgICB9XG59XG5mdW5jdGlvbiBhZGRfdHJhbnNmb3JtKG5vZGUsIGEpIHtcbiAgICBjb25zdCBiID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAoYS5sZWZ0ICE9PSBiLmxlZnQgfHwgYS50b3AgIT09IGIudG9wKSB7XG4gICAgICAgIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShub2RlKTtcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtID0gc3R5bGUudHJhbnNmb3JtID09PSAnbm9uZScgPyAnJyA6IHN0eWxlLnRyYW5zZm9ybTtcbiAgICAgICAgbm9kZS5zdHlsZS50cmFuc2Zvcm0gPSBgJHt0cmFuc2Zvcm19IHRyYW5zbGF0ZSgke2EubGVmdCAtIGIubGVmdH1weCwgJHthLnRvcCAtIGIudG9wfXB4KWA7XG4gICAgfVxufVxuXG5sZXQgY3VycmVudF9jb21wb25lbnQ7XG5mdW5jdGlvbiBzZXRfY3VycmVudF9jb21wb25lbnQoY29tcG9uZW50KSB7XG4gICAgY3VycmVudF9jb21wb25lbnQgPSBjb21wb25lbnQ7XG59XG5mdW5jdGlvbiBnZXRfY3VycmVudF9jb21wb25lbnQoKSB7XG4gICAgaWYgKCFjdXJyZW50X2NvbXBvbmVudClcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGdW5jdGlvbiBjYWxsZWQgb3V0c2lkZSBjb21wb25lbnQgaW5pdGlhbGl6YXRpb25gKTtcbiAgICByZXR1cm4gY3VycmVudF9jb21wb25lbnQ7XG59XG5mdW5jdGlvbiBiZWZvcmVVcGRhdGUoZm4pIHtcbiAgICBnZXRfY3VycmVudF9jb21wb25lbnQoKS4kJC5iZWZvcmVfdXBkYXRlLnB1c2goZm4pO1xufVxuZnVuY3Rpb24gb25Nb3VudChmbikge1xuICAgIGdldF9jdXJyZW50X2NvbXBvbmVudCgpLiQkLm9uX21vdW50LnB1c2goZm4pO1xufVxuZnVuY3Rpb24gYWZ0ZXJVcGRhdGUoZm4pIHtcbiAgICBnZXRfY3VycmVudF9jb21wb25lbnQoKS4kJC5hZnRlcl91cGRhdGUucHVzaChmbik7XG59XG5mdW5jdGlvbiBvbkRlc3Ryb3koZm4pIHtcbiAgICBnZXRfY3VycmVudF9jb21wb25lbnQoKS4kJC5vbl9kZXN0cm95LnB1c2goZm4pO1xufVxuZnVuY3Rpb24gY3JlYXRlRXZlbnREaXNwYXRjaGVyKCkge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IGdldF9jdXJyZW50X2NvbXBvbmVudCgpO1xuICAgIHJldHVybiAodHlwZSwgZGV0YWlsKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IGNvbXBvbmVudC4kJC5jYWxsYmFja3NbdHlwZV07XG4gICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIC8vIFRPRE8gYXJlIHRoZXJlIHNpdHVhdGlvbnMgd2hlcmUgZXZlbnRzIGNvdWxkIGJlIGRpc3BhdGNoZWRcbiAgICAgICAgICAgIC8vIGluIGEgc2VydmVyIChub24tRE9NKSBlbnZpcm9ubWVudD9cbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gY3VzdG9tX2V2ZW50KHR5cGUsIGRldGFpbCk7XG4gICAgICAgICAgICBjYWxsYmFja3Muc2xpY2UoKS5mb3JFYWNoKGZuID0+IHtcbiAgICAgICAgICAgICAgICBmbi5jYWxsKGNvbXBvbmVudCwgZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZnVuY3Rpb24gc2V0Q29udGV4dChrZXksIGNvbnRleHQpIHtcbiAgICBnZXRfY3VycmVudF9jb21wb25lbnQoKS4kJC5jb250ZXh0LnNldChrZXksIGNvbnRleHQpO1xufVxuZnVuY3Rpb24gZ2V0Q29udGV4dChrZXkpIHtcbiAgICByZXR1cm4gZ2V0X2N1cnJlbnRfY29tcG9uZW50KCkuJCQuY29udGV4dC5nZXQoa2V5KTtcbn1cbi8vIFRPRE8gZmlndXJlIG91dCBpZiB3ZSBzdGlsbCB3YW50IHRvIHN1cHBvcnRcbi8vIHNob3J0aGFuZCBldmVudHMsIG9yIGlmIHdlIHdhbnQgdG8gaW1wbGVtZW50XG4vLyBhIHJlYWwgYnViYmxpbmcgbWVjaGFuaXNtXG5mdW5jdGlvbiBidWJibGUoY29tcG9uZW50LCBldmVudCkge1xuICAgIGNvbnN0IGNhbGxiYWNrcyA9IGNvbXBvbmVudC4kJC5jYWxsYmFja3NbZXZlbnQudHlwZV07XG4gICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgICBjYWxsYmFja3Muc2xpY2UoKS5mb3JFYWNoKGZuID0+IGZuKGV2ZW50KSk7XG4gICAgfVxufVxuXG5jb25zdCBkaXJ0eV9jb21wb25lbnRzID0gW107XG5jb25zdCBpbnRyb3MgPSB7IGVuYWJsZWQ6IGZhbHNlIH07XG5jb25zdCBiaW5kaW5nX2NhbGxiYWNrcyA9IFtdO1xuY29uc3QgcmVuZGVyX2NhbGxiYWNrcyA9IFtdO1xuY29uc3QgZmx1c2hfY2FsbGJhY2tzID0gW107XG5jb25zdCByZXNvbHZlZF9wcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5sZXQgdXBkYXRlX3NjaGVkdWxlZCA9IGZhbHNlO1xuZnVuY3Rpb24gc2NoZWR1bGVfdXBkYXRlKCkge1xuICAgIGlmICghdXBkYXRlX3NjaGVkdWxlZCkge1xuICAgICAgICB1cGRhdGVfc2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgICAgcmVzb2x2ZWRfcHJvbWlzZS50aGVuKGZsdXNoKTtcbiAgICB9XG59XG5mdW5jdGlvbiB0aWNrKCkge1xuICAgIHNjaGVkdWxlX3VwZGF0ZSgpO1xuICAgIHJldHVybiByZXNvbHZlZF9wcm9taXNlO1xufVxuZnVuY3Rpb24gYWRkX3JlbmRlcl9jYWxsYmFjayhmbikge1xuICAgIHJlbmRlcl9jYWxsYmFja3MucHVzaChmbik7XG59XG5mdW5jdGlvbiBhZGRfZmx1c2hfY2FsbGJhY2soZm4pIHtcbiAgICBmbHVzaF9jYWxsYmFja3MucHVzaChmbik7XG59XG5sZXQgZmx1c2hpbmcgPSBmYWxzZTtcbmNvbnN0IHNlZW5fY2FsbGJhY2tzID0gbmV3IFNldCgpO1xuZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgaWYgKGZsdXNoaW5nKVxuICAgICAgICByZXR1cm47XG4gICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgIGRvIHtcbiAgICAgICAgLy8gZmlyc3QsIGNhbGwgYmVmb3JlVXBkYXRlIGZ1bmN0aW9uc1xuICAgICAgICAvLyBhbmQgdXBkYXRlIGNvbXBvbmVudHNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaXJ0eV9jb21wb25lbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnQgPSBkaXJ0eV9jb21wb25lbnRzW2ldO1xuICAgICAgICAgICAgc2V0X2N1cnJlbnRfY29tcG9uZW50KGNvbXBvbmVudCk7XG4gICAgICAgICAgICB1cGRhdGUoY29tcG9uZW50LiQkKTtcbiAgICAgICAgfVxuICAgICAgICBzZXRfY3VycmVudF9jb21wb25lbnQobnVsbCk7XG4gICAgICAgIGRpcnR5X2NvbXBvbmVudHMubGVuZ3RoID0gMDtcbiAgICAgICAgd2hpbGUgKGJpbmRpbmdfY2FsbGJhY2tzLmxlbmd0aClcbiAgICAgICAgICAgIGJpbmRpbmdfY2FsbGJhY2tzLnBvcCgpKCk7XG4gICAgICAgIC8vIHRoZW4sIG9uY2UgY29tcG9uZW50cyBhcmUgdXBkYXRlZCwgY2FsbFxuICAgICAgICAvLyBhZnRlclVwZGF0ZSBmdW5jdGlvbnMuIFRoaXMgbWF5IGNhdXNlXG4gICAgICAgIC8vIHN1YnNlcXVlbnQgdXBkYXRlcy4uLlxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlbmRlcl9jYWxsYmFja3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gcmVuZGVyX2NhbGxiYWNrc1tpXTtcbiAgICAgICAgICAgIGlmICghc2Vlbl9jYWxsYmFja3MuaGFzKGNhbGxiYWNrKSkge1xuICAgICAgICAgICAgICAgIC8vIC4uLnNvIGd1YXJkIGFnYWluc3QgaW5maW5pdGUgbG9vcHNcbiAgICAgICAgICAgICAgICBzZWVuX2NhbGxiYWNrcy5hZGQoY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVuZGVyX2NhbGxiYWNrcy5sZW5ndGggPSAwO1xuICAgIH0gd2hpbGUgKGRpcnR5X2NvbXBvbmVudHMubGVuZ3RoKTtcbiAgICB3aGlsZSAoZmx1c2hfY2FsbGJhY2tzLmxlbmd0aCkge1xuICAgICAgICBmbHVzaF9jYWxsYmFja3MucG9wKCkoKTtcbiAgICB9XG4gICAgdXBkYXRlX3NjaGVkdWxlZCA9IGZhbHNlO1xuICAgIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgc2Vlbl9jYWxsYmFja3MuY2xlYXIoKTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZSgkJCkge1xuICAgIGlmICgkJC5mcmFnbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAkJC51cGRhdGUoKTtcbiAgICAgICAgcnVuX2FsbCgkJC5iZWZvcmVfdXBkYXRlKTtcbiAgICAgICAgY29uc3QgZGlydHkgPSAkJC5kaXJ0eTtcbiAgICAgICAgJCQuZGlydHkgPSBbLTFdO1xuICAgICAgICAkJC5mcmFnbWVudCAmJiAkJC5mcmFnbWVudC5wKCQkLmN0eCwgZGlydHkpO1xuICAgICAgICAkJC5hZnRlcl91cGRhdGUuZm9yRWFjaChhZGRfcmVuZGVyX2NhbGxiYWNrKTtcbiAgICB9XG59XG5cbmxldCBwcm9taXNlO1xuZnVuY3Rpb24gd2FpdCgpIHtcbiAgICBpZiAoIXByb21pc2UpIHtcbiAgICAgICAgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICBwcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcHJvbWlzZSA9IG51bGw7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cbmZ1bmN0aW9uIGRpc3BhdGNoKG5vZGUsIGRpcmVjdGlvbiwga2luZCkge1xuICAgIG5vZGUuZGlzcGF0Y2hFdmVudChjdXN0b21fZXZlbnQoYCR7ZGlyZWN0aW9uID8gJ2ludHJvJyA6ICdvdXRybyd9JHtraW5kfWApKTtcbn1cbmNvbnN0IG91dHJvaW5nID0gbmV3IFNldCgpO1xubGV0IG91dHJvcztcbmZ1bmN0aW9uIGdyb3VwX291dHJvcygpIHtcbiAgICBvdXRyb3MgPSB7XG4gICAgICAgIHI6IDAsXG4gICAgICAgIGM6IFtdLFxuICAgICAgICBwOiBvdXRyb3MgLy8gcGFyZW50IGdyb3VwXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNoZWNrX291dHJvcygpIHtcbiAgICBpZiAoIW91dHJvcy5yKSB7XG4gICAgICAgIHJ1bl9hbGwob3V0cm9zLmMpO1xuICAgIH1cbiAgICBvdXRyb3MgPSBvdXRyb3MucDtcbn1cbmZ1bmN0aW9uIHRyYW5zaXRpb25faW4oYmxvY2ssIGxvY2FsKSB7XG4gICAgaWYgKGJsb2NrICYmIGJsb2NrLmkpIHtcbiAgICAgICAgb3V0cm9pbmcuZGVsZXRlKGJsb2NrKTtcbiAgICAgICAgYmxvY2suaShsb2NhbCk7XG4gICAgfVxufVxuZnVuY3Rpb24gdHJhbnNpdGlvbl9vdXQoYmxvY2ssIGxvY2FsLCBkZXRhY2gsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGJsb2NrICYmIGJsb2NrLm8pIHtcbiAgICAgICAgaWYgKG91dHJvaW5nLmhhcyhibG9jaykpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIG91dHJvaW5nLmFkZChibG9jayk7XG4gICAgICAgIG91dHJvcy5jLnB1c2goKCkgPT4ge1xuICAgICAgICAgICAgb3V0cm9pbmcuZGVsZXRlKGJsb2NrKTtcbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChkZXRhY2gpXG4gICAgICAgICAgICAgICAgICAgIGJsb2NrLmQoMSk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGJsb2NrLm8obG9jYWwpO1xuICAgIH1cbn1cbmNvbnN0IG51bGxfdHJhbnNpdGlvbiA9IHsgZHVyYXRpb246IDAgfTtcbmZ1bmN0aW9uIGNyZWF0ZV9pbl90cmFuc2l0aW9uKG5vZGUsIGZuLCBwYXJhbXMpIHtcbiAgICBsZXQgY29uZmlnID0gZm4obm9kZSwgcGFyYW1zKTtcbiAgICBsZXQgcnVubmluZyA9IGZhbHNlO1xuICAgIGxldCBhbmltYXRpb25fbmFtZTtcbiAgICBsZXQgdGFzaztcbiAgICBsZXQgdWlkID0gMDtcbiAgICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgICAgICBpZiAoYW5pbWF0aW9uX25hbWUpXG4gICAgICAgICAgICBkZWxldGVfcnVsZShub2RlLCBhbmltYXRpb25fbmFtZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGdvKCkge1xuICAgICAgICBjb25zdCB7IGRlbGF5ID0gMCwgZHVyYXRpb24gPSAzMDAsIGVhc2luZyA9IGlkZW50aXR5LCB0aWNrID0gbm9vcCwgY3NzIH0gPSBjb25maWcgfHwgbnVsbF90cmFuc2l0aW9uO1xuICAgICAgICBpZiAoY3NzKVxuICAgICAgICAgICAgYW5pbWF0aW9uX25hbWUgPSBjcmVhdGVfcnVsZShub2RlLCAwLCAxLCBkdXJhdGlvbiwgZGVsYXksIGVhc2luZywgY3NzLCB1aWQrKyk7XG4gICAgICAgIHRpY2soMCwgMSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0X3RpbWUgPSBub3coKSArIGRlbGF5O1xuICAgICAgICBjb25zdCBlbmRfdGltZSA9IHN0YXJ0X3RpbWUgKyBkdXJhdGlvbjtcbiAgICAgICAgaWYgKHRhc2spXG4gICAgICAgICAgICB0YXNrLmFib3J0KCk7XG4gICAgICAgIHJ1bm5pbmcgPSB0cnVlO1xuICAgICAgICBhZGRfcmVuZGVyX2NhbGxiYWNrKCgpID0+IGRpc3BhdGNoKG5vZGUsIHRydWUsICdzdGFydCcpKTtcbiAgICAgICAgdGFzayA9IGxvb3Aobm93ID0+IHtcbiAgICAgICAgICAgIGlmIChydW5uaW5nKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vdyA+PSBlbmRfdGltZSkge1xuICAgICAgICAgICAgICAgICAgICB0aWNrKDEsIDApO1xuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaChub2RlLCB0cnVlLCAnZW5kJyk7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5vdyA+PSBzdGFydF90aW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHQgPSBlYXNpbmcoKG5vdyAtIHN0YXJ0X3RpbWUpIC8gZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB0aWNrKHQsIDEgLSB0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcnVubmluZztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGxldCBzdGFydGVkID0gZmFsc2U7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnQoKSB7XG4gICAgICAgICAgICBpZiAoc3RhcnRlZClcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBkZWxldGVfcnVsZShub2RlKTtcbiAgICAgICAgICAgIGlmIChpc19mdW5jdGlvbihjb25maWcpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnID0gY29uZmlnKCk7XG4gICAgICAgICAgICAgICAgd2FpdCgpLnRoZW4oZ28pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZ28oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgaW52YWxpZGF0ZSgpIHtcbiAgICAgICAgICAgIHN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgICAgZW5kKCkge1xuICAgICAgICAgICAgaWYgKHJ1bm5pbmcpIHtcbiAgICAgICAgICAgICAgICBjbGVhbnVwKCk7XG4gICAgICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZV9vdXRfdHJhbnNpdGlvbihub2RlLCBmbiwgcGFyYW1zKSB7XG4gICAgbGV0IGNvbmZpZyA9IGZuKG5vZGUsIHBhcmFtcyk7XG4gICAgbGV0IHJ1bm5pbmcgPSB0cnVlO1xuICAgIGxldCBhbmltYXRpb25fbmFtZTtcbiAgICBjb25zdCBncm91cCA9IG91dHJvcztcbiAgICBncm91cC5yICs9IDE7XG4gICAgZnVuY3Rpb24gZ28oKSB7XG4gICAgICAgIGNvbnN0IHsgZGVsYXkgPSAwLCBkdXJhdGlvbiA9IDMwMCwgZWFzaW5nID0gaWRlbnRpdHksIHRpY2sgPSBub29wLCBjc3MgfSA9IGNvbmZpZyB8fCBudWxsX3RyYW5zaXRpb247XG4gICAgICAgIGlmIChjc3MpXG4gICAgICAgICAgICBhbmltYXRpb25fbmFtZSA9IGNyZWF0ZV9ydWxlKG5vZGUsIDEsIDAsIGR1cmF0aW9uLCBkZWxheSwgZWFzaW5nLCBjc3MpO1xuICAgICAgICBjb25zdCBzdGFydF90aW1lID0gbm93KCkgKyBkZWxheTtcbiAgICAgICAgY29uc3QgZW5kX3RpbWUgPSBzdGFydF90aW1lICsgZHVyYXRpb247XG4gICAgICAgIGFkZF9yZW5kZXJfY2FsbGJhY2soKCkgPT4gZGlzcGF0Y2gobm9kZSwgZmFsc2UsICdzdGFydCcpKTtcbiAgICAgICAgbG9vcChub3cgPT4ge1xuICAgICAgICAgICAgaWYgKHJ1bm5pbmcpIHtcbiAgICAgICAgICAgICAgICBpZiAobm93ID49IGVuZF90aW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpY2soMCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoKG5vZGUsIGZhbHNlLCAnZW5kJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghLS1ncm91cC5yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzIHdpbGwgcmVzdWx0IGluIGBlbmQoKWAgYmVpbmcgY2FsbGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gd2UgZG9uJ3QgbmVlZCB0byBjbGVhbiB1cCBoZXJlXG4gICAgICAgICAgICAgICAgICAgICAgICBydW5fYWxsKGdyb3VwLmMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5vdyA+PSBzdGFydF90aW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHQgPSBlYXNpbmcoKG5vdyAtIHN0YXJ0X3RpbWUpIC8gZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB0aWNrKDEgLSB0LCB0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcnVubmluZztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChpc19mdW5jdGlvbihjb25maWcpKSB7XG4gICAgICAgIHdhaXQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbmZpZyA9IGNvbmZpZygpO1xuICAgICAgICAgICAgZ28oKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBnbygpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBlbmQocmVzZXQpIHtcbiAgICAgICAgICAgIGlmIChyZXNldCAmJiBjb25maWcudGljaykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy50aWNrKDEsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJ1bm5pbmcpIHtcbiAgICAgICAgICAgICAgICBpZiAoYW5pbWF0aW9uX25hbWUpXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZV9ydWxlKG5vZGUsIGFuaW1hdGlvbl9uYW1lKTtcbiAgICAgICAgICAgICAgICBydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufVxuZnVuY3Rpb24gY3JlYXRlX2JpZGlyZWN0aW9uYWxfdHJhbnNpdGlvbihub2RlLCBmbiwgcGFyYW1zLCBpbnRybykge1xuICAgIGxldCBjb25maWcgPSBmbihub2RlLCBwYXJhbXMpO1xuICAgIGxldCB0ID0gaW50cm8gPyAwIDogMTtcbiAgICBsZXQgcnVubmluZ19wcm9ncmFtID0gbnVsbDtcbiAgICBsZXQgcGVuZGluZ19wcm9ncmFtID0gbnVsbDtcbiAgICBsZXQgYW5pbWF0aW9uX25hbWUgPSBudWxsO1xuICAgIGZ1bmN0aW9uIGNsZWFyX2FuaW1hdGlvbigpIHtcbiAgICAgICAgaWYgKGFuaW1hdGlvbl9uYW1lKVxuICAgICAgICAgICAgZGVsZXRlX3J1bGUobm9kZSwgYW5pbWF0aW9uX25hbWUpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbml0KHByb2dyYW0sIGR1cmF0aW9uKSB7XG4gICAgICAgIGNvbnN0IGQgPSBwcm9ncmFtLmIgLSB0O1xuICAgICAgICBkdXJhdGlvbiAqPSBNYXRoLmFicyhkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGE6IHQsXG4gICAgICAgICAgICBiOiBwcm9ncmFtLmIsXG4gICAgICAgICAgICBkLFxuICAgICAgICAgICAgZHVyYXRpb24sXG4gICAgICAgICAgICBzdGFydDogcHJvZ3JhbS5zdGFydCxcbiAgICAgICAgICAgIGVuZDogcHJvZ3JhbS5zdGFydCArIGR1cmF0aW9uLFxuICAgICAgICAgICAgZ3JvdXA6IHByb2dyYW0uZ3JvdXBcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ28oYikge1xuICAgICAgICBjb25zdCB7IGRlbGF5ID0gMCwgZHVyYXRpb24gPSAzMDAsIGVhc2luZyA9IGlkZW50aXR5LCB0aWNrID0gbm9vcCwgY3NzIH0gPSBjb25maWcgfHwgbnVsbF90cmFuc2l0aW9uO1xuICAgICAgICBjb25zdCBwcm9ncmFtID0ge1xuICAgICAgICAgICAgc3RhcnQ6IG5vdygpICsgZGVsYXksXG4gICAgICAgICAgICBiXG4gICAgICAgIH07XG4gICAgICAgIGlmICghYikge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZSB0b2RvOiBpbXByb3ZlIHR5cGluZ3NcbiAgICAgICAgICAgIHByb2dyYW0uZ3JvdXAgPSBvdXRyb3M7XG4gICAgICAgICAgICBvdXRyb3MuciArPSAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChydW5uaW5nX3Byb2dyYW0pIHtcbiAgICAgICAgICAgIHBlbmRpbmdfcHJvZ3JhbSA9IHByb2dyYW07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGFuIGludHJvLCBhbmQgdGhlcmUncyBhIGRlbGF5LCB3ZSBuZWVkIHRvIGRvXG4gICAgICAgICAgICAvLyBhbiBpbml0aWFsIHRpY2sgYW5kL29yIGFwcGx5IENTUyBhbmltYXRpb24gaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIGlmIChjc3MpIHtcbiAgICAgICAgICAgICAgICBjbGVhcl9hbmltYXRpb24oKTtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25fbmFtZSA9IGNyZWF0ZV9ydWxlKG5vZGUsIHQsIGIsIGR1cmF0aW9uLCBkZWxheSwgZWFzaW5nLCBjc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGIpXG4gICAgICAgICAgICAgICAgdGljaygwLCAxKTtcbiAgICAgICAgICAgIHJ1bm5pbmdfcHJvZ3JhbSA9IGluaXQocHJvZ3JhbSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgYWRkX3JlbmRlcl9jYWxsYmFjaygoKSA9PiBkaXNwYXRjaChub2RlLCBiLCAnc3RhcnQnKSk7XG4gICAgICAgICAgICBsb29wKG5vdyA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBlbmRpbmdfcHJvZ3JhbSAmJiBub3cgPiBwZW5kaW5nX3Byb2dyYW0uc3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcnVubmluZ19wcm9ncmFtID0gaW5pdChwZW5kaW5nX3Byb2dyYW0sIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ19wcm9ncmFtID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2gobm9kZSwgcnVubmluZ19wcm9ncmFtLmIsICdzdGFydCcpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGVhcl9hbmltYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbl9uYW1lID0gY3JlYXRlX3J1bGUobm9kZSwgdCwgcnVubmluZ19wcm9ncmFtLmIsIHJ1bm5pbmdfcHJvZ3JhbS5kdXJhdGlvbiwgMCwgZWFzaW5nLCBjb25maWcuY3NzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocnVubmluZ19wcm9ncmFtKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub3cgPj0gcnVubmluZ19wcm9ncmFtLmVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGljayh0ID0gcnVubmluZ19wcm9ncmFtLmIsIDEgLSB0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoKG5vZGUsIHJ1bm5pbmdfcHJvZ3JhbS5iLCAnZW5kJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXBlbmRpbmdfcHJvZ3JhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlJ3JlIGRvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocnVubmluZ19wcm9ncmFtLmIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW50cm8g4oCUIHdlIGNhbiB0aWR5IHVwIGltbWVkaWF0ZWx5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyX2FuaW1hdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3V0cm8g4oCUIG5lZWRzIHRvIGJlIGNvb3JkaW5hdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghLS1ydW5uaW5nX3Byb2dyYW0uZ3JvdXAucilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bl9hbGwocnVubmluZ19wcm9ncmFtLmdyb3VwLmMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5pbmdfcHJvZ3JhbSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobm93ID49IHJ1bm5pbmdfcHJvZ3JhbS5zdGFydCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcCA9IG5vdyAtIHJ1bm5pbmdfcHJvZ3JhbS5zdGFydDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHQgPSBydW5uaW5nX3Byb2dyYW0uYSArIHJ1bm5pbmdfcHJvZ3JhbS5kICogZWFzaW5nKHAgLyBydW5uaW5nX3Byb2dyYW0uZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGljayh0LCAxIC0gdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuICEhKHJ1bm5pbmdfcHJvZ3JhbSB8fCBwZW5kaW5nX3Byb2dyYW0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcnVuKGIpIHtcbiAgICAgICAgICAgIGlmIChpc19mdW5jdGlvbihjb25maWcpKSB7XG4gICAgICAgICAgICAgICAgd2FpdCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZyA9IGNvbmZpZygpO1xuICAgICAgICAgICAgICAgICAgICBnbyhiKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGdvKGIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlbmQoKSB7XG4gICAgICAgICAgICBjbGVhcl9hbmltYXRpb24oKTtcbiAgICAgICAgICAgIHJ1bm5pbmdfcHJvZ3JhbSA9IHBlbmRpbmdfcHJvZ3JhbSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5mdW5jdGlvbiBoYW5kbGVfcHJvbWlzZShwcm9taXNlLCBpbmZvKSB7XG4gICAgY29uc3QgdG9rZW4gPSBpbmZvLnRva2VuID0ge307XG4gICAgZnVuY3Rpb24gdXBkYXRlKHR5cGUsIGluZGV4LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChpbmZvLnRva2VuICE9PSB0b2tlbilcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaW5mby5yZXNvbHZlZCA9IHZhbHVlO1xuICAgICAgICBsZXQgY2hpbGRfY3R4ID0gaW5mby5jdHg7XG4gICAgICAgIGlmIChrZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY2hpbGRfY3R4ID0gY2hpbGRfY3R4LnNsaWNlKCk7XG4gICAgICAgICAgICBjaGlsZF9jdHhba2V5XSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJsb2NrID0gdHlwZSAmJiAoaW5mby5jdXJyZW50ID0gdHlwZSkoY2hpbGRfY3R4KTtcbiAgICAgICAgbGV0IG5lZWRzX2ZsdXNoID0gZmFsc2U7XG4gICAgICAgIGlmIChpbmZvLmJsb2NrKSB7XG4gICAgICAgICAgICBpZiAoaW5mby5ibG9ja3MpIHtcbiAgICAgICAgICAgICAgICBpbmZvLmJsb2Nrcy5mb3JFYWNoKChibG9jaywgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPT0gaW5kZXggJiYgYmxvY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX291dHJvcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvbl9vdXQoYmxvY2ssIDEsIDEsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvLmJsb2Nrc1tpXSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrX291dHJvcygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbmZvLmJsb2NrLmQoMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBibG9jay5jKCk7XG4gICAgICAgICAgICB0cmFuc2l0aW9uX2luKGJsb2NrLCAxKTtcbiAgICAgICAgICAgIGJsb2NrLm0oaW5mby5tb3VudCgpLCBpbmZvLmFuY2hvcik7XG4gICAgICAgICAgICBuZWVkc19mbHVzaCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaW5mby5ibG9jayA9IGJsb2NrO1xuICAgICAgICBpZiAoaW5mby5ibG9ja3MpXG4gICAgICAgICAgICBpbmZvLmJsb2Nrc1tpbmRleF0gPSBibG9jaztcbiAgICAgICAgaWYgKG5lZWRzX2ZsdXNoKSB7XG4gICAgICAgICAgICBmbHVzaCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc19wcm9taXNlKHByb21pc2UpKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRfY29tcG9uZW50ID0gZ2V0X2N1cnJlbnRfY29tcG9uZW50KCk7XG4gICAgICAgIHByb21pc2UudGhlbih2YWx1ZSA9PiB7XG4gICAgICAgICAgICBzZXRfY3VycmVudF9jb21wb25lbnQoY3VycmVudF9jb21wb25lbnQpO1xuICAgICAgICAgICAgdXBkYXRlKGluZm8udGhlbiwgMSwgaW5mby52YWx1ZSwgdmFsdWUpO1xuICAgICAgICAgICAgc2V0X2N1cnJlbnRfY29tcG9uZW50KG51bGwpO1xuICAgICAgICB9LCBlcnJvciA9PiB7XG4gICAgICAgICAgICBpZiAoIWluZm8uaGFzQ2F0Y2gpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNldF9jdXJyZW50X2NvbXBvbmVudChjdXJyZW50X2NvbXBvbmVudCk7XG4gICAgICAgICAgICB1cGRhdGUoaW5mby5jYXRjaCwgMiwgaW5mby5lcnJvciwgZXJyb3IpO1xuICAgICAgICAgICAgc2V0X2N1cnJlbnRfY29tcG9uZW50KG51bGwpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gaWYgd2UgcHJldmlvdXNseSBoYWQgYSB0aGVuL2NhdGNoIGJsb2NrLCBkZXN0cm95IGl0XG4gICAgICAgIGlmIChpbmZvLmN1cnJlbnQgIT09IGluZm8ucGVuZGluZykge1xuICAgICAgICAgICAgdXBkYXRlKGluZm8ucGVuZGluZywgMCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKGluZm8uY3VycmVudCAhPT0gaW5mby50aGVuKSB7XG4gICAgICAgICAgICB1cGRhdGUoaW5mby50aGVuLCAxLCBpbmZvLnZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGluZm8ucmVzb2x2ZWQgPSBwcm9taXNlO1xuICAgIH1cbn1cblxuY29uc3QgZ2xvYmFscyA9ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgID8gd2luZG93XG4gICAgOiB0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgPyBnbG9iYWxUaGlzXG4gICAgICAgIDogZ2xvYmFsKTtcblxuZnVuY3Rpb24gZGVzdHJveV9ibG9jayhibG9jaywgbG9va3VwKSB7XG4gICAgYmxvY2suZCgxKTtcbiAgICBsb29rdXAuZGVsZXRlKGJsb2NrLmtleSk7XG59XG5mdW5jdGlvbiBvdXRyb19hbmRfZGVzdHJveV9ibG9jayhibG9jaywgbG9va3VwKSB7XG4gICAgdHJhbnNpdGlvbl9vdXQoYmxvY2ssIDEsIDEsICgpID0+IHtcbiAgICAgICAgbG9va3VwLmRlbGV0ZShibG9jay5rZXkpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gZml4X2FuZF9kZXN0cm95X2Jsb2NrKGJsb2NrLCBsb29rdXApIHtcbiAgICBibG9jay5mKCk7XG4gICAgZGVzdHJveV9ibG9jayhibG9jaywgbG9va3VwKTtcbn1cbmZ1bmN0aW9uIGZpeF9hbmRfb3V0cm9fYW5kX2Rlc3Ryb3lfYmxvY2soYmxvY2ssIGxvb2t1cCkge1xuICAgIGJsb2NrLmYoKTtcbiAgICBvdXRyb19hbmRfZGVzdHJveV9ibG9jayhibG9jaywgbG9va3VwKTtcbn1cbmZ1bmN0aW9uIHVwZGF0ZV9rZXllZF9lYWNoKG9sZF9ibG9ja3MsIGRpcnR5LCBnZXRfa2V5LCBkeW5hbWljLCBjdHgsIGxpc3QsIGxvb2t1cCwgbm9kZSwgZGVzdHJveSwgY3JlYXRlX2VhY2hfYmxvY2ssIG5leHQsIGdldF9jb250ZXh0KSB7XG4gICAgbGV0IG8gPSBvbGRfYmxvY2tzLmxlbmd0aDtcbiAgICBsZXQgbiA9IGxpc3QubGVuZ3RoO1xuICAgIGxldCBpID0gbztcbiAgICBjb25zdCBvbGRfaW5kZXhlcyA9IHt9O1xuICAgIHdoaWxlIChpLS0pXG4gICAgICAgIG9sZF9pbmRleGVzW29sZF9ibG9ja3NbaV0ua2V5XSA9IGk7XG4gICAgY29uc3QgbmV3X2Jsb2NrcyA9IFtdO1xuICAgIGNvbnN0IG5ld19sb29rdXAgPSBuZXcgTWFwKCk7XG4gICAgY29uc3QgZGVsdGFzID0gbmV3IE1hcCgpO1xuICAgIGkgPSBuO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgY29uc3QgY2hpbGRfY3R4ID0gZ2V0X2NvbnRleHQoY3R4LCBsaXN0LCBpKTtcbiAgICAgICAgY29uc3Qga2V5ID0gZ2V0X2tleShjaGlsZF9jdHgpO1xuICAgICAgICBsZXQgYmxvY2sgPSBsb29rdXAuZ2V0KGtleSk7XG4gICAgICAgIGlmICghYmxvY2spIHtcbiAgICAgICAgICAgIGJsb2NrID0gY3JlYXRlX2VhY2hfYmxvY2soa2V5LCBjaGlsZF9jdHgpO1xuICAgICAgICAgICAgYmxvY2suYygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGR5bmFtaWMpIHtcbiAgICAgICAgICAgIGJsb2NrLnAoY2hpbGRfY3R4LCBkaXJ0eSk7XG4gICAgICAgIH1cbiAgICAgICAgbmV3X2xvb2t1cC5zZXQoa2V5LCBuZXdfYmxvY2tzW2ldID0gYmxvY2spO1xuICAgICAgICBpZiAoa2V5IGluIG9sZF9pbmRleGVzKVxuICAgICAgICAgICAgZGVsdGFzLnNldChrZXksIE1hdGguYWJzKGkgLSBvbGRfaW5kZXhlc1trZXldKSk7XG4gICAgfVxuICAgIGNvbnN0IHdpbGxfbW92ZSA9IG5ldyBTZXQoKTtcbiAgICBjb25zdCBkaWRfbW92ZSA9IG5ldyBTZXQoKTtcbiAgICBmdW5jdGlvbiBpbnNlcnQoYmxvY2spIHtcbiAgICAgICAgdHJhbnNpdGlvbl9pbihibG9jaywgMSk7XG4gICAgICAgIGJsb2NrLm0obm9kZSwgbmV4dCk7XG4gICAgICAgIGxvb2t1cC5zZXQoYmxvY2sua2V5LCBibG9jayk7XG4gICAgICAgIG5leHQgPSBibG9jay5maXJzdDtcbiAgICAgICAgbi0tO1xuICAgIH1cbiAgICB3aGlsZSAobyAmJiBuKSB7XG4gICAgICAgIGNvbnN0IG5ld19ibG9jayA9IG5ld19ibG9ja3NbbiAtIDFdO1xuICAgICAgICBjb25zdCBvbGRfYmxvY2sgPSBvbGRfYmxvY2tzW28gLSAxXTtcbiAgICAgICAgY29uc3QgbmV3X2tleSA9IG5ld19ibG9jay5rZXk7XG4gICAgICAgIGNvbnN0IG9sZF9rZXkgPSBvbGRfYmxvY2sua2V5O1xuICAgICAgICBpZiAobmV3X2Jsb2NrID09PSBvbGRfYmxvY2spIHtcbiAgICAgICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgICAgICAgIG5leHQgPSBuZXdfYmxvY2suZmlyc3Q7XG4gICAgICAgICAgICBvLS07XG4gICAgICAgICAgICBuLS07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIW5ld19sb29rdXAuaGFzKG9sZF9rZXkpKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgb2xkIGJsb2NrXG4gICAgICAgICAgICBkZXN0cm95KG9sZF9ibG9jaywgbG9va3VwKTtcbiAgICAgICAgICAgIG8tLTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghbG9va3VwLmhhcyhuZXdfa2V5KSB8fCB3aWxsX21vdmUuaGFzKG5ld19rZXkpKSB7XG4gICAgICAgICAgICBpbnNlcnQobmV3X2Jsb2NrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkaWRfbW92ZS5oYXMob2xkX2tleSkpIHtcbiAgICAgICAgICAgIG8tLTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZWx0YXMuZ2V0KG5ld19rZXkpID4gZGVsdGFzLmdldChvbGRfa2V5KSkge1xuICAgICAgICAgICAgZGlkX21vdmUuYWRkKG5ld19rZXkpO1xuICAgICAgICAgICAgaW5zZXJ0KG5ld19ibG9jayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3aWxsX21vdmUuYWRkKG9sZF9rZXkpO1xuICAgICAgICAgICAgby0tO1xuICAgICAgICB9XG4gICAgfVxuICAgIHdoaWxlIChvLS0pIHtcbiAgICAgICAgY29uc3Qgb2xkX2Jsb2NrID0gb2xkX2Jsb2Nrc1tvXTtcbiAgICAgICAgaWYgKCFuZXdfbG9va3VwLmhhcyhvbGRfYmxvY2sua2V5KSlcbiAgICAgICAgICAgIGRlc3Ryb3kob2xkX2Jsb2NrLCBsb29rdXApO1xuICAgIH1cbiAgICB3aGlsZSAobilcbiAgICAgICAgaW5zZXJ0KG5ld19ibG9ja3NbbiAtIDFdKTtcbiAgICByZXR1cm4gbmV3X2Jsb2Nrcztcbn1cbmZ1bmN0aW9uIHZhbGlkYXRlX2VhY2hfa2V5cyhjdHgsIGxpc3QsIGdldF9jb250ZXh0LCBnZXRfa2V5KSB7XG4gICAgY29uc3Qga2V5cyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qga2V5ID0gZ2V0X2tleShnZXRfY29udGV4dChjdHgsIGxpc3QsIGkpKTtcbiAgICAgICAgaWYgKGtleXMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGhhdmUgZHVwbGljYXRlIGtleXMgaW4gYSBrZXllZCBlYWNoYCk7XG4gICAgICAgIH1cbiAgICAgICAga2V5cy5hZGQoa2V5KTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldF9zcHJlYWRfdXBkYXRlKGxldmVscywgdXBkYXRlcykge1xuICAgIGNvbnN0IHVwZGF0ZSA9IHt9O1xuICAgIGNvbnN0IHRvX251bGxfb3V0ID0ge307XG4gICAgY29uc3QgYWNjb3VudGVkX2ZvciA9IHsgJCRzY29wZTogMSB9O1xuICAgIGxldCBpID0gbGV2ZWxzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIGNvbnN0IG8gPSBsZXZlbHNbaV07XG4gICAgICAgIGNvbnN0IG4gPSB1cGRhdGVzW2ldO1xuICAgICAgICBpZiAobikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbykge1xuICAgICAgICAgICAgICAgIGlmICghKGtleSBpbiBuKSlcbiAgICAgICAgICAgICAgICAgICAgdG9fbnVsbF9vdXRba2V5XSA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBuKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFhY2NvdW50ZWRfZm9yW2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlW2tleV0gPSBuW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGFjY291bnRlZF9mb3Jba2V5XSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV2ZWxzW2ldID0gbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIG8pIHtcbiAgICAgICAgICAgICAgICBhY2NvdW50ZWRfZm9yW2tleV0gPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IGluIHRvX251bGxfb3V0KSB7XG4gICAgICAgIGlmICghKGtleSBpbiB1cGRhdGUpKVxuICAgICAgICAgICAgdXBkYXRlW2tleV0gPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB1cGRhdGU7XG59XG5mdW5jdGlvbiBnZXRfc3ByZWFkX29iamVjdChzcHJlYWRfcHJvcHMpIHtcbiAgICByZXR1cm4gdHlwZW9mIHNwcmVhZF9wcm9wcyA9PT0gJ29iamVjdCcgJiYgc3ByZWFkX3Byb3BzICE9PSBudWxsID8gc3ByZWFkX3Byb3BzIDoge307XG59XG5cbi8vIHNvdXJjZTogaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvaW5kaWNlcy5odG1sXG5jb25zdCBib29sZWFuX2F0dHJpYnV0ZXMgPSBuZXcgU2V0KFtcbiAgICAnYWxsb3dmdWxsc2NyZWVuJyxcbiAgICAnYWxsb3dwYXltZW50cmVxdWVzdCcsXG4gICAgJ2FzeW5jJyxcbiAgICAnYXV0b2ZvY3VzJyxcbiAgICAnYXV0b3BsYXknLFxuICAgICdjaGVja2VkJyxcbiAgICAnY29udHJvbHMnLFxuICAgICdkZWZhdWx0JyxcbiAgICAnZGVmZXInLFxuICAgICdkaXNhYmxlZCcsXG4gICAgJ2Zvcm1ub3ZhbGlkYXRlJyxcbiAgICAnaGlkZGVuJyxcbiAgICAnaXNtYXAnLFxuICAgICdsb29wJyxcbiAgICAnbXVsdGlwbGUnLFxuICAgICdtdXRlZCcsXG4gICAgJ25vbW9kdWxlJyxcbiAgICAnbm92YWxpZGF0ZScsXG4gICAgJ29wZW4nLFxuICAgICdwbGF5c2lubGluZScsXG4gICAgJ3JlYWRvbmx5JyxcbiAgICAncmVxdWlyZWQnLFxuICAgICdyZXZlcnNlZCcsXG4gICAgJ3NlbGVjdGVkJ1xuXSk7XG5cbmNvbnN0IGludmFsaWRfYXR0cmlidXRlX25hbWVfY2hhcmFjdGVyID0gL1tcXHMnXCI+Lz1cXHV7RkREMH0tXFx1e0ZERUZ9XFx1e0ZGRkV9XFx1e0ZGRkZ9XFx1ezFGRkZFfVxcdXsxRkZGRn1cXHV7MkZGRkV9XFx1ezJGRkZGfVxcdXszRkZGRX1cXHV7M0ZGRkZ9XFx1ezRGRkZFfVxcdXs0RkZGRn1cXHV7NUZGRkV9XFx1ezVGRkZGfVxcdXs2RkZGRX1cXHV7NkZGRkZ9XFx1ezdGRkZFfVxcdXs3RkZGRn1cXHV7OEZGRkV9XFx1ezhGRkZGfVxcdXs5RkZGRX1cXHV7OUZGRkZ9XFx1e0FGRkZFfVxcdXtBRkZGRn1cXHV7QkZGRkV9XFx1e0JGRkZGfVxcdXtDRkZGRX1cXHV7Q0ZGRkZ9XFx1e0RGRkZFfVxcdXtERkZGRn1cXHV7RUZGRkV9XFx1e0VGRkZGfVxcdXtGRkZGRX1cXHV7RkZGRkZ9XFx1ezEwRkZGRX1cXHV7MTBGRkZGfV0vdTtcbi8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL3N5bnRheC5odG1sI2F0dHJpYnV0ZXMtMlxuLy8gaHR0cHM6Ly9pbmZyYS5zcGVjLndoYXR3Zy5vcmcvI25vbmNoYXJhY3RlclxuZnVuY3Rpb24gc3ByZWFkKGFyZ3MsIGNsYXNzZXNfdG9fYWRkKSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IE9iamVjdC5hc3NpZ24oe30sIC4uLmFyZ3MpO1xuICAgIGlmIChjbGFzc2VzX3RvX2FkZCkge1xuICAgICAgICBpZiAoYXR0cmlidXRlcy5jbGFzcyA9PSBudWxsKSB7XG4gICAgICAgICAgICBhdHRyaWJ1dGVzLmNsYXNzID0gY2xhc3Nlc190b19hZGQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhdHRyaWJ1dGVzLmNsYXNzICs9ICcgJyArIGNsYXNzZXNfdG9fYWRkO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBzdHIgPSAnJztcbiAgICBPYmplY3Qua2V5cyhhdHRyaWJ1dGVzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgICBpZiAoaW52YWxpZF9hdHRyaWJ1dGVfbmFtZV9jaGFyYWN0ZXIudGVzdChuYW1lKSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBhdHRyaWJ1dGVzW25hbWVdO1xuICAgICAgICBpZiAodmFsdWUgPT09IHRydWUpXG4gICAgICAgICAgICBzdHIgKz0gXCIgXCIgKyBuYW1lO1xuICAgICAgICBlbHNlIGlmIChib29sZWFuX2F0dHJpYnV0ZXMuaGFzKG5hbWUudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSlcbiAgICAgICAgICAgICAgICBzdHIgKz0gXCIgXCIgKyBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHN0ciArPSBgICR7bmFtZX09XCIke1N0cmluZyh2YWx1ZSkucmVwbGFjZSgvXCIvZywgJyYjMzQ7JykucmVwbGFjZSgvJy9nLCAnJiMzOTsnKX1cImA7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gc3RyO1xufVxuY29uc3QgZXNjYXBlZCA9IHtcbiAgICAnXCInOiAnJnF1b3Q7JyxcbiAgICBcIidcIjogJyYjMzk7JyxcbiAgICAnJic6ICcmYW1wOycsXG4gICAgJzwnOiAnJmx0OycsXG4gICAgJz4nOiAnJmd0Oydcbn07XG5mdW5jdGlvbiBlc2NhcGUoaHRtbCkge1xuICAgIHJldHVybiBTdHJpbmcoaHRtbCkucmVwbGFjZSgvW1wiJyY8Pl0vZywgbWF0Y2ggPT4gZXNjYXBlZFttYXRjaF0pO1xufVxuZnVuY3Rpb24gZWFjaChpdGVtcywgZm4pIHtcbiAgICBsZXQgc3RyID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBzdHIgKz0gZm4oaXRlbXNbaV0sIGkpO1xuICAgIH1cbiAgICByZXR1cm4gc3RyO1xufVxuY29uc3QgbWlzc2luZ19jb21wb25lbnQgPSB7XG4gICAgJCRyZW5kZXI6ICgpID0+ICcnXG59O1xuZnVuY3Rpb24gdmFsaWRhdGVfY29tcG9uZW50KGNvbXBvbmVudCwgbmFtZSkge1xuICAgIGlmICghY29tcG9uZW50IHx8ICFjb21wb25lbnQuJCRyZW5kZXIpIHtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdzdmVsdGU6Y29tcG9uZW50JylcbiAgICAgICAgICAgIG5hbWUgKz0gJyB0aGlzPXsuLi59JztcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGA8JHtuYW1lfT4gaXMgbm90IGEgdmFsaWQgU1NSIGNvbXBvbmVudC4gWW91IG1heSBuZWVkIHRvIHJldmlldyB5b3VyIGJ1aWxkIGNvbmZpZyB0byBlbnN1cmUgdGhhdCBkZXBlbmRlbmNpZXMgYXJlIGNvbXBpbGVkLCByYXRoZXIgdGhhbiBpbXBvcnRlZCBhcyBwcmUtY29tcGlsZWQgbW9kdWxlc2ApO1xuICAgIH1cbiAgICByZXR1cm4gY29tcG9uZW50O1xufVxuZnVuY3Rpb24gZGVidWcoZmlsZSwgbGluZSwgY29sdW1uLCB2YWx1ZXMpIHtcbiAgICBjb25zb2xlLmxvZyhge0BkZWJ1Z30gJHtmaWxlID8gZmlsZSArICcgJyA6ICcnfSgke2xpbmV9OiR7Y29sdW1ufSlgKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2codmFsdWVzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG4gICAgcmV0dXJuICcnO1xufVxubGV0IG9uX2Rlc3Ryb3k7XG5mdW5jdGlvbiBjcmVhdGVfc3NyX2NvbXBvbmVudChmbikge1xuICAgIGZ1bmN0aW9uICQkcmVuZGVyKHJlc3VsdCwgcHJvcHMsIGJpbmRpbmdzLCBzbG90cykge1xuICAgICAgICBjb25zdCBwYXJlbnRfY29tcG9uZW50ID0gY3VycmVudF9jb21wb25lbnQ7XG4gICAgICAgIGNvbnN0ICQkID0ge1xuICAgICAgICAgICAgb25fZGVzdHJveSxcbiAgICAgICAgICAgIGNvbnRleHQ6IG5ldyBNYXAocGFyZW50X2NvbXBvbmVudCA/IHBhcmVudF9jb21wb25lbnQuJCQuY29udGV4dCA6IFtdKSxcbiAgICAgICAgICAgIC8vIHRoZXNlIHdpbGwgYmUgaW1tZWRpYXRlbHkgZGlzY2FyZGVkXG4gICAgICAgICAgICBvbl9tb3VudDogW10sXG4gICAgICAgICAgICBiZWZvcmVfdXBkYXRlOiBbXSxcbiAgICAgICAgICAgIGFmdGVyX3VwZGF0ZTogW10sXG4gICAgICAgICAgICBjYWxsYmFja3M6IGJsYW5rX29iamVjdCgpXG4gICAgICAgIH07XG4gICAgICAgIHNldF9jdXJyZW50X2NvbXBvbmVudCh7ICQkIH0pO1xuICAgICAgICBjb25zdCBodG1sID0gZm4ocmVzdWx0LCBwcm9wcywgYmluZGluZ3MsIHNsb3RzKTtcbiAgICAgICAgc2V0X2N1cnJlbnRfY29tcG9uZW50KHBhcmVudF9jb21wb25lbnQpO1xuICAgICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmVuZGVyOiAocHJvcHMgPSB7fSwgb3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgICAgICAgICBvbl9kZXN0cm95ID0gW107XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB7IHRpdGxlOiAnJywgaGVhZDogJycsIGNzczogbmV3IFNldCgpIH07XG4gICAgICAgICAgICBjb25zdCBodG1sID0gJCRyZW5kZXIocmVzdWx0LCBwcm9wcywge30sIG9wdGlvbnMpO1xuICAgICAgICAgICAgcnVuX2FsbChvbl9kZXN0cm95KTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaHRtbCxcbiAgICAgICAgICAgICAgICBjc3M6IHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogQXJyYXkuZnJvbShyZXN1bHQuY3NzKS5tYXAoY3NzID0+IGNzcy5jb2RlKS5qb2luKCdcXG4nKSxcbiAgICAgICAgICAgICAgICAgICAgbWFwOiBudWxsIC8vIFRPRE9cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGhlYWQ6IHJlc3VsdC50aXRsZSArIHJlc3VsdC5oZWFkXG4gICAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICAkJHJlbmRlclxuICAgIH07XG59XG5mdW5jdGlvbiBhZGRfYXR0cmlidXRlKG5hbWUsIHZhbHVlLCBib29sZWFuKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwgfHwgKGJvb2xlYW4gJiYgIXZhbHVlKSlcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIHJldHVybiBgICR7bmFtZX0ke3ZhbHVlID09PSB0cnVlID8gJycgOiBgPSR7dHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IEpTT04uc3RyaW5naWZ5KGVzY2FwZSh2YWx1ZSkpIDogYFwiJHt2YWx1ZX1cImB9YH1gO1xufVxuZnVuY3Rpb24gYWRkX2NsYXNzZXMoY2xhc3Nlcykge1xuICAgIHJldHVybiBjbGFzc2VzID8gYCBjbGFzcz1cIiR7Y2xhc3Nlc31cImAgOiBgYDtcbn1cblxuZnVuY3Rpb24gYmluZChjb21wb25lbnQsIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgY29uc3QgaW5kZXggPSBjb21wb25lbnQuJCQucHJvcHNbbmFtZV07XG4gICAgaWYgKGluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29tcG9uZW50LiQkLmJvdW5kW2luZGV4XSA9IGNhbGxiYWNrO1xuICAgICAgICBjYWxsYmFjayhjb21wb25lbnQuJCQuY3R4W2luZGV4XSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY3JlYXRlX2NvbXBvbmVudChibG9jaykge1xuICAgIGJsb2NrICYmIGJsb2NrLmMoKTtcbn1cbmZ1bmN0aW9uIGNsYWltX2NvbXBvbmVudChibG9jaywgcGFyZW50X25vZGVzKSB7XG4gICAgYmxvY2sgJiYgYmxvY2subChwYXJlbnRfbm9kZXMpO1xufVxuZnVuY3Rpb24gbW91bnRfY29tcG9uZW50KGNvbXBvbmVudCwgdGFyZ2V0LCBhbmNob3IpIHtcbiAgICBjb25zdCB7IGZyYWdtZW50LCBvbl9tb3VudCwgb25fZGVzdHJveSwgYWZ0ZXJfdXBkYXRlIH0gPSBjb21wb25lbnQuJCQ7XG4gICAgZnJhZ21lbnQgJiYgZnJhZ21lbnQubSh0YXJnZXQsIGFuY2hvcik7XG4gICAgLy8gb25Nb3VudCBoYXBwZW5zIGJlZm9yZSB0aGUgaW5pdGlhbCBhZnRlclVwZGF0ZVxuICAgIGFkZF9yZW5kZXJfY2FsbGJhY2soKCkgPT4ge1xuICAgICAgICBjb25zdCBuZXdfb25fZGVzdHJveSA9IG9uX21vdW50Lm1hcChydW4pLmZpbHRlcihpc19mdW5jdGlvbik7XG4gICAgICAgIGlmIChvbl9kZXN0cm95KSB7XG4gICAgICAgICAgICBvbl9kZXN0cm95LnB1c2goLi4ubmV3X29uX2Rlc3Ryb3kpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gRWRnZSBjYXNlIC0gY29tcG9uZW50IHdhcyBkZXN0cm95ZWQgaW1tZWRpYXRlbHksXG4gICAgICAgICAgICAvLyBtb3N0IGxpa2VseSBhcyBhIHJlc3VsdCBvZiBhIGJpbmRpbmcgaW5pdGlhbGlzaW5nXG4gICAgICAgICAgICBydW5fYWxsKG5ld19vbl9kZXN0cm95KTtcbiAgICAgICAgfVxuICAgICAgICBjb21wb25lbnQuJCQub25fbW91bnQgPSBbXTtcbiAgICB9KTtcbiAgICBhZnRlcl91cGRhdGUuZm9yRWFjaChhZGRfcmVuZGVyX2NhbGxiYWNrKTtcbn1cbmZ1bmN0aW9uIGRlc3Ryb3lfY29tcG9uZW50KGNvbXBvbmVudCwgZGV0YWNoaW5nKSB7XG4gICAgY29uc3QgJCQgPSBjb21wb25lbnQuJCQ7XG4gICAgaWYgKCQkLmZyYWdtZW50ICE9PSBudWxsKSB7XG4gICAgICAgIHJ1bl9hbGwoJCQub25fZGVzdHJveSk7XG4gICAgICAgICQkLmZyYWdtZW50ICYmICQkLmZyYWdtZW50LmQoZGV0YWNoaW5nKTtcbiAgICAgICAgLy8gVE9ETyBudWxsIG91dCBvdGhlciByZWZzLCBpbmNsdWRpbmcgY29tcG9uZW50LiQkIChidXQgbmVlZCB0b1xuICAgICAgICAvLyBwcmVzZXJ2ZSBmaW5hbCBzdGF0ZT8pXG4gICAgICAgICQkLm9uX2Rlc3Ryb3kgPSAkJC5mcmFnbWVudCA9IG51bGw7XG4gICAgICAgICQkLmN0eCA9IFtdO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1ha2VfZGlydHkoY29tcG9uZW50LCBpKSB7XG4gICAgaWYgKGNvbXBvbmVudC4kJC5kaXJ0eVswXSA9PT0gLTEpIHtcbiAgICAgICAgZGlydHlfY29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgICAgIHNjaGVkdWxlX3VwZGF0ZSgpO1xuICAgICAgICBjb21wb25lbnQuJCQuZGlydHkuZmlsbCgwKTtcbiAgICB9XG4gICAgY29tcG9uZW50LiQkLmRpcnR5WyhpIC8gMzEpIHwgMF0gfD0gKDEgPDwgKGkgJSAzMSkpO1xufVxuZnVuY3Rpb24gaW5pdChjb21wb25lbnQsIG9wdGlvbnMsIGluc3RhbmNlLCBjcmVhdGVfZnJhZ21lbnQsIG5vdF9lcXVhbCwgcHJvcHMsIGRpcnR5ID0gWy0xXSkge1xuICAgIGNvbnN0IHBhcmVudF9jb21wb25lbnQgPSBjdXJyZW50X2NvbXBvbmVudDtcbiAgICBzZXRfY3VycmVudF9jb21wb25lbnQoY29tcG9uZW50KTtcbiAgICBjb25zdCBwcm9wX3ZhbHVlcyA9IG9wdGlvbnMucHJvcHMgfHwge307XG4gICAgY29uc3QgJCQgPSBjb21wb25lbnQuJCQgPSB7XG4gICAgICAgIGZyYWdtZW50OiBudWxsLFxuICAgICAgICBjdHg6IG51bGwsXG4gICAgICAgIC8vIHN0YXRlXG4gICAgICAgIHByb3BzLFxuICAgICAgICB1cGRhdGU6IG5vb3AsXG4gICAgICAgIG5vdF9lcXVhbCxcbiAgICAgICAgYm91bmQ6IGJsYW5rX29iamVjdCgpLFxuICAgICAgICAvLyBsaWZlY3ljbGVcbiAgICAgICAgb25fbW91bnQ6IFtdLFxuICAgICAgICBvbl9kZXN0cm95OiBbXSxcbiAgICAgICAgYmVmb3JlX3VwZGF0ZTogW10sXG4gICAgICAgIGFmdGVyX3VwZGF0ZTogW10sXG4gICAgICAgIGNvbnRleHQ6IG5ldyBNYXAocGFyZW50X2NvbXBvbmVudCA/IHBhcmVudF9jb21wb25lbnQuJCQuY29udGV4dCA6IFtdKSxcbiAgICAgICAgLy8gZXZlcnl0aGluZyBlbHNlXG4gICAgICAgIGNhbGxiYWNrczogYmxhbmtfb2JqZWN0KCksXG4gICAgICAgIGRpcnR5LFxuICAgICAgICBza2lwX2JvdW5kOiBmYWxzZVxuICAgIH07XG4gICAgbGV0IHJlYWR5ID0gZmFsc2U7XG4gICAgJCQuY3R4ID0gaW5zdGFuY2VcbiAgICAgICAgPyBpbnN0YW5jZShjb21wb25lbnQsIHByb3BfdmFsdWVzLCAoaSwgcmV0LCAuLi5yZXN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHJlc3QubGVuZ3RoID8gcmVzdFswXSA6IHJldDtcbiAgICAgICAgICAgIGlmICgkJC5jdHggJiYgbm90X2VxdWFsKCQkLmN0eFtpXSwgJCQuY3R4W2ldID0gdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEkJC5za2lwX2JvdW5kICYmICQkLmJvdW5kW2ldKVxuICAgICAgICAgICAgICAgICAgICAkJC5ib3VuZFtpXSh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlYWR5KVxuICAgICAgICAgICAgICAgICAgICBtYWtlX2RpcnR5KGNvbXBvbmVudCwgaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9KVxuICAgICAgICA6IFtdO1xuICAgICQkLnVwZGF0ZSgpO1xuICAgIHJlYWR5ID0gdHJ1ZTtcbiAgICBydW5fYWxsKCQkLmJlZm9yZV91cGRhdGUpO1xuICAgIC8vIGBmYWxzZWAgYXMgYSBzcGVjaWFsIGNhc2Ugb2Ygbm8gRE9NIGNvbXBvbmVudFxuICAgICQkLmZyYWdtZW50ID0gY3JlYXRlX2ZyYWdtZW50ID8gY3JlYXRlX2ZyYWdtZW50KCQkLmN0eCkgOiBmYWxzZTtcbiAgICBpZiAob3B0aW9ucy50YXJnZXQpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuaHlkcmF0ZSkge1xuICAgICAgICAgICAgY29uc3Qgbm9kZXMgPSBjaGlsZHJlbihvcHRpb25zLnRhcmdldCk7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgJCQuZnJhZ21lbnQgJiYgJCQuZnJhZ21lbnQubChub2Rlcyk7XG4gICAgICAgICAgICBub2Rlcy5mb3JFYWNoKGRldGFjaCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgJCQuZnJhZ21lbnQgJiYgJCQuZnJhZ21lbnQuYygpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmludHJvKVxuICAgICAgICAgICAgdHJhbnNpdGlvbl9pbihjb21wb25lbnQuJCQuZnJhZ21lbnQpO1xuICAgICAgICBtb3VudF9jb21wb25lbnQoY29tcG9uZW50LCBvcHRpb25zLnRhcmdldCwgb3B0aW9ucy5hbmNob3IpO1xuICAgICAgICBmbHVzaCgpO1xuICAgIH1cbiAgICBzZXRfY3VycmVudF9jb21wb25lbnQocGFyZW50X2NvbXBvbmVudCk7XG59XG5sZXQgU3ZlbHRlRWxlbWVudDtcbmlmICh0eXBlb2YgSFRNTEVsZW1lbnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBTdmVsdGVFbGVtZW50ID0gY2xhc3MgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgIHRoaXMuYXR0YWNoU2hhZG93KHsgbW9kZTogJ29wZW4nIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZSB0b2RvOiBpbXByb3ZlIHR5cGluZ3NcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMuJCQuc2xvdHRlZCkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgdG9kbzogaW1wcm92ZSB0eXBpbmdzXG4gICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZCh0aGlzLiQkLnNsb3R0ZWRba2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrKGF0dHIsIF9vbGRWYWx1ZSwgbmV3VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXNbYXR0cl0gPSBuZXdWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICAkZGVzdHJveSgpIHtcbiAgICAgICAgICAgIGRlc3Ryb3lfY29tcG9uZW50KHRoaXMsIDEpO1xuICAgICAgICAgICAgdGhpcy4kZGVzdHJveSA9IG5vb3A7XG4gICAgICAgIH1cbiAgICAgICAgJG9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAvLyBUT0RPIHNob3VsZCB0aGlzIGRlbGVnYXRlIHRvIGFkZEV2ZW50TGlzdGVuZXI/XG4gICAgICAgICAgICBjb25zdCBjYWxsYmFja3MgPSAodGhpcy4kJC5jYWxsYmFja3NbdHlwZV0gfHwgKHRoaXMuJCQuY2FsbGJhY2tzW3R5cGVdID0gW10pKTtcbiAgICAgICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBjYWxsYmFja3MuaW5kZXhPZihjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSlcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgICRzZXQoJCRwcm9wcykge1xuICAgICAgICAgICAgaWYgKHRoaXMuJCRzZXQgJiYgIWlzX2VtcHR5KCQkcHJvcHMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kJC5za2lwX2JvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLiQkc2V0KCQkcHJvcHMpO1xuICAgICAgICAgICAgICAgIHRoaXMuJCQuc2tpcF9ib3VuZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn1cbmNsYXNzIFN2ZWx0ZUNvbXBvbmVudCB7XG4gICAgJGRlc3Ryb3koKSB7XG4gICAgICAgIGRlc3Ryb3lfY29tcG9uZW50KHRoaXMsIDEpO1xuICAgICAgICB0aGlzLiRkZXN0cm95ID0gbm9vcDtcbiAgICB9XG4gICAgJG9uKHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrcyA9ICh0aGlzLiQkLmNhbGxiYWNrc1t0eXBlXSB8fCAodGhpcy4kJC5jYWxsYmFja3NbdHlwZV0gPSBbXSkpO1xuICAgICAgICBjYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IGNhbGxiYWNrcy5pbmRleE9mKGNhbGxiYWNrKTtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpXG4gICAgICAgICAgICAgICAgY2FsbGJhY2tzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgICRzZXQoJCRwcm9wcykge1xuICAgICAgICBpZiAodGhpcy4kJHNldCAmJiAhaXNfZW1wdHkoJCRwcm9wcykpIHtcbiAgICAgICAgICAgIHRoaXMuJCQuc2tpcF9ib3VuZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLiQkc2V0KCQkcHJvcHMpO1xuICAgICAgICAgICAgdGhpcy4kJC5za2lwX2JvdW5kID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRpc3BhdGNoX2Rldih0eXBlLCBkZXRhaWwpIHtcbiAgICBkb2N1bWVudC5kaXNwYXRjaEV2ZW50KGN1c3RvbV9ldmVudCh0eXBlLCBPYmplY3QuYXNzaWduKHsgdmVyc2lvbjogJzMuMjUuMCcgfSwgZGV0YWlsKSkpO1xufVxuZnVuY3Rpb24gYXBwZW5kX2Rldih0YXJnZXQsIG5vZGUpIHtcbiAgICBkaXNwYXRjaF9kZXYoXCJTdmVsdGVET01JbnNlcnRcIiwgeyB0YXJnZXQsIG5vZGUgfSk7XG4gICAgYXBwZW5kKHRhcmdldCwgbm9kZSk7XG59XG5mdW5jdGlvbiBpbnNlcnRfZGV2KHRhcmdldCwgbm9kZSwgYW5jaG9yKSB7XG4gICAgZGlzcGF0Y2hfZGV2KFwiU3ZlbHRlRE9NSW5zZXJ0XCIsIHsgdGFyZ2V0LCBub2RlLCBhbmNob3IgfSk7XG4gICAgaW5zZXJ0KHRhcmdldCwgbm9kZSwgYW5jaG9yKTtcbn1cbmZ1bmN0aW9uIGRldGFjaF9kZXYobm9kZSkge1xuICAgIGRpc3BhdGNoX2RldihcIlN2ZWx0ZURPTVJlbW92ZVwiLCB7IG5vZGUgfSk7XG4gICAgZGV0YWNoKG5vZGUpO1xufVxuZnVuY3Rpb24gZGV0YWNoX2JldHdlZW5fZGV2KGJlZm9yZSwgYWZ0ZXIpIHtcbiAgICB3aGlsZSAoYmVmb3JlLm5leHRTaWJsaW5nICYmIGJlZm9yZS5uZXh0U2libGluZyAhPT0gYWZ0ZXIpIHtcbiAgICAgICAgZGV0YWNoX2RldihiZWZvcmUubmV4dFNpYmxpbmcpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGRldGFjaF9iZWZvcmVfZGV2KGFmdGVyKSB7XG4gICAgd2hpbGUgKGFmdGVyLnByZXZpb3VzU2libGluZykge1xuICAgICAgICBkZXRhY2hfZGV2KGFmdGVyLnByZXZpb3VzU2libGluZyk7XG4gICAgfVxufVxuZnVuY3Rpb24gZGV0YWNoX2FmdGVyX2RldihiZWZvcmUpIHtcbiAgICB3aGlsZSAoYmVmb3JlLm5leHRTaWJsaW5nKSB7XG4gICAgICAgIGRldGFjaF9kZXYoYmVmb3JlLm5leHRTaWJsaW5nKTtcbiAgICB9XG59XG5mdW5jdGlvbiBsaXN0ZW5fZGV2KG5vZGUsIGV2ZW50LCBoYW5kbGVyLCBvcHRpb25zLCBoYXNfcHJldmVudF9kZWZhdWx0LCBoYXNfc3RvcF9wcm9wYWdhdGlvbikge1xuICAgIGNvbnN0IG1vZGlmaWVycyA9IG9wdGlvbnMgPT09IHRydWUgPyBbXCJjYXB0dXJlXCJdIDogb3B0aW9ucyA/IEFycmF5LmZyb20oT2JqZWN0LmtleXMob3B0aW9ucykpIDogW107XG4gICAgaWYgKGhhc19wcmV2ZW50X2RlZmF1bHQpXG4gICAgICAgIG1vZGlmaWVycy5wdXNoKCdwcmV2ZW50RGVmYXVsdCcpO1xuICAgIGlmIChoYXNfc3RvcF9wcm9wYWdhdGlvbilcbiAgICAgICAgbW9kaWZpZXJzLnB1c2goJ3N0b3BQcm9wYWdhdGlvbicpO1xuICAgIGRpc3BhdGNoX2RldihcIlN2ZWx0ZURPTUFkZEV2ZW50TGlzdGVuZXJcIiwgeyBub2RlLCBldmVudCwgaGFuZGxlciwgbW9kaWZpZXJzIH0pO1xuICAgIGNvbnN0IGRpc3Bvc2UgPSBsaXN0ZW4obm9kZSwgZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGRpc3BhdGNoX2RldihcIlN2ZWx0ZURPTVJlbW92ZUV2ZW50TGlzdGVuZXJcIiwgeyBub2RlLCBldmVudCwgaGFuZGxlciwgbW9kaWZpZXJzIH0pO1xuICAgICAgICBkaXNwb3NlKCk7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGF0dHJfZGV2KG5vZGUsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgICBhdHRyKG5vZGUsIGF0dHJpYnV0ZSwgdmFsdWUpO1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKVxuICAgICAgICBkaXNwYXRjaF9kZXYoXCJTdmVsdGVET01SZW1vdmVBdHRyaWJ1dGVcIiwgeyBub2RlLCBhdHRyaWJ1dGUgfSk7XG4gICAgZWxzZVxuICAgICAgICBkaXNwYXRjaF9kZXYoXCJTdmVsdGVET01TZXRBdHRyaWJ1dGVcIiwgeyBub2RlLCBhdHRyaWJ1dGUsIHZhbHVlIH0pO1xufVxuZnVuY3Rpb24gcHJvcF9kZXYobm9kZSwgcHJvcGVydHksIHZhbHVlKSB7XG4gICAgbm9kZVtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICBkaXNwYXRjaF9kZXYoXCJTdmVsdGVET01TZXRQcm9wZXJ0eVwiLCB7IG5vZGUsIHByb3BlcnR5LCB2YWx1ZSB9KTtcbn1cbmZ1bmN0aW9uIGRhdGFzZXRfZGV2KG5vZGUsIHByb3BlcnR5LCB2YWx1ZSkge1xuICAgIG5vZGUuZGF0YXNldFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICBkaXNwYXRjaF9kZXYoXCJTdmVsdGVET01TZXREYXRhc2V0XCIsIHsgbm9kZSwgcHJvcGVydHksIHZhbHVlIH0pO1xufVxuZnVuY3Rpb24gc2V0X2RhdGFfZGV2KHRleHQsIGRhdGEpIHtcbiAgICBkYXRhID0gJycgKyBkYXRhO1xuICAgIGlmICh0ZXh0Lndob2xlVGV4dCA9PT0gZGF0YSlcbiAgICAgICAgcmV0dXJuO1xuICAgIGRpc3BhdGNoX2RldihcIlN2ZWx0ZURPTVNldERhdGFcIiwgeyBub2RlOiB0ZXh0LCBkYXRhIH0pO1xuICAgIHRleHQuZGF0YSA9IGRhdGE7XG59XG5mdW5jdGlvbiB2YWxpZGF0ZV9lYWNoX2FyZ3VtZW50KGFyZykge1xuICAgIGlmICh0eXBlb2YgYXJnICE9PSAnc3RyaW5nJyAmJiAhKGFyZyAmJiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiAnbGVuZ3RoJyBpbiBhcmcpKSB7XG4gICAgICAgIGxldCBtc2cgPSAneyNlYWNofSBvbmx5IGl0ZXJhdGVzIG92ZXIgYXJyYXktbGlrZSBvYmplY3RzLic7XG4gICAgICAgIGlmICh0eXBlb2YgU3ltYm9sID09PSAnZnVuY3Rpb24nICYmIGFyZyAmJiBTeW1ib2wuaXRlcmF0b3IgaW4gYXJnKSB7XG4gICAgICAgICAgICBtc2cgKz0gJyBZb3UgY2FuIHVzZSBhIHNwcmVhZCB0byBjb252ZXJ0IHRoaXMgaXRlcmFibGUgaW50byBhbiBhcnJheS4nO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlX3Nsb3RzKG5hbWUsIHNsb3QsIGtleXMpIHtcbiAgICBmb3IgKGNvbnN0IHNsb3Rfa2V5IG9mIE9iamVjdC5rZXlzKHNsb3QpKSB7XG4gICAgICAgIGlmICghfmtleXMuaW5kZXhPZihzbG90X2tleSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgPCR7bmFtZX0+IHJlY2VpdmVkIGFuIHVuZXhwZWN0ZWQgc2xvdCBcIiR7c2xvdF9rZXl9XCIuYCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5jbGFzcyBTdmVsdGVDb21wb25lbnREZXYgZXh0ZW5kcyBTdmVsdGVDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zIHx8ICghb3B0aW9ucy50YXJnZXQgJiYgIW9wdGlvbnMuJCRpbmxpbmUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCd0YXJnZXQnIGlzIGEgcmVxdWlyZWQgb3B0aW9uYCk7XG4gICAgICAgIH1cbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG4gICAgJGRlc3Ryb3koKSB7XG4gICAgICAgIHN1cGVyLiRkZXN0cm95KCk7XG4gICAgICAgIHRoaXMuJGRlc3Ryb3kgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYENvbXBvbmVudCB3YXMgYWxyZWFkeSBkZXN0cm95ZWRgKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG4gICAgICAgIH07XG4gICAgfVxuICAgICRjYXB0dXJlX3N0YXRlKCkgeyB9XG4gICAgJGluamVjdF9zdGF0ZSgpIHsgfVxufVxuZnVuY3Rpb24gbG9vcF9ndWFyZCh0aW1lb3V0KSB7XG4gICAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGlmIChEYXRlLm5vdygpIC0gc3RhcnQgPiB0aW1lb3V0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEluZmluaXRlIGxvb3AgZGV0ZWN0ZWRgKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbmV4cG9ydCB7IEh0bWxUYWcsIFN2ZWx0ZUNvbXBvbmVudCwgU3ZlbHRlQ29tcG9uZW50RGV2LCBTdmVsdGVFbGVtZW50LCBhY3Rpb25fZGVzdHJveWVyLCBhZGRfYXR0cmlidXRlLCBhZGRfY2xhc3NlcywgYWRkX2ZsdXNoX2NhbGxiYWNrLCBhZGRfbG9jYXRpb24sIGFkZF9yZW5kZXJfY2FsbGJhY2ssIGFkZF9yZXNpemVfbGlzdGVuZXIsIGFkZF90cmFuc2Zvcm0sIGFmdGVyVXBkYXRlLCBhcHBlbmQsIGFwcGVuZF9kZXYsIGFzc2lnbiwgYXR0ciwgYXR0cl9kZXYsIGJlZm9yZVVwZGF0ZSwgYmluZCwgYmluZGluZ19jYWxsYmFja3MsIGJsYW5rX29iamVjdCwgYnViYmxlLCBjaGVja19vdXRyb3MsIGNoaWxkcmVuLCBjbGFpbV9jb21wb25lbnQsIGNsYWltX2VsZW1lbnQsIGNsYWltX3NwYWNlLCBjbGFpbV90ZXh0LCBjbGVhcl9sb29wcywgY29tcG9uZW50X3N1YnNjcmliZSwgY29tcHV0ZV9yZXN0X3Byb3BzLCBjb21wdXRlX3Nsb3RzLCBjcmVhdGVFdmVudERpc3BhdGNoZXIsIGNyZWF0ZV9hbmltYXRpb24sIGNyZWF0ZV9iaWRpcmVjdGlvbmFsX3RyYW5zaXRpb24sIGNyZWF0ZV9jb21wb25lbnQsIGNyZWF0ZV9pbl90cmFuc2l0aW9uLCBjcmVhdGVfb3V0X3RyYW5zaXRpb24sIGNyZWF0ZV9zbG90LCBjcmVhdGVfc3NyX2NvbXBvbmVudCwgY3VycmVudF9jb21wb25lbnQsIGN1c3RvbV9ldmVudCwgZGF0YXNldF9kZXYsIGRlYnVnLCBkZXN0cm95X2Jsb2NrLCBkZXN0cm95X2NvbXBvbmVudCwgZGVzdHJveV9lYWNoLCBkZXRhY2gsIGRldGFjaF9hZnRlcl9kZXYsIGRldGFjaF9iZWZvcmVfZGV2LCBkZXRhY2hfYmV0d2Vlbl9kZXYsIGRldGFjaF9kZXYsIGRpcnR5X2NvbXBvbmVudHMsIGRpc3BhdGNoX2RldiwgZWFjaCwgZWxlbWVudCwgZWxlbWVudF9pcywgZW1wdHksIGVzY2FwZSwgZXNjYXBlZCwgZXhjbHVkZV9pbnRlcm5hbF9wcm9wcywgZml4X2FuZF9kZXN0cm95X2Jsb2NrLCBmaXhfYW5kX291dHJvX2FuZF9kZXN0cm95X2Jsb2NrLCBmaXhfcG9zaXRpb24sIGZsdXNoLCBnZXRDb250ZXh0LCBnZXRfYmluZGluZ19ncm91cF92YWx1ZSwgZ2V0X2N1cnJlbnRfY29tcG9uZW50LCBnZXRfc2xvdF9jaGFuZ2VzLCBnZXRfc2xvdF9jb250ZXh0LCBnZXRfc3ByZWFkX29iamVjdCwgZ2V0X3NwcmVhZF91cGRhdGUsIGdldF9zdG9yZV92YWx1ZSwgZ2xvYmFscywgZ3JvdXBfb3V0cm9zLCBoYW5kbGVfcHJvbWlzZSwgaGFzX3Byb3AsIGlkZW50aXR5LCBpbml0LCBpbnNlcnQsIGluc2VydF9kZXYsIGludHJvcywgaW52YWxpZF9hdHRyaWJ1dGVfbmFtZV9jaGFyYWN0ZXIsIGlzX2NsaWVudCwgaXNfY3Jvc3NvcmlnaW4sIGlzX2VtcHR5LCBpc19mdW5jdGlvbiwgaXNfcHJvbWlzZSwgbGlzdGVuLCBsaXN0ZW5fZGV2LCBsb29wLCBsb29wX2d1YXJkLCBtaXNzaW5nX2NvbXBvbmVudCwgbW91bnRfY29tcG9uZW50LCBub29wLCBub3RfZXF1YWwsIG5vdywgbnVsbF90b19lbXB0eSwgb2JqZWN0X3dpdGhvdXRfcHJvcGVydGllcywgb25EZXN0cm95LCBvbk1vdW50LCBvbmNlLCBvdXRyb19hbmRfZGVzdHJveV9ibG9jaywgcHJldmVudF9kZWZhdWx0LCBwcm9wX2RldiwgcXVlcnlfc2VsZWN0b3JfYWxsLCByYWYsIHJ1biwgcnVuX2FsbCwgc2FmZV9ub3RfZXF1YWwsIHNjaGVkdWxlX3VwZGF0ZSwgc2VsZWN0X211bHRpcGxlX3ZhbHVlLCBzZWxlY3Rfb3B0aW9uLCBzZWxlY3Rfb3B0aW9ucywgc2VsZWN0X3ZhbHVlLCBzZWxmLCBzZXRDb250ZXh0LCBzZXRfYXR0cmlidXRlcywgc2V0X2N1cnJlbnRfY29tcG9uZW50LCBzZXRfY3VzdG9tX2VsZW1lbnRfZGF0YSwgc2V0X2RhdGEsIHNldF9kYXRhX2Rldiwgc2V0X2lucHV0X3R5cGUsIHNldF9pbnB1dF92YWx1ZSwgc2V0X25vdywgc2V0X3JhZiwgc2V0X3N0b3JlX3ZhbHVlLCBzZXRfc3R5bGUsIHNldF9zdmdfYXR0cmlidXRlcywgc3BhY2UsIHNwcmVhZCwgc3RvcF9wcm9wYWdhdGlvbiwgc3Vic2NyaWJlLCBzdmdfZWxlbWVudCwgdGV4dCwgdGljaywgdGltZV9yYW5nZXNfdG9fYXJyYXksIHRvX251bWJlciwgdG9nZ2xlX2NsYXNzLCB0cmFuc2l0aW9uX2luLCB0cmFuc2l0aW9uX291dCwgdXBkYXRlX2tleWVkX2VhY2gsIHVwZGF0ZV9zbG90LCB2YWxpZGF0ZV9jb21wb25lbnQsIHZhbGlkYXRlX2VhY2hfYXJndW1lbnQsIHZhbGlkYXRlX2VhY2hfa2V5cywgdmFsaWRhdGVfc2xvdHMsIHZhbGlkYXRlX3N0b3JlLCB4bGlua19hdHRyIH07XG4iLCJpbXBvcnQgeyByZWFkYWJsZSwgd3JpdGFibGUgfSBmcm9tIFwic3ZlbHRlL3N0b3JlXCI7XHJcbmltcG9ydCB7IHJlYWN0aXZlLCB3YXRjaEVmZmVjdCB9IGZyb20gXCJ2dWVcIjtcclxuLyoqIOaYr+S4jeaYr+W8gOWPkeeOr+WigyAqL1xyXG5leHBvcnQgY29uc3QgaXNEZXYgPSAod2luZG93IGFzIGFueSkuX19sbGVqX191c2VyanNfX2Rldl9fID09PSB0cnVlO1xyXG4vKiog5piv5ZCm5byA5ZCv57yW6L6RICovXHJcbmV4cG9ydCBjb25zdCBlbGVtZW50RWRpdCA9IHdyaXRhYmxlKGZhbHNlKTtcclxuZXhwb3J0IGNvbnN0IGNvbmZpZyA9IHJlYWN0aXZlKHtcclxuICBzdGF0ZTogMCwgLy/mmK/lvIDlj5Hnjq/looPoh6rliqjlvIDlkK9cclxuICAvKiog5piv5ZCm5byA5ZCv57yW6L6RICovIGVsZW1lbnRFZGl0OiBpc0RldixcclxuICAvKiog5pyN5Yqh5Zmo5Zyw5Z2AICovXHJcbiAgc2VydmVySXA6IFwiaHR0cHM6Ly9zaGVuemlsb25nLmNuL25vdGUvXCIsIC8vIGlzRGV2ID8gJ2h0dHBzOi8vMTI3LjAuMC4xL25vdGUvJyA6ICdodHRwczovL3NoZW56aWxvbmcuY24vbm90ZS8nLFxyXG4gIC8qKiDpobXpnaLnmoR1cmwgKi9cclxuICBsb2NhdGlvblVybDogZGVjb2RlVVJJQ29tcG9uZW50KGxvY2F0aW9uLm9yaWdpbiArIGxvY2F0aW9uLnBhdGhuYW1lKSxcclxuICAvKiog5a2Y5YKo55m75b2V5Yet6K+B55qEICovXHJcbiAgbG9naW5DcmVkZW50aWFsczogXCJsb2dpbkNyZWRlbnRpYWxzXCIsXHJcbn0pO1xyXG53YXRjaEVmZmVjdCgoKSA9PiB7XHJcbiAgLyoqIOWQjOatpeaYr+WQpuW8gOWQr+e8lui+keeahOeKtuaAgee7mSB3cml0YWJsZSAgKi9cclxuICBlbGVtZW50RWRpdC5zZXQoY29uZmlnLmVsZW1lbnRFZGl0KTtcclxufSk7XHJcbi8qKiDlrZjlgqjlkb3ku6TmoIjnmoTlnLDmlrkgKi9cclxuZXhwb3J0IGNvbnN0IEFsbFN0b3JlTmFtZSA9IFwiX3N0b3JlTmFtZV9sbGVqX1wiICsgY29uZmlnLmxvY2F0aW9uVXJsO1xyXG5leHBvcnQgZGVmYXVsdCBjb25maWc7XHJcbiIsImltcG9ydCB7IE1lc3NhZ2UgfSBmcm9tIFwiLi4vdWkvbWVzc2FnZVwiO1xyXG5pbXBvcnQgeyBnZXRTZWxlY3RvcnMsIGxvZyB9IGZyb20gXCIuLi91dGlsXCI7XHJcbmltcG9ydCB7IG5vdGVfbGlzdF9zdG9yZSB9IGZyb20gXCIuLi9zdGF0ZS9zdG9yZVwiO1xyXG5pbXBvcnQgeyBnZXQgfSBmcm9tIFwic3ZlbHRlL3N0b3JlXCI7XHJcbmltcG9ydCB7IHN0eWxlTGlzdCB9IGZyb20gXCIuLi9zdGF0ZS9oaWdobGlnaHRlZF9zdHlsZVwiO1xyXG5pbXBvcnQgeyBjdXJTdG9yZSB9IGZyb20gXCIuLi9saWIvc3RvcmVcIjtcclxuXHJcbi8qKiDmr4/kuIDkuKrlkb3ku6Tpg73lupTor6Xlrp7njrDnmoTkuJzopb8gKi9cclxuZXhwb3J0IGNsYXNzIENvbW1hbmQge1xyXG4gIHNlbGVjdEVMOiBIVE1MRWxlbWVudDtcclxuICBjb25zdHJ1Y3RvcigvKiog5ZG95Luk5omn6KGM55qE5YWD57SgICovIHNlbGVjdD86IEhUTUxFbGVtZW50KSB7XHJcbiAgICB0aGlzLnNlbGVjdEVMID0gc2VsZWN0O1xyXG4gIH1cclxuICAvKiog5omn6KGM6L+Z5Liq5ZG95LukICovXHJcbiAgZG8oKSB7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqIOaSpOmUgOi/meS4quWRveS7pCAqL1xyXG4gIHVuZG8oKSB7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqIOmHjeaWsOaJp+ihjOWRveS7pCAqL1xyXG4gIHJlZG8oKSB7XHJcbiAgICByZXR1cm4gdGhpcy5kbygpO1xyXG4gIH1cclxuICAvKiog5bCG5ZG95Luk5Y+Y5oiQ5Y+v5Lul6L2s5YyW5Li6anNvbuWtl+espuS4sueahOWvueixoSAqL1xyXG4gIHRvSlNPTigpOiBjb21tYW5kSlNPTiB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBzZWxlY3RFTDogZ2V0U2VsZWN0b3JzKHRoaXMuc2VsZWN0RUwpLFxyXG4gICAgICBjb25zdHJ1Y3RvcjogKDxhbnk+dGhpcykuX19wcm90b19fLmNvbnN0cnVjdG9yLm5hbWUsXHJcbiAgICB9O1xyXG4gIH1cclxuICAvKiog55So5LqO5Y+v5Lul5L2/55SoIHRvSlNPTiDnlJ/miJDnmoTmlbDmja7ph43lu7rlip/og73mlYjmnpwgKi9cclxuICBwdWJsaWMgc3RhdGljIOmHjeW7uihvYmo6IGNvbW1hbmRKU09OKSB7XHJcbiAgICByZXR1cm4gbmV3IHRoaXMoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihvYmouc2VsZWN0RUwpKTtcclxuICB9XHJcbiAgLyoqIOWKoOi9vWNvbW1hbmRKU09O6L2s5Y+Y5Li65ZG95LukLOmAmui/h+azm+Wei+adpeaehOmAoOWvueixoeeahOaWueW8jyAqL1xyXG4gIHN0YXRpYyBsb2FkPFQ+KG9iajogVCwgQ0xBU1M6IHsg6YeN5bu6OiAocGFyOiBUKSA9PiBDb21tYW5kIH0pIHtcclxuICAgIHJldHVybiBDTEFTUy7ph43lu7oob2JqKTtcclxuICB9XHJcbn1cclxuXHJcbi8qKiDliKDpmaTkuIDkuKrlhYPntKAgKi9cclxuZXhwb3J0IGNsYXNzIGRlbGV0ZVNlbGVjdCBleHRlbmRzIENvbW1hbmQge1xyXG4gIC8qKiDooqvpgInkuK3lhYPntKDnmoTmmL7npLrnirbmgIEgKi9cclxuICBzZWxlY3RFTF9kaXNwbGF5OiBzdHJpbmc7XHJcbiAgZG8oKSB7XHJcbiAgICB0aGlzLnNlbGVjdEVMX2Rpc3BsYXkgPSB0aGlzLnNlbGVjdEVMLnN0eWxlLmRpc3BsYXk7XHJcbiAgICB0aGlzLnNlbGVjdEVMLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICB1bmRvKCkge1xyXG4gICAgdGhpcy5zZWxlY3RFTC5zdHlsZS5kaXNwbGF5ID0gdGhpcy5zZWxlY3RFTF9kaXNwbGF5O1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG59XHJcbi8qKiDkvb/lhYPntKDlj6/nvJbovpEgKi9cclxuZXhwb3J0IGNsYXNzIGVkaXRTZWxlY3QgZXh0ZW5kcyBDb21tYW5kIHtcclxuICBzZWxlY3RFTF9jb250ZW50RWRpdGFibGU6IHN0cmluZztcclxuICBkbygpIHtcclxuICAgIHRoaXMuc2VsZWN0RUxfY29udGVudEVkaXRhYmxlID0gdGhpcy5zZWxlY3RFTC5jb250ZW50RWRpdGFibGU7XHJcbiAgICB0aGlzLnNlbGVjdEVMLmNvbnRlbnRFZGl0YWJsZSA9IFwidHJ1ZVwiO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIHVuZG8oKSB7XHJcbiAgICB0aGlzLnNlbGVjdEVMLmNvbnRlbnRFZGl0YWJsZSA9IHRoaXMuc2VsZWN0RUxfY29udGVudEVkaXRhYmxlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG59XHJcbi8qKiDkvb/lhYPntKDkuI3lj6/nvJbovpEgKi9cclxuZXhwb3J0IGNsYXNzIGNsb3NlRWRpdFNlbGVjdCBleHRlbmRzIENvbW1hbmQge1xyXG4gIHNlbGVjdEVMX2NvbnRlbnRFZGl0YWJsZTogc3RyaW5nO1xyXG4gIGRvKCkge1xyXG4gICAgdGhpcy5zZWxlY3RFTF9jb250ZW50RWRpdGFibGUgPSB0aGlzLnNlbGVjdEVMLmNvbnRlbnRFZGl0YWJsZTtcclxuICAgIHRoaXMuc2VsZWN0RUwuY29udGVudEVkaXRhYmxlID0gXCJmYWxzZVwiO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIHVuZG8oKSB7XHJcbiAgICB0aGlzLnNlbGVjdEVMLmNvbnRlbnRFZGl0YWJsZSA9IHRoaXMuc2VsZWN0RUxfY29udGVudEVkaXRhYmxlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG59XHJcbi8qKiDmlrDlop7kuIDkuKrnrJTorrAgKi9cclxuZXhwb3J0IGNsYXNzIGFkZE5vdGUgZXh0ZW5kcyBDb21tYW5kIHtcclxuICBkbygpIHtcclxuICAgIHRoaXMuc2VsZWN0RUw7XHJcbiAgICBub3RlX2xpc3Rfc3RvcmUudXBkYXRlKChsaXN0KSA9PiB7XHJcbiAgICAgIGxpc3QucHVzaCh7XHJcbiAgICAgICAgcG9pbnQ6IHRoaXMuc2VsZWN0RUwsXHJcbiAgICAgICAgY29udGVudDogXCI2NjY2NjY2XCIsXHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gbGlzdDtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIHVuZG8oKSB7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgcmVkbygpIHtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxufVxyXG5cclxuLyoqIOmrmOS6ruWKn+iDvSAqL1xyXG5leHBvcnQgY2xhc3MgSGlnaGxpZ2h0ZWQgZXh0ZW5kcyBDb21tYW5kIHtcclxuICAvKiogY3NzIOexu+WQjSAqL1xyXG4gIHB1YmxpYyBjbGFzc05hbWUgPSBgbGxlai1wYWdlX25vdGVzLXN0eWxlLSR7Y3VyU3RvcmUuSGlnaGxpZ2h0ZWRfY291bnQrK31gO1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc3R5bGVUZXh0OiBzdHJpbmcpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgfVxyXG4gIGRvKCkge1xyXG4gICAgc3R5bGVMaXN0LnVwZGF0ZSgocikgPT4ge1xyXG4gICAgICByZXR1cm4gWy4uLnIsIHRoaXMuZ2V0UmF3U3R5bGVUZXh0KCldO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgZ2V0UmF3U3R5bGVUZXh0KCkge1xyXG4gICAgcmV0dXJuIGBcclxuICAgIC4ke3RoaXMuY2xhc3NOYW1lfXtcclxuICAgICAgJHt0aGlzLnN0eWxlVGV4dH1cclxuICAgIH1cclxuICAgIGA7XHJcbiAgfVxyXG4gIHVuZG8oKSB7XHJcbiAgICBzdHlsZUxpc3QudXBkYXRlKChyKSA9PiB7XHJcbiAgICAgIHJldHVybiByLmZpbHRlcigoZWwpID0+IGVsICE9PSB0aGlzLmdldFJhd1N0eWxlVGV4dCgpKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIHN0YXRpYyDph43lu7oob2JqOiBSZXR1cm5UeXBlPEhpZ2hsaWdodGVkW1widG9KU09OXCJdPikge1xyXG4gICAgY29uc3QgciA9IG5ldyB0aGlzKG9iai5zdHlsZVRleHQpO1xyXG4gICAgci5jbGFzc05hbWUgPSBvYmouY2xhc3NOYW1lO1xyXG4gICAgcmV0dXJuIHI7XHJcbiAgfVxyXG4gIHRvSlNPTigpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHNlbGVjdEVMOiBcIlwiLFxyXG4gICAgICBjbGFzc05hbWU6IHRoaXMuY2xhc3NOYW1lLFxyXG4gICAgICBzdHlsZVRleHQ6IHRoaXMuc3R5bGVUZXh0LFxyXG4gICAgICBjb25zdHJ1Y3RvcjogKDxhbnk+dGhpcykuX19wcm90b19fLmNvbnN0cnVjdG9yLm5hbWUsXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG5cclxuLyoqIOWRveS7pOaOp+WItuWZqCAqL1xyXG5leHBvcnQgY29uc3QgQ29tbWFuZENvbnRyb2w6IENvbW1hbmRDb250cm9sID0ge1xyXG4gIGNvbW1hbmRTdGFjazogW10sXHJcbiAgYmFja091dFN0YWNrOiBbXSxcclxuICBwdXNoQ29tbWFuZChjb21tYW5kKSB7XHJcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kU3RhY2sucHVzaChjb21tYW5kKTtcclxuICB9LFxyXG4gIHJ1bihjb21tYW5kKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLmJhY2tPdXRTdGFjay5zcGxpY2UoMCwgdGhpcy5iYWNrT3V0U3RhY2subGVuZ3RoKTtcclxuICAgICAgcmV0dXJuIHRoaXMucHVzaENvbW1hbmQoY29tbWFuZC5kbygpKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCLlkb3ku6TmiafooYzlpLHotKVcIiwgY29tbWFuZCwgZXJyb3IpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIC0xO1xyXG4gIH0sXHJcbiAgYmFja091dCgpIHtcclxuICAgIGlmICh0aGlzLmNvbW1hbmRTdGFjay5sZW5ndGggPT09IDApIHtcclxuICAgICAgTWVzc2FnZS5nZXRNZXNzYWdlKHsgbXNnOiBcIuWRveS7pOagiOW3suepuu+8jOaXoOazlei/m+ihjOaSpOmUgFwiIH0pLmF1dG9IaWRlKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNvbnN0IGNvbW1hbmQgPSB0aGlzLmNvbW1hbmRTdGFjay5wb3AoKTtcclxuICAgIHJldHVybiB0aGlzLmJhY2tPdXRTdGFjay5wdXNoKGNvbW1hbmQudW5kbygpKTtcclxuICB9LFxyXG4gIHJlZm9ybSgpIHtcclxuICAgIGlmICh0aGlzLmJhY2tPdXRTdGFjay5sZW5ndGggPT09IDApIHtcclxuICAgICAgTWVzc2FnZS5nZXRNZXNzYWdlKHsgbXNnOiBcIuaSpOmUgOagiOW3suepuu+8jOaXoOazlei/m+ihjOmHjeWBmlwiIH0pLmF1dG9IaWRlKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNvbnN0IGNvbW1hbmQgPSB0aGlzLmJhY2tPdXRTdGFjay5wb3AoKTtcclxuICAgIHJldHVybiB0aGlzLmNvbW1hbmRTdGFjay5wdXNoKGNvbW1hbmQucmVkbygpKTtcclxuICB9LFxyXG4gIC8qKiDku45qc29u6YeN5bu65ZG95Luk5qCIICovXHJcbiAgbG9hZENvbW1hbmRKU09OKG9iaikge1xyXG4gICAgbG9nKFwiLeaJp+ihjOWRveS7pC1cIiwgb2JqLmNvbnN0cnVjdG9yKTtcclxuICAgIGlmIChvYmouY29uc3RydWN0b3IgPT09IFwiZGVsZXRlU2VsZWN0XCIpIHJldHVybiBDb21tYW5kLmxvYWQob2JqLCBkZWxldGVTZWxlY3QpO1xyXG4gICAgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gXCJlZGl0U2VsZWN0XCIpIHJldHVybiBDb21tYW5kLmxvYWQob2JqLCBlZGl0U2VsZWN0KTtcclxuICAgIGlmIChvYmouY29uc3RydWN0b3IgPT09IFwiY2xvc2VFZGl0U2VsZWN0XCIpIHJldHVybiBDb21tYW5kLmxvYWQob2JqLCBjbG9zZUVkaXRTZWxlY3QpO1xyXG4gICAgaWYgKG9iai5jb25zdHJ1Y3RvciA9PT0gXCJhZGROb3RlXCIpIHJldHVybiBDb21tYW5kLmxvYWQob2JqLCBhZGROb3RlKTtcclxuICAgIGlmIChvYmouY29uc3RydWN0b3IgPT09IFwiSGlnaGxpZ2h0ZWRcIikgcmV0dXJuIENvbW1hbmQubG9hZChvYmogYXMgYW55LCBIaWdobGlnaHRlZCk7XHJcbiAgfSxcclxuICBnZXRDb21tYW5kU3RhY2tKU09OKCkge1xyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuY29tbWFuZFN0YWNrKTtcclxuICB9LFxyXG4gIGxvYWRDb21tYW5kSnNvbkFuZFJ1bihjb21tYW5kSlNPTikge1xyXG4gICAgY29tbWFuZEpTT04ubWFwKHRoaXMubG9hZENvbW1hbmRKU09OKS5mb3JFYWNoKChjb21tYW5kKSA9PiB0aGlzLnJ1bihjb21tYW5kKSk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9LFxyXG59O1xyXG5cclxuLyoqIOinhOWumuS6huWRveS7pOi9rOaIkCBqc29uIOeahOe7k+aehCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIGNvbW1hbmRKU09OIHtcclxuICAvKiog6YCJ5oup5ZmoICovXHJcbiAgc2VsZWN0RUw6IHN0cmluZztcclxuICAvKiog5p6E6YCg5Ye95pWw55qE5ZCN5a2X77yM5LiA6Iis5bCx5piv57G75ZCNICovXHJcbiAgY29uc3RydWN0b3I6IHN0cmluZztcclxuICAvKiog5rOo5oSP77yM6KaB6IO96KKr5bqP5YiX5YyWICovXHJcbiAgW2s6IHN0cmluZ106IGFueTtcclxufVxyXG4vKiog5ZG95Luk5o6n5Yi25Zmo55qE5o6l5Y+jICovXHJcbmludGVyZmFjZSBDb21tYW5kQ29udHJvbCB7XHJcbiAgLyoqIOWRveS7pOagiO+8jOaJp+ihjOi/h+eahCAqL1xyXG4gIGNvbW1hbmRTdGFjazogQ29tbWFuZFtdO1xyXG4gIC8qKiDmkqTplIDmoIjvvIzooqvmkqTplIDnmoTlkb3ku6QgKi9cclxuICBiYWNrT3V0U3RhY2s6IENvbW1hbmRbXTtcclxuICAvKiog5ZCR5ZG95Luk5qCI5Lit5re75Yqg5LiA5Liq5ZG95LukICovXHJcbiAgcHVzaENvbW1hbmQoY29tbWFuZDogQ29tbWFuZCk6IG51bWJlcjtcclxuICAvKiog5omn6KGM5LiA5Liq5ZG95Luk5bm25Yqg5YWl5ZG95Luk5qCI77yM5riF56m65pKk6ZSA5qCIICovXHJcbiAgcnVuKGNvbW1hbmQ6IENvbW1hbmQpOiBudW1iZXI7XHJcbiAgLyoqIOaSpOmUgOacgOWQjuS4gOS4quWRveS7pOW5tuWKoOWFpeaSpOa2iOagiCAqL1xyXG4gIGJhY2tPdXQoKTogbnVtYmVyO1xyXG4gIC8qKiDph43lgZos6YeN5YGa5pKk6ZSA5qCI5Lit55qE5ZG95LukLOWRveS7pOS8muiiq+i9rOenu+iHs+WRveS7pOagiCAqL1xyXG4gIHJlZm9ybSgpOiBudW1iZXI7XHJcbiAgLyoqIOWKoOi9vWNvbW1hbmRKU09O6L2s5YyW5Li65ZG95Luk5a+56LGhICovXHJcbiAgbG9hZENvbW1hbmRKU09OKG9iajogY29tbWFuZEpTT04pOiBDb21tYW5kO1xyXG5cclxuICAvKiog6I635Y+W5ZG95Luk5qCI55qESlNPTuWtl+espuS4siAqL1xyXG4gIGdldENvbW1hbmRTdGFja0pTT04oKTogc3RyaW5nO1xyXG5cclxuICAvKiog5Yqg6L295ZG95Luk5qCI55qESlNPTuWtl+espuS4suW5tuS4lOaJp+ihjCAqL1xyXG4gIGxvYWRDb21tYW5kSnNvbkFuZFJ1bihjb21tYW5kSlNPTjogY29tbWFuZEpTT05bXSk6IGJvb2xlYW47XHJcbn1cclxuIiwiaW1wb3J0IHsgZGVyaXZlZCwgZ2V0LCB3cml0YWJsZSB9IGZyb20gXCJzdmVsdGUvc3RvcmVcIjtcclxuaW1wb3J0IHsgaXNEZXYgfSBmcm9tIFwiLi9jb25maWdcIjtcclxuaW1wb3J0IHsgQ29tbWFuZENvbnRyb2wsIEhpZ2hsaWdodGVkIH0gZnJvbSBcIi4vZnVuL2NvbW1hbmRcIjtcclxuaW1wb3J0IHsgZWRpdEVsZW1lbnQgfSBmcm9tIFwiLi9zdGF0ZVwiO1xyXG4vKiog55So5LqO5aSN5Yi25paH5pys55qEaW5wdXQgICAqL1xyXG5jb25zdCBpbnB1dF9jb3B5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRleHRhcmVhXCIpO1xyXG5pbnB1dF9jb3B5LmlkID0gXCJfX1wiO1xyXG5pbnB1dF9jb3B5LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjsgLy/kuI3og73orr7nva7kuLpub25l5Zug5Li65Lya5a+86Ie05rKh5pyJ5Y+v6K6/6Zeu5oCnXHJcbmlucHV0X2NvcHkuc2V0QXR0cmlidXRlKFxyXG4gIFwic3R5bGVcIixcclxuICBgXHJcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgICAgIHRvcDogLTk5OTlweDtcclxuICAgICAgICBsZWZ0OiAtOTk5OXB4O2AsXHJcbik7XHJcbmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaW5wdXRfY29weSk7XHJcbi8qKiDlpI3liLbkuIDkuKrlhYPntKDnmoR0aXRpbCDmiJbogIXkuIDmrrXlrZfnrKbkuLLliLDliarotLTmnb8gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvcHlUaXRsZShlbDogSFRNTEVsZW1lbnQgfCBzdHJpbmcpIHtcclxuICBsZXQgdGl0bGU7XHJcbiAgaWYgKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIikgdGl0bGUgPSBlbDtcclxuICBlbHNlIHRpdGxlID0gZWwuZ2V0QXR0cmlidXRlKFwidGl0bGVcIik7XHJcblxyXG4gIGlucHV0X2NvcHkuc2V0QXR0cmlidXRlKFwicmVhZG9ubHlcIiwgXCJyZWFkb25seVwiKTtcclxuICBpbnB1dF9jb3B5LnNldEF0dHJpYnV0ZShcInZhbHVlXCIsIHRpdGxlKTtcclxuICBpbnB1dF9jb3B5LnZhbHVlID0gdGl0bGU7XHJcbiAgaW5wdXRfY29weS5zZWxlY3QoKTtcclxuICBpbnB1dF9jb3B5LnNldFNlbGVjdGlvblJhbmdlKDAsIDk5OTkpO1xyXG4gIGRvY3VtZW50LmV4ZWNDb21tYW5kKFwiY29weVwiKTtcclxufVxyXG4vKiog5bel5YW357G7ICovXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBjb3B5VGl0bGUsXHJcbn07XHJcblxyXG4vKiog6I635Y+W5LiA5Liq5YWD57Sg55qE6YCJ5oup5ZmoICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRTZWxlY3RvcnMoZWw6IEVsZW1lbnQpIHtcclxuICAvKiog6YCa6L+HcGF0aOi3r+W+hOadpeehruWumuWFg+e0oCAqL1xyXG4gIGxldCBwYXRoU2VsZWN0b3JzID0gbm9kZVBhdGgoZWwpXHJcbiAgICAucmV2ZXJzZSgpXHJcbiAgICAubWFwKChlbCkgPT4ge1xyXG4gICAgICByZXR1cm4gZWwubm9kZU5hbWUgKyBgOm50aC1jaGlsZCgke2dldEluZGV4KGVsKX0pYDtcclxuICAgIH0pXHJcbiAgICAuam9pbihcIj5cIik7XHJcblxyXG4gIC8qKiDpgJrov4dpZOS7peWPimNsYXNz5p2l56Gu5a6a5YWD57SgICovXHJcbiAgbGV0IGlkX2NsYXNzTmFtZSA9IFwiXCI7XHJcbiAgY29uc3QgaWQgPSBlbC5pZDtcclxuICBpZiAoaWQpIGlkX2NsYXNzTmFtZSArPSBgIyR7aWR9YDtcclxuXHJcbiAgQXJyYXkuZnJvbShlbC5jbGFzc0xpc3QpXHJcbiAgICAvKiog5o6S6Zmk6Ieq5a6a5LmJ57G75ZCNICovXHJcbiAgICAuZmlsdGVyKChlbCkgPT4gZWwuaW5jbHVkZXMoXCJfbGxlal9cIikpXHJcbiAgICAuZm9yRWFjaCgoY2xhc3NOYW1lKSA9PiB7XHJcbiAgICAgIGlkX2NsYXNzTmFtZSArPSBgLiR7Y2xhc3NOYW1lfWA7XHJcbiAgICB9KTtcclxuXHJcbiAgLyoqIG50aC1jaGlsZCDpgInmi6kg55yL5a6D5piv56ys5Yeg5Liq5YWD57SgICovXHJcbiAgY29uc3QgaW5kZXggPSBnZXRJbmRleChlbCk7XHJcblxyXG4gIC8qKiDmnIDnu4jmnoTpgKDlh7rmnaXnmoTpgInmi6nlmaggKi9cclxuICByZXR1cm4gYCR7cGF0aFNlbGVjdG9yc30ke2lkX2NsYXNzTmFtZX06bnRoLWNoaWxkKCR7aW5kZXh9KWA7XHJcbn1cclxuXHJcbi8qKiDojrflj5blhYPntKDlroPlnKjnrKzlh6DkvY0gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEluZGV4KGVsOiBFbGVtZW50KSB7XHJcbiAgaWYgKGVsLm5vZGVOYW1lID09PSBcIkhUTUxcIikgcmV0dXJuIDE7XHJcbiAgaWYgKGVsLnBhcmVudEVsZW1lbnQgPT09IG51bGwpIHtcclxuICAgIHJldHVybiAxO1xyXG4gIH1cclxuICByZXR1cm4gMSArIEFycmF5LmZyb20oZWwucGFyZW50RWxlbWVudC5jaGlsZHJlbikuZmluZEluZGV4KChjaGlsZCkgPT4gY2hpbGQgPT09IGVsKTtcclxufVxyXG5cclxuLyoqIOiOt+WPluS4gOS4quWFg+e0oOeahOaJgOacieeItuiKgueCueWIsGh0bWzkuLrmraIgICovXHJcbmV4cG9ydCBmdW5jdGlvbiBub2RlUGF0aCguLi5wYXRoOiBFbGVtZW50W10pOiBIVE1MRWxlbWVudFtdIHtcclxuICB3aGlsZSAocGF0aFtwYXRoLmxlbmd0aCAtIDFdLnBhcmVudEVsZW1lbnQgIT0gbnVsbCkge1xyXG4gICAgcGF0aC5wdXNoKHBhdGhbcGF0aC5sZW5ndGggLSAxXS5wYXJlbnRFbGVtZW50KTtcclxuICB9XHJcbiAgLyoqIOWPqumcgOimgeaYr0hUTUxFbGVtZW5055qEICovXHJcbiAgY29uc3QgSFRNTEVsZW1lbnRQYXRoID0gPEhUTUxFbGVtZW50W10+cGF0aC5maWx0ZXIoKGVsKSA9PiBlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KTtcclxuICByZXR1cm4gSFRNTEVsZW1lbnRQYXRoO1xyXG59XHJcblxyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0SlNvbih1cmw6IHN0cmluZywgZGF0YT86IGFueSkge1xyXG4gIGNvbnN0IHN0ciA9IGF3YWl0IGFqYXhfZ2V0KHVybCwgZGF0YSk7XHJcbiAgY29uc3QgcmVzID0gSlNPTi5wYXJzZShzdHIpO1xyXG4gIGNvbnNvbGUubG9nKHVybCwgZGF0YSwgcmVzKTtcclxuICByZXR1cm4gcmVzO1xyXG59XHJcblxyXG4vKiog5rK554y055qEYWpheGdldCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gYWpheF9nZXQodXJsOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gIGlmIChkYXRhKSB1cmwgKz0gXCI/XCIgKyBqc29uVG9VUkxwYXIoZGF0YSk7XHJcbiAgaWYgKHdpbmRvdy5oYXNPd25Qcm9wZXJ0eShcIkdNXCIpICYmIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eShcIkdNXCIpKVxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgR00ueG1sSHR0cFJlcXVlc3Qoe1xyXG4gICAgICAgIG1ldGhvZDogXCJHRVRcIixcclxuICAgICAgICB1cmwsXHJcbiAgICAgICAgb25sb2FkOiBmdW5jdGlvbiAocmVzcG9uc2U6IGFueSkge1xyXG4gICAgICAgICAgcmVzb2x2ZShyZXNwb25zZS5yZXNwb25zZVRleHQpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgb25lcnJvcjogcmVqZWN0LFxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIGVsc2VcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgIGNvbnN0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xyXG4gICAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJlc29sdmUoeGhyLnJlc3BvbnNlVGV4dCk7XHJcbiAgICAgIH0pO1xyXG4gICAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIHJlamVjdCk7XHJcbiAgICAgIHhoci5vcGVuKFwiZ2V0XCIsIHVybCk7XHJcbiAgICAgIHhoci5zZW5kKCk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuLyoqIGpzb24g6L2sIHVybHBhciDlj6rog73ovazkuIDlsYIgKi9cclxuZnVuY3Rpb24ganNvblRvVVJMcGFyKGpzb246IGFueSkge1xyXG4gIHJldHVybiBPYmplY3Qua2V5cyhqc29uKVxyXG4gICAgLm1hcChmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KGpzb25ba2V5XSk7XHJcbiAgICB9KVxyXG4gICAgLmpvaW4oXCImXCIpO1xyXG59XHJcblxyXG4vKiog5byA5Y+R5pe255qE6LCD6K+VbG9nICovXHJcbmV4cG9ydCBmdW5jdGlvbiBsb2coLi4uYXJnOiBhbnlbXSkge1xyXG4gIGlmIChpc0RldikgY29uc29sZS5sb2coYFtkZXZdIGAsIC4uLmFyZyk7XHJcbn1cclxuXHJcbi8qKiDnlKjmiLfpgInkuK3kuovku7YgKi9cclxuZXhwb3J0IG5hbWVzcGFjZSBTZWxlY3Rpb25FdmVudCB7XHJcbiAgLyoqIOihqOekuueUqOaIt+mAieS4reeahOWvueixoe+8jOWUr+S4gOeahOOAguS4jeeUqOavj+asoeWOu+iOt+WPliAqL1xyXG4gIGNvbnN0IHMgPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgLyoqIOaYr+WQpuWkhOS6jiByYW5nZSDnmoTpgInkuK3nirbmgIEgKi9cclxuICBleHBvcnQgY29uc3QgaXNSYW5nZSA9IHdyaXRhYmxlKGZhbHNlKTtcclxuICAvKiog6YCJ5Yy65byA5aeL5L2N572u55qE5YWD57Sg55qEIHJlY3QgKi9cclxuICBleHBvcnQgY29uc3QgYW5jaG9yUmVjdCA9IGRlcml2ZWQoaXNSYW5nZSwgKCRpc1JhbmdlKSA9PiB7XHJcbiAgICBpZiAoISRpc1JhbmdlKSByZXR1cm47XHJcbiAgICBjb25zdCBub2RlID0gcy5hbmNob3JOb2RlO1xyXG4gICAgY29uc3QgZWwgPSBub2RlIGluc3RhbmNlb2YgRWxlbWVudCA/IG5vZGUgOiBub2RlLnBhcmVudEVsZW1lbnQ7XHJcbiAgICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICByZXR1cm4gcmVjdDtcclxuICB9KTtcclxuXHJcbiAgZXhwb3J0IGZ1bmN0aW9uIOmrmOS6rihvcHRpb25zOiB7IHRleHREZWNvcmF0aW9uPzogc3RyaW5nOyBzdHlsZT86IHN0cmluZyB9ID0ge30pIHtcclxuICAgIGNvbnN0IGggPSBuZXcgSGlnaGxpZ2h0ZWQob3B0aW9ucy5zdHlsZSk7XHJcbiAgICBDb21tYW5kQ29udHJvbC5ydW4oaCk7XHJcbiAgICBjb25zdCBjbGFzc05hbWUgPSBoLmNsYXNzTmFtZTtcclxuICAgIGNvbnN0IHRhZ05hbWUgPSBcInNwYW5cIjtcclxuICAgIGxldCDpgInkuK3nmoTmiYDmnInoioLngrkgPSBbXSBhcyBOb2RlW107XHJcbiAgICBpZiAoLyoqIOi3qOWFg+e0oOS6hiAqLyBzLmFuY2hvck5vZGUgIT09IHMuZm9jdXNOb2RlKSB7XHJcbiAgICAgIGNvbnN0IHN0YXJ0UmFuZ2UgPSBzLmdldFJhbmdlQXQoMCk7XHJcbiAgICAgIGNvbnN0IGVuZFJhbmdlID0gcy5nZXRSYW5nZUF0KHMucmFuZ2VDb3VudCAtIDEpO1xyXG4gICAgICBsZXQgc3RhcnROb2RlID0gc3RhcnRSYW5nZS5zdGFydENvbnRhaW5lcjtcclxuICAgICAgbGV0IGVuZE5vZGUgPSBlbmRSYW5nZS5lbmRDb250YWluZXI7XHJcblxyXG4gICAgICBsZXQgY3VyID0gc3RhcnROb2RlO1xyXG4gICAgICBpZiAoY3VyIGluc3RhbmNlb2YgVGV4dCkge1xyXG4gICAgICAgIGNvbnN0IHMgPSBzdGFydFJhbmdlO1xyXG4gICAgICAgIGNvbnN0IHQyID0gY3VyLnNwbGl0VGV4dChzLnN0YXJ0T2Zmc2V0KTtcclxuICAgICAgICBjb25zdCB0MyA9IHQyLm5leHRTaWJsaW5nO1xyXG4gICAgICAgIGNvbnN0IHdyYXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xyXG4gICAgICAgIHdyYXAuYXBwZW5kQ2hpbGQodDIpO1xyXG4gICAgICAgIGN1ci5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh3cmFwLCB0Myk7XHJcbiAgICAgIH1cclxuICAgICAgY3VyID0gZW5kTm9kZTtcclxuICAgICAgaWYgKGN1ciBpbnN0YW5jZW9mIFRleHQpIHtcclxuICAgICAgICBjb25zdCBzID0gZW5kUmFuZ2U7XHJcbiAgICAgICAgY29uc3QgdDIgPSBjdXIuc3BsaXRUZXh0KHMuZW5kT2Zmc2V0KTtcclxuICAgICAgICBjb25zdCB3cmFwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcclxuICAgICAgICB3cmFwLmFwcGVuZENoaWxkKGN1cik7XHJcbiAgICAgICAgdDIucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUod3JhcCwgdDIpO1xyXG5cclxuICAgICAgICBlbmROb2RlID0gdDI7XHJcbiAgICAgIH1cclxuICAgICAg6YCJ5Lit55qE5omA5pyJ6IqC54K5ID0gZ2V0SW50ZXJtZWRpYXRlTm9kZXMoc3RhcnROb2RlLCBlbmROb2RlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8qKiDljZXlhYPntKDnsbsgKi9cclxuICAgICAgY29uc3QgY3VyID0gcy5hbmNob3JOb2RlO1xyXG4gICAgICBpZiAoY3VyIGluc3RhbmNlb2YgVGV4dCkge1xyXG4gICAgICAgIGNvbnN0IHQyID0gY3VyLnNwbGl0VGV4dChzLmFuY2hvck9mZnNldCk7XHJcbiAgICAgICAgY29uc3QgdDMgPSB0Mi5zcGxpdFRleHQocy5mb2N1c09mZnNldCk7XHJcbiAgICAgICAg6YCJ5Lit55qE5omA5pyJ6IqC54K5LnB1c2godDIpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIOmAieS4reeahOaJgOacieiKgueCuS5wdXNoKGN1cik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGNvbnNvbGUubG9nKFwi6YCJ5Lit55qE5omA5pyJ6IqC54K5XCIsIOmAieS4reeahOaJgOacieiKgueCuSk7XHJcbiAgICDpgInkuK3nmoTmiYDmnInoioLngrkuZm9yRWFjaCgobm9kZSkgPT4ge1xyXG4gICAgICBsZXQgZWw7XHJcbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRWxlbWVudCkge1xyXG4gICAgICAgIGVsID0gbm9kZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvKiog5a+557qv5paH5pys6IqC54K56L+b6KGM5YyF6KOF77yM5Zug5Li657qv5paH5pys6IqC54K55peg5rOV6ZmE5Yqg5qC35byP562J5bGe5oCnICovXHJcbiAgICAgICAgY29uc3Qgd3JhcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XHJcbiAgICAgICAgY29uc3QgdDIgPSBub2RlLm5leHRTaWJsaW5nO1xyXG4gICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZTtcclxuICAgICAgICB3cmFwLmFwcGVuZENoaWxkKG5vZGUpO1xyXG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod3JhcCwgdDIpO1xyXG4gICAgICAgIGVsID0gd3JhcDtcclxuICAgICAgfVxyXG4gICAgICBlbC5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSk7XHJcbiAgICB9KTtcclxuICAgIC8qKiDov5nkupvlhYPntKDooqvmt7vliqDkuobnsbvlkI3vvIznlJroh7PooqvljIXoo7nkuobkuIDlsYLjgILlsZ7kuo7ooqvmsaHmn5PnmoTlhYPntKAs55u05o6l5qCH6K6w5LuW5Lus55qE54i25LqyICovXHJcbiAgICBjb25zdCDlhbHlrZjlsYIgPSBnZXRJbnRlcm1lZGlhdGVOb2Rlcy7lr7vmib7lhbHlrZjlsYIoLi4u6YCJ5Lit55qE5omA5pyJ6IqC54K5KTtcclxuICAgIC8vIGNvbnNvbGUubG9nKFwiW+WFseWtmOWxgl1cIiwg5YWx5a2Y5bGCKTtcclxuICAgIGxldCBwYXJlbnQgPSDlhbHlrZjlsYJbMF0ucGFyZW50RWxlbWVudDtcclxuICAgIC8qKiDpgb/lhY3moIforrDnmoTmmK/kuI3lpJ/lpKfnmoTlhYPntKDvvIzlrp7pmYXkuIrkuZ/mmK/lm6DkuLrlr7vmib7lhYPntKDnmoTmlrnms5XkuI3lpJ/lpb3lkKbliJnkuZ/nlKjkuI3nnYDov5nkuKogKi9cclxuICAgIHdoaWxlIChwYXJlbnQuY2xhc3NOYW1lLmluY2x1ZGVzKFwibGxlai1wYWdlX25vdGVzLXN0eWxlXCIpKSB7XHJcbiAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xyXG4gICAgfVxyXG4gICAgZWRpdEVsZW1lbnQuYWRkKHBhcmVudCk7XHJcbiAgfVxyXG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzZWxlY3Rpb25jaGFuZ2VcIiwgKCkgPT4ge1xyXG4gICAgaXNSYW5nZS5zZXQocy50eXBlID09PSBcIlJhbmdlXCIpO1xyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRJbnRlcm1lZGlhdGVOb2RlcyhhOiBOb2RlLCBiOiBOb2RlKTogTm9kZVtdIHtcclxuICByZXR1cm4gZ2V0SW50ZXJtZWRpYXRlTm9kZXMu6I635Y+W5Lik5YWD57Sg5LmL6Ze055qE5YWD57SgKGEsIGIpO1xyXG59XHJcbm5hbWVzcGFjZSBnZXRJbnRlcm1lZGlhdGVOb2RlcyB7XHJcbiAgZXhwb3J0IGZ1bmN0aW9uIOWvu+aJvuWFseWtmOWxgiguLi5hcmdzOiBOb2RlW10pOiBOb2RlW10ge1xyXG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgIHJldHVybiBhcmdzO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcGFyZW50TGlzdCA9IGFyZ3NcclxuICAgICAgLm1hcCgoZWwpID0+IOiOt+WPlueItumTvui3ryhlbCkucmV2ZXJzZSgpKVxyXG4gICAgICAuc29ydCgoYSwgYikgPT4ge1xyXG4gICAgICAgIHJldHVybiBhLmxlbmd0aCAtIGIubGVuZ3RoO1xyXG4gICAgICB9KTtcclxuICAgIGNvbnN0IOacgOefremTvui3ryA9IHBhcmVudExpc3RbMF07XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IOacgOefremTvui3ry5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBlbGVtZW50ID0g5pyA55+t6ZO+6LevW2ldO1xyXG4gICAgICBjb25zdCDmraTlsYLmmK/lkKblhajnm7jkvLwgPSBwYXJlbnRMaXN0Lm1hcCgoZWwpID0+IGVsW2ldKS5ldmVyeSgoZWwpID0+IGVsID09PSBlbGVtZW50KTtcclxuICAgICAgaWYgKOatpOWxguaYr+WQpuWFqOebuOS8vCA9PT0gZmFsc2UpIHtcclxuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSjmnIDnn63pk77ot69baSAtIDFdLmNoaWxkTm9kZXMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKiDotormjqXov5Fub2Rl55qE5YWD57Sg6LaK5Zyo5YmN6Z2iICovXHJcbiAgZXhwb3J0IGZ1bmN0aW9uIOiOt+WPlueItumTvui3ryhub2RlOiBOb2RlKSB7XHJcbiAgICBjb25zdCBsaXN0ID0gW10gYXMgTm9kZVtdO1xyXG4gICAgbGlzdC5wdXNoKG5vZGUpO1xyXG4gICAgbGV0IGN1ciA9IG5vZGU7XHJcbiAgICB3aGlsZSAoY3VyLnBhcmVudE5vZGUpIHtcclxuICAgICAgbGlzdC5wdXNoKGN1ci5wYXJlbnROb2RlKTtcclxuICAgICAgY3VyID0gY3VyLnBhcmVudE5vZGU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGlzdDtcclxuICB9XHJcbiAgZXhwb3J0IGZ1bmN0aW9uIOWQjumdoueahOWFhOW8n+WFg+e0oChub2RlOiBOb2RlKSB7XHJcbiAgICBjb25zdCBsaXN0ID0gW10gYXMgTm9kZVtdO1xyXG4gICAgbGV0IGN1ciA9IG5vZGU7XHJcbiAgICB3aGlsZSAoY3VyLm5leHRTaWJsaW5nKSB7XHJcbiAgICAgIGxpc3QucHVzaChjdXIubmV4dFNpYmxpbmcpO1xyXG4gICAgICBjdXIgPSBjdXIubmV4dFNpYmxpbmc7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGlzdDtcclxuICB9XHJcbiAgZXhwb3J0IGZ1bmN0aW9uIOWJjemdoueahOWFhOW8n+WFg+e0oChub2RlOiBOb2RlKSB7XHJcbiAgICBjb25zdCBsaXN0ID0gW10gYXMgTm9kZVtdO1xyXG4gICAgbGV0IGN1ciA9IG5vZGU7XHJcbiAgICB3aGlsZSAoY3VyLnByZXZpb3VzU2libGluZykge1xyXG4gICAgICBsaXN0LnB1c2goY3VyLnByZXZpb3VzU2libGluZyk7XHJcbiAgICAgIGN1ciA9IGN1ci5wcmV2aW91c1NpYmxpbmc7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGlzdDtcclxuICB9XHJcbiAgZXhwb3J0IGZ1bmN0aW9uIOiOt+WPluS4pOWFg+e0oOS5i+mXtOeahOWFg+e0oChhOiBOb2RlLCBiOiBOb2RlKSB7XHJcbiAgICBjb25zdCBsaXN0ID0gW10gYXMgTm9kZVtdO1xyXG4gICAgY29uc3QgYVBhcmVudExpc3QgPSDojrflj5bniLbpk77ot68oYSkucmV2ZXJzZSgpO1xyXG4gICAgY29uc3QgYlBhcmVudExpc3QgPSDojrflj5bniLbpk77ot68oYikucmV2ZXJzZSgpO1xyXG4gICAgLyoqIOaJvuWHuiBhIOS4jiBiIOWcqOWFseWtmOWxgueahOeItuWFg+e0oCAqL1xyXG4gICAgY29uc3Qg55+t6ZO+6LevID0gYVBhcmVudExpc3QubGVuZ3RoID4gYlBhcmVudExpc3QubGVuZ3RoID8gYlBhcmVudExpc3QgOiBhUGFyZW50TGlzdDtcclxuICAgIGxldCBuMSA9IOefremTvui3r1swXTtcclxuICAgIGxldCBuMiA9IOefremTvui3r1swXTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwg55+t6ZO+6LevLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIG4xID0gYVBhcmVudExpc3RbaV07XHJcbiAgICAgIG4yID0gYlBhcmVudExpc3RbaV07XHJcbiAgICAgIGlmIChuMSAhPT0gbjIpIHtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLyoqIOiOt+WPluWFseWtmOWxguS4remXtOeahOWFg+e0oCAqL1xyXG4gICAgbGV0IGN1ciA9IG4xLm5leHRTaWJsaW5nIGFzIE5vZGU7XHJcbiAgICB3aGlsZSAoY3VyICE9PSBuMiAmJiBjdXIubmV4dFNpYmxpbmcgIT09IG51bGwpIHtcclxuICAgICAgbGlzdC5wdXNoKGN1cik7XHJcbiAgICAgIGN1ciA9IGN1ci5uZXh0U2libGluZztcclxuICAgIH1cclxuXHJcbiAgICAvKiog5Yik5patIGEg5piv5ZCm5ZyoIGLliY3pnaIgKi9cclxuICAgIGN1ciA9IG4xO1xyXG4gICAgbGV0IG4x5Zyo5YmNID0gZmFsc2U7XHJcbiAgICB3aGlsZSAoY3VyLm5leHRTaWJsaW5nKSB7XHJcbiAgICAgIGlmIChuMiA9PT0gY3VyKSB7XHJcbiAgICAgICAgbjHlnKjliY0gPSB0cnVlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGN1ciA9IGN1ci5uZXh0U2libGluZztcclxuICAgIH1cclxuICAgIGNvbnN0IFtwcmUsIG5leHRdID0gbjHlnKjliY0gPyBbYSwgYl0gOiBbYiwgYV07XHJcbiAgICBjb25zdCDlhbHlrZjlsYIgPSDlr7vmib7lhbHlrZjlsYIoYSwgYik7XHJcbiAgICBjdXIgPSBwcmU7XHJcbiAgICB3aGlsZSAoIeWFseWtmOWxgi5pbmNsdWRlcyhjdXIpKSB7XHJcbiAgICAgIGxpc3QucHVzaCguLi7lkI7pnaLnmoTlhYTlvJ/lhYPntKAoY3VyKSk7XHJcbiAgICAgIGN1ciA9IGN1ci5wYXJlbnROb2RlO1xyXG4gICAgfVxyXG4gICAgY3VyID0gbmV4dDtcclxuICAgIHdoaWxlICgh5YWx5a2Y5bGCLmluY2x1ZGVzKGN1cikpIHtcclxuICAgICAgbGlzdC5wdXNoKC4uLuWJjemdoueahOWFhOW8n+WFg+e0oChjdXIpKTtcclxuICAgICAgY3VyID0gY3VyLnBhcmVudE5vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxpc3Q7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0V2luZG93KCkge1xyXG4gIHJldHVybiB0eXBlb2YgdW5zYWZlV2luZG93ID09PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdW5zYWZlV2luZG93O1xyXG59XHJcbiIsIi8vIC8vIEZpcmViYXNlIEFwcCAodGhlIGNvcmUgRmlyZWJhc2UgU0RLKSBpcyBhbHdheXMgcmVxdWlyZWQgYW5kXHJcbi8vIC8vIG11c3QgYmUgbGlzdGVkIGJlZm9yZSBvdGhlciBGaXJlYmFzZSBTREtzXHJcbi8vIGltcG9ydCAqIGFzIGZpcmViYXNlIGZyb20gXCJmaXJlYmFzZS9hcHBcIjtcclxuXHJcbi8vIC8vIEFkZCB0aGUgRmlyZWJhc2Ugc2VydmljZXMgdGhhdCB5b3Ugd2FudCB0byB1c2VcclxuLy8gaW1wb3J0IFwiZmlyZWJhc2UvYXV0aFwiO1xyXG4vLyBpbXBvcnQgXCJmaXJlYmFzZS9maXJlc3RvcmVcIjtcclxuXHJcbi8vIGZpcmViYXNlLmluaXRpYWxpemVBcHAoe1xyXG4vLyAgIGFwaUtleTogXCJBSXphU3lDWHk2X0d3Vm9ncVB3WnlKai1LUFhJYi1KZlFhVy1NVFlcIixcclxuLy8gICBhdXRoRG9tYWluOiBcImxsZWotMmU4NTEuZmlyZWJhc2VhcHAuY29tXCIsXHJcbi8vICAgZGF0YWJhc2VVUkw6IFwiaHR0cHM6Ly9sbGVqLTJlODUxLmZpcmViYXNlaW8uY29tXCIsXHJcbi8vICAgcHJvamVjdElkOiBcImxsZWotMmU4NTFcIixcclxuLy8gICBzdG9yYWdlQnVja2V0OiBcImxsZWotMmU4NTEuYXBwc3BvdC5jb21cIixcclxuLy8gICBtZXNzYWdpbmdTZW5kZXJJZDogXCI0MTk3OTkxMjI4NTJcIixcclxuLy8gICBhcHBJZDogXCIxOjQxOTc5OTEyMjg1Mjp3ZWI6MzZkZGIyMzE4MDMxNGE4Yjk4NzczMVwiLFxyXG4vLyAgIG1lYXN1cmVtZW50SWQ6IFwiRy1TTjQyRVNaWDc4XCIsXHJcbi8vIH0pO1xyXG5cclxuZXhwb3J0IGNvbnN0IGZpcmVTdG9yZSA9IHt9XHJcblxyXG4vLyAvKiog55uR5ZCs55So5oi354q25oCB5pS55Y+YICovXHJcbi8vIC8vIGZpcmViYXNlLmF1dGgoKS5vbkF1dGhTdGF0ZUNoYW5nZWQoZnVuY3Rpb24gKHVzZXIpIHtcclxuLy8gLy8gICBpZiAodXNlcikge1xyXG4vLyAvLyAgICAgY29uc29sZS5sb2coXCJb55m75b2V5oiQ5YqfXVwiLCB1c2VyLmVtYWlsKTtcclxuLy8gLy8gICB9XHJcbi8vIC8vIH0pO1xyXG5cclxuLy8gLy8gZmlyZWJhc2VcclxuLy8gLy8gICAuYXV0aCgpXHJcbi8vIC8vICAgLnNpZ25JbldpdGhFbWFpbEFuZFBhc3N3b3JkKFwiYWRtaW5Ac2hlbnppbG9uZy5jblwiLCBcIjk4NzQ1NjMyMVwiKVxyXG4vLyAvLyAgIC5jYXRjaChmdW5jdGlvbiAoZXJyb3IpIHtcclxuLy8gLy8gICAgIC8vIEhhbmRsZSBFcnJvcnMgaGVyZS5cclxuLy8gLy8gICAgIHZhciBlcnJvckNvZGUgPSBlcnJvci5jb2RlO1xyXG4vLyAvLyAgICAgdmFyIGVycm9yTWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XHJcbi8vIC8vICAgICAvLyAuLi5cclxuLy8gLy8gICB9KTtcclxuIiwiLyoqIOW9k+WJjeiiq+mAieS4reeahOWFg+e0oCAqL1xyXG5cclxuaW1wb3J0IHsgZmlyZVN0b3JlIH0gZnJvbSBcIi4vcmVtb3RlLnN0YXRlXCI7XHJcblxyXG5leHBvcnQgbGV0IGN1cnJlbnRFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuXHJcbmV4cG9ydCBsZXQgcGF0aDogSFRNTEVsZW1lbnRbXTtcclxuXHJcbi8qKiDkv67mlLnlvZPliY3mjIflkJHnmoTlhYPntKDlkozot6/lvoQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFBhdGgoZWxMaXN0OiBIVE1MRWxlbWVudFtdKSB7XHJcbiAgcGF0aCA9IGVsTGlzdDtcclxuICBjdXJyZW50RWxlbWVudCA9IGVsTGlzdFswXTtcclxufVxyXG5cclxuLyoqIOagh+iusOiiq+S/ruaUueWQjueahOWFg+e0oCjooqvmsaHmn5PkuobnmoTlhYPntKAp77yM5Lul5L6/5L+d5a2Y5L+u5pS555qE5YaF5a65ICovXHJcbmV4cG9ydCBjb25zdCBlZGl0RWxlbWVudDogU2V0PEVsZW1lbnQ+ID0gbmV3IFNldCgpO1xyXG5cclxuLy8gY29uc3QgZ2xvYmFsU2V0dGluZ1JlZiA9IGZpcmVTdG9yZS5kb2MoXCJzZXR0aW5nL2dsb2JhbFwiKTtcclxuLy8gZ2xvYmFsU2V0dGluZ1JlZi5vblNuYXBzaG90KHtcclxuLy8gICBuZXh0KHIpIHtcclxuLy8gICAgIGNvbnNvbGUubG9nKFwiWyAgICByXVwiLCByLmRhdGEoKSk7XHJcbi8vICAgfSxcclxuLy8gfSk7XHJcbi8vIGdsb2JhbFNldHRpbmdSZWYudXBkYXRlKHtcclxuLy8gICB0ZXN0OiAzLFxyXG4vLyB9KTtcclxuLy8gZ2xvYmFsU2V0dGluZ1JlZlxyXG4vLyAgIC8vICAgLmRvYyhcInNhbXBsZXMvc2FuZHdpY2hEYXRhXCIpXHJcbi8vICAgLmdldCgpXHJcbi8vICAgLnRoZW4oKHIpID0+IHt9KTtcclxuIiwiaW1wb3J0IHsgbm9vcCwgc2FmZV9ub3RfZXF1YWwsIHN1YnNjcmliZSwgcnVuX2FsbCwgaXNfZnVuY3Rpb24gfSBmcm9tICcuLi9pbnRlcm5hbCc7XG5leHBvcnQgeyBnZXRfc3RvcmVfdmFsdWUgYXMgZ2V0IH0gZnJvbSAnLi4vaW50ZXJuYWwnO1xuXG5jb25zdCBzdWJzY3JpYmVyX3F1ZXVlID0gW107XG4vKipcbiAqIENyZWF0ZXMgYSBgUmVhZGFibGVgIHN0b3JlIHRoYXQgYWxsb3dzIHJlYWRpbmcgYnkgc3Vic2NyaXB0aW9uLlxuICogQHBhcmFtIHZhbHVlIGluaXRpYWwgdmFsdWVcbiAqIEBwYXJhbSB7U3RhcnRTdG9wTm90aWZpZXJ9c3RhcnQgc3RhcnQgYW5kIHN0b3Agbm90aWZpY2F0aW9ucyBmb3Igc3Vic2NyaXB0aW9uc1xuICovXG5mdW5jdGlvbiByZWFkYWJsZSh2YWx1ZSwgc3RhcnQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdWJzY3JpYmU6IHdyaXRhYmxlKHZhbHVlLCBzdGFydCkuc3Vic2NyaWJlXG4gICAgfTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgYFdyaXRhYmxlYCBzdG9yZSB0aGF0IGFsbG93cyBib3RoIHVwZGF0aW5nIGFuZCByZWFkaW5nIGJ5IHN1YnNjcmlwdGlvbi5cbiAqIEBwYXJhbSB7Kj19dmFsdWUgaW5pdGlhbCB2YWx1ZVxuICogQHBhcmFtIHtTdGFydFN0b3BOb3RpZmllcj19c3RhcnQgc3RhcnQgYW5kIHN0b3Agbm90aWZpY2F0aW9ucyBmb3Igc3Vic2NyaXB0aW9uc1xuICovXG5mdW5jdGlvbiB3cml0YWJsZSh2YWx1ZSwgc3RhcnQgPSBub29wKSB7XG4gICAgbGV0IHN0b3A7XG4gICAgY29uc3Qgc3Vic2NyaWJlcnMgPSBbXTtcbiAgICBmdW5jdGlvbiBzZXQobmV3X3ZhbHVlKSB7XG4gICAgICAgIGlmIChzYWZlX25vdF9lcXVhbCh2YWx1ZSwgbmV3X3ZhbHVlKSkge1xuICAgICAgICAgICAgdmFsdWUgPSBuZXdfdmFsdWU7XG4gICAgICAgICAgICBpZiAoc3RvcCkgeyAvLyBzdG9yZSBpcyByZWFkeVxuICAgICAgICAgICAgICAgIGNvbnN0IHJ1bl9xdWV1ZSA9ICFzdWJzY3JpYmVyX3F1ZXVlLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN1YnNjcmliZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHMgPSBzdWJzY3JpYmVyc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgc1sxXSgpO1xuICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyX3F1ZXVlLnB1c2gocywgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocnVuX3F1ZXVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3Vic2NyaWJlcl9xdWV1ZS5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlcl9xdWV1ZVtpXVswXShzdWJzY3JpYmVyX3F1ZXVlW2kgKyAxXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlcl9xdWV1ZS5sZW5ndGggPSAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiB1cGRhdGUoZm4pIHtcbiAgICAgICAgc2V0KGZuKHZhbHVlKSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHN1YnNjcmliZShydW4sIGludmFsaWRhdGUgPSBub29wKSB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBbcnVuLCBpbnZhbGlkYXRlXTtcbiAgICAgICAgc3Vic2NyaWJlcnMucHVzaChzdWJzY3JpYmVyKTtcbiAgICAgICAgaWYgKHN1YnNjcmliZXJzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgc3RvcCA9IHN0YXJ0KHNldCkgfHwgbm9vcDtcbiAgICAgICAgfVxuICAgICAgICBydW4odmFsdWUpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzdWJzY3JpYmVycy5pbmRleE9mKHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc3Vic2NyaWJlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgc3RvcCgpO1xuICAgICAgICAgICAgICAgIHN0b3AgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4geyBzZXQsIHVwZGF0ZSwgc3Vic2NyaWJlIH07XG59XG5mdW5jdGlvbiBkZXJpdmVkKHN0b3JlcywgZm4sIGluaXRpYWxfdmFsdWUpIHtcbiAgICBjb25zdCBzaW5nbGUgPSAhQXJyYXkuaXNBcnJheShzdG9yZXMpO1xuICAgIGNvbnN0IHN0b3Jlc19hcnJheSA9IHNpbmdsZVxuICAgICAgICA/IFtzdG9yZXNdXG4gICAgICAgIDogc3RvcmVzO1xuICAgIGNvbnN0IGF1dG8gPSBmbi5sZW5ndGggPCAyO1xuICAgIHJldHVybiByZWFkYWJsZShpbml0aWFsX3ZhbHVlLCAoc2V0KSA9PiB7XG4gICAgICAgIGxldCBpbml0ZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgICAgIGxldCBwZW5kaW5nID0gMDtcbiAgICAgICAgbGV0IGNsZWFudXAgPSBub29wO1xuICAgICAgICBjb25zdCBzeW5jID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHBlbmRpbmcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjbGVhbnVwKCk7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBmbihzaW5nbGUgPyB2YWx1ZXNbMF0gOiB2YWx1ZXMsIHNldCk7XG4gICAgICAgICAgICBpZiAoYXV0bykge1xuICAgICAgICAgICAgICAgIHNldChyZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY2xlYW51cCA9IGlzX2Z1bmN0aW9uKHJlc3VsdCkgPyByZXN1bHQgOiBub29wO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1bnN1YnNjcmliZXJzID0gc3RvcmVzX2FycmF5Lm1hcCgoc3RvcmUsIGkpID0+IHN1YnNjcmliZShzdG9yZSwgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB2YWx1ZXNbaV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIHBlbmRpbmcgJj0gfigxIDw8IGkpO1xuICAgICAgICAgICAgaWYgKGluaXRlZCkge1xuICAgICAgICAgICAgICAgIHN5bmMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgKCkgPT4ge1xuICAgICAgICAgICAgcGVuZGluZyB8PSAoMSA8PCBpKTtcbiAgICAgICAgfSkpO1xuICAgICAgICBpbml0ZWQgPSB0cnVlO1xuICAgICAgICBzeW5jKCk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBzdG9wKCkge1xuICAgICAgICAgICAgcnVuX2FsbCh1bnN1YnNjcmliZXJzKTtcbiAgICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgfTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IHsgZGVyaXZlZCwgcmVhZGFibGUsIHdyaXRhYmxlIH07XG4iLCJpbXBvcnQgeyB3cml0YWJsZSB9IGZyb20gXCJzdmVsdGUvc3RvcmVcIjtcclxuXHJcbi8qKiDnm67liY3lnKjlkYjnjrDnmoTmtojmga/liJfooaggKi9cclxuZXhwb3J0IGNvbnN0IG1lc3NhZ2VMaXN0ID0gd3JpdGFibGUoW10pO1xyXG5cclxuLyoqIOa2iOaBr+eahOWfuuexuyDmianlsZXnsbvorrDlvpfph43lhpkgdGhhdE1lc3NhZ2Ug5Lul5YWN5YWs55So5Ye6546wYnVnICovXHJcbmV4cG9ydCBjbGFzcyBNZXNzYWdlIHtcclxuICAvKiog55So5p2l5oyH5ZCR5LiN5ZCM55qE57G777yM5Lul5L6/5omp5bGV6L+Z5Liq57G755qE57G755qEb2xkX21lc3NhZ2XkuI3ooqvlhaznlKggKi9cclxuICBwcml2YXRlIGF1dG9IaWRlVGltZSA9IDEwMDAgKiAzO1xyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXI6IE1lc3NhZ2VfRGF0YSkge31cclxuXHJcbiAgLyoqIOWxleekumVsICovXHJcbiAgc2hvdygpIHtcclxuICAgIG1lc3NhZ2VMaXN0LnVwZGF0ZSgocikgPT4gWy4uLnIsIHRoaXNdKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuICAvKiog6ZqQ6JePZWwgKi9cclxuICBoaWRlKCkge1xyXG4gICAgbWVzc2FnZUxpc3QudXBkYXRlKChyKSA9PiByLmZpbHRlcigoZWwpID0+IHRoaXMgIT09IGVsKSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcbiAgLyoqIOWxleekumVsICBhdXRvSGlkZVRpbWUg5q+r56eS5ZCO6ZqQ6JePKi9cclxuICBhdXRvSGlkZSgpIHtcclxuICAgIHRoaXMuc2hvdygpO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgfSwgdGhpcy5hdXRvSGlkZVRpbWUpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG4gIC8qKiDojrflj5bkuIDkuKpNZXNzYWdl5a+56LGhICovXHJcbiAgc3RhdGljIGdldE1lc3NhZ2UocGFyOiBNZXNzYWdlX0RhdGEpIHtcclxuICAgIHJldHVybiBuZXcgTWVzc2FnZShwYXIpO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBNZXNzYWdlX0RhdGEge1xyXG4gIG1zZzogc3RyaW5nO1xyXG4gIHN0eWxlPzogc3RyaW5nO1xyXG59XHJcbiIsImltcG9ydCB7IHJlYWN0aXZlIH0gZnJvbSBcInZ1ZVwiO1xyXG5pbXBvcnQgeyBsb2FkQ2hhbmdlcyB9IGZyb20gXCIuLi9mdW4vZnVuXCI7XHJcbmltcG9ydCB7IEFsbFN0b3JlTmFtZSB9IGZyb20gXCIuLi9jb25maWdcIjtcclxuaW1wb3J0IHR5cGUgeyBjb21tYW5kSlNPTiB9IGZyb20gXCIuLi9mdW4vY29tbWFuZFwiO1xyXG5cclxuLyoqIOiuvue9ruS4gOadoeacrOWcsOWtmOWCqCAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0TG9jYWxJdGVtKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZykge1xyXG4gIC8v5Li65LqG5Zyo6Z2e5rK554y0546v5aKD5LiL5a2Y5YKo5L6d5pen6IO96LW35LiA6YOo5YiG55qE5L2c55SoXHJcbiAgaWYgKHR5cGVvZiB1bnNhZmVXaW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgIHJldHVybiBhd2FpdCBHTS5zZXRWYWx1ZShuYW1lLCB2YWx1ZSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBhd2FpdCBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShuYW1lLCBTdHJpbmcodmFsdWUpKTtcclxuICB9XHJcbn1cclxuXHJcbi8qKiDor7vlj5bkuIDmnaHmnKzlnLDlrZjlgqggKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldExvY2FsSXRlbTxUPigvKiog6ZSu5ZCNICovIG5hbWU6IHN0cmluZywgLyoqIOayoeacieeahOaXtuWAmeeahOm7mOiupOWAvCAqLyBkZWZhdWx0VmFsdWU/OiBUKSB7XHJcbiAgaWYgKHR5cGVvZiB1bnNhZmVXaW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IEdNLmdldFZhbHVlKG5hbWUsIGRlZmF1bHRWYWx1ZSk7XHJcbiAgICByZXR1cm4gcmVzO1xyXG4gIH0gZWxzZSB7XHJcbiAgICAvL+S4uuS6huWcqOmdnuayueeMtOeOr+Wig+S4i+WtmOWCqOS+neaXp+iDvei1t+S4gOmDqOWIhueahOS9nOeUqFxyXG4gICAgY29uc3QgdmFsdWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShuYW1lKTtcclxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIGF3YWl0IGRlZmF1bHRWYWx1ZTtcclxuICAgIHJldHVybiBhd2FpdCB2YWx1ZTtcclxuICB9XHJcbn1cclxuXHJcbi8qKiDmiYDmnInooqvlrZjlgqjnmoTkuJzopb8gKi9cclxuZXhwb3J0IGludGVyZmFjZSBBbGxTdG9yZSB7XHJcbiAgQ29tbWFuZFN0YWNrOiBjb21tYW5kSlNPTltdO1xyXG4gIGVsZW1lbnRfTGlzdDoge1xyXG4gICAgWy8qKiDpgInmi6nlmaggKi8gbmFtZTogc3RyaW5nXTogLyoqIGlubmVySFRNTCAqLyBzdHJpbmc7XHJcbiAgfTtcclxuICBIaWdobGlnaHRlZF9jb3VudDogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgY3VyU3RvcmUgPSByZWFjdGl2ZSh7XHJcbiAgQ29tbWFuZFN0YWNrOiBbXSBhcyBjb21tYW5kSlNPTltdLFxyXG4gIGVsZW1lbnRfTGlzdDoge30gYXMge1xyXG4gICAgWy8qKiDpgInmi6nlmaggKi8gbmFtZTogc3RyaW5nXTogLyoqIGlubmVySFRNTCAqLyBzdHJpbmc7XHJcbiAgfSxcclxuICAvKiog55So5LqO6K6w5b2V6auY5LquIGlkIOmBv+WFjeaWsOmrmOS6ruWHuueOsOmHjeWkjSAqL1xyXG4gIEhpZ2hsaWdodGVkX2NvdW50OiAwIGFzIG51bWJlcixcclxufSk7XHJcblxyXG5nZXRMb2NhbEl0ZW0oQWxsU3RvcmVOYW1lLCBcInt9XCIpLnRoZW4oKHMpID0+IHtcclxuICBPYmplY3QuYXNzaWduKGN1clN0b3JlLCBKU09OLnBhcnNlKHMpKTtcclxuICAvKiog6Ieq5Yqo5Yqg6L295pys5Zyw5pqC5a2Y5pu05pS5ICovXHJcbiAgKGFzeW5jICgpID0+IHtcclxuICAgIGNvbnNvbGUubG9nKGN1clN0b3JlKTtcclxuICAgIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSBcImNvbXBsZXRlXCIpIHtcclxuICAgICAgbG9hZENoYW5nZXMoY3VyU3RvcmUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBsb2FkQ2hhbmdlcyhjdXJTdG9yZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH0pKCk7XHJcbn0pO1xyXG4iLCJpbXBvcnQgY29uZmlnIGZyb20gXCIuLi9jb25maWdcIjtcclxuaW1wb3J0IHsgc2V0TG9jYWxJdGVtLCBnZXRMb2NhbEl0ZW0gfSBmcm9tIFwiLi4vbGliL3N0b3JlXCI7XHJcbmltcG9ydCB7IGdldEpTb24gfSBmcm9tIFwiLi4vdXRpbFwiO1xyXG5cclxuLyoqIOeUqOadpeivhuWIq+i6q+S7veeahGtleSAqL1xyXG5sZXQga2V5PScnXHJcblxyXG4vKiog6ZmE5bim55m75b2V5L+h5oGv55qEYWpheCAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXVfZ2V0SlNPTih1cmw6c3RyaW5nLGRhdGE/OmFueSl7XHJcbiAgICBpZihkYXRhPT09dW5kZWZpbmVkKVxyXG4gICAgICAgIGRhdGE9e31cclxuICAgIGRhdGEua2V5PWtleT9rZXk6YXdhaXQgZ2V0TG9jYWxJdGVtKGNvbmZpZy5sb2dpbkNyZWRlbnRpYWxzKVxyXG4gICAgcmV0dXJuIGdldEpTb24odXJsLGRhdGEpXHJcbn1cclxuXHJcbi8qKiDnmbvlvZUgKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIF9sb2dpbihwYXI6e1xyXG4gICAgdXNlcjogc3RyaW5nLFxyXG4gICAgc2VjcmV0X2tleTogc3RyaW5nLFxyXG59KXtcclxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGdldEpTb24oY29uZmlnLnNlcnZlcklwICsgJ2xvZ2luJywgcGFyKVxyXG4gICAgaWYocmVzLmJvZHkgJiYgcmVzLmJvZHkubGVuZ3RoPjApXHJcbiAgICAgICAga2V5PXJlcy5ib2R5XHJcbiAgICBzZXRMb2NhbEl0ZW0oY29uZmlnLmxvZ2luQ3JlZGVudGlhbHMsa2V5KVxyXG4gICAgcmV0dXJuIHJlc1xyXG59XHJcblxyXG4vKiog5rOo5YaMICovXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW1vdGVfcmVnaXN0ZXIocGFyOiB7XHJcbiAgICB1c2VyOiBzdHJpbmcsXHJcbiAgICBzZWNyZXRfa2V5OiBzdHJpbmcsXHJcbn0pIHtcclxuICAgIHJldHVybiBhd2FpdCBnZXRKU29uKGNvbmZpZy5zZXJ2ZXJJcCArICdyZWdpc3RlcicsIHBhcilcclxufVxyXG5cclxuLyoqIOiOt+WPluWtmOWCqOW6kyAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVtb3RlX2dldFN0b3JlKHBhcjoge1xyXG4gICAgdXJsOiBzdHJpbmcsXHJcbn0pIHtcclxuICAgIHJldHVybiBhd2FpdCBhdV9nZXRKU09OKGNvbmZpZy5zZXJ2ZXJJcCArICdnZXRTdG9yZScsIHBhcilcclxufVxyXG5cclxuLyoqIOiuvue9ruWtmOWCqOW6kyAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVtb3RlX3NldFN0b3JlKHBhcjoge1xyXG4gICAgdXJsOiBzdHJpbmcsXHJcbiAgICBzdG9yZTogc3RyaW5nXHJcbn0pIHtcclxuICAgIHJldHVybiBhd2FpdCBhdV9nZXRKU09OKGNvbmZpZy5zZXJ2ZXJJcCArICdzZXRTdG9yZScsIHBhcilcclxufVxyXG5cclxuLyoqIOiOt+WPluWtmOWCqOW6kyAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVtb3RlX2dldEFsbFN0b3JlKCkge1xyXG4gICAgcmV0dXJuIGF3YWl0IGF1X2dldEpTT04oY29uZmlnLnNlcnZlcklwICsgJ2dldEFsbFN0b3JlJylcclxufSIsImV4cG9ydCBjbGFzcyBTdHlsZSB7XHJcbiAgICBzdGF0aWMgbWVzc2FnZSA9IGBcclxuICAgIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XHJcbiAgICBwb3NpdGlvbjogZml4ZWQ7XHJcbiAgICB0b3A6IDIwcHg7XHJcbiAgICBsZWZ0OiAzMHB4O1xyXG4gICAgYW5pbWF0aW9uOiBsbGVqX215Zmlyc3QgNXM7XHJcbiAgICB6LWluZGV4OjgwMDtcclxuICAgIGBcclxuICAgIHN0YXRpYyB3YXJuaW5nID0gYFxyXG4gICAgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7XHJcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZWQ7XHJcbiAgICBwb3NpdGlvbjogZml4ZWQ7XHJcbiAgICB0b3A6IDIwcHg7XHJcbiAgICBsZWZ0OiAzMHB4O1xyXG4gICAgei1pbmRleDo4MDA7XHJcbiAgICBgXHJcbiAgICBzdGF0aWMgbm90ZSA9IGBcclxuICAgIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrO1xyXG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2M2YzViYTtcclxuICAgIHBvc2l0aW9uOiBzdGlja3k7XHJcbiAgICB0b3A6IDIwcHg7XHJcbiAgICBsZWZ0OiAzMHB4O1xyXG4gICAgd2lkdGg6IGF1dG87XHJcbiAgICBoZWlnaHQ6IGF1dG87XHJcbiAgICB6LWluZGV4OjgwMDtcclxuICAgIGBcclxufVxyXG5cclxuLyoqIOazqOWFpeWKqOeUuyAqL1xyXG5jb25zdCBrZXlmcmFtZXM9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcclxua2V5ZnJhbWVzLmlubmVySFRNTD1gXHJcbkBrZXlmcmFtZXMgbGxlal9teWZpcnN0XHJcbntcclxuICAgIGZyb20geyBiYWNrZ3JvdW5kOiByZWQ7Y29sb3I6d2hpdGU7IH1cclxuICAgIHRvIHsgYmFja2dyb3VuZDogeWVsbG93O2NvbG9yOmJsYWNrOyB9XHJcbn1cclxuYFxyXG5kb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKGtleWZyYW1lcykiLCJpbXBvcnQgeyBNZXNzYWdlLCBNZXNzYWdlX0RhdGEgfSBmcm9tIFwiLi9tZXNzYWdlXCI7XHJcbmltcG9ydCB7IFN0eWxlIH0gZnJvbSBcIi4vc3R5bGVcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBXYXJuaW5nIGV4dGVuZHMgTWVzc2FnZXtcclxuICAgIGNvbnN0cnVjdG9yKHsgbXNnIH06IE1lc3NhZ2VfRGF0YSl7XHJcbiAgICAgICAgc3VwZXIoeyBtc2cgLHN0eWxlOlN0eWxlLndhcm5pbmd9KVxyXG4gICAgfVxyXG59IiwiaW1wb3J0IGNvbmZpZywgeyBBbGxTdG9yZU5hbWUgfSBmcm9tIFwiLi4vY29uZmlnXCI7XHJcbmltcG9ydCB7IEFsbFN0b3JlLCBjdXJTdG9yZSwgc2V0TG9jYWxJdGVtIH0gZnJvbSBcIi4uL2xpYi9zdG9yZVwiO1xyXG5pbXBvcnQgeyBNZXNzYWdlIH0gZnJvbSBcIi4uL3VpL21lc3NhZ2VcIjtcclxuaW1wb3J0IHsgcmVtb3RlX2dldFN0b3JlLCByZW1vdGVfc2V0U3RvcmUsIHJlbW90ZV9yZWdpc3RlciwgX2xvZ2luIH0gZnJvbSBcIi4vYWpheFwiO1xyXG5pbXBvcnQgeyBDb21tYW5kQ29udHJvbCwgZWRpdFNlbGVjdCwgZGVsZXRlU2VsZWN0LCBjbG9zZUVkaXRTZWxlY3QsIGFkZE5vdGUgfSBmcm9tIFwiLi9jb21tYW5kXCI7XHJcbmltcG9ydCB7IGN1cnJlbnRFbGVtZW50LCBlZGl0RWxlbWVudCwgc2V0UGF0aCB9IGZyb20gXCIuLi9zdGF0ZS9pbmRleFwiO1xyXG5pbXBvcnQgeyBXYXJuaW5nIH0gZnJvbSBcIi4uL3VpL3dhcm5pbmdcIjtcclxuaW1wb3J0ICQsIHsgZ2V0U2VsZWN0b3JzLCBub2RlUGF0aCwgbG9nIH0gZnJvbSBcIi4uL3V0aWxcIjtcclxuXHJcbi8qKiDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDwn4+z4oCN8J+MiCDmj5Dkvpvnu5nnlKjmiLfkvb/nlKjnmoTlip/og70g8J+Ps+KAjfCfjIjilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZBcclxuICpcclxuICoqIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkPCfmqcg5o+Q5L6b57uZ55So5oi35L2/55So55qE5Yqf6IO9IPCfmqfilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgKi9cclxuXHJcbmV4cG9ydCBjb25zdCBmdW4gPSB7XHJcbiAgLyoqIOS9v+WFg+e0oOWPr+e8lui+kSAqL1xyXG4gIGVkaXRFbGVtZW50KCkge1xyXG4gICAgaWYgKGN1cnJlbnRFbGVtZW50LmlubmVySFRNTC5sZW5ndGggPiAxMCAqIDEwMDApXHJcbiAgICAgIHJldHVybiBuZXcgV2FybmluZyh7IG1zZzogXCLor6XlhYPntKDlhoXlrrnov4flpKfvvIzor7fpgInmi6nmm7Tnoa7lrprnmoTmlofmnKzlhYPntKDjgIJcIiB9KS5hdXRvSGlkZSgpO1xyXG4gICAgQ29tbWFuZENvbnRyb2wucnVuKG5ldyBlZGl0U2VsZWN0KGN1cnJlbnRFbGVtZW50KSk7XHJcbiAgfSxcclxuICAvKiog5Yig6Zmk5YWD57SgICovXHJcbiAgZGVsZXRlRWxlbWVudCgpIHtcclxuICAgIENvbW1hbmRDb250cm9sLnJ1bihuZXcgZGVsZXRlU2VsZWN0KGN1cnJlbnRFbGVtZW50KSk7XHJcbiAgfSxcclxuICAvKiog5aSN5Yi2dGl0bGUgKi9cclxuICBjb3B5VGl0bGUoKSB7XHJcbiAgICAkLmNvcHlUaXRsZShjdXJyZW50RWxlbWVudCk7XHJcbiAgfSxcclxuICAvKiog5YWz6Zet5Y+v57yW6L6RICovXHJcbiAgY2xvc2VFZGl0KCkge1xyXG4gICAgQ29tbWFuZENvbnRyb2wucnVuKG5ldyBjbG9zZUVkaXRTZWxlY3QoY3VycmVudEVsZW1lbnQpKTtcclxuICB9LFxyXG4gIC8qKiDmkqTplIAgKi9cclxuICBiYWNrT3V0KCkge1xyXG4gICAgQ29tbWFuZENvbnRyb2wuYmFja091dCgpO1xyXG4gIH0sXHJcbiAgLyoqIOmHjeWBmiAqL1xyXG4gIHVuZG8oKSB7XHJcbiAgICBDb21tYW5kQ29udHJvbC5yZWZvcm0oKTtcclxuICB9LFxyXG4gIC8qKiDmlrDlop7nrJTorrAgKi9cclxuICBhZGROb3RlKCkge1xyXG4gICAgQ29tbWFuZENvbnRyb2wucnVuKG5ldyBhZGROb3RlKGN1cnJlbnRFbGVtZW50KSk7XHJcbiAgfSxcclxuICAvKiog5L+d5a2Y5omA5pyJ55qE5L+u5pS5ICovXHJcbiAgc2F2ZUNoYW5nZXMoKSB7XHJcbiAgICBzYXZlQ2hhbmdlcyhlZGl0RWxlbWVudCk7XHJcbiAgICBuZXcgTWVzc2FnZSh7IG1zZzogXCLkv53lrZjmiJDlip9cIiB9KS5hdXRvSGlkZSgpO1xyXG4gIH0sXHJcbiAgLyoqIOWwhuS/ruaUueS4iuS8oOWIsOS6keerryAqL1xyXG4gIGFzeW5jIHVwbG9hZFRoZSgpIHtcclxuICAgIHJlbW90ZV9zZXRTdG9yZSh7XHJcbiAgICAgIHVybDogY29uZmlnLmxvY2F0aW9uVXJsLFxyXG4gICAgICBzdG9yZTogYXdhaXQgc2F2ZUNoYW5nZXMoZWRpdEVsZW1lbnQpLFxyXG4gICAgfSkudGhlbigocikgPT4ge1xyXG4gICAgICBuZXcgTWVzc2FnZSh7IG1zZzogXCLkupHnq6/lrZjlgqg6XCIgKyByLm1lc3NhZ2UgfSkuYXV0b0hpZGUoKTtcclxuICAgIH0pO1xyXG4gIH0sXHJcbiAgLyoqIOS7juS6keerr+S4i+i9veS/ruaUuSAqL1xyXG4gIGRvd25sb2FkVGhlKCkge1xyXG4gICAgbmV3IE1lc3NhZ2UoeyBtc2c6IFwi5q2j5Zyo6K+75Y+W5LqR56uv5a2Y5YKoXCIgfSkuYXV0b0hpZGUoKTtcclxuICAgIHJlbW90ZV9nZXRTdG9yZSh7XHJcbiAgICAgIHVybDogY29uZmlnLmxvY2F0aW9uVXJsLFxyXG4gICAgfSkudGhlbigocikgPT4ge1xyXG4gICAgICBpZiAoci5ib2R5ID09PSB1bmRlZmluZWQgfHwgci5ib2R5Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBNZXNzYWdlKHsgbXNnOiBcIuS6keerr+WtmOWCqDpcIiArIHIubWVzc2FnZSB9KS5hdXRvSGlkZSgpO1xyXG4gICAgICBjb25zdCBhbGxTdG9yZSA9IDxBbGxTdG9yZT5KU09OLnBhcnNlKHIuYm9keVswXS5zdG9yZSk7XHJcbiAgICAgIGxvYWRDaGFuZ2VzKGFsbFN0b3JlKTtcclxuICAgICAgbmV3IE1lc3NhZ2UoeyBtc2c6IFwi5LqR56uv5a2Y5YKoOlwiICsgci5tZXNzYWdlIH0pLmF1dG9IaWRlKCk7XHJcbiAgICB9KTtcclxuICB9LFxyXG4gIC8qKiDms6jlhowgKi9cclxuICByZWdpc3RlcigpIHtcclxuICAgIHJlZ2lzdGVyKCk7XHJcbiAgfSxcclxuICAvKiog55m75b2VICovXHJcbiAgbG9naW4oKSB7XHJcbiAgICBsb2dpbigpO1xyXG4gIH0sXHJcbn07XHJcbi8qKiDmjInplK7lkozlh73mlbDnmoTmmKDlsITlhbPns7sgKi9cclxuZXhwb3J0IGNvbnN0IEtleU1hcCA9IHtcclxuICBLZXlROiBbZnVuLmVkaXRFbGVtZW50XSxcclxuICBLZXlEOiBbZnVuLmRlbGV0ZUVsZW1lbnRdLFxyXG4gIEtleUM6IFtmdW4uY29weVRpdGxlXSxcclxuICBLZXlXOiBbZnVuLmNsb3NlRWRpdF0sXHJcbiAgS2V5WjogW2Z1bi5iYWNrT3V0XSxcclxuICBLZXlZOiBbZnVuLnVuZG9dLFxyXG4gIEtleU46IFtmdW4uYWRkTm90ZV0sXHJcbiAgS2V5UzogW2Z1bi5zYXZlQ2hhbmdlc10sXHJcbiAgS2V5TzogW2Z1bi51cGxvYWRUaGVdLFxyXG4gIEtleVA6IFtmdW4uZG93bmxvYWRUaGUsIGZ1bi5zYXZlQ2hhbmdlc10sXHJcbiAgS2V5SzogW2Z1bi5yZWdpc3Rlcl0sXHJcbiAgS2V5TDogW2Z1bi5sb2dpbl0sXHJcbn07XHJcblxyXG4vKiog5L+d5a2Y5L+u5pS5ICovXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYXZlQ2hhbmdlcyhlZGl0RWxlbWVudDogU2V0PEVsZW1lbnQ+KSB7XHJcbiAgY29uc3QgZGF0YSA9IHtcclxuICAgIGVsZW1lbnRfTGlzdDoge30gYXMgQWxsU3RvcmVbXCJlbGVtZW50X0xpc3RcIl0sXHJcbiAgICBDb21tYW5kU3RhY2s6IENvbW1hbmRDb250cm9sLmNvbW1hbmRTdGFjayxcclxuICB9O1xyXG4gIC8qKiDojrflj5bkv67mlLnov4fnmoTlhYPntKDnmoRodG1sICovXHJcbiAgZWRpdEVsZW1lbnQuZm9yRWFjaCgoZWwpID0+IHtcclxuICAgIGNvbnN0IHNlbGVjdG9ycyA9IGdldFNlbGVjdG9ycyhlbCk7XHJcbiAgICBkYXRhLmVsZW1lbnRfTGlzdFtzZWxlY3RvcnNdID0gZWwuaW5uZXJIVE1MO1xyXG4gIH0pO1xyXG4gIGNvbnN0IGRhdGFfc3RyID0gSlNPTi5zdHJpbmdpZnkoT2JqZWN0LmFzc2lnbihjdXJTdG9yZSwgZGF0YSkpO1xyXG4gIGF3YWl0IHNldExvY2FsSXRlbShBbGxTdG9yZU5hbWUsIEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcclxuICByZXR1cm4gZGF0YV9zdHI7XHJcbn1cclxuXHJcbi8qKiDliqDovb3kv67mlLkgKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRDaGFuZ2VzKGFsbFN0b3JlOiBBbGxTdG9yZSkge1xyXG4gIC8qKiDlsIbkv67mlLnov4fnmoQgaHRtbCDlhpnlm57ljrsgKi9cclxuICBmb3IgKGNvbnN0IHNlbGVjdG9ycyBpbiBhbGxTdG9yZS5lbGVtZW50X0xpc3QpIHtcclxuICAgIGNvbnN0IGh0bWwgPSBhbGxTdG9yZS5lbGVtZW50X0xpc3Rbc2VsZWN0b3JzXTtcclxuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcnMpO1xyXG4gICAgaWYgKGVsID09PSBudWxsKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYCR7c2VsZWN0b3JzfSDnmoTlhYPntKDml6Dms5Xmib7liLDvvIzml6Dms5Xph43lhplgKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGVkaXRFbGVtZW50LmFkZCg8SFRNTEVsZW1lbnQ+ZWwpO1xyXG4gICAgICBlbC5pbm5lckhUTUwgPSBodG1sO1xyXG4gICAgICBsb2coXCIt6YeN5YaZLVwiLCBlbCk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIC8qKiDph43mlrDmiafooYzlkb3ku6TmoIggKi9cclxuICBDb21tYW5kQ29udHJvbC5sb2FkQ29tbWFuZEpzb25BbmRSdW4oYWxsU3RvcmUuQ29tbWFuZFN0YWNrKTtcclxufVxyXG5cclxuZnVuY3Rpb24gbG9naW4oKSB7XHJcbiAgY29uc3QgdGl0bGUgPSBcIj4+Pue9kemhteeslOiusDw8PFxcblwiO1xyXG4gIGNvbnN0IHVzZXIgPSBwcm9tcHQodGl0bGUgKyBcIuivt+i+k+WFpeeUqOaIt+WQjVwiKTtcclxuICBpZiAodXNlciA9PT0gbnVsbCkgcmV0dXJuO1xyXG4gIGNvbnN0IHNlY3JldF9rZXkgPSBwcm9tcHQodGl0bGUgKyBcIuivt+i+k+WFpeWvhumSpeOAglwiKTtcclxuICBpZiAoc2VjcmV0X2tleSA9PT0gbnVsbCkgcmV0dXJuO1xyXG4gIF9sb2dpbih7XHJcbiAgICB1c2VyLFxyXG4gICAgc2VjcmV0X2tleSxcclxuICB9KS50aGVuKChyKSA9PiB7XHJcbiAgICBuZXcgTWVzc2FnZSh7IG1zZzogci5tZXNzYWdlIH0pLmF1dG9IaWRlKCk7XHJcbiAgfSk7XHJcbn1cclxuZnVuY3Rpb24gcmVnaXN0ZXIoKSB7XHJcbiAgY29uc3QgdGl0bGUgPSBcIj4+Pue9kemhteeslOiusDw8PFxcblwiO1xyXG4gIGNvbnN0IHVzZXIgPSBwcm9tcHQodGl0bGUgKyBcIuivt+i+k+WFpeeUqOaIt+WQjVwiKTtcclxuICBpZiAodXNlciA9PT0gbnVsbCkgcmV0dXJuO1xyXG4gIGNvbnN0IHNlY3JldF9rZXkgPSBwcm9tcHQodGl0bGUgKyBcIuivt+i+k+WFpeWvhumSpeOAguimgeiusOS9j+WTpu+8jOayoeacieaPkOS+m+aJvuWbnuWKn+iDvVwiKTtcclxuICBpZiAoc2VjcmV0X2tleSA9PT0gbnVsbCkgcmV0dXJuO1xyXG4gIHJlbW90ZV9yZWdpc3Rlcih7XHJcbiAgICB1c2VyLFxyXG4gICAgc2VjcmV0X2tleSxcclxuICB9KS50aGVuKChyKSA9PiB7XHJcbiAgICBuZXcgTWVzc2FnZSh7IG1zZzogci5tZXNzYWdlIH0pLmF1dG9IaWRlKCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKiDova7lu5Pnur8s55So5Lul5pi+56S65b2T5YmN5YWD57SgICovXHJcbmV4cG9ydCBmdW5jdGlvbiBvdXRsaW5lKGVsOiBIVE1MRWxlbWVudCkge1xyXG4gIGVsLmNsYXNzTGlzdC5hZGQoXCJ1c2VyX2pzX2xsZWpfb3V0bGluZVwiKTtcclxuICBzZXRUaW1lb3V0KHJlZHVjdGlvbiwgNDAwKTtcclxuICBmdW5jdGlvbiByZWR1Y3Rpb24oKSB7XHJcbiAgICBpZiAoZWwgPT0gY3VycmVudEVsZW1lbnQpIHtcclxuICAgICAgb3V0bGluZShlbCk7XHJcbiAgICAgIC8qKiDpvKDmoIfov5jlnKjov5nkuKrlhYPntKDkuIrvvIzlho3nrYnkvJogKi9cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgZWwuY2xhc3NMaXN0LnJlbW92ZShcInVzZXJfanNfbGxlal9vdXRsaW5lXCIpO1xyXG4gIH1cclxufVxyXG4vKiog55uR5ZCs6byg5qCH56e75YqoICovXHJcbmV4cG9ydCBmdW5jdGlvbiBvbl9tb3VzZShldmVudDogTW91c2VFdmVudCkge1xyXG4gIGlmIChldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xyXG4gICAgc2V0UGF0aChub2RlUGF0aChldmVudC50YXJnZXQpKTtcclxuXHJcbiAgICBpZiAoY29uZmlnLmVsZW1lbnRFZGl0KSB7XHJcbiAgICAgIG91dGxpbmUoZXZlbnQudGFyZ2V0KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuLyoqIOebkea1i+aMiemUruS6i+S7tiAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25fa2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gIGNvbnN0IGNvZGUgPSBldmVudC5jb2RlO1xyXG4gIC8v5pyJ5YWD57Sg6I635b6X54Sm54K577yM6KeG5Li65q2j5Zyo6L6T5YWl5paH5pys77yM5LiN5omn6KGM5oyH5LukXHJcbiAgaWYgKFxyXG4gICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIjpmb2N1c1wiKSB8fFxyXG4gICAgLyoqIOWmguaenOebruagh+WFg+e0oOaYr+iHquWumuS5iee7hOS7tueahOivneS4iumdoui/meS4qui/mOajgOa1i+S4jeS6hu+8jOmcgOimgeajgOa1iyBzaGFkb3cg5Lit5piv5ZCm5a2Y5Zyo54Sm54K5ICovXHJcbiAgICAoKGV2ZW50LnRhcmdldCBhcyBhbnkpLnNoYWRvd1Jvb3QgJiYgKGV2ZW50LnRhcmdldCBhcyBhbnkpLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihcIjpmb2N1c1wiKSlcclxuICApIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcbiAgLyoqIOWIh+aNoue8lui+keaooeW8jyAqL1xyXG4gIGlmIChjb2RlID09PSBcIkYyXCIgfHwgY29kZSA9PT0gXCJLZXlNXCIpIHtcclxuICAgIHJldHVybiBzd2l0Y2hTdGF0ZShldmVudCk7XHJcbiAgfVxyXG5cclxuICAvKiog5rKh5pyJ5byA5ZCv57yW6L6R5Yqf6IO9ICovXHJcbiAgaWYgKGNvbmZpZy5lbGVtZW50RWRpdCA9PT0gZmFsc2UpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChjb2RlIGluIEtleU1hcCkge1xyXG4gICAgLyoqIOaJp+ihjOaMiemUrue7keWumueahOWHveaVsCAqL1xyXG4gICAgY29uc3QgZnVuY19saXN0ID0gS2V5TWFwW2NvZGUgYXMga2V5b2YgdHlwZW9mIEtleU1hcF07XHJcbiAgICBsb2coXHJcbiAgICAgIGBb5oyJ5LiL5LqGXSAke2NvZGV9LOaJp+ihjOS6hjpgLFxyXG4gICAgICAoZnVuY19saXN0IGFzIEZ1bmN0aW9uW10pLm1hcCgoZikgPT4gZi5uYW1lKSxcclxuICAgICk7XHJcblxyXG4gICAgZnVuY19saXN0LmZvckVhY2goKGZ1bmMpID0+IHtcclxuICAgICAgZnVuYygpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcbi8qKiDnvJbovpHkuovku7YgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG9uX2lucHV0KGV2ZW50OiBFdmVudCkge1xyXG4gIGlmIChldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xyXG4gICAgY29uc3QgZWwgPSBldmVudC50YXJnZXQ7XHJcbiAgICBpZiAoZWwuaW5uZXJIVE1MLmxlbmd0aCA+IDEwICogMTAwMClcclxuICAgICAgbmV3IFdhcm5pbmcoe1xyXG4gICAgICAgIG1zZzogXCLor6XlhYPntKBodG1s5YaF5a656L+H5aSn77yM5bCG5LiN5Lya5L+d5a2Y6L+Z6YeM55qE5L+u5pS577yM6K+36YCJ5oup5pu056Gu5a6a55qE5paH5pys5YWD57Sg44CCXCIsXHJcbiAgICAgIH0pLmF1dG9IaWRlKCk7XHJcbiAgICBlbHNlIGVkaXRFbGVtZW50LmFkZChlbCk7XHJcbiAgfVxyXG59XHJcbi8qKiDliIfmjaLnirbmgIEgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHN3aXRjaFN0YXRlKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgY29uZmlnLmVsZW1lbnRFZGl0ID0gIWNvbmZpZy5lbGVtZW50RWRpdDtcclxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIGV2ZW50LnJldHVyblZhbHVlID0gZmFsc2U7XHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59XHJcbiIsImltcG9ydCB7IEVNUFRZX09CSiwgaXNBcnJheSwgaXNJbnRlZ2VyS2V5LCBpc1N5bWJvbCwgZXh0ZW5kLCBoYXNPd24sIGlzT2JqZWN0LCBoYXNDaGFuZ2VkLCBjYXBpdGFsaXplLCB0b1Jhd1R5cGUsIGRlZiwgaXNGdW5jdGlvbiwgTk9PUCB9IGZyb20gJ0B2dWUvc2hhcmVkJztcblxuY29uc3QgdGFyZ2V0TWFwID0gbmV3IFdlYWtNYXAoKTtcclxuY29uc3QgZWZmZWN0U3RhY2sgPSBbXTtcclxubGV0IGFjdGl2ZUVmZmVjdDtcclxuY29uc3QgSVRFUkFURV9LRVkgPSBTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gJ2l0ZXJhdGUnIDogJycpO1xyXG5jb25zdCBNQVBfS0VZX0lURVJBVEVfS0VZID0gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdNYXAga2V5IGl0ZXJhdGUnIDogJycpO1xyXG5mdW5jdGlvbiBpc0VmZmVjdChmbikge1xyXG4gICAgcmV0dXJuIGZuICYmIGZuLl9pc0VmZmVjdCA9PT0gdHJ1ZTtcclxufVxyXG5mdW5jdGlvbiBlZmZlY3QoZm4sIG9wdGlvbnMgPSBFTVBUWV9PQkopIHtcclxuICAgIGlmIChpc0VmZmVjdChmbikpIHtcclxuICAgICAgICBmbiA9IGZuLnJhdztcclxuICAgIH1cclxuICAgIGNvbnN0IGVmZmVjdCA9IGNyZWF0ZVJlYWN0aXZlRWZmZWN0KGZuLCBvcHRpb25zKTtcclxuICAgIGlmICghb3B0aW9ucy5sYXp5KSB7XHJcbiAgICAgICAgZWZmZWN0KCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZWZmZWN0O1xyXG59XHJcbmZ1bmN0aW9uIHN0b3AoZWZmZWN0KSB7XHJcbiAgICBpZiAoZWZmZWN0LmFjdGl2ZSkge1xyXG4gICAgICAgIGNsZWFudXAoZWZmZWN0KTtcclxuICAgICAgICBpZiAoZWZmZWN0Lm9wdGlvbnMub25TdG9wKSB7XHJcbiAgICAgICAgICAgIGVmZmVjdC5vcHRpb25zLm9uU3RvcCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlZmZlY3QuYWN0aXZlID0gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxubGV0IHVpZCA9IDA7XHJcbmZ1bmN0aW9uIGNyZWF0ZVJlYWN0aXZlRWZmZWN0KGZuLCBvcHRpb25zKSB7XHJcbiAgICBjb25zdCBlZmZlY3QgPSBmdW5jdGlvbiByZWFjdGl2ZUVmZmVjdCgpIHtcclxuICAgICAgICBpZiAoIWVmZmVjdC5hY3RpdmUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2NoZWR1bGVyID8gdW5kZWZpbmVkIDogZm4oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFlZmZlY3RTdGFjay5pbmNsdWRlcyhlZmZlY3QpKSB7XHJcbiAgICAgICAgICAgIGNsZWFudXAoZWZmZWN0KTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGVuYWJsZVRyYWNraW5nKCk7XHJcbiAgICAgICAgICAgICAgICBlZmZlY3RTdGFjay5wdXNoKGVmZmVjdCk7XHJcbiAgICAgICAgICAgICAgICBhY3RpdmVFZmZlY3QgPSBlZmZlY3Q7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZm4oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmaW5hbGx5IHtcclxuICAgICAgICAgICAgICAgIGVmZmVjdFN0YWNrLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgcmVzZXRUcmFja2luZygpO1xyXG4gICAgICAgICAgICAgICAgYWN0aXZlRWZmZWN0ID0gZWZmZWN0U3RhY2tbZWZmZWN0U3RhY2subGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgZWZmZWN0LmlkID0gdWlkKys7XHJcbiAgICBlZmZlY3QuX2lzRWZmZWN0ID0gdHJ1ZTtcclxuICAgIGVmZmVjdC5hY3RpdmUgPSB0cnVlO1xyXG4gICAgZWZmZWN0LnJhdyA9IGZuO1xyXG4gICAgZWZmZWN0LmRlcHMgPSBbXTtcclxuICAgIGVmZmVjdC5vcHRpb25zID0gb3B0aW9ucztcclxuICAgIHJldHVybiBlZmZlY3Q7XHJcbn1cclxuZnVuY3Rpb24gY2xlYW51cChlZmZlY3QpIHtcclxuICAgIGNvbnN0IHsgZGVwcyB9ID0gZWZmZWN0O1xyXG4gICAgaWYgKGRlcHMubGVuZ3RoKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXBzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGRlcHNbaV0uZGVsZXRlKGVmZmVjdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRlcHMubGVuZ3RoID0gMDtcclxuICAgIH1cclxufVxyXG5sZXQgc2hvdWxkVHJhY2sgPSB0cnVlO1xyXG5jb25zdCB0cmFja1N0YWNrID0gW107XHJcbmZ1bmN0aW9uIHBhdXNlVHJhY2tpbmcoKSB7XHJcbiAgICB0cmFja1N0YWNrLnB1c2goc2hvdWxkVHJhY2spO1xyXG4gICAgc2hvdWxkVHJhY2sgPSBmYWxzZTtcclxufVxyXG5mdW5jdGlvbiBlbmFibGVUcmFja2luZygpIHtcclxuICAgIHRyYWNrU3RhY2sucHVzaChzaG91bGRUcmFjayk7XHJcbiAgICBzaG91bGRUcmFjayA9IHRydWU7XHJcbn1cclxuZnVuY3Rpb24gcmVzZXRUcmFja2luZygpIHtcclxuICAgIGNvbnN0IGxhc3QgPSB0cmFja1N0YWNrLnBvcCgpO1xyXG4gICAgc2hvdWxkVHJhY2sgPSBsYXN0ID09PSB1bmRlZmluZWQgPyB0cnVlIDogbGFzdDtcclxufVxyXG5mdW5jdGlvbiB0cmFjayh0YXJnZXQsIHR5cGUsIGtleSkge1xyXG4gICAgaWYgKCFzaG91bGRUcmFjayB8fCBhY3RpdmVFZmZlY3QgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBkZXBzTWFwID0gdGFyZ2V0TWFwLmdldCh0YXJnZXQpO1xyXG4gICAgaWYgKCFkZXBzTWFwKSB7XHJcbiAgICAgICAgdGFyZ2V0TWFwLnNldCh0YXJnZXQsIChkZXBzTWFwID0gbmV3IE1hcCgpKSk7XHJcbiAgICB9XHJcbiAgICBsZXQgZGVwID0gZGVwc01hcC5nZXQoa2V5KTtcclxuICAgIGlmICghZGVwKSB7XHJcbiAgICAgICAgZGVwc01hcC5zZXQoa2V5LCAoZGVwID0gbmV3IFNldCgpKSk7XHJcbiAgICB9XHJcbiAgICBpZiAoIWRlcC5oYXMoYWN0aXZlRWZmZWN0KSkge1xyXG4gICAgICAgIGRlcC5hZGQoYWN0aXZlRWZmZWN0KTtcclxuICAgICAgICBhY3RpdmVFZmZlY3QuZGVwcy5wdXNoKGRlcCk7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBhY3RpdmVFZmZlY3Qub3B0aW9ucy5vblRyYWNrKSB7XHJcbiAgICAgICAgICAgIGFjdGl2ZUVmZmVjdC5vcHRpb25zLm9uVHJhY2soe1xyXG4gICAgICAgICAgICAgICAgZWZmZWN0OiBhY3RpdmVFZmZlY3QsXHJcbiAgICAgICAgICAgICAgICB0YXJnZXQsXHJcbiAgICAgICAgICAgICAgICB0eXBlLFxyXG4gICAgICAgICAgICAgICAga2V5XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiB0cmlnZ2VyKHRhcmdldCwgdHlwZSwga2V5LCBuZXdWYWx1ZSwgb2xkVmFsdWUsIG9sZFRhcmdldCkge1xyXG4gICAgY29uc3QgZGVwc01hcCA9IHRhcmdldE1hcC5nZXQodGFyZ2V0KTtcclxuICAgIGlmICghZGVwc01hcCkge1xyXG4gICAgICAgIC8vIG5ldmVyIGJlZW4gdHJhY2tlZFxyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGNvbnN0IGVmZmVjdHMgPSBuZXcgU2V0KCk7XHJcbiAgICBjb25zdCBhZGQgPSAoZWZmZWN0c1RvQWRkKSA9PiB7XHJcbiAgICAgICAgaWYgKGVmZmVjdHNUb0FkZCkge1xyXG4gICAgICAgICAgICBlZmZlY3RzVG9BZGQuZm9yRWFjaChlZmZlY3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVmZmVjdCAhPT0gYWN0aXZlRWZmZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWZmZWN0cy5hZGQoZWZmZWN0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGlmICh0eXBlID09PSBcImNsZWFyXCIgLyogQ0xFQVIgKi8pIHtcclxuICAgICAgICAvLyBjb2xsZWN0aW9uIGJlaW5nIGNsZWFyZWRcclxuICAgICAgICAvLyB0cmlnZ2VyIGFsbCBlZmZlY3RzIGZvciB0YXJnZXRcclxuICAgICAgICBkZXBzTWFwLmZvckVhY2goYWRkKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGtleSA9PT0gJ2xlbmd0aCcgJiYgaXNBcnJheSh0YXJnZXQpKSB7XHJcbiAgICAgICAgZGVwc01hcC5mb3JFYWNoKChkZXAsIGtleSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoa2V5ID09PSAnbGVuZ3RoJyB8fCBrZXkgPj0gbmV3VmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGFkZChkZXApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICAvLyBzY2hlZHVsZSBydW5zIGZvciBTRVQgfCBBREQgfCBERUxFVEVcclxuICAgICAgICBpZiAoa2V5ICE9PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgYWRkKGRlcHNNYXAuZ2V0KGtleSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBhbHNvIHJ1biBmb3IgaXRlcmF0aW9uIGtleSBvbiBBREQgfCBERUxFVEUgfCBNYXAuU0VUXHJcbiAgICAgICAgY29uc3Qgc2hvdWxkVHJpZ2dlckl0ZXJhdGlvbiA9ICh0eXBlID09PSBcImFkZFwiIC8qIEFERCAqLyAmJlxyXG4gICAgICAgICAgICAoIWlzQXJyYXkodGFyZ2V0KSB8fCBpc0ludGVnZXJLZXkoa2V5KSkpIHx8XHJcbiAgICAgICAgICAgICh0eXBlID09PSBcImRlbGV0ZVwiIC8qIERFTEVURSAqLyAmJiAhaXNBcnJheSh0YXJnZXQpKTtcclxuICAgICAgICBpZiAoc2hvdWxkVHJpZ2dlckl0ZXJhdGlvbiB8fFxyXG4gICAgICAgICAgICAodHlwZSA9PT0gXCJzZXRcIiAvKiBTRVQgKi8gJiYgdGFyZ2V0IGluc3RhbmNlb2YgTWFwKSkge1xyXG4gICAgICAgICAgICBhZGQoZGVwc01hcC5nZXQoaXNBcnJheSh0YXJnZXQpID8gJ2xlbmd0aCcgOiBJVEVSQVRFX0tFWSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoc2hvdWxkVHJpZ2dlckl0ZXJhdGlvbiAmJiB0YXJnZXQgaW5zdGFuY2VvZiBNYXApIHtcclxuICAgICAgICAgICAgYWRkKGRlcHNNYXAuZ2V0KE1BUF9LRVlfSVRFUkFURV9LRVkpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBjb25zdCBydW4gPSAoZWZmZWN0KSA9PiB7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBlZmZlY3Qub3B0aW9ucy5vblRyaWdnZXIpIHtcclxuICAgICAgICAgICAgZWZmZWN0Lm9wdGlvbnMub25UcmlnZ2VyKHtcclxuICAgICAgICAgICAgICAgIGVmZmVjdCxcclxuICAgICAgICAgICAgICAgIHRhcmdldCxcclxuICAgICAgICAgICAgICAgIGtleSxcclxuICAgICAgICAgICAgICAgIHR5cGUsXHJcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZSxcclxuICAgICAgICAgICAgICAgIG9sZFZhbHVlLFxyXG4gICAgICAgICAgICAgICAgb2xkVGFyZ2V0XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZWZmZWN0Lm9wdGlvbnMuc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgICAgIGVmZmVjdC5vcHRpb25zLnNjaGVkdWxlcihlZmZlY3QpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZWZmZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGVmZmVjdHMuZm9yRWFjaChydW4pO1xyXG59XG5cbmNvbnN0IGJ1aWx0SW5TeW1ib2xzID0gbmV3IFNldChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhTeW1ib2wpXHJcbiAgICAubWFwKGtleSA9PiBTeW1ib2xba2V5XSlcclxuICAgIC5maWx0ZXIoaXNTeW1ib2wpKTtcclxuY29uc3QgZ2V0ID0gLyojX19QVVJFX18qLyBjcmVhdGVHZXR0ZXIoKTtcclxuY29uc3Qgc2hhbGxvd0dldCA9IC8qI19fUFVSRV9fKi8gY3JlYXRlR2V0dGVyKGZhbHNlLCB0cnVlKTtcclxuY29uc3QgcmVhZG9ubHlHZXQgPSAvKiNfX1BVUkVfXyovIGNyZWF0ZUdldHRlcih0cnVlKTtcclxuY29uc3Qgc2hhbGxvd1JlYWRvbmx5R2V0ID0gLyojX19QVVJFX18qLyBjcmVhdGVHZXR0ZXIodHJ1ZSwgdHJ1ZSk7XHJcbmNvbnN0IGFycmF5SW5zdHJ1bWVudGF0aW9ucyA9IHt9O1xyXG5bJ2luY2x1ZGVzJywgJ2luZGV4T2YnLCAnbGFzdEluZGV4T2YnXS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICBhcnJheUluc3RydW1lbnRhdGlvbnNba2V5XSA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XHJcbiAgICAgICAgY29uc3QgYXJyID0gdG9SYXcodGhpcyk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICB0cmFjayhhcnIsIFwiZ2V0XCIgLyogR0VUICovLCBpICsgJycpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB3ZSBydW4gdGhlIG1ldGhvZCB1c2luZyB0aGUgb3JpZ2luYWwgYXJncyBmaXJzdCAod2hpY2ggbWF5IGJlIHJlYWN0aXZlKVxyXG4gICAgICAgIGNvbnN0IHJlcyA9IGFycltrZXldKC4uLmFyZ3MpO1xyXG4gICAgICAgIGlmIChyZXMgPT09IC0xIHx8IHJlcyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgLy8gaWYgdGhhdCBkaWRuJ3Qgd29yaywgcnVuIGl0IGFnYWluIHVzaW5nIHJhdyB2YWx1ZXMuXHJcbiAgICAgICAgICAgIHJldHVybiBhcnJba2V5XSguLi5hcmdzLm1hcCh0b1JhdykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcztcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59KTtcclxuZnVuY3Rpb24gY3JlYXRlR2V0dGVyKGlzUmVhZG9ubHkgPSBmYWxzZSwgc2hhbGxvdyA9IGZhbHNlKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikge1xyXG4gICAgICAgIGlmIChrZXkgPT09IFwiX192X2lzUmVhY3RpdmVcIiAvKiBJU19SRUFDVElWRSAqLykge1xyXG4gICAgICAgICAgICByZXR1cm4gIWlzUmVhZG9ubHk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGtleSA9PT0gXCJfX3ZfaXNSZWFkb25seVwiIC8qIElTX1JFQURPTkxZICovKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpc1JlYWRvbmx5O1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChrZXkgPT09IFwiX192X3Jhd1wiIC8qIFJBVyAqLyAmJlxyXG4gICAgICAgICAgICByZWNlaXZlciA9PT0gKGlzUmVhZG9ubHkgPyByZWFkb25seU1hcCA6IHJlYWN0aXZlTWFwKS5nZXQodGFyZ2V0KSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB0YXJnZXRJc0FycmF5ID0gaXNBcnJheSh0YXJnZXQpO1xyXG4gICAgICAgIGlmICh0YXJnZXRJc0FycmF5ICYmIGhhc093bihhcnJheUluc3RydW1lbnRhdGlvbnMsIGtleSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KGFycmF5SW5zdHJ1bWVudGF0aW9ucywga2V5LCByZWNlaXZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJlcyA9IFJlZmxlY3QuZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcik7XHJcbiAgICAgICAgY29uc3Qga2V5SXNTeW1ib2wgPSBpc1N5bWJvbChrZXkpO1xyXG4gICAgICAgIGlmIChrZXlJc1N5bWJvbFxyXG4gICAgICAgICAgICA/IGJ1aWx0SW5TeW1ib2xzLmhhcyhrZXkpXHJcbiAgICAgICAgICAgIDoga2V5ID09PSBgX19wcm90b19fYCB8fCBrZXkgPT09IGBfX3ZfaXNSZWZgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghaXNSZWFkb25seSkge1xyXG4gICAgICAgICAgICB0cmFjayh0YXJnZXQsIFwiZ2V0XCIgLyogR0VUICovLCBrZXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoc2hhbGxvdykge1xyXG4gICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNSZWYocmVzKSkge1xyXG4gICAgICAgICAgICAvLyByZWYgdW53cmFwcGluZyAtIGRvZXMgbm90IGFwcGx5IGZvciBBcnJheSArIGludGVnZXIga2V5LlxyXG4gICAgICAgICAgICBjb25zdCBzaG91bGRVbndyYXAgPSAhdGFyZ2V0SXNBcnJheSB8fCAhaXNJbnRlZ2VyS2V5KGtleSk7XHJcbiAgICAgICAgICAgIHJldHVybiBzaG91bGRVbndyYXAgPyByZXMudmFsdWUgOiByZXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpc09iamVjdChyZXMpKSB7XHJcbiAgICAgICAgICAgIC8vIENvbnZlcnQgcmV0dXJuZWQgdmFsdWUgaW50byBhIHByb3h5IGFzIHdlbGwuIHdlIGRvIHRoZSBpc09iamVjdCBjaGVja1xyXG4gICAgICAgICAgICAvLyBoZXJlIHRvIGF2b2lkIGludmFsaWQgdmFsdWUgd2FybmluZy4gQWxzbyBuZWVkIHRvIGxhenkgYWNjZXNzIHJlYWRvbmx5XHJcbiAgICAgICAgICAgIC8vIGFuZCByZWFjdGl2ZSBoZXJlIHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY3kuXHJcbiAgICAgICAgICAgIHJldHVybiBpc1JlYWRvbmx5ID8gcmVhZG9ubHkocmVzKSA6IHJlYWN0aXZlKHJlcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9O1xyXG59XHJcbmNvbnN0IHNldCA9IC8qI19fUFVSRV9fKi8gY3JlYXRlU2V0dGVyKCk7XHJcbmNvbnN0IHNoYWxsb3dTZXQgPSAvKiNfX1BVUkVfXyovIGNyZWF0ZVNldHRlcih0cnVlKTtcclxuZnVuY3Rpb24gY3JlYXRlU2V0dGVyKHNoYWxsb3cgPSBmYWxzZSkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHNldCh0YXJnZXQsIGtleSwgdmFsdWUsIHJlY2VpdmVyKSB7XHJcbiAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0YXJnZXRba2V5XTtcclxuICAgICAgICBpZiAoIXNoYWxsb3cpIHtcclxuICAgICAgICAgICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7XHJcbiAgICAgICAgICAgIGlmICghaXNBcnJheSh0YXJnZXQpICYmIGlzUmVmKG9sZFZhbHVlKSAmJiAhaXNSZWYodmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZS52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgaGFkS2V5ID0gaXNBcnJheSh0YXJnZXQpICYmIGlzSW50ZWdlcktleShrZXkpXHJcbiAgICAgICAgICAgID8gTnVtYmVyKGtleSkgPCB0YXJnZXQubGVuZ3RoXHJcbiAgICAgICAgICAgIDogaGFzT3duKHRhcmdldCwga2V5KTtcclxuICAgICAgICBjb25zdCByZXN1bHQgPSBSZWZsZWN0LnNldCh0YXJnZXQsIGtleSwgdmFsdWUsIHJlY2VpdmVyKTtcclxuICAgICAgICAvLyBkb24ndCB0cmlnZ2VyIGlmIHRhcmdldCBpcyBzb21ldGhpbmcgdXAgaW4gdGhlIHByb3RvdHlwZSBjaGFpbiBvZiBvcmlnaW5hbFxyXG4gICAgICAgIGlmICh0YXJnZXQgPT09IHRvUmF3KHJlY2VpdmVyKSkge1xyXG4gICAgICAgICAgICBpZiAoIWhhZEtleSkge1xyXG4gICAgICAgICAgICAgICAgdHJpZ2dlcih0YXJnZXQsIFwiYWRkXCIgLyogQUREICovLCBrZXksIHZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChoYXNDaGFuZ2VkKHZhbHVlLCBvbGRWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIHRyaWdnZXIodGFyZ2V0LCBcInNldFwiIC8qIFNFVCAqLywga2V5LCB2YWx1ZSwgb2xkVmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwga2V5KSB7XHJcbiAgICBjb25zdCBoYWRLZXkgPSBoYXNPd24odGFyZ2V0LCBrZXkpO1xyXG4gICAgY29uc3Qgb2xkVmFsdWUgPSB0YXJnZXRba2V5XTtcclxuICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBrZXkpO1xyXG4gICAgaWYgKHJlc3VsdCAmJiBoYWRLZXkpIHtcclxuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJkZWxldGVcIiAvKiBERUxFVEUgKi8sIGtleSwgdW5kZWZpbmVkLCBvbGRWYWx1ZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbmZ1bmN0aW9uIGhhcyh0YXJnZXQsIGtleSkge1xyXG4gICAgY29uc3QgcmVzdWx0ID0gUmVmbGVjdC5oYXModGFyZ2V0LCBrZXkpO1xyXG4gICAgaWYgKCFpc1N5bWJvbChrZXkpIHx8ICFidWlsdEluU3ltYm9scy5oYXMoa2V5KSkge1xyXG4gICAgICAgIHRyYWNrKHRhcmdldCwgXCJoYXNcIiAvKiBIQVMgKi8sIGtleSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbmZ1bmN0aW9uIG93bktleXModGFyZ2V0KSB7XHJcbiAgICB0cmFjayh0YXJnZXQsIFwiaXRlcmF0ZVwiIC8qIElURVJBVEUgKi8sIElURVJBVEVfS0VZKTtcclxuICAgIHJldHVybiBSZWZsZWN0Lm93bktleXModGFyZ2V0KTtcclxufVxyXG5jb25zdCBtdXRhYmxlSGFuZGxlcnMgPSB7XHJcbiAgICBnZXQsXHJcbiAgICBzZXQsXHJcbiAgICBkZWxldGVQcm9wZXJ0eSxcclxuICAgIGhhcyxcclxuICAgIG93bktleXNcclxufTtcclxuY29uc3QgcmVhZG9ubHlIYW5kbGVycyA9IHtcclxuICAgIGdldDogcmVhZG9ubHlHZXQsXHJcbiAgICBzZXQodGFyZ2V0LCBrZXkpIHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgU2V0IG9wZXJhdGlvbiBvbiBrZXkgXCIke1N0cmluZyhrZXkpfVwiIGZhaWxlZDogdGFyZ2V0IGlzIHJlYWRvbmx5LmAsIHRhcmdldCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuICAgIGRlbGV0ZVByb3BlcnR5KHRhcmdldCwga2V5KSB7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYERlbGV0ZSBvcGVyYXRpb24gb24ga2V5IFwiJHtTdHJpbmcoa2V5KX1cIiBmYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLCB0YXJnZXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxufTtcclxuY29uc3Qgc2hhbGxvd1JlYWN0aXZlSGFuZGxlcnMgPSBleHRlbmQoe30sIG11dGFibGVIYW5kbGVycywge1xyXG4gICAgZ2V0OiBzaGFsbG93R2V0LFxyXG4gICAgc2V0OiBzaGFsbG93U2V0XHJcbn0pO1xyXG4vLyBQcm9wcyBoYW5kbGVycyBhcmUgc3BlY2lhbCBpbiB0aGUgc2Vuc2UgdGhhdCBpdCBzaG91bGQgbm90IHVud3JhcCB0b3AtbGV2ZWxcclxuLy8gcmVmcyAoaW4gb3JkZXIgdG8gYWxsb3cgcmVmcyB0byBiZSBleHBsaWNpdGx5IHBhc3NlZCBkb3duKSwgYnV0IHNob3VsZFxyXG4vLyByZXRhaW4gdGhlIHJlYWN0aXZpdHkgb2YgdGhlIG5vcm1hbCByZWFkb25seSBvYmplY3QuXHJcbmNvbnN0IHNoYWxsb3dSZWFkb25seUhhbmRsZXJzID0gZXh0ZW5kKHt9LCByZWFkb25seUhhbmRsZXJzLCB7XHJcbiAgICBnZXQ6IHNoYWxsb3dSZWFkb25seUdldFxyXG59KTtcblxuY29uc3QgdG9SZWFjdGl2ZSA9ICh2YWx1ZSkgPT4gaXNPYmplY3QodmFsdWUpID8gcmVhY3RpdmUodmFsdWUpIDogdmFsdWU7XHJcbmNvbnN0IHRvUmVhZG9ubHkgPSAodmFsdWUpID0+IGlzT2JqZWN0KHZhbHVlKSA/IHJlYWRvbmx5KHZhbHVlKSA6IHZhbHVlO1xyXG5jb25zdCB0b1NoYWxsb3cgPSAodmFsdWUpID0+IHZhbHVlO1xyXG5jb25zdCBnZXRQcm90byA9ICh2KSA9PiBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHYpO1xyXG5mdW5jdGlvbiBnZXQkMSh0YXJnZXQsIGtleSwgaXNSZWFkb25seSA9IGZhbHNlLCBpc1NoYWxsb3cgPSBmYWxzZSkge1xyXG4gICAgLy8gIzE3NzI6IHJlYWRvbmx5KHJlYWN0aXZlKE1hcCkpIHNob3VsZCByZXR1cm4gcmVhZG9ubHkgKyByZWFjdGl2ZSB2ZXJzaW9uXHJcbiAgICAvLyBvZiB0aGUgdmFsdWVcclxuICAgIHRhcmdldCA9IHRhcmdldFtcIl9fdl9yYXdcIiAvKiBSQVcgKi9dO1xyXG4gICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTtcclxuICAgIGNvbnN0IHJhd0tleSA9IHRvUmF3KGtleSk7XHJcbiAgICBpZiAoa2V5ICE9PSByYXdLZXkpIHtcclxuICAgICAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiZ2V0XCIgLyogR0VUICovLCBrZXkpO1xyXG4gICAgfVxyXG4gICAgIWlzUmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCBcImdldFwiIC8qIEdFVCAqLywgcmF3S2V5KTtcclxuICAgIGNvbnN0IHsgaGFzIH0gPSBnZXRQcm90byhyYXdUYXJnZXQpO1xyXG4gICAgY29uc3Qgd3JhcCA9IGlzUmVhZG9ubHkgPyB0b1JlYWRvbmx5IDogaXNTaGFsbG93ID8gdG9TaGFsbG93IDogdG9SZWFjdGl2ZTtcclxuICAgIGlmIChoYXMuY2FsbChyYXdUYXJnZXQsIGtleSkpIHtcclxuICAgICAgICByZXR1cm4gd3JhcCh0YXJnZXQuZ2V0KGtleSkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaGFzLmNhbGwocmF3VGFyZ2V0LCByYXdLZXkpKSB7XHJcbiAgICAgICAgcmV0dXJuIHdyYXAodGFyZ2V0LmdldChyYXdLZXkpKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBoYXMkMShrZXksIGlzUmVhZG9ubHkgPSBmYWxzZSkge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpc1tcIl9fdl9yYXdcIiAvKiBSQVcgKi9dO1xyXG4gICAgY29uc3QgcmF3VGFyZ2V0ID0gdG9SYXcodGFyZ2V0KTtcclxuICAgIGNvbnN0IHJhd0tleSA9IHRvUmF3KGtleSk7XHJcbiAgICBpZiAoa2V5ICE9PSByYXdLZXkpIHtcclxuICAgICAgICAhaXNSZWFkb25seSAmJiB0cmFjayhyYXdUYXJnZXQsIFwiaGFzXCIgLyogSEFTICovLCBrZXkpO1xyXG4gICAgfVxyXG4gICAgIWlzUmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCBcImhhc1wiIC8qIEhBUyAqLywgcmF3S2V5KTtcclxuICAgIHJldHVybiBrZXkgPT09IHJhd0tleVxyXG4gICAgICAgID8gdGFyZ2V0LmhhcyhrZXkpXHJcbiAgICAgICAgOiB0YXJnZXQuaGFzKGtleSkgfHwgdGFyZ2V0LmhhcyhyYXdLZXkpO1xyXG59XHJcbmZ1bmN0aW9uIHNpemUodGFyZ2V0LCBpc1JlYWRvbmx5ID0gZmFsc2UpIHtcclxuICAgIHRhcmdldCA9IHRhcmdldFtcIl9fdl9yYXdcIiAvKiBSQVcgKi9dO1xyXG4gICAgIWlzUmVhZG9ubHkgJiYgdHJhY2sodG9SYXcodGFyZ2V0KSwgXCJpdGVyYXRlXCIgLyogSVRFUkFURSAqLywgSVRFUkFURV9LRVkpO1xyXG4gICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgJ3NpemUnLCB0YXJnZXQpO1xyXG59XHJcbmZ1bmN0aW9uIGFkZCh2YWx1ZSkge1xyXG4gICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7XHJcbiAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcclxuICAgIGNvbnN0IHByb3RvID0gZ2V0UHJvdG8odGFyZ2V0KTtcclxuICAgIGNvbnN0IGhhZEtleSA9IHByb3RvLmhhcy5jYWxsKHRhcmdldCwgdmFsdWUpO1xyXG4gICAgY29uc3QgcmVzdWx0ID0gcHJvdG8uYWRkLmNhbGwodGFyZ2V0LCB2YWx1ZSk7XHJcbiAgICBpZiAoIWhhZEtleSkge1xyXG4gICAgICAgIHRyaWdnZXIodGFyZ2V0LCBcImFkZFwiIC8qIEFERCAqLywgdmFsdWUsIHZhbHVlKTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuZnVuY3Rpb24gc2V0JDEoa2V5LCB2YWx1ZSkge1xyXG4gICAgdmFsdWUgPSB0b1Jhdyh2YWx1ZSk7XHJcbiAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcclxuICAgIGNvbnN0IHsgaGFzLCBnZXQsIHNldCB9ID0gZ2V0UHJvdG8odGFyZ2V0KTtcclxuICAgIGxldCBoYWRLZXkgPSBoYXMuY2FsbCh0YXJnZXQsIGtleSk7XHJcbiAgICBpZiAoIWhhZEtleSkge1xyXG4gICAgICAgIGtleSA9IHRvUmF3KGtleSk7XHJcbiAgICAgICAgaGFkS2V5ID0gaGFzLmNhbGwodGFyZ2V0LCBrZXkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgY2hlY2tJZGVudGl0eUtleXModGFyZ2V0LCBoYXMsIGtleSk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBvbGRWYWx1ZSA9IGdldC5jYWxsKHRhcmdldCwga2V5KTtcclxuICAgIGNvbnN0IHJlc3VsdCA9IHNldC5jYWxsKHRhcmdldCwga2V5LCB2YWx1ZSk7XHJcbiAgICBpZiAoIWhhZEtleSkge1xyXG4gICAgICAgIHRyaWdnZXIodGFyZ2V0LCBcImFkZFwiIC8qIEFERCAqLywga2V5LCB2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChoYXNDaGFuZ2VkKHZhbHVlLCBvbGRWYWx1ZSkpIHtcclxuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJzZXRcIiAvKiBTRVQgKi8sIGtleSwgdmFsdWUsIG9sZFZhbHVlKTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuZnVuY3Rpb24gZGVsZXRlRW50cnkoa2V5KSB7XHJcbiAgICBjb25zdCB0YXJnZXQgPSB0b1Jhdyh0aGlzKTtcclxuICAgIGNvbnN0IHsgaGFzLCBnZXQsIGRlbGV0ZTogZGVsIH0gPSBnZXRQcm90byh0YXJnZXQpO1xyXG4gICAgbGV0IGhhZEtleSA9IGhhcy5jYWxsKHRhcmdldCwga2V5KTtcclxuICAgIGlmICghaGFkS2V5KSB7XHJcbiAgICAgICAga2V5ID0gdG9SYXcoa2V5KTtcclxuICAgICAgICBoYWRLZXkgPSBoYXMuY2FsbCh0YXJnZXQsIGtleSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhcywga2V5KTtcclxuICAgIH1cclxuICAgIGNvbnN0IG9sZFZhbHVlID0gZ2V0ID8gZ2V0LmNhbGwodGFyZ2V0LCBrZXkpIDogdW5kZWZpbmVkO1xyXG4gICAgLy8gZm9yd2FyZCB0aGUgb3BlcmF0aW9uIGJlZm9yZSBxdWV1ZWluZyByZWFjdGlvbnNcclxuICAgIGNvbnN0IHJlc3VsdCA9IGRlbC5jYWxsKHRhcmdldCwga2V5KTtcclxuICAgIGlmIChoYWRLZXkpIHtcclxuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgXCJkZWxldGVcIiAvKiBERUxFVEUgKi8sIGtleSwgdW5kZWZpbmVkLCBvbGRWYWx1ZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbmZ1bmN0aW9uIGNsZWFyKCkge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gdG9SYXcodGhpcyk7XHJcbiAgICBjb25zdCBoYWRJdGVtcyA9IHRhcmdldC5zaXplICE9PSAwO1xyXG4gICAgY29uc3Qgb2xkVGFyZ2V0ID0gKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpXHJcbiAgICAgICAgPyB0YXJnZXQgaW5zdGFuY2VvZiBNYXBcclxuICAgICAgICAgICAgPyBuZXcgTWFwKHRhcmdldClcclxuICAgICAgICAgICAgOiBuZXcgU2V0KHRhcmdldClcclxuICAgICAgICA6IHVuZGVmaW5lZDtcclxuICAgIC8vIGZvcndhcmQgdGhlIG9wZXJhdGlvbiBiZWZvcmUgcXVldWVpbmcgcmVhY3Rpb25zXHJcbiAgICBjb25zdCByZXN1bHQgPSBnZXRQcm90byh0YXJnZXQpLmNsZWFyLmNhbGwodGFyZ2V0KTtcclxuICAgIGlmIChoYWRJdGVtcykge1xyXG4gICAgICAgIHRyaWdnZXIodGFyZ2V0LCBcImNsZWFyXCIgLyogQ0xFQVIgKi8sIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBvbGRUYXJnZXQpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGlzUmVhZG9ubHksIGlzU2hhbGxvdykge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcpIHtcclxuICAgICAgICBjb25zdCBvYnNlcnZlZCA9IHRoaXM7XHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gb2JzZXJ2ZWRbXCJfX3ZfcmF3XCIgLyogUkFXICovXTtcclxuICAgICAgICBjb25zdCByYXdUYXJnZXQgPSB0b1Jhdyh0YXJnZXQpO1xyXG4gICAgICAgIGNvbnN0IHdyYXAgPSBpc1JlYWRvbmx5ID8gdG9SZWFkb25seSA6IGlzU2hhbGxvdyA/IHRvU2hhbGxvdyA6IHRvUmVhY3RpdmU7XHJcbiAgICAgICAgIWlzUmVhZG9ubHkgJiYgdHJhY2socmF3VGFyZ2V0LCBcIml0ZXJhdGVcIiAvKiBJVEVSQVRFICovLCBJVEVSQVRFX0tFWSk7XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIGltcG9ydGFudDogbWFrZSBzdXJlIHRoZSBjYWxsYmFjayBpc1xyXG4gICAgICAgICAgICAvLyAxLiBpbnZva2VkIHdpdGggdGhlIHJlYWN0aXZlIG1hcCBhcyBgdGhpc2AgYW5kIDNyZCBhcmdcclxuICAgICAgICAgICAgLy8gMi4gdGhlIHZhbHVlIHJlY2VpdmVkIHNob3VsZCBiZSBhIGNvcnJlc3BvbmRpbmcgcmVhY3RpdmUvcmVhZG9ubHkuXHJcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHdyYXAodmFsdWUpLCB3cmFwKGtleSksIG9ic2VydmVkKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbn1cclxuZnVuY3Rpb24gY3JlYXRlSXRlcmFibGVNZXRob2QobWV0aG9kLCBpc1JlYWRvbmx5LCBpc1NoYWxsb3cpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncykge1xyXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXNbXCJfX3ZfcmF3XCIgLyogUkFXICovXTtcclxuICAgICAgICBjb25zdCByYXdUYXJnZXQgPSB0b1Jhdyh0YXJnZXQpO1xyXG4gICAgICAgIGNvbnN0IGlzTWFwID0gcmF3VGFyZ2V0IGluc3RhbmNlb2YgTWFwO1xyXG4gICAgICAgIGNvbnN0IGlzUGFpciA9IG1ldGhvZCA9PT0gJ2VudHJpZXMnIHx8IChtZXRob2QgPT09IFN5bWJvbC5pdGVyYXRvciAmJiBpc01hcCk7XHJcbiAgICAgICAgY29uc3QgaXNLZXlPbmx5ID0gbWV0aG9kID09PSAna2V5cycgJiYgaXNNYXA7XHJcbiAgICAgICAgY29uc3QgaW5uZXJJdGVyYXRvciA9IHRhcmdldFttZXRob2RdKC4uLmFyZ3MpO1xyXG4gICAgICAgIGNvbnN0IHdyYXAgPSBpc1JlYWRvbmx5ID8gdG9SZWFkb25seSA6IGlzU2hhbGxvdyA/IHRvU2hhbGxvdyA6IHRvUmVhY3RpdmU7XHJcbiAgICAgICAgIWlzUmVhZG9ubHkgJiZcclxuICAgICAgICAgICAgdHJhY2socmF3VGFyZ2V0LCBcIml0ZXJhdGVcIiAvKiBJVEVSQVRFICovLCBpc0tleU9ubHkgPyBNQVBfS0VZX0lURVJBVEVfS0VZIDogSVRFUkFURV9LRVkpO1xyXG4gICAgICAgIC8vIHJldHVybiBhIHdyYXBwZWQgaXRlcmF0b3Igd2hpY2ggcmV0dXJucyBvYnNlcnZlZCB2ZXJzaW9ucyBvZiB0aGVcclxuICAgICAgICAvLyB2YWx1ZXMgZW1pdHRlZCBmcm9tIHRoZSByZWFsIGl0ZXJhdG9yXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgLy8gaXRlcmF0b3IgcHJvdG9jb2xcclxuICAgICAgICAgICAgbmV4dCgpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHsgdmFsdWUsIGRvbmUgfSA9IGlubmVySXRlcmF0b3IubmV4dCgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRvbmVcclxuICAgICAgICAgICAgICAgICAgICA/IHsgdmFsdWUsIGRvbmUgfVxyXG4gICAgICAgICAgICAgICAgICAgIDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogaXNQYWlyID8gW3dyYXAodmFsdWVbMF0pLCB3cmFwKHZhbHVlWzFdKV0gOiB3cmFwKHZhbHVlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8vIGl0ZXJhYmxlIHByb3RvY29sXHJcbiAgICAgICAgICAgIFtTeW1ib2wuaXRlcmF0b3JdKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfTtcclxufVxyXG5mdW5jdGlvbiBjcmVhdGVSZWFkb25seU1ldGhvZCh0eXBlKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKC4uLmFyZ3MpIHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IGFyZ3NbMF0gPyBgb24ga2V5IFwiJHthcmdzWzBdfVwiIGAgOiBgYDtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKGAke2NhcGl0YWxpemUodHlwZSl9IG9wZXJhdGlvbiAke2tleX1mYWlsZWQ6IHRhcmdldCBpcyByZWFkb25seS5gLCB0b1Jhdyh0aGlzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0eXBlID09PSBcImRlbGV0ZVwiIC8qIERFTEVURSAqLyA/IGZhbHNlIDogdGhpcztcclxuICAgIH07XHJcbn1cclxuY29uc3QgbXV0YWJsZUluc3RydW1lbnRhdGlvbnMgPSB7XHJcbiAgICBnZXQoa2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIGdldCQxKHRoaXMsIGtleSk7XHJcbiAgICB9LFxyXG4gICAgZ2V0IHNpemUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHNpemUodGhpcyk7XHJcbiAgICB9LFxyXG4gICAgaGFzOiBoYXMkMSxcclxuICAgIGFkZCxcclxuICAgIHNldDogc2V0JDEsXHJcbiAgICBkZWxldGU6IGRlbGV0ZUVudHJ5LFxyXG4gICAgY2xlYXIsXHJcbiAgICBmb3JFYWNoOiBjcmVhdGVGb3JFYWNoKGZhbHNlLCBmYWxzZSlcclxufTtcclxuY29uc3Qgc2hhbGxvd0luc3RydW1lbnRhdGlvbnMgPSB7XHJcbiAgICBnZXQoa2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIGdldCQxKHRoaXMsIGtleSwgZmFsc2UsIHRydWUpO1xyXG4gICAgfSxcclxuICAgIGdldCBzaXplKCkge1xyXG4gICAgICAgIHJldHVybiBzaXplKHRoaXMpO1xyXG4gICAgfSxcclxuICAgIGhhczogaGFzJDEsXHJcbiAgICBhZGQsXHJcbiAgICBzZXQ6IHNldCQxLFxyXG4gICAgZGVsZXRlOiBkZWxldGVFbnRyeSxcclxuICAgIGNsZWFyLFxyXG4gICAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaChmYWxzZSwgdHJ1ZSlcclxufTtcclxuY29uc3QgcmVhZG9ubHlJbnN0cnVtZW50YXRpb25zID0ge1xyXG4gICAgZ2V0KGtleSkge1xyXG4gICAgICAgIHJldHVybiBnZXQkMSh0aGlzLCBrZXksIHRydWUpO1xyXG4gICAgfSxcclxuICAgIGdldCBzaXplKCkge1xyXG4gICAgICAgIHJldHVybiBzaXplKHRoaXMsIHRydWUpO1xyXG4gICAgfSxcclxuICAgIGhhcyhrZXkpIHtcclxuICAgICAgICByZXR1cm4gaGFzJDEuY2FsbCh0aGlzLCBrZXksIHRydWUpO1xyXG4gICAgfSxcclxuICAgIGFkZDogY3JlYXRlUmVhZG9ubHlNZXRob2QoXCJhZGRcIiAvKiBBREQgKi8pLFxyXG4gICAgc2V0OiBjcmVhdGVSZWFkb25seU1ldGhvZChcInNldFwiIC8qIFNFVCAqLyksXHJcbiAgICBkZWxldGU6IGNyZWF0ZVJlYWRvbmx5TWV0aG9kKFwiZGVsZXRlXCIgLyogREVMRVRFICovKSxcclxuICAgIGNsZWFyOiBjcmVhdGVSZWFkb25seU1ldGhvZChcImNsZWFyXCIgLyogQ0xFQVIgKi8pLFxyXG4gICAgZm9yRWFjaDogY3JlYXRlRm9yRWFjaCh0cnVlLCBmYWxzZSlcclxufTtcclxuY29uc3QgaXRlcmF0b3JNZXRob2RzID0gWydrZXlzJywgJ3ZhbHVlcycsICdlbnRyaWVzJywgU3ltYm9sLml0ZXJhdG9yXTtcclxuaXRlcmF0b3JNZXRob2RzLmZvckVhY2gobWV0aG9kID0+IHtcclxuICAgIG11dGFibGVJbnN0cnVtZW50YXRpb25zW21ldGhvZF0gPSBjcmVhdGVJdGVyYWJsZU1ldGhvZChtZXRob2QsIGZhbHNlLCBmYWxzZSk7XHJcbiAgICByZWFkb25seUluc3RydW1lbnRhdGlvbnNbbWV0aG9kXSA9IGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgdHJ1ZSwgZmFsc2UpO1xyXG4gICAgc2hhbGxvd0luc3RydW1lbnRhdGlvbnNbbWV0aG9kXSA9IGNyZWF0ZUl0ZXJhYmxlTWV0aG9kKG1ldGhvZCwgZmFsc2UsIHRydWUpO1xyXG59KTtcclxuZnVuY3Rpb24gY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGlzUmVhZG9ubHksIHNoYWxsb3cpIHtcclxuICAgIGNvbnN0IGluc3RydW1lbnRhdGlvbnMgPSBzaGFsbG93XHJcbiAgICAgICAgPyBzaGFsbG93SW5zdHJ1bWVudGF0aW9uc1xyXG4gICAgICAgIDogaXNSZWFkb25seVxyXG4gICAgICAgICAgICA/IHJlYWRvbmx5SW5zdHJ1bWVudGF0aW9uc1xyXG4gICAgICAgICAgICA6IG11dGFibGVJbnN0cnVtZW50YXRpb25zO1xyXG4gICAgcmV0dXJuICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IHtcclxuICAgICAgICBpZiAoa2V5ID09PSBcIl9fdl9pc1JlYWN0aXZlXCIgLyogSVNfUkVBQ1RJVkUgKi8pIHtcclxuICAgICAgICAgICAgcmV0dXJuICFpc1JlYWRvbmx5O1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChrZXkgPT09IFwiX192X2lzUmVhZG9ubHlcIiAvKiBJU19SRUFET05MWSAqLykge1xyXG4gICAgICAgICAgICByZXR1cm4gaXNSZWFkb25seTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoa2V5ID09PSBcIl9fdl9yYXdcIiAvKiBSQVcgKi8pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KGhhc093bihpbnN0cnVtZW50YXRpb25zLCBrZXkpICYmIGtleSBpbiB0YXJnZXRcclxuICAgICAgICAgICAgPyBpbnN0cnVtZW50YXRpb25zXHJcbiAgICAgICAgICAgIDogdGFyZ2V0LCBrZXksIHJlY2VpdmVyKTtcclxuICAgIH07XHJcbn1cclxuY29uc3QgbXV0YWJsZUNvbGxlY3Rpb25IYW5kbGVycyA9IHtcclxuICAgIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGZhbHNlLCBmYWxzZSlcclxufTtcclxuY29uc3Qgc2hhbGxvd0NvbGxlY3Rpb25IYW5kbGVycyA9IHtcclxuICAgIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKGZhbHNlLCB0cnVlKVxyXG59O1xyXG5jb25zdCByZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycyA9IHtcclxuICAgIGdldDogY3JlYXRlSW5zdHJ1bWVudGF0aW9uR2V0dGVyKHRydWUsIGZhbHNlKVxyXG59O1xyXG5mdW5jdGlvbiBjaGVja0lkZW50aXR5S2V5cyh0YXJnZXQsIGhhcywga2V5KSB7XHJcbiAgICBjb25zdCByYXdLZXkgPSB0b1JhdyhrZXkpO1xyXG4gICAgaWYgKHJhd0tleSAhPT0ga2V5ICYmIGhhcy5jYWxsKHRhcmdldCwgcmF3S2V5KSkge1xyXG4gICAgICAgIGNvbnN0IHR5cGUgPSB0b1Jhd1R5cGUodGFyZ2V0KTtcclxuICAgICAgICBjb25zb2xlLndhcm4oYFJlYWN0aXZlICR7dHlwZX0gY29udGFpbnMgYm90aCB0aGUgcmF3IGFuZCByZWFjdGl2ZSBgICtcclxuICAgICAgICAgICAgYHZlcnNpb25zIG9mIHRoZSBzYW1lIG9iamVjdCR7dHlwZSA9PT0gYE1hcGAgPyBgYXMga2V5c2AgOiBgYH0sIGAgK1xyXG4gICAgICAgICAgICBgd2hpY2ggY2FuIGxlYWQgdG8gaW5jb25zaXN0ZW5jaWVzLiBgICtcclxuICAgICAgICAgICAgYEF2b2lkIGRpZmZlcmVudGlhdGluZyBiZXR3ZWVuIHRoZSByYXcgYW5kIHJlYWN0aXZlIHZlcnNpb25zIGAgK1xyXG4gICAgICAgICAgICBgb2YgYW4gb2JqZWN0IGFuZCBvbmx5IHVzZSB0aGUgcmVhY3RpdmUgdmVyc2lvbiBpZiBwb3NzaWJsZS5gKTtcclxuICAgIH1cclxufVxuXG5jb25zdCByZWFjdGl2ZU1hcCA9IG5ldyBXZWFrTWFwKCk7XHJcbmNvbnN0IHJlYWRvbmx5TWFwID0gbmV3IFdlYWtNYXAoKTtcclxuZnVuY3Rpb24gdGFyZ2V0VHlwZU1hcChyYXdUeXBlKSB7XHJcbiAgICBzd2l0Y2ggKHJhd1R5cGUpIHtcclxuICAgICAgICBjYXNlICdPYmplY3QnOlxyXG4gICAgICAgIGNhc2UgJ0FycmF5JzpcclxuICAgICAgICAgICAgcmV0dXJuIDEgLyogQ09NTU9OICovO1xyXG4gICAgICAgIGNhc2UgJ01hcCc6XHJcbiAgICAgICAgY2FzZSAnU2V0JzpcclxuICAgICAgICBjYXNlICdXZWFrTWFwJzpcclxuICAgICAgICBjYXNlICdXZWFrU2V0JzpcclxuICAgICAgICAgICAgcmV0dXJuIDIgLyogQ09MTEVDVElPTiAqLztcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICByZXR1cm4gMCAvKiBJTlZBTElEICovO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGdldFRhcmdldFR5cGUodmFsdWUpIHtcclxuICAgIHJldHVybiB2YWx1ZVtcIl9fdl9za2lwXCIgLyogU0tJUCAqL10gfHwgIU9iamVjdC5pc0V4dGVuc2libGUodmFsdWUpXHJcbiAgICAgICAgPyAwIC8qIElOVkFMSUQgKi9cclxuICAgICAgICA6IHRhcmdldFR5cGVNYXAodG9SYXdUeXBlKHZhbHVlKSk7XHJcbn1cclxuZnVuY3Rpb24gcmVhY3RpdmUodGFyZ2V0KSB7XHJcbiAgICAvLyBpZiB0cnlpbmcgdG8gb2JzZXJ2ZSBhIHJlYWRvbmx5IHByb3h5LCByZXR1cm4gdGhlIHJlYWRvbmx5IHZlcnNpb24uXHJcbiAgICBpZiAodGFyZ2V0ICYmIHRhcmdldFtcIl9fdl9pc1JlYWRvbmx5XCIgLyogSVNfUkVBRE9OTFkgKi9dKSB7XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgIH1cclxuICAgIHJldHVybiBjcmVhdGVSZWFjdGl2ZU9iamVjdCh0YXJnZXQsIGZhbHNlLCBtdXRhYmxlSGFuZGxlcnMsIG11dGFibGVDb2xsZWN0aW9uSGFuZGxlcnMpO1xyXG59XHJcbi8vIFJldHVybiBhIHJlYWN0aXZlLWNvcHkgb2YgdGhlIG9yaWdpbmFsIG9iamVjdCwgd2hlcmUgb25seSB0aGUgcm9vdCBsZXZlbFxyXG4vLyBwcm9wZXJ0aWVzIGFyZSByZWFjdGl2ZSwgYW5kIGRvZXMgTk9UIHVud3JhcCByZWZzIG5vciByZWN1cnNpdmVseSBjb252ZXJ0XHJcbi8vIHJldHVybmVkIHByb3BlcnRpZXMuXHJcbmZ1bmN0aW9uIHNoYWxsb3dSZWFjdGl2ZSh0YXJnZXQpIHtcclxuICAgIHJldHVybiBjcmVhdGVSZWFjdGl2ZU9iamVjdCh0YXJnZXQsIGZhbHNlLCBzaGFsbG93UmVhY3RpdmVIYW5kbGVycywgc2hhbGxvd0NvbGxlY3Rpb25IYW5kbGVycyk7XHJcbn1cclxuZnVuY3Rpb24gcmVhZG9ubHkodGFyZ2V0KSB7XHJcbiAgICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QodGFyZ2V0LCB0cnVlLCByZWFkb25seUhhbmRsZXJzLCByZWFkb25seUNvbGxlY3Rpb25IYW5kbGVycyk7XHJcbn1cclxuLy8gUmV0dXJuIGEgcmVhY3RpdmUtY29weSBvZiB0aGUgb3JpZ2luYWwgb2JqZWN0LCB3aGVyZSBvbmx5IHRoZSByb290IGxldmVsXHJcbi8vIHByb3BlcnRpZXMgYXJlIHJlYWRvbmx5LCBhbmQgZG9lcyBOT1QgdW53cmFwIHJlZnMgbm9yIHJlY3Vyc2l2ZWx5IGNvbnZlcnRcclxuLy8gcmV0dXJuZWQgcHJvcGVydGllcy5cclxuLy8gVGhpcyBpcyB1c2VkIGZvciBjcmVhdGluZyB0aGUgcHJvcHMgcHJveHkgb2JqZWN0IGZvciBzdGF0ZWZ1bCBjb21wb25lbnRzLlxyXG5mdW5jdGlvbiBzaGFsbG93UmVhZG9ubHkodGFyZ2V0KSB7XHJcbiAgICByZXR1cm4gY3JlYXRlUmVhY3RpdmVPYmplY3QodGFyZ2V0LCB0cnVlLCBzaGFsbG93UmVhZG9ubHlIYW5kbGVycywgcmVhZG9ubHlDb2xsZWN0aW9uSGFuZGxlcnMpO1xyXG59XHJcbmZ1bmN0aW9uIGNyZWF0ZVJlYWN0aXZlT2JqZWN0KHRhcmdldCwgaXNSZWFkb25seSwgYmFzZUhhbmRsZXJzLCBjb2xsZWN0aW9uSGFuZGxlcnMpIHtcclxuICAgIGlmICghaXNPYmplY3QodGFyZ2V0KSkge1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKGB2YWx1ZSBjYW5ub3QgYmUgbWFkZSByZWFjdGl2ZTogJHtTdHJpbmcodGFyZ2V0KX1gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgIH1cclxuICAgIC8vIHRhcmdldCBpcyBhbHJlYWR5IGEgUHJveHksIHJldHVybiBpdC5cclxuICAgIC8vIGV4Y2VwdGlvbjogY2FsbGluZyByZWFkb25seSgpIG9uIGEgcmVhY3RpdmUgb2JqZWN0XHJcbiAgICBpZiAodGFyZ2V0W1wiX192X3Jhd1wiIC8qIFJBVyAqL10gJiZcclxuICAgICAgICAhKGlzUmVhZG9ubHkgJiYgdGFyZ2V0W1wiX192X2lzUmVhY3RpdmVcIiAvKiBJU19SRUFDVElWRSAqL10pKSB7XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgIH1cclxuICAgIC8vIHRhcmdldCBhbHJlYWR5IGhhcyBjb3JyZXNwb25kaW5nIFByb3h5XHJcbiAgICBjb25zdCBwcm94eU1hcCA9IGlzUmVhZG9ubHkgPyByZWFkb25seU1hcCA6IHJlYWN0aXZlTWFwO1xyXG4gICAgY29uc3QgZXhpc3RpbmdQcm94eSA9IHByb3h5TWFwLmdldCh0YXJnZXQpO1xyXG4gICAgaWYgKGV4aXN0aW5nUHJveHkpIHtcclxuICAgICAgICByZXR1cm4gZXhpc3RpbmdQcm94eTtcclxuICAgIH1cclxuICAgIC8vIG9ubHkgYSB3aGl0ZWxpc3Qgb2YgdmFsdWUgdHlwZXMgY2FuIGJlIG9ic2VydmVkLlxyXG4gICAgY29uc3QgdGFyZ2V0VHlwZSA9IGdldFRhcmdldFR5cGUodGFyZ2V0KTtcclxuICAgIGlmICh0YXJnZXRUeXBlID09PSAwIC8qIElOVkFMSUQgKi8pIHtcclxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgfVxyXG4gICAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkodGFyZ2V0LCB0YXJnZXRUeXBlID09PSAyIC8qIENPTExFQ1RJT04gKi8gPyBjb2xsZWN0aW9uSGFuZGxlcnMgOiBiYXNlSGFuZGxlcnMpO1xyXG4gICAgcHJveHlNYXAuc2V0KHRhcmdldCwgcHJveHkpO1xyXG4gICAgcmV0dXJuIHByb3h5O1xyXG59XHJcbmZ1bmN0aW9uIGlzUmVhY3RpdmUodmFsdWUpIHtcclxuICAgIGlmIChpc1JlYWRvbmx5KHZhbHVlKSkge1xyXG4gICAgICAgIHJldHVybiBpc1JlYWN0aXZlKHZhbHVlW1wiX192X3Jhd1wiIC8qIFJBVyAqL10pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuICEhKHZhbHVlICYmIHZhbHVlW1wiX192X2lzUmVhY3RpdmVcIiAvKiBJU19SRUFDVElWRSAqL10pO1xyXG59XHJcbmZ1bmN0aW9uIGlzUmVhZG9ubHkodmFsdWUpIHtcclxuICAgIHJldHVybiAhISh2YWx1ZSAmJiB2YWx1ZVtcIl9fdl9pc1JlYWRvbmx5XCIgLyogSVNfUkVBRE9OTFkgKi9dKTtcclxufVxyXG5mdW5jdGlvbiBpc1Byb3h5KHZhbHVlKSB7XHJcbiAgICByZXR1cm4gaXNSZWFjdGl2ZSh2YWx1ZSkgfHwgaXNSZWFkb25seSh2YWx1ZSk7XHJcbn1cclxuZnVuY3Rpb24gdG9SYXcob2JzZXJ2ZWQpIHtcclxuICAgIHJldHVybiAoKG9ic2VydmVkICYmIHRvUmF3KG9ic2VydmVkW1wiX192X3Jhd1wiIC8qIFJBVyAqL10pKSB8fCBvYnNlcnZlZCk7XHJcbn1cclxuZnVuY3Rpb24gbWFya1Jhdyh2YWx1ZSkge1xyXG4gICAgZGVmKHZhbHVlLCBcIl9fdl9za2lwXCIgLyogU0tJUCAqLywgdHJ1ZSk7XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cblxuY29uc3QgY29udmVydCA9ICh2YWwpID0+IGlzT2JqZWN0KHZhbCkgPyByZWFjdGl2ZSh2YWwpIDogdmFsO1xyXG5mdW5jdGlvbiBpc1JlZihyKSB7XHJcbiAgICByZXR1cm4gQm9vbGVhbihyICYmIHIuX192X2lzUmVmID09PSB0cnVlKTtcclxufVxyXG5mdW5jdGlvbiByZWYodmFsdWUpIHtcclxuICAgIHJldHVybiBjcmVhdGVSZWYodmFsdWUpO1xyXG59XHJcbmZ1bmN0aW9uIHNoYWxsb3dSZWYodmFsdWUpIHtcclxuICAgIHJldHVybiBjcmVhdGVSZWYodmFsdWUsIHRydWUpO1xyXG59XHJcbmNsYXNzIFJlZkltcGwge1xyXG4gICAgY29uc3RydWN0b3IoX3Jhd1ZhbHVlLCBfc2hhbGxvdyA9IGZhbHNlKSB7XHJcbiAgICAgICAgdGhpcy5fcmF3VmFsdWUgPSBfcmF3VmFsdWU7XHJcbiAgICAgICAgdGhpcy5fc2hhbGxvdyA9IF9zaGFsbG93O1xyXG4gICAgICAgIHRoaXMuX192X2lzUmVmID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLl92YWx1ZSA9IF9zaGFsbG93ID8gX3Jhd1ZhbHVlIDogY29udmVydChfcmF3VmFsdWUpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHZhbHVlKCkge1xyXG4gICAgICAgIHRyYWNrKHRvUmF3KHRoaXMpLCBcImdldFwiIC8qIEdFVCAqLywgJ3ZhbHVlJyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gICAgfVxyXG4gICAgc2V0IHZhbHVlKG5ld1ZhbCkge1xyXG4gICAgICAgIGlmIChoYXNDaGFuZ2VkKHRvUmF3KG5ld1ZhbCksIHRoaXMuX3Jhd1ZhbHVlKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9yYXdWYWx1ZSA9IG5ld1ZhbDtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB0aGlzLl9zaGFsbG93ID8gbmV3VmFsIDogY29udmVydChuZXdWYWwpO1xyXG4gICAgICAgICAgICB0cmlnZ2VyKHRvUmF3KHRoaXMpLCBcInNldFwiIC8qIFNFVCAqLywgJ3ZhbHVlJywgbmV3VmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY3JlYXRlUmVmKHJhd1ZhbHVlLCBzaGFsbG93ID0gZmFsc2UpIHtcclxuICAgIGlmIChpc1JlZihyYXdWYWx1ZSkpIHtcclxuICAgICAgICByZXR1cm4gcmF3VmFsdWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3IFJlZkltcGwocmF3VmFsdWUsIHNoYWxsb3cpO1xyXG59XHJcbmZ1bmN0aW9uIHRyaWdnZXJSZWYocmVmKSB7XHJcbiAgICB0cmlnZ2VyKHJlZiwgXCJzZXRcIiAvKiBTRVQgKi8sICd2YWx1ZScsIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/IHJlZi52YWx1ZSA6IHZvaWQgMCk7XHJcbn1cclxuZnVuY3Rpb24gdW5yZWYocmVmKSB7XHJcbiAgICByZXR1cm4gaXNSZWYocmVmKSA/IHJlZi52YWx1ZSA6IHJlZjtcclxufVxyXG5jb25zdCBzaGFsbG93VW53cmFwSGFuZGxlcnMgPSB7XHJcbiAgICBnZXQ6ICh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpID0+IHVucmVmKFJlZmxlY3QuZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikpLFxyXG4gICAgc2V0OiAodGFyZ2V0LCBrZXksIHZhbHVlLCByZWNlaXZlcikgPT4ge1xyXG4gICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGFyZ2V0W2tleV07XHJcbiAgICAgICAgaWYgKGlzUmVmKG9sZFZhbHVlKSAmJiAhaXNSZWYodmFsdWUpKSB7XHJcbiAgICAgICAgICAgIG9sZFZhbHVlLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIFJlZmxlY3Quc2V0KHRhcmdldCwga2V5LCB2YWx1ZSwgcmVjZWl2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuZnVuY3Rpb24gcHJveHlSZWZzKG9iamVjdFdpdGhSZWZzKSB7XHJcbiAgICByZXR1cm4gaXNSZWFjdGl2ZShvYmplY3RXaXRoUmVmcylcclxuICAgICAgICA/IG9iamVjdFdpdGhSZWZzXHJcbiAgICAgICAgOiBuZXcgUHJveHkob2JqZWN0V2l0aFJlZnMsIHNoYWxsb3dVbndyYXBIYW5kbGVycyk7XHJcbn1cclxuY2xhc3MgQ3VzdG9tUmVmSW1wbCB7XHJcbiAgICBjb25zdHJ1Y3RvcihmYWN0b3J5KSB7XHJcbiAgICAgICAgdGhpcy5fX3ZfaXNSZWYgPSB0cnVlO1xyXG4gICAgICAgIGNvbnN0IHsgZ2V0LCBzZXQgfSA9IGZhY3RvcnkoKCkgPT4gdHJhY2sodGhpcywgXCJnZXRcIiAvKiBHRVQgKi8sICd2YWx1ZScpLCAoKSA9PiB0cmlnZ2VyKHRoaXMsIFwic2V0XCIgLyogU0VUICovLCAndmFsdWUnKSk7XHJcbiAgICAgICAgdGhpcy5fZ2V0ID0gZ2V0O1xyXG4gICAgICAgIHRoaXMuX3NldCA9IHNldDtcclxuICAgIH1cclxuICAgIGdldCB2YWx1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0KCk7XHJcbiAgICB9XHJcbiAgICBzZXQgdmFsdWUobmV3VmFsKSB7XHJcbiAgICAgICAgdGhpcy5fc2V0KG5ld1ZhbCk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY3VzdG9tUmVmKGZhY3RvcnkpIHtcclxuICAgIHJldHVybiBuZXcgQ3VzdG9tUmVmSW1wbChmYWN0b3J5KTtcclxufVxyXG5mdW5jdGlvbiB0b1JlZnMob2JqZWN0KSB7XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFpc1Byb3h5KG9iamVjdCkpIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oYHRvUmVmcygpIGV4cGVjdHMgYSByZWFjdGl2ZSBvYmplY3QgYnV0IHJlY2VpdmVkIGEgcGxhaW4gb25lLmApO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmV0ID0gaXNBcnJheShvYmplY3QpID8gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpIDoge307XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmplY3QpIHtcclxuICAgICAgICByZXRba2V5XSA9IHRvUmVmKG9iamVjdCwga2V5KTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXQ7XHJcbn1cclxuY2xhc3MgT2JqZWN0UmVmSW1wbCB7XHJcbiAgICBjb25zdHJ1Y3Rvcihfb2JqZWN0LCBfa2V5KSB7XHJcbiAgICAgICAgdGhpcy5fb2JqZWN0ID0gX29iamVjdDtcclxuICAgICAgICB0aGlzLl9rZXkgPSBfa2V5O1xyXG4gICAgICAgIHRoaXMuX192X2lzUmVmID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGdldCB2YWx1ZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fb2JqZWN0W3RoaXMuX2tleV07XHJcbiAgICB9XHJcbiAgICBzZXQgdmFsdWUobmV3VmFsKSB7XHJcbiAgICAgICAgdGhpcy5fb2JqZWN0W3RoaXMuX2tleV0gPSBuZXdWYWw7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gdG9SZWYob2JqZWN0LCBrZXkpIHtcclxuICAgIHJldHVybiBuZXcgT2JqZWN0UmVmSW1wbChvYmplY3QsIGtleSk7XHJcbn1cblxuY2xhc3MgQ29tcHV0ZWRSZWZJbXBsIHtcclxuICAgIGNvbnN0cnVjdG9yKGdldHRlciwgX3NldHRlciwgaXNSZWFkb25seSkge1xyXG4gICAgICAgIHRoaXMuX3NldHRlciA9IF9zZXR0ZXI7XHJcbiAgICAgICAgdGhpcy5fZGlydHkgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuX192X2lzUmVmID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmVmZmVjdCA9IGVmZmVjdChnZXR0ZXIsIHtcclxuICAgICAgICAgICAgbGF6eTogdHJ1ZSxcclxuICAgICAgICAgICAgc2NoZWR1bGVyOiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2RpcnR5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGlydHkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXIodG9SYXcodGhpcyksIFwic2V0XCIgLyogU0VUICovLCAndmFsdWUnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXNbXCJfX3ZfaXNSZWFkb25seVwiIC8qIElTX1JFQURPTkxZICovXSA9IGlzUmVhZG9ubHk7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsdWUoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2RpcnR5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdGhpcy5lZmZlY3QoKTtcclxuICAgICAgICAgICAgdGhpcy5fZGlydHkgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdHJhY2sodG9SYXcodGhpcyksIFwiZ2V0XCIgLyogR0VUICovLCAndmFsdWUnKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWU7XHJcbiAgICB9XHJcbiAgICBzZXQgdmFsdWUobmV3VmFsdWUpIHtcclxuICAgICAgICB0aGlzLl9zZXR0ZXIobmV3VmFsdWUpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGNvbXB1dGVkKGdldHRlck9yT3B0aW9ucykge1xyXG4gICAgbGV0IGdldHRlcjtcclxuICAgIGxldCBzZXR0ZXI7XHJcbiAgICBpZiAoaXNGdW5jdGlvbihnZXR0ZXJPck9wdGlvbnMpKSB7XHJcbiAgICAgICAgZ2V0dGVyID0gZ2V0dGVyT3JPcHRpb25zO1xyXG4gICAgICAgIHNldHRlciA9IChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKVxyXG4gICAgICAgICAgICA/ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignV3JpdGUgb3BlcmF0aW9uIGZhaWxlZDogY29tcHV0ZWQgdmFsdWUgaXMgcmVhZG9ubHknKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA6IE5PT1A7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBnZXR0ZXIgPSBnZXR0ZXJPck9wdGlvbnMuZ2V0O1xyXG4gICAgICAgIHNldHRlciA9IGdldHRlck9yT3B0aW9ucy5zZXQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3IENvbXB1dGVkUmVmSW1wbChnZXR0ZXIsIHNldHRlciwgaXNGdW5jdGlvbihnZXR0ZXJPck9wdGlvbnMpIHx8ICFnZXR0ZXJPck9wdGlvbnMuc2V0KTtcclxufVxuXG5leHBvcnQgeyBJVEVSQVRFX0tFWSwgY29tcHV0ZWQsIGN1c3RvbVJlZiwgZWZmZWN0LCBlbmFibGVUcmFja2luZywgaXNQcm94eSwgaXNSZWFjdGl2ZSwgaXNSZWFkb25seSwgaXNSZWYsIG1hcmtSYXcsIHBhdXNlVHJhY2tpbmcsIHByb3h5UmVmcywgcmVhY3RpdmUsIHJlYWRvbmx5LCByZWYsIHJlc2V0VHJhY2tpbmcsIHNoYWxsb3dSZWFjdGl2ZSwgc2hhbGxvd1JlYWRvbmx5LCBzaGFsbG93UmVmLCBzdG9wLCB0b1JhdywgdG9SZWYsIHRvUmVmcywgdHJhY2ssIHRyaWdnZXIsIHRyaWdnZXJSZWYsIHVucmVmIH07XG4iLCJpbXBvcnQgeyBwYXVzZVRyYWNraW5nLCByZXNldFRyYWNraW5nLCBpc1JlZiwgdG9SYXcsIGlzUHJveHksIHNoYWxsb3dSZWFjdGl2ZSwgdHJpZ2dlciwgZWZmZWN0LCBzdG9wLCBpc1JlYWN0aXZlLCByZWFjdGl2ZSwgc2hhbGxvd1JlYWRvbmx5LCB0cmFjaywgcHJveHlSZWZzLCBjb21wdXRlZCBhcyBjb21wdXRlZCQxLCByZWYgfSBmcm9tICdAdnVlL3JlYWN0aXZpdHknO1xuZXhwb3J0IHsgY3VzdG9tUmVmLCBpc1Byb3h5LCBpc1JlYWN0aXZlLCBpc1JlYWRvbmx5LCBpc1JlZiwgbWFya1JhdywgcHJveHlSZWZzLCByZWFjdGl2ZSwgcmVhZG9ubHksIHJlZiwgc2hhbGxvd1JlYWN0aXZlLCBzaGFsbG93UmVhZG9ubHksIHNoYWxsb3dSZWYsIHRvUmF3LCB0b1JlZiwgdG9SZWZzLCB0cmlnZ2VyUmVmLCB1bnJlZiB9IGZyb20gJ0B2dWUvcmVhY3Rpdml0eSc7XG5pbXBvcnQgeyBpc1N0cmluZywgaXNGdW5jdGlvbiwgaXNQcm9taXNlLCBpc0FycmF5LCBleHRlbmQsIGlzTW9kZWxMaXN0ZW5lciwgaXNPbiwgY2FwaXRhbGl6ZSwgY2FtZWxpemUsIEVNUFRZX0FSUiwgbm9ybWFsaXplQ2xhc3MsIGlzT2JqZWN0LCBub3JtYWxpemVTdHlsZSwgRU1QVFlfT0JKLCBoeXBoZW5hdGUsIGhhc093biwgZGVmLCBpc1Jlc2VydmVkUHJvcCwgdG9SYXdUeXBlLCBtYWtlTWFwLCByZW1vdmUsIGludm9rZUFycmF5Rm5zLCBOTywgZ2V0R2xvYmFsVGhpcywgTk9PUCwgaGFzQ2hhbmdlZCwgaXNHbG9iYWxseVdoaXRlbGlzdGVkIH0gZnJvbSAnQHZ1ZS9zaGFyZWQnO1xuZXhwb3J0IHsgY2FtZWxpemUsIGNhcGl0YWxpemUsIHRvRGlzcGxheVN0cmluZyB9IGZyb20gJ0B2dWUvc2hhcmVkJztcblxuY29uc3Qgc3RhY2sgPSBbXTtcclxuZnVuY3Rpb24gcHVzaFdhcm5pbmdDb250ZXh0KHZub2RlKSB7XHJcbiAgICBzdGFjay5wdXNoKHZub2RlKTtcclxufVxyXG5mdW5jdGlvbiBwb3BXYXJuaW5nQ29udGV4dCgpIHtcclxuICAgIHN0YWNrLnBvcCgpO1xyXG59XHJcbmZ1bmN0aW9uIHdhcm4obXNnLCAuLi5hcmdzKSB7XHJcbiAgICAvLyBhdm9pZCBwcm9wcyBmb3JtYXR0aW5nIG9yIHdhcm4gaGFuZGxlciB0cmFja2luZyBkZXBzIHRoYXQgbWlnaHQgYmUgbXV0YXRlZFxyXG4gICAgLy8gZHVyaW5nIHBhdGNoLCBsZWFkaW5nIHRvIGluZmluaXRlIHJlY3Vyc2lvbi5cclxuICAgIHBhdXNlVHJhY2tpbmcoKTtcclxuICAgIGNvbnN0IGluc3RhbmNlID0gc3RhY2subGVuZ3RoID8gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV0uY29tcG9uZW50IDogbnVsbDtcclxuICAgIGNvbnN0IGFwcFdhcm5IYW5kbGVyID0gaW5zdGFuY2UgJiYgaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcud2FybkhhbmRsZXI7XHJcbiAgICBjb25zdCB0cmFjZSA9IGdldENvbXBvbmVudFRyYWNlKCk7XHJcbiAgICBpZiAoYXBwV2FybkhhbmRsZXIpIHtcclxuICAgICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoYXBwV2FybkhhbmRsZXIsIGluc3RhbmNlLCAxMSAvKiBBUFBfV0FSTl9IQU5ETEVSICovLCBbXHJcbiAgICAgICAgICAgIG1zZyArIGFyZ3Muam9pbignJyksXHJcbiAgICAgICAgICAgIGluc3RhbmNlICYmIGluc3RhbmNlLnByb3h5LFxyXG4gICAgICAgICAgICB0cmFjZVxyXG4gICAgICAgICAgICAgICAgLm1hcCgoeyB2bm9kZSB9KSA9PiBgYXQgPCR7Zm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgdm5vZGUudHlwZSl9PmApXHJcbiAgICAgICAgICAgICAgICAuam9pbignXFxuJyksXHJcbiAgICAgICAgICAgIHRyYWNlXHJcbiAgICAgICAgXSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBjb25zdCB3YXJuQXJncyA9IFtgW1Z1ZSB3YXJuXTogJHttc2d9YCwgLi4uYXJnc107XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXHJcbiAgICAgICAgaWYgKHRyYWNlLmxlbmd0aCAmJlxyXG4gICAgICAgICAgICAvLyBhdm9pZCBzcGFtbWluZyBjb25zb2xlIGR1cmluZyB0ZXN0c1xyXG4gICAgICAgICAgICAhZmFsc2UpIHtcclxuICAgICAgICAgICAgd2FybkFyZ3MucHVzaChgXFxuYCwgLi4uZm9ybWF0VHJhY2UodHJhY2UpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc29sZS53YXJuKC4uLndhcm5BcmdzKTtcclxuICAgIH1cclxuICAgIHJlc2V0VHJhY2tpbmcoKTtcclxufVxyXG5mdW5jdGlvbiBnZXRDb21wb25lbnRUcmFjZSgpIHtcclxuICAgIGxldCBjdXJyZW50Vk5vZGUgPSBzdGFja1tzdGFjay5sZW5ndGggLSAxXTtcclxuICAgIGlmICghY3VycmVudFZOb2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfVxyXG4gICAgLy8gd2UgY2FuJ3QganVzdCB1c2UgdGhlIHN0YWNrIGJlY2F1c2UgaXQgd2lsbCBiZSBpbmNvbXBsZXRlIGR1cmluZyB1cGRhdGVzXHJcbiAgICAvLyB0aGF0IGRpZCBub3Qgc3RhcnQgZnJvbSB0aGUgcm9vdC4gUmUtY29uc3RydWN0IHRoZSBwYXJlbnQgY2hhaW4gdXNpbmdcclxuICAgIC8vIGluc3RhbmNlIHBhcmVudCBwb2ludGVycy5cclxuICAgIGNvbnN0IG5vcm1hbGl6ZWRTdGFjayA9IFtdO1xyXG4gICAgd2hpbGUgKGN1cnJlbnRWTm9kZSkge1xyXG4gICAgICAgIGNvbnN0IGxhc3QgPSBub3JtYWxpemVkU3RhY2tbMF07XHJcbiAgICAgICAgaWYgKGxhc3QgJiYgbGFzdC52bm9kZSA9PT0gY3VycmVudFZOb2RlKSB7XHJcbiAgICAgICAgICAgIGxhc3QucmVjdXJzZUNvdW50Kys7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBub3JtYWxpemVkU3RhY2sucHVzaCh7XHJcbiAgICAgICAgICAgICAgICB2bm9kZTogY3VycmVudFZOb2RlLFxyXG4gICAgICAgICAgICAgICAgcmVjdXJzZUNvdW50OiAwXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBwYXJlbnRJbnN0YW5jZSA9IGN1cnJlbnRWTm9kZS5jb21wb25lbnQgJiYgY3VycmVudFZOb2RlLmNvbXBvbmVudC5wYXJlbnQ7XHJcbiAgICAgICAgY3VycmVudFZOb2RlID0gcGFyZW50SW5zdGFuY2UgJiYgcGFyZW50SW5zdGFuY2Uudm5vZGU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbm9ybWFsaXplZFN0YWNrO1xyXG59XHJcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbmZ1bmN0aW9uIGZvcm1hdFRyYWNlKHRyYWNlKSB7XHJcbiAgICBjb25zdCBsb2dzID0gW107XHJcbiAgICB0cmFjZS5mb3JFYWNoKChlbnRyeSwgaSkgPT4ge1xyXG4gICAgICAgIGxvZ3MucHVzaCguLi4oaSA9PT0gMCA/IFtdIDogW2BcXG5gXSksIC4uLmZvcm1hdFRyYWNlRW50cnkoZW50cnkpKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGxvZ3M7XHJcbn1cclxuZnVuY3Rpb24gZm9ybWF0VHJhY2VFbnRyeSh7IHZub2RlLCByZWN1cnNlQ291bnQgfSkge1xyXG4gICAgY29uc3QgcG9zdGZpeCA9IHJlY3Vyc2VDb3VudCA+IDAgPyBgLi4uICgke3JlY3Vyc2VDb3VudH0gcmVjdXJzaXZlIGNhbGxzKWAgOiBgYDtcclxuICAgIGNvbnN0IGlzUm9vdCA9IHZub2RlLmNvbXBvbmVudCA/IHZub2RlLmNvbXBvbmVudC5wYXJlbnQgPT0gbnVsbCA6IGZhbHNlO1xyXG4gICAgY29uc3Qgb3BlbiA9IGAgYXQgPCR7Zm9ybWF0Q29tcG9uZW50TmFtZSh2bm9kZS5jb21wb25lbnQsIHZub2RlLnR5cGUsIGlzUm9vdCl9YDtcclxuICAgIGNvbnN0IGNsb3NlID0gYD5gICsgcG9zdGZpeDtcclxuICAgIHJldHVybiB2bm9kZS5wcm9wc1xyXG4gICAgICAgID8gW29wZW4sIC4uLmZvcm1hdFByb3BzKHZub2RlLnByb3BzKSwgY2xvc2VdXHJcbiAgICAgICAgOiBbb3BlbiArIGNsb3NlXTtcclxufVxyXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG5mdW5jdGlvbiBmb3JtYXRQcm9wcyhwcm9wcykge1xyXG4gICAgY29uc3QgcmVzID0gW107XHJcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocHJvcHMpO1xyXG4gICAga2V5cy5zbGljZSgwLCAzKS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgcmVzLnB1c2goLi4uZm9ybWF0UHJvcChrZXksIHByb3BzW2tleV0pKTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGtleXMubGVuZ3RoID4gMykge1xyXG4gICAgICAgIHJlcy5wdXNoKGAgLi4uYCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzO1xyXG59XHJcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbmZ1bmN0aW9uIGZvcm1hdFByb3Aoa2V5LCB2YWx1ZSwgcmF3KSB7XHJcbiAgICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XHJcbiAgICAgICAgdmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XHJcbiAgICAgICAgcmV0dXJuIHJhdyA/IHZhbHVlIDogW2Ake2tleX09JHt2YWx1ZX1gXTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHxcclxuICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJyB8fFxyXG4gICAgICAgIHZhbHVlID09IG51bGwpIHtcclxuICAgICAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT0ke3ZhbHVlfWBdO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNSZWYodmFsdWUpKSB7XHJcbiAgICAgICAgdmFsdWUgPSBmb3JtYXRQcm9wKGtleSwgdG9SYXcodmFsdWUudmFsdWUpLCB0cnVlKTtcclxuICAgICAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT1SZWY8YCwgdmFsdWUsIGA+YF07XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xyXG4gICAgICAgIHJldHVybiBbYCR7a2V5fT1mbiR7dmFsdWUubmFtZSA/IGA8JHt2YWx1ZS5uYW1lfT5gIDogYGB9YF07XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICB2YWx1ZSA9IHRvUmF3KHZhbHVlKTtcclxuICAgICAgICByZXR1cm4gcmF3ID8gdmFsdWUgOiBbYCR7a2V5fT1gLCB2YWx1ZV07XHJcbiAgICB9XHJcbn1cblxuY29uc3QgRXJyb3JUeXBlU3RyaW5ncyA9IHtcclxuICAgIFtcImJjXCIgLyogQkVGT1JFX0NSRUFURSAqL106ICdiZWZvcmVDcmVhdGUgaG9vaycsXHJcbiAgICBbXCJjXCIgLyogQ1JFQVRFRCAqL106ICdjcmVhdGVkIGhvb2snLFxyXG4gICAgW1wiYm1cIiAvKiBCRUZPUkVfTU9VTlQgKi9dOiAnYmVmb3JlTW91bnQgaG9vaycsXHJcbiAgICBbXCJtXCIgLyogTU9VTlRFRCAqL106ICdtb3VudGVkIGhvb2snLFxyXG4gICAgW1wiYnVcIiAvKiBCRUZPUkVfVVBEQVRFICovXTogJ2JlZm9yZVVwZGF0ZSBob29rJyxcclxuICAgIFtcInVcIiAvKiBVUERBVEVEICovXTogJ3VwZGF0ZWQnLFxyXG4gICAgW1wiYnVtXCIgLyogQkVGT1JFX1VOTU9VTlQgKi9dOiAnYmVmb3JlVW5tb3VudCBob29rJyxcclxuICAgIFtcInVtXCIgLyogVU5NT1VOVEVEICovXTogJ3VubW91bnRlZCBob29rJyxcclxuICAgIFtcImFcIiAvKiBBQ1RJVkFURUQgKi9dOiAnYWN0aXZhdGVkIGhvb2snLFxyXG4gICAgW1wiZGFcIiAvKiBERUFDVElWQVRFRCAqL106ICdkZWFjdGl2YXRlZCBob29rJyxcclxuICAgIFtcImVjXCIgLyogRVJST1JfQ0FQVFVSRUQgKi9dOiAnZXJyb3JDYXB0dXJlZCBob29rJyxcclxuICAgIFtcInJ0Y1wiIC8qIFJFTkRFUl9UUkFDS0VEICovXTogJ3JlbmRlclRyYWNrZWQgaG9vaycsXHJcbiAgICBbXCJydGdcIiAvKiBSRU5ERVJfVFJJR0dFUkVEICovXTogJ3JlbmRlclRyaWdnZXJlZCBob29rJyxcclxuICAgIFswIC8qIFNFVFVQX0ZVTkNUSU9OICovXTogJ3NldHVwIGZ1bmN0aW9uJyxcclxuICAgIFsxIC8qIFJFTkRFUl9GVU5DVElPTiAqL106ICdyZW5kZXIgZnVuY3Rpb24nLFxyXG4gICAgWzIgLyogV0FUQ0hfR0VUVEVSICovXTogJ3dhdGNoZXIgZ2V0dGVyJyxcclxuICAgIFszIC8qIFdBVENIX0NBTExCQUNLICovXTogJ3dhdGNoZXIgY2FsbGJhY2snLFxyXG4gICAgWzQgLyogV0FUQ0hfQ0xFQU5VUCAqL106ICd3YXRjaGVyIGNsZWFudXAgZnVuY3Rpb24nLFxyXG4gICAgWzUgLyogTkFUSVZFX0VWRU5UX0hBTkRMRVIgKi9dOiAnbmF0aXZlIGV2ZW50IGhhbmRsZXInLFxyXG4gICAgWzYgLyogQ09NUE9ORU5UX0VWRU5UX0hBTkRMRVIgKi9dOiAnY29tcG9uZW50IGV2ZW50IGhhbmRsZXInLFxyXG4gICAgWzcgLyogVk5PREVfSE9PSyAqL106ICd2bm9kZSBob29rJyxcclxuICAgIFs4IC8qIERJUkVDVElWRV9IT09LICovXTogJ2RpcmVjdGl2ZSBob29rJyxcclxuICAgIFs5IC8qIFRSQU5TSVRJT05fSE9PSyAqL106ICd0cmFuc2l0aW9uIGhvb2snLFxyXG4gICAgWzEwIC8qIEFQUF9FUlJPUl9IQU5ETEVSICovXTogJ2FwcCBlcnJvckhhbmRsZXInLFxyXG4gICAgWzExIC8qIEFQUF9XQVJOX0hBTkRMRVIgKi9dOiAnYXBwIHdhcm5IYW5kbGVyJyxcclxuICAgIFsxMiAvKiBGVU5DVElPTl9SRUYgKi9dOiAncmVmIGZ1bmN0aW9uJyxcclxuICAgIFsxMyAvKiBBU1lOQ19DT01QT05FTlRfTE9BREVSICovXTogJ2FzeW5jIGNvbXBvbmVudCBsb2FkZXInLFxyXG4gICAgWzE0IC8qIFNDSEVEVUxFUiAqL106ICdzY2hlZHVsZXIgZmx1c2guIFRoaXMgaXMgbGlrZWx5IGEgVnVlIGludGVybmFscyBidWcuICcgK1xyXG4gICAgICAgICdQbGVhc2Ugb3BlbiBhbiBpc3N1ZSBhdCBodHRwczovL25ldy1pc3N1ZS52dWVqcy5vcmcvP3JlcG89dnVlanMvdnVlLW5leHQnXHJcbn07XHJcbmZ1bmN0aW9uIGNhbGxXaXRoRXJyb3JIYW5kbGluZyhmbiwgaW5zdGFuY2UsIHR5cGUsIGFyZ3MpIHtcclxuICAgIGxldCByZXM7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHJlcyA9IGFyZ3MgPyBmbiguLi5hcmdzKSA6IGZuKCk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgdHlwZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzO1xyXG59XHJcbmZ1bmN0aW9uIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGZuLCBpbnN0YW5jZSwgdHlwZSwgYXJncykge1xyXG4gICAgaWYgKGlzRnVuY3Rpb24oZm4pKSB7XHJcbiAgICAgICAgY29uc3QgcmVzID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKGZuLCBpbnN0YW5jZSwgdHlwZSwgYXJncyk7XHJcbiAgICAgICAgaWYgKHJlcyAmJiBpc1Byb21pc2UocmVzKSkge1xyXG4gICAgICAgICAgICByZXMuY2F0Y2goZXJyID0+IHtcclxuICAgICAgICAgICAgICAgIGhhbmRsZUVycm9yKGVyciwgaW5zdGFuY2UsIHR5cGUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlcztcclxuICAgIH1cclxuICAgIGNvbnN0IHZhbHVlcyA9IFtdO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlcy5wdXNoKGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGZuW2ldLCBpbnN0YW5jZSwgdHlwZSwgYXJncykpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlcztcclxufVxyXG5mdW5jdGlvbiBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCB0eXBlKSB7XHJcbiAgICBjb25zdCBjb250ZXh0Vk5vZGUgPSBpbnN0YW5jZSA/IGluc3RhbmNlLnZub2RlIDogbnVsbDtcclxuICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgIGxldCBjdXIgPSBpbnN0YW5jZS5wYXJlbnQ7XHJcbiAgICAgICAgLy8gdGhlIGV4cG9zZWQgaW5zdGFuY2UgaXMgdGhlIHJlbmRlciBwcm94eSB0byBrZWVwIGl0IGNvbnNpc3RlbnQgd2l0aCAyLnhcclxuICAgICAgICBjb25zdCBleHBvc2VkSW5zdGFuY2UgPSBpbnN0YW5jZS5wcm94eTtcclxuICAgICAgICAvLyBpbiBwcm9kdWN0aW9uIHRoZSBob29rIHJlY2VpdmVzIG9ubHkgdGhlIGVycm9yIGNvZGVcclxuICAgICAgICBjb25zdCBlcnJvckluZm8gPSAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyBFcnJvclR5cGVTdHJpbmdzW3R5cGVdIDogdHlwZTtcclxuICAgICAgICB3aGlsZSAoY3VyKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVycm9yQ2FwdHVyZWRIb29rcyA9IGN1ci5lYztcclxuICAgICAgICAgICAgaWYgKGVycm9yQ2FwdHVyZWRIb29rcykge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlcnJvckNhcHR1cmVkSG9va3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3JDYXB0dXJlZEhvb2tzW2ldKGVyciwgZXhwb3NlZEluc3RhbmNlLCBlcnJvckluZm8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3VyID0gY3VyLnBhcmVudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYXBwLWxldmVsIGhhbmRsaW5nXHJcbiAgICAgICAgY29uc3QgYXBwRXJyb3JIYW5kbGVyID0gaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcuZXJyb3JIYW5kbGVyO1xyXG4gICAgICAgIGlmIChhcHBFcnJvckhhbmRsZXIpIHtcclxuICAgICAgICAgICAgY2FsbFdpdGhFcnJvckhhbmRsaW5nKGFwcEVycm9ySGFuZGxlciwgbnVsbCwgMTAgLyogQVBQX0VSUk9SX0hBTkRMRVIgKi8sIFtlcnIsIGV4cG9zZWRJbnN0YW5jZSwgZXJyb3JJbmZvXSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBsb2dFcnJvcihlcnIsIHR5cGUsIGNvbnRleHRWTm9kZSk7XHJcbn1cclxuZnVuY3Rpb24gbG9nRXJyb3IoZXJyLCB0eXBlLCBjb250ZXh0Vk5vZGUpIHtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICBjb25zdCBpbmZvID0gRXJyb3JUeXBlU3RyaW5nc1t0eXBlXTtcclxuICAgICAgICBpZiAoY29udGV4dFZOb2RlKSB7XHJcbiAgICAgICAgICAgIHB1c2hXYXJuaW5nQ29udGV4dChjb250ZXh0Vk5vZGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB3YXJuKGBVbmhhbmRsZWQgZXJyb3Ike2luZm8gPyBgIGR1cmluZyBleGVjdXRpb24gb2YgJHtpbmZvfWAgOiBgYH1gKTtcclxuICAgICAgICBpZiAoY29udGV4dFZOb2RlKSB7XHJcbiAgICAgICAgICAgIHBvcFdhcm5pbmdDb250ZXh0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNyYXNoIGluIGRldiBzbyBpdCdzIG1vcmUgbm90aWNlYWJsZVxyXG4gICAgICAgIHRocm93IGVycjtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIHJlY292ZXIgaW4gcHJvZCB0byByZWR1Y2UgdGhlIGltcGFjdCBvbiBlbmQtdXNlclxyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcclxuICAgIH1cclxufVxuXG5sZXQgaXNGbHVzaGluZyA9IGZhbHNlO1xyXG5sZXQgaXNGbHVzaFBlbmRpbmcgPSBmYWxzZTtcclxuY29uc3QgcXVldWUgPSBbXTtcclxubGV0IGZsdXNoSW5kZXggPSAwO1xyXG5jb25zdCBwZW5kaW5nUHJlRmx1c2hDYnMgPSBbXTtcclxubGV0IGFjdGl2ZVByZUZsdXNoQ2JzID0gbnVsbDtcclxubGV0IHByZUZsdXNoSW5kZXggPSAwO1xyXG5jb25zdCBwZW5kaW5nUG9zdEZsdXNoQ2JzID0gW107XHJcbmxldCBhY3RpdmVQb3N0Rmx1c2hDYnMgPSBudWxsO1xyXG5sZXQgcG9zdEZsdXNoSW5kZXggPSAwO1xyXG5jb25zdCByZXNvbHZlZFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcclxubGV0IGN1cnJlbnRGbHVzaFByb21pc2UgPSBudWxsO1xyXG5sZXQgY3VycmVudFByZUZsdXNoUGFyZW50Sm9iID0gbnVsbDtcclxuY29uc3QgUkVDVVJTSU9OX0xJTUlUID0gMTAwO1xyXG5mdW5jdGlvbiBuZXh0VGljayhmbikge1xyXG4gICAgY29uc3QgcCA9IGN1cnJlbnRGbHVzaFByb21pc2UgfHwgcmVzb2x2ZWRQcm9taXNlO1xyXG4gICAgcmV0dXJuIGZuID8gcC50aGVuKGZuKSA6IHA7XHJcbn1cclxuZnVuY3Rpb24gcXVldWVKb2Ioam9iKSB7XHJcbiAgICAvLyB0aGUgZGVkdXBlIHNlYXJjaCB1c2VzIHRoZSBzdGFydEluZGV4IGFyZ3VtZW50IG9mIEFycmF5LmluY2x1ZGVzKClcclxuICAgIC8vIGJ5IGRlZmF1bHQgdGhlIHNlYXJjaCBpbmRleCBpbmNsdWRlcyB0aGUgY3VycmVudCBqb2IgdGhhdCBpcyBiZWluZyBydW5cclxuICAgIC8vIHNvIGl0IGNhbm5vdCByZWN1cnNpdmVseSB0cmlnZ2VyIGl0c2VsZiBhZ2Fpbi5cclxuICAgIC8vIGlmIHRoZSBqb2IgaXMgYSB3YXRjaCgpIGNhbGxiYWNrLCB0aGUgc2VhcmNoIHdpbGwgc3RhcnQgd2l0aCBhICsxIGluZGV4IHRvXHJcbiAgICAvLyBhbGxvdyBpdCByZWN1cnNpdmVseSB0cmlnZ2VyIGl0c2VsZiAtIGl0IGlzIHRoZSB1c2VyJ3MgcmVzcG9uc2liaWxpdHkgdG9cclxuICAgIC8vIGVuc3VyZSBpdCBkb2Vzbid0IGVuZCB1cCBpbiBhbiBpbmZpbml0ZSBsb29wLlxyXG4gICAgaWYgKCghcXVldWUubGVuZ3RoIHx8XHJcbiAgICAgICAgIXF1ZXVlLmluY2x1ZGVzKGpvYiwgaXNGbHVzaGluZyAmJiBqb2IuYWxsb3dSZWN1cnNlID8gZmx1c2hJbmRleCArIDEgOiBmbHVzaEluZGV4KSkgJiZcclxuICAgICAgICBqb2IgIT09IGN1cnJlbnRQcmVGbHVzaFBhcmVudEpvYikge1xyXG4gICAgICAgIHF1ZXVlLnB1c2goam9iKTtcclxuICAgICAgICBxdWV1ZUZsdXNoKCk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gcXVldWVGbHVzaCgpIHtcclxuICAgIGlmICghaXNGbHVzaGluZyAmJiAhaXNGbHVzaFBlbmRpbmcpIHtcclxuICAgICAgICBpc0ZsdXNoUGVuZGluZyA9IHRydWU7XHJcbiAgICAgICAgY3VycmVudEZsdXNoUHJvbWlzZSA9IHJlc29sdmVkUHJvbWlzZS50aGVuKGZsdXNoSm9icyk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gaW52YWxpZGF0ZUpvYihqb2IpIHtcclxuICAgIGNvbnN0IGkgPSBxdWV1ZS5pbmRleE9mKGpvYik7XHJcbiAgICBpZiAoaSA+IC0xKSB7XHJcbiAgICAgICAgcXVldWVbaV0gPSBudWxsO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIHF1ZXVlQ2IoY2IsIGFjdGl2ZVF1ZXVlLCBwZW5kaW5nUXVldWUsIGluZGV4KSB7XHJcbiAgICBpZiAoIWlzQXJyYXkoY2IpKSB7XHJcbiAgICAgICAgaWYgKCFhY3RpdmVRdWV1ZSB8fFxyXG4gICAgICAgICAgICAhYWN0aXZlUXVldWUuaW5jbHVkZXMoY2IsIGNiLmFsbG93UmVjdXJzZSA/IGluZGV4ICsgMSA6IGluZGV4KSkge1xyXG4gICAgICAgICAgICBwZW5kaW5nUXVldWUucHVzaChjYik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gaWYgY2IgaXMgYW4gYXJyYXksIGl0IGlzIGEgY29tcG9uZW50IGxpZmVjeWNsZSBob29rIHdoaWNoIGNhbiBvbmx5IGJlXHJcbiAgICAgICAgLy8gdHJpZ2dlcmVkIGJ5IGEgam9iLCB3aGljaCBpcyBhbHJlYWR5IGRlZHVwZWQgaW4gdGhlIG1haW4gcXVldWUsIHNvXHJcbiAgICAgICAgLy8gd2UgY2FuIHNraXAgZHVwbGljYXRlIGNoZWNrIGhlcmUgdG8gaW1wcm92ZSBwZXJmXHJcbiAgICAgICAgcGVuZGluZ1F1ZXVlLnB1c2goLi4uY2IpO1xyXG4gICAgfVxyXG4gICAgcXVldWVGbHVzaCgpO1xyXG59XHJcbmZ1bmN0aW9uIHF1ZXVlUHJlRmx1c2hDYihjYikge1xyXG4gICAgcXVldWVDYihjYiwgYWN0aXZlUHJlRmx1c2hDYnMsIHBlbmRpbmdQcmVGbHVzaENicywgcHJlRmx1c2hJbmRleCk7XHJcbn1cclxuZnVuY3Rpb24gcXVldWVQb3N0Rmx1c2hDYihjYikge1xyXG4gICAgcXVldWVDYihjYiwgYWN0aXZlUG9zdEZsdXNoQ2JzLCBwZW5kaW5nUG9zdEZsdXNoQ2JzLCBwb3N0Rmx1c2hJbmRleCk7XHJcbn1cclxuZnVuY3Rpb24gZmx1c2hQcmVGbHVzaENicyhzZWVuLCBwYXJlbnRKb2IgPSBudWxsKSB7XHJcbiAgICBpZiAocGVuZGluZ1ByZUZsdXNoQ2JzLmxlbmd0aCkge1xyXG4gICAgICAgIGN1cnJlbnRQcmVGbHVzaFBhcmVudEpvYiA9IHBhcmVudEpvYjtcclxuICAgICAgICBhY3RpdmVQcmVGbHVzaENicyA9IFsuLi5uZXcgU2V0KHBlbmRpbmdQcmVGbHVzaENicyldO1xyXG4gICAgICAgIHBlbmRpbmdQcmVGbHVzaENicy5sZW5ndGggPSAwO1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgc2VlbiA9IHNlZW4gfHwgbmV3IE1hcCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKHByZUZsdXNoSW5kZXggPSAwOyBwcmVGbHVzaEluZGV4IDwgYWN0aXZlUHJlRmx1c2hDYnMubGVuZ3RoOyBwcmVGbHVzaEluZGV4KyspIHtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tSZWN1cnNpdmVVcGRhdGVzKHNlZW4sIGFjdGl2ZVByZUZsdXNoQ2JzW3ByZUZsdXNoSW5kZXhdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhY3RpdmVQcmVGbHVzaENic1twcmVGbHVzaEluZGV4XSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBhY3RpdmVQcmVGbHVzaENicyA9IG51bGw7XHJcbiAgICAgICAgcHJlRmx1c2hJbmRleCA9IDA7XHJcbiAgICAgICAgY3VycmVudFByZUZsdXNoUGFyZW50Sm9iID0gbnVsbDtcclxuICAgICAgICAvLyByZWN1cnNpdmVseSBmbHVzaCB1bnRpbCBpdCBkcmFpbnNcclxuICAgICAgICBmbHVzaFByZUZsdXNoQ2JzKHNlZW4sIHBhcmVudEpvYik7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gZmx1c2hQb3N0Rmx1c2hDYnMoc2Vlbikge1xyXG4gICAgaWYgKHBlbmRpbmdQb3N0Rmx1c2hDYnMubGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgZGVkdXBlZCA9IFsuLi5uZXcgU2V0KHBlbmRpbmdQb3N0Rmx1c2hDYnMpXTtcclxuICAgICAgICBwZW5kaW5nUG9zdEZsdXNoQ2JzLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgLy8gIzE5NDcgYWxyZWFkeSBoYXMgYWN0aXZlIHF1ZXVlLCBuZXN0ZWQgZmx1c2hQb3N0Rmx1c2hDYnMgY2FsbFxyXG4gICAgICAgIGlmIChhY3RpdmVQb3N0Rmx1c2hDYnMpIHtcclxuICAgICAgICAgICAgYWN0aXZlUG9zdEZsdXNoQ2JzLnB1c2goLi4uZGVkdXBlZCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgYWN0aXZlUG9zdEZsdXNoQ2JzID0gZGVkdXBlZDtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgIHNlZW4gPSBzZWVuIHx8IG5ldyBNYXAoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYWN0aXZlUG9zdEZsdXNoQ2JzLnNvcnQoKGEsIGIpID0+IGdldElkKGEpIC0gZ2V0SWQoYikpO1xyXG4gICAgICAgIGZvciAocG9zdEZsdXNoSW5kZXggPSAwOyBwb3N0Rmx1c2hJbmRleCA8IGFjdGl2ZVBvc3RGbHVzaENicy5sZW5ndGg7IHBvc3RGbHVzaEluZGV4KyspIHtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tSZWN1cnNpdmVVcGRhdGVzKHNlZW4sIGFjdGl2ZVBvc3RGbHVzaENic1twb3N0Rmx1c2hJbmRleF0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGFjdGl2ZVBvc3RGbHVzaENic1twb3N0Rmx1c2hJbmRleF0oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYWN0aXZlUG9zdEZsdXNoQ2JzID0gbnVsbDtcclxuICAgICAgICBwb3N0Rmx1c2hJbmRleCA9IDA7XHJcbiAgICB9XHJcbn1cclxuY29uc3QgZ2V0SWQgPSAoam9iKSA9PiBqb2IuaWQgPT0gbnVsbCA/IEluZmluaXR5IDogam9iLmlkO1xyXG5mdW5jdGlvbiBmbHVzaEpvYnMoc2Vlbikge1xyXG4gICAgaXNGbHVzaFBlbmRpbmcgPSBmYWxzZTtcclxuICAgIGlzRmx1c2hpbmcgPSB0cnVlO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIHNlZW4gPSBzZWVuIHx8IG5ldyBNYXAoKTtcclxuICAgIH1cclxuICAgIGZsdXNoUHJlRmx1c2hDYnMoc2Vlbik7XHJcbiAgICAvLyBTb3J0IHF1ZXVlIGJlZm9yZSBmbHVzaC5cclxuICAgIC8vIFRoaXMgZW5zdXJlcyB0aGF0OlxyXG4gICAgLy8gMS4gQ29tcG9uZW50cyBhcmUgdXBkYXRlZCBmcm9tIHBhcmVudCB0byBjaGlsZC4gKGJlY2F1c2UgcGFyZW50IGlzIGFsd2F5c1xyXG4gICAgLy8gICAgY3JlYXRlZCBiZWZvcmUgdGhlIGNoaWxkIHNvIGl0cyByZW5kZXIgZWZmZWN0IHdpbGwgaGF2ZSBzbWFsbGVyXHJcbiAgICAvLyAgICBwcmlvcml0eSBudW1iZXIpXHJcbiAgICAvLyAyLiBJZiBhIGNvbXBvbmVudCBpcyB1bm1vdW50ZWQgZHVyaW5nIGEgcGFyZW50IGNvbXBvbmVudCdzIHVwZGF0ZSxcclxuICAgIC8vICAgIGl0cyB1cGRhdGUgY2FuIGJlIHNraXBwZWQuXHJcbiAgICAvLyBKb2JzIGNhbiBuZXZlciBiZSBudWxsIGJlZm9yZSBmbHVzaCBzdGFydHMsIHNpbmNlIHRoZXkgYXJlIG9ubHkgaW52YWxpZGF0ZWRcclxuICAgIC8vIGR1cmluZyBleGVjdXRpb24gb2YgYW5vdGhlciBmbHVzaGVkIGpvYi5cclxuICAgIHF1ZXVlLnNvcnQoKGEsIGIpID0+IGdldElkKGEpIC0gZ2V0SWQoYikpO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICBmb3IgKGZsdXNoSW5kZXggPSAwOyBmbHVzaEluZGV4IDwgcXVldWUubGVuZ3RoOyBmbHVzaEluZGV4KyspIHtcclxuICAgICAgICAgICAgY29uc3Qgam9iID0gcXVldWVbZmx1c2hJbmRleF07XHJcbiAgICAgICAgICAgIGlmIChqb2IpIHtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2Vlbiwgam9iKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhbGxXaXRoRXJyb3JIYW5kbGluZyhqb2IsIG51bGwsIDE0IC8qIFNDSEVEVUxFUiAqLyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICBmbHVzaEluZGV4ID0gMDtcclxuICAgICAgICBxdWV1ZS5sZW5ndGggPSAwO1xyXG4gICAgICAgIGZsdXNoUG9zdEZsdXNoQ2JzKHNlZW4pO1xyXG4gICAgICAgIGlzRmx1c2hpbmcgPSBmYWxzZTtcclxuICAgICAgICBjdXJyZW50Rmx1c2hQcm9taXNlID0gbnVsbDtcclxuICAgICAgICAvLyBzb21lIHBvc3RGbHVzaENiIHF1ZXVlZCBqb2JzIVxyXG4gICAgICAgIC8vIGtlZXAgZmx1c2hpbmcgdW50aWwgaXQgZHJhaW5zLlxyXG4gICAgICAgIGlmIChxdWV1ZS5sZW5ndGggfHwgcGVuZGluZ1Bvc3RGbHVzaENicy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgZmx1c2hKb2JzKHNlZW4pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBjaGVja1JlY3Vyc2l2ZVVwZGF0ZXMoc2VlbiwgZm4pIHtcclxuICAgIGlmICghc2Vlbi5oYXMoZm4pKSB7XHJcbiAgICAgICAgc2Vlbi5zZXQoZm4sIDEpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgY29uc3QgY291bnQgPSBzZWVuLmdldChmbik7XHJcbiAgICAgICAgaWYgKGNvdW50ID4gUkVDVVJTSU9OX0xJTUlUKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTWF4aW11bSByZWN1cnNpdmUgdXBkYXRlcyBleGNlZWRlZC4gYCArXHJcbiAgICAgICAgICAgICAgICBgVGhpcyBtZWFucyB5b3UgaGF2ZSBhIHJlYWN0aXZlIGVmZmVjdCB0aGF0IGlzIG11dGF0aW5nIGl0cyBvd24gYCArXHJcbiAgICAgICAgICAgICAgICBgZGVwZW5kZW5jaWVzIGFuZCB0aHVzIHJlY3Vyc2l2ZWx5IHRyaWdnZXJpbmcgaXRzZWxmLiBQb3NzaWJsZSBzb3VyY2VzIGAgK1xyXG4gICAgICAgICAgICAgICAgYGluY2x1ZGUgY29tcG9uZW50IHRlbXBsYXRlLCByZW5kZXIgZnVuY3Rpb24sIHVwZGF0ZWQgaG9vayBvciBgICtcclxuICAgICAgICAgICAgICAgIGB3YXRjaGVyIHNvdXJjZSBmdW5jdGlvbi5gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHNlZW4uc2V0KGZuLCBjb3VudCArIDEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxuXG5sZXQgaXNIbXJVcGRhdGluZyA9IGZhbHNlO1xyXG5jb25zdCBobXJEaXJ0eUNvbXBvbmVudHMgPSBuZXcgU2V0KCk7XHJcbi8vIEV4cG9zZSB0aGUgSE1SIHJ1bnRpbWUgb24gdGhlIGdsb2JhbCBvYmplY3RcclxuLy8gVGhpcyBtYWtlcyBpdCBlbnRpcmVseSB0cmVlLXNoYWthYmxlIHdpdGhvdXQgcG9sbHV0aW5nIHRoZSBleHBvcnRzIGFuZCBtYWtlc1xyXG4vLyBpdCBlYXNpZXIgdG8gYmUgdXNlZCBpbiB0b29saW5ncyBsaWtlIHZ1ZS1sb2FkZXJcclxuLy8gTm90ZTogZm9yIGEgY29tcG9uZW50IHRvIGJlIGVsaWdpYmxlIGZvciBITVIgaXQgYWxzbyBuZWVkcyB0aGUgX19obXJJZCBvcHRpb25cclxuLy8gdG8gYmUgc2V0IHNvIHRoYXQgaXRzIGluc3RhbmNlcyBjYW4gYmUgcmVnaXN0ZXJlZCAvIHJlbW92ZWQuXHJcbmlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgIGNvbnN0IGdsb2JhbE9iamVjdCA9IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgICAgPyBnbG9iYWxcclxuICAgICAgICA6IHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICAgICAgICA/IHNlbGZcclxuICAgICAgICAgICAgOiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICAgICAgICAgICAgPyB3aW5kb3dcclxuICAgICAgICAgICAgICAgIDoge307XHJcbiAgICBnbG9iYWxPYmplY3QuX19WVUVfSE1SX1JVTlRJTUVfXyA9IHtcclxuICAgICAgICBjcmVhdGVSZWNvcmQ6IHRyeVdyYXAoY3JlYXRlUmVjb3JkKSxcclxuICAgICAgICByZXJlbmRlcjogdHJ5V3JhcChyZXJlbmRlciksXHJcbiAgICAgICAgcmVsb2FkOiB0cnlXcmFwKHJlbG9hZClcclxuICAgIH07XHJcbn1cclxuY29uc3QgbWFwID0gbmV3IE1hcCgpO1xyXG5mdW5jdGlvbiByZWdpc3RlckhNUihpbnN0YW5jZSkge1xyXG4gICAgY29uc3QgaWQgPSBpbnN0YW5jZS50eXBlLl9faG1ySWQ7XHJcbiAgICBsZXQgcmVjb3JkID0gbWFwLmdldChpZCk7XHJcbiAgICBpZiAoIXJlY29yZCkge1xyXG4gICAgICAgIGNyZWF0ZVJlY29yZChpZCk7XHJcbiAgICAgICAgcmVjb3JkID0gbWFwLmdldChpZCk7XHJcbiAgICB9XHJcbiAgICByZWNvcmQuYWRkKGluc3RhbmNlKTtcclxufVxyXG5mdW5jdGlvbiB1bnJlZ2lzdGVySE1SKGluc3RhbmNlKSB7XHJcbiAgICBtYXAuZ2V0KGluc3RhbmNlLnR5cGUuX19obXJJZCkuZGVsZXRlKGluc3RhbmNlKTtcclxufVxyXG5mdW5jdGlvbiBjcmVhdGVSZWNvcmQoaWQpIHtcclxuICAgIGlmIChtYXAuaGFzKGlkKSkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIG1hcC5zZXQoaWQsIG5ldyBTZXQoKSk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxufVxyXG5mdW5jdGlvbiByZXJlbmRlcihpZCwgbmV3UmVuZGVyKSB7XHJcbiAgICBjb25zdCByZWNvcmQgPSBtYXAuZ2V0KGlkKTtcclxuICAgIGlmICghcmVjb3JkKVxyXG4gICAgICAgIHJldHVybjtcclxuICAgIC8vIEFycmF5LmZyb20gY3JlYXRlcyBhIHNuYXBzaG90IHdoaWNoIGF2b2lkcyB0aGUgc2V0IGJlaW5nIG11dGF0ZWQgZHVyaW5nXHJcbiAgICAvLyB1cGRhdGVzXHJcbiAgICBBcnJheS5mcm9tKHJlY29yZCkuZm9yRWFjaChpbnN0YW5jZSA9PiB7XHJcbiAgICAgICAgaWYgKG5ld1JlbmRlcikge1xyXG4gICAgICAgICAgICBpbnN0YW5jZS5yZW5kZXIgPSBuZXdSZW5kZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGluc3RhbmNlLnJlbmRlckNhY2hlID0gW107XHJcbiAgICAgICAgLy8gdGhpcyBmbGFnIGZvcmNlcyBjaGlsZCBjb21wb25lbnRzIHdpdGggc2xvdCBjb250ZW50IHRvIHVwZGF0ZVxyXG4gICAgICAgIGlzSG1yVXBkYXRpbmcgPSB0cnVlO1xyXG4gICAgICAgIGluc3RhbmNlLnVwZGF0ZSgpO1xyXG4gICAgICAgIGlzSG1yVXBkYXRpbmcgPSBmYWxzZTtcclxuICAgIH0pO1xyXG59XHJcbmZ1bmN0aW9uIHJlbG9hZChpZCwgbmV3Q29tcCkge1xyXG4gICAgY29uc3QgcmVjb3JkID0gbWFwLmdldChpZCk7XHJcbiAgICBpZiAoIXJlY29yZClcclxuICAgICAgICByZXR1cm47XHJcbiAgICAvLyBBcnJheS5mcm9tIGNyZWF0ZXMgYSBzbmFwc2hvdCB3aGljaCBhdm9pZHMgdGhlIHNldCBiZWluZyBtdXRhdGVkIGR1cmluZ1xyXG4gICAgLy8gdXBkYXRlc1xyXG4gICAgQXJyYXkuZnJvbShyZWNvcmQpLmZvckVhY2goaW5zdGFuY2UgPT4ge1xyXG4gICAgICAgIGNvbnN0IGNvbXAgPSBpbnN0YW5jZS50eXBlO1xyXG4gICAgICAgIGlmICghaG1yRGlydHlDb21wb25lbnRzLmhhcyhjb21wKSkge1xyXG4gICAgICAgICAgICAvLyAxLiBVcGRhdGUgZXhpc3RpbmcgY29tcCBkZWZpbml0aW9uIHRvIG1hdGNoIG5ldyBvbmVcclxuICAgICAgICAgICAgZXh0ZW5kKGNvbXAsIG5ld0NvbXApO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjb21wKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gbmV3Q29tcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgY29tcFtrZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIDIuIE1hcmsgY29tcG9uZW50IGRpcnR5LiBUaGlzIGZvcmNlcyB0aGUgcmVuZGVyZXIgdG8gcmVwbGFjZSB0aGUgY29tcG9uZW50XHJcbiAgICAgICAgICAgIC8vIG9uIHBhdGNoLlxyXG4gICAgICAgICAgICBobXJEaXJ0eUNvbXBvbmVudHMuYWRkKGNvbXApO1xyXG4gICAgICAgICAgICAvLyAzLiBNYWtlIHN1cmUgdG8gdW5tYXJrIHRoZSBjb21wb25lbnQgYWZ0ZXIgdGhlIHJlbG9hZC5cclxuICAgICAgICAgICAgcXVldWVQb3N0Rmx1c2hDYigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBobXJEaXJ0eUNvbXBvbmVudHMuZGVsZXRlKGNvbXApO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGluc3RhbmNlLnBhcmVudCkge1xyXG4gICAgICAgICAgICAvLyA0LiBGb3JjZSB0aGUgcGFyZW50IGluc3RhbmNlIHRvIHJlLXJlbmRlci4gVGhpcyB3aWxsIGNhdXNlIGFsbCB1cGRhdGVkXHJcbiAgICAgICAgICAgIC8vIGNvbXBvbmVudHMgdG8gYmUgdW5tb3VudGVkIGFuZCByZS1tb3VudGVkLiBRdWV1ZSB0aGUgdXBkYXRlIHNvIHRoYXQgd2VcclxuICAgICAgICAgICAgLy8gZG9uJ3QgZW5kIHVwIGZvcmNpbmcgdGhlIHNhbWUgcGFyZW50IHRvIHJlLXJlbmRlciBtdWx0aXBsZSB0aW1lcy5cclxuICAgICAgICAgICAgcXVldWVKb2IoaW5zdGFuY2UucGFyZW50LnVwZGF0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGluc3RhbmNlLmFwcENvbnRleHQucmVsb2FkKSB7XHJcbiAgICAgICAgICAgIC8vIHJvb3QgaW5zdGFuY2UgbW91bnRlZCB2aWEgY3JlYXRlQXBwKCkgaGFzIGEgcmVsb2FkIG1ldGhvZFxyXG4gICAgICAgICAgICBpbnN0YW5jZS5hcHBDb250ZXh0LnJlbG9hZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAvLyByb290IGluc3RhbmNlIGluc2lkZSB0cmVlIGNyZWF0ZWQgdmlhIHJhdyByZW5kZXIoKS4gRm9yY2UgcmVsb2FkLlxyXG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tITVJdIFJvb3Qgb3IgbWFudWFsbHkgbW91bnRlZCBpbnN0YW5jZSBtb2RpZmllZC4gRnVsbCByZWxvYWQgcmVxdWlyZWQuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gdHJ5V3JhcChmbikge1xyXG4gICAgcmV0dXJuIChpZCwgYXJnKSA9PiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmV0dXJuIGZuKGlkLCBhcmcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFtITVJdIFNvbWV0aGluZyB3ZW50IHdyb25nIGR1cmluZyBWdWUgY29tcG9uZW50IGhvdC1yZWxvYWQuIGAgK1xyXG4gICAgICAgICAgICAgICAgYEZ1bGwgcmVsb2FkIHJlcXVpcmVkLmApO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cblxuLy8gbWFyayB0aGUgY3VycmVudCByZW5kZXJpbmcgaW5zdGFuY2UgZm9yIGFzc2V0IHJlc29sdXRpb24gKGUuZy5cclxuLy8gcmVzb2x2ZUNvbXBvbmVudCwgcmVzb2x2ZURpcmVjdGl2ZSkgZHVyaW5nIHJlbmRlclxyXG5sZXQgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gbnVsbDtcclxuZnVuY3Rpb24gc2V0Q3VycmVudFJlbmRlcmluZ0luc3RhbmNlKGluc3RhbmNlKSB7XHJcbiAgICBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UgPSBpbnN0YW5jZTtcclxufVxyXG4vLyBkZXYgb25seSBmbGFnIHRvIHRyYWNrIHdoZXRoZXIgJGF0dHJzIHdhcyB1c2VkIGR1cmluZyByZW5kZXIuXHJcbi8vIElmICRhdHRycyB3YXMgdXNlZCBkdXJpbmcgcmVuZGVyIHRoZW4gdGhlIHdhcm5pbmcgZm9yIGZhaWxlZCBhdHRyc1xyXG4vLyBmYWxsdGhyb3VnaCBjYW4gYmUgc3VwcHJlc3NlZC5cclxubGV0IGFjY2Vzc2VkQXR0cnMgPSBmYWxzZTtcclxuZnVuY3Rpb24gbWFya0F0dHJzQWNjZXNzZWQoKSB7XHJcbiAgICBhY2Nlc3NlZEF0dHJzID0gdHJ1ZTtcclxufVxyXG5mdW5jdGlvbiByZW5kZXJDb21wb25lbnRSb290KGluc3RhbmNlKSB7XHJcbiAgICBjb25zdCB7IHR5cGU6IENvbXBvbmVudCwgdm5vZGUsIHByb3h5LCB3aXRoUHJveHksIHByb3BzLCBwcm9wc09wdGlvbnM6IFtwcm9wc09wdGlvbnNdLCBzbG90cywgYXR0cnMsIGVtaXQsIHJlbmRlciwgcmVuZGVyQ2FjaGUsIGRhdGEsIHNldHVwU3RhdGUsIGN0eCB9ID0gaW5zdGFuY2U7XHJcbiAgICBsZXQgcmVzdWx0O1xyXG4gICAgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlID0gaW5zdGFuY2U7XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgYWNjZXNzZWRBdHRycyA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgdHJ5IHtcclxuICAgICAgICBsZXQgZmFsbHRocm91Z2hBdHRycztcclxuICAgICAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNCAvKiBTVEFURUZVTF9DT01QT05FTlQgKi8pIHtcclxuICAgICAgICAgICAgLy8gd2l0aFByb3h5IGlzIGEgcHJveHkgd2l0aCBhIGRpZmZlcmVudCBgaGFzYCB0cmFwIG9ubHkgZm9yXHJcbiAgICAgICAgICAgIC8vIHJ1bnRpbWUtY29tcGlsZWQgcmVuZGVyIGZ1bmN0aW9ucyB1c2luZyBgd2l0aGAgYmxvY2suXHJcbiAgICAgICAgICAgIGNvbnN0IHByb3h5VG9Vc2UgPSB3aXRoUHJveHkgfHwgcHJveHk7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IG5vcm1hbGl6ZVZOb2RlKHJlbmRlci5jYWxsKHByb3h5VG9Vc2UsIHByb3h5VG9Vc2UsIHJlbmRlckNhY2hlLCBwcm9wcywgc2V0dXBTdGF0ZSwgZGF0YSwgY3R4KSk7XHJcbiAgICAgICAgICAgIGZhbGx0aHJvdWdoQXR0cnMgPSBhdHRycztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGZ1bmN0aW9uYWxcclxuICAgICAgICAgICAgY29uc3QgcmVuZGVyID0gQ29tcG9uZW50O1xyXG4gICAgICAgICAgICAvLyBpbiBkZXYsIG1hcmsgYXR0cnMgYWNjZXNzZWQgaWYgb3B0aW9uYWwgcHJvcHMgKGF0dHJzID09PSBwcm9wcylcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBhdHRycyA9PT0gcHJvcHMpIHtcclxuICAgICAgICAgICAgICAgIG1hcmtBdHRyc0FjY2Vzc2VkKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmVzdWx0ID0gbm9ybWFsaXplVk5vZGUocmVuZGVyLmxlbmd0aCA+IDFcclxuICAgICAgICAgICAgICAgID8gcmVuZGVyKHByb3BzLCAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJylcclxuICAgICAgICAgICAgICAgICAgICA/IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0IGF0dHJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhdHRycztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2xvdHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVtaXRcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgOiB7IGF0dHJzLCBzbG90cywgZW1pdCB9KVxyXG4gICAgICAgICAgICAgICAgOiByZW5kZXIocHJvcHMsIG51bGwgLyogd2Uga25vdyBpdCBkb2Vzbid0IG5lZWQgaXQgKi8pKTtcclxuICAgICAgICAgICAgZmFsbHRocm91Z2hBdHRycyA9IENvbXBvbmVudC5wcm9wc1xyXG4gICAgICAgICAgICAgICAgPyBhdHRyc1xyXG4gICAgICAgICAgICAgICAgOiBnZXRGdW5jdGlvbmFsRmFsbHRocm91Z2goYXR0cnMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBhdHRyIG1lcmdpbmdcclxuICAgICAgICAvLyBpbiBkZXYgbW9kZSwgY29tbWVudHMgYXJlIHByZXNlcnZlZCwgYW5kIGl0J3MgcG9zc2libGUgZm9yIGEgdGVtcGxhdGVcclxuICAgICAgICAvLyB0byBoYXZlIGNvbW1lbnRzIGFsb25nIHNpZGUgdGhlIHJvb3QgZWxlbWVudCB3aGljaCBtYWtlcyBpdCBhIGZyYWdtZW50XHJcbiAgICAgICAgbGV0IHJvb3QgPSByZXN1bHQ7XHJcbiAgICAgICAgbGV0IHNldFJvb3QgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICA7XHJcbiAgICAgICAgICAgIFtyb290LCBzZXRSb290XSA9IGdldENoaWxkUm9vdChyZXN1bHQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoQ29tcG9uZW50LmluaGVyaXRBdHRycyAhPT0gZmFsc2UgJiYgZmFsbHRocm91Z2hBdHRycykge1xyXG4gICAgICAgICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoZmFsbHRocm91Z2hBdHRycyk7XHJcbiAgICAgICAgICAgIGNvbnN0IHsgc2hhcGVGbGFnIH0gPSByb290O1xyXG4gICAgICAgICAgICBpZiAoa2V5cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzaGFwZUZsYWcgJiAxIC8qIEVMRU1FTlQgKi8gfHxcclxuICAgICAgICAgICAgICAgICAgICBzaGFwZUZsYWcgJiA2IC8qIENPTVBPTkVOVCAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wc09wdGlvbnMgJiYga2V5cy5zb21lKGlzTW9kZWxMaXN0ZW5lcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgYSB2LW1vZGVsIGxpc3RlbmVyIChvblVwZGF0ZTp4eHgpIGhhcyBhIGNvcnJlc3BvbmRpbmcgZGVjbGFyZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvcCwgaXQgaW5kaWNhdGVzIHRoaXMgY29tcG9uZW50IGV4cGVjdHMgdG8gaGFuZGxlIHYtbW9kZWwgYW5kXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGl0IHNob3VsZCBub3QgZmFsbHRocm91Z2guXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlbGF0ZWQ6ICMxNTQzLCAjMTY0MywgIzE5ODlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmFsbHRocm91Z2hBdHRycyA9IGZpbHRlck1vZGVsTGlzdGVuZXJzKGZhbGx0aHJvdWdoQXR0cnMsIHByb3BzT3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJvb3QgPSBjbG9uZVZOb2RlKHJvb3QsIGZhbGx0aHJvdWdoQXR0cnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFhY2Nlc3NlZEF0dHJzICYmIHJvb3QudHlwZSAhPT0gQ29tbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFsbEF0dHJzID0gT2JqZWN0LmtleXMoYXR0cnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50QXR0cnMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRyYUF0dHJzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBhbGxBdHRycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gYWxsQXR0cnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc09uKGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZSB2LW1vZGVsIGhhbmRsZXJzIHdoZW4gdGhleSBmYWlsIHRvIGZhbGx0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzTW9kZWxMaXN0ZW5lcihrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGBvbmAsIGxvd2VyY2FzZSBmaXJzdCBsZXR0ZXIgdG8gcmVmbGVjdCBldmVudCBjYXNpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhY2N1cmF0ZWx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRBdHRycy5wdXNoKGtleVsyXS50b0xvd2VyQ2FzZSgpICsga2V5LnNsaWNlKDMpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhQXR0cnMucHVzaChrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChleHRyYUF0dHJzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBFeHRyYW5lb3VzIG5vbi1wcm9wcyBhdHRyaWJ1dGVzIChgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAke2V4dHJhQXR0cnMuam9pbignLCAnKX0pIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYHdlcmUgcGFzc2VkIHRvIGNvbXBvbmVudCBidXQgY291bGQgbm90IGJlIGF1dG9tYXRpY2FsbHkgaW5oZXJpdGVkIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYGJlY2F1c2UgY29tcG9uZW50IHJlbmRlcnMgZnJhZ21lbnQgb3IgdGV4dCByb290IG5vZGVzLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnRBdHRycy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2FybihgRXh0cmFuZW91cyBub24tZW1pdHMgZXZlbnQgbGlzdGVuZXJzIChgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGAke2V2ZW50QXR0cnMuam9pbignLCAnKX0pIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYHdlcmUgcGFzc2VkIHRvIGNvbXBvbmVudCBidXQgY291bGQgbm90IGJlIGF1dG9tYXRpY2FsbHkgaW5oZXJpdGVkIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYGJlY2F1c2UgY29tcG9uZW50IHJlbmRlcnMgZnJhZ21lbnQgb3IgdGV4dCByb290IG5vZGVzLiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBJZiB0aGUgbGlzdGVuZXIgaXMgaW50ZW5kZWQgdG8gYmUgYSBjb21wb25lbnQgY3VzdG9tIGV2ZW50IGxpc3RlbmVyIG9ubHksIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYGRlY2xhcmUgaXQgdXNpbmcgdGhlIFwiZW1pdHNcIiBvcHRpb24uYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGluaGVyaXQgZGlyZWN0aXZlc1xyXG4gICAgICAgIGlmICh2bm9kZS5kaXJzKSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWlzRWxlbWVudFJvb3Qocm9vdCkpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYFJ1bnRpbWUgZGlyZWN0aXZlIHVzZWQgb24gY29tcG9uZW50IHdpdGggbm9uLWVsZW1lbnQgcm9vdCBub2RlLiBgICtcclxuICAgICAgICAgICAgICAgICAgICBgVGhlIGRpcmVjdGl2ZXMgd2lsbCBub3QgZnVuY3Rpb24gYXMgaW50ZW5kZWQuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcm9vdC5kaXJzID0gdm5vZGUuZGlycztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaW5oZXJpdCB0cmFuc2l0aW9uIGRhdGFcclxuICAgICAgICBpZiAodm5vZGUudHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFpc0VsZW1lbnRSb290KHJvb3QpKSB7XHJcbiAgICAgICAgICAgICAgICB3YXJuKGBDb21wb25lbnQgaW5zaWRlIDxUcmFuc2l0aW9uPiByZW5kZXJzIG5vbi1lbGVtZW50IHJvb3Qgbm9kZSBgICtcclxuICAgICAgICAgICAgICAgICAgICBgdGhhdCBjYW5ub3QgYmUgYW5pbWF0ZWQuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcm9vdC50cmFuc2l0aW9uID0gdm5vZGUudHJhbnNpdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBzZXRSb290KSB7XHJcbiAgICAgICAgICAgIHNldFJvb3Qocm9vdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXN1bHQgPSByb290O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGNhdGNoIChlcnIpIHtcclxuICAgICAgICBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCAxIC8qIFJFTkRFUl9GVU5DVElPTiAqLyk7XHJcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlVk5vZGUoQ29tbWVudCk7XHJcbiAgICB9XHJcbiAgICBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UgPSBudWxsO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG4vKipcclxuICogZGV2IG9ubHlcclxuICovXHJcbmNvbnN0IGdldENoaWxkUm9vdCA9ICh2bm9kZSkgPT4ge1xyXG4gICAgaWYgKHZub2RlLnR5cGUgIT09IEZyYWdtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIFt2bm9kZSwgdW5kZWZpbmVkXTtcclxuICAgIH1cclxuICAgIGNvbnN0IHJhd0NoaWxkcmVuID0gdm5vZGUuY2hpbGRyZW47XHJcbiAgICBjb25zdCBkeW5hbWljQ2hpbGRyZW4gPSB2bm9kZS5keW5hbWljQ2hpbGRyZW47XHJcbiAgICBjb25zdCBjaGlsZHJlbiA9IHJhd0NoaWxkcmVuLmZpbHRlcihjaGlsZCA9PiB7XHJcbiAgICAgICAgcmV0dXJuICEoaXNWTm9kZShjaGlsZCkgJiZcclxuICAgICAgICAgICAgY2hpbGQudHlwZSA9PT0gQ29tbWVudCAmJlxyXG4gICAgICAgICAgICBjaGlsZC5jaGlsZHJlbiAhPT0gJ3YtaWYnKTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGNoaWxkcmVuLmxlbmd0aCAhPT0gMSkge1xyXG4gICAgICAgIHJldHVybiBbdm5vZGUsIHVuZGVmaW5lZF07XHJcbiAgICB9XHJcbiAgICBjb25zdCBjaGlsZFJvb3QgPSBjaGlsZHJlblswXTtcclxuICAgIGNvbnN0IGluZGV4ID0gcmF3Q2hpbGRyZW4uaW5kZXhPZihjaGlsZFJvb3QpO1xyXG4gICAgY29uc3QgZHluYW1pY0luZGV4ID0gZHluYW1pY0NoaWxkcmVuID8gZHluYW1pY0NoaWxkcmVuLmluZGV4T2YoY2hpbGRSb290KSA6IC0xO1xyXG4gICAgY29uc3Qgc2V0Um9vdCA9ICh1cGRhdGVkUm9vdCkgPT4ge1xyXG4gICAgICAgIHJhd0NoaWxkcmVuW2luZGV4XSA9IHVwZGF0ZWRSb290O1xyXG4gICAgICAgIGlmIChkeW5hbWljSW5kZXggPiAtMSkge1xyXG4gICAgICAgICAgICBkeW5hbWljQ2hpbGRyZW5bZHluYW1pY0luZGV4XSA9IHVwZGF0ZWRSb290O1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChkeW5hbWljQ2hpbGRyZW4gJiYgdXBkYXRlZFJvb3QucGF0Y2hGbGFnID4gMCkge1xyXG4gICAgICAgICAgICBkeW5hbWljQ2hpbGRyZW4ucHVzaCh1cGRhdGVkUm9vdCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBbbm9ybWFsaXplVk5vZGUoY2hpbGRSb290KSwgc2V0Um9vdF07XHJcbn07XHJcbmNvbnN0IGdldEZ1bmN0aW9uYWxGYWxsdGhyb3VnaCA9IChhdHRycykgPT4ge1xyXG4gICAgbGV0IHJlcztcclxuICAgIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7XHJcbiAgICAgICAgaWYgKGtleSA9PT0gJ2NsYXNzJyB8fCBrZXkgPT09ICdzdHlsZScgfHwgaXNPbihrZXkpKSB7XHJcbiAgICAgICAgICAgIChyZXMgfHwgKHJlcyA9IHt9KSlba2V5XSA9IGF0dHJzW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlcztcclxufTtcclxuY29uc3QgZmlsdGVyTW9kZWxMaXN0ZW5lcnMgPSAoYXR0cnMsIHByb3BzKSA9PiB7XHJcbiAgICBjb25zdCByZXMgPSB7fTtcclxuICAgIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7XHJcbiAgICAgICAgaWYgKCFpc01vZGVsTGlzdGVuZXIoa2V5KSB8fCAhKGtleS5zbGljZSg5KSBpbiBwcm9wcykpIHtcclxuICAgICAgICAgICAgcmVzW2tleV0gPSBhdHRyc1trZXldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXM7XHJcbn07XHJcbmNvbnN0IGlzRWxlbWVudFJvb3QgPSAodm5vZGUpID0+IHtcclxuICAgIHJldHVybiAodm5vZGUuc2hhcGVGbGFnICYgNiAvKiBDT01QT05FTlQgKi8gfHxcclxuICAgICAgICB2bm9kZS5zaGFwZUZsYWcgJiAxIC8qIEVMRU1FTlQgKi8gfHxcclxuICAgICAgICB2bm9kZS50eXBlID09PSBDb21tZW50IC8vIHBvdGVudGlhbCB2LWlmIGJyYW5jaCBzd2l0Y2hcclxuICAgICk7XHJcbn07XHJcbmZ1bmN0aW9uIHNob3VsZFVwZGF0ZUNvbXBvbmVudChwcmV2Vk5vZGUsIG5leHRWTm9kZSwgb3B0aW1pemVkKSB7XHJcbiAgICBjb25zdCB7IHByb3BzOiBwcmV2UHJvcHMsIGNoaWxkcmVuOiBwcmV2Q2hpbGRyZW4gfSA9IHByZXZWTm9kZTtcclxuICAgIGNvbnN0IHsgcHJvcHM6IG5leHRQcm9wcywgY2hpbGRyZW46IG5leHRDaGlsZHJlbiwgcGF0Y2hGbGFnIH0gPSBuZXh0Vk5vZGU7XHJcbiAgICAvLyBQYXJlbnQgY29tcG9uZW50J3MgcmVuZGVyIGZ1bmN0aW9uIHdhcyBob3QtdXBkYXRlZC4gU2luY2UgdGhpcyBtYXkgaGF2ZVxyXG4gICAgLy8gY2F1c2VkIHRoZSBjaGlsZCBjb21wb25lbnQncyBzbG90cyBjb250ZW50IHRvIGhhdmUgY2hhbmdlZCwgd2UgbmVlZCB0b1xyXG4gICAgLy8gZm9yY2UgdGhlIGNoaWxkIHRvIHVwZGF0ZSBhcyB3ZWxsLlxyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAocHJldkNoaWxkcmVuIHx8IG5leHRDaGlsZHJlbikgJiYgaXNIbXJVcGRhdGluZykge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgLy8gZm9yY2UgY2hpbGQgdXBkYXRlIGZvciBydW50aW1lIGRpcmVjdGl2ZSBvciB0cmFuc2l0aW9uIG9uIGNvbXBvbmVudCB2bm9kZS5cclxuICAgIGlmIChuZXh0Vk5vZGUuZGlycyB8fCBuZXh0Vk5vZGUudHJhbnNpdGlvbikge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgaWYgKG9wdGltaXplZCAmJiBwYXRjaEZsYWcgPiAwKSB7XHJcbiAgICAgICAgaWYgKHBhdGNoRmxhZyAmIDEwMjQgLyogRFlOQU1JQ19TTE9UUyAqLykge1xyXG4gICAgICAgICAgICAvLyBzbG90IGNvbnRlbnQgdGhhdCByZWZlcmVuY2VzIHZhbHVlcyB0aGF0IG1pZ2h0IGhhdmUgY2hhbmdlZCxcclxuICAgICAgICAgICAgLy8gZS5nLiBpbiBhIHYtZm9yXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocGF0Y2hGbGFnICYgMTYgLyogRlVMTF9QUk9QUyAqLykge1xyXG4gICAgICAgICAgICBpZiAoIXByZXZQcm9wcykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICEhbmV4dFByb3BzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHByZXNlbmNlIG9mIHRoaXMgZmxhZyBpbmRpY2F0ZXMgcHJvcHMgYXJlIGFsd2F5cyBub24tbnVsbFxyXG4gICAgICAgICAgICByZXR1cm4gaGFzUHJvcHNDaGFuZ2VkKHByZXZQcm9wcywgbmV4dFByb3BzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAocGF0Y2hGbGFnICYgOCAvKiBQUk9QUyAqLykge1xyXG4gICAgICAgICAgICBjb25zdCBkeW5hbWljUHJvcHMgPSBuZXh0Vk5vZGUuZHluYW1pY1Byb3BzO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGR5bmFtaWNQcm9wcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gZHluYW1pY1Byb3BzW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKG5leHRQcm9wc1trZXldICE9PSBwcmV2UHJvcHNba2V5XSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gdGhpcyBwYXRoIGlzIG9ubHkgdGFrZW4gYnkgbWFudWFsbHkgd3JpdHRlbiByZW5kZXIgZnVuY3Rpb25zXHJcbiAgICAgICAgLy8gc28gcHJlc2VuY2Ugb2YgYW55IGNoaWxkcmVuIGxlYWRzIHRvIGEgZm9yY2VkIHVwZGF0ZVxyXG4gICAgICAgIGlmIChwcmV2Q2hpbGRyZW4gfHwgbmV4dENoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgIGlmICghbmV4dENoaWxkcmVuIHx8ICFuZXh0Q2hpbGRyZW4uJHN0YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHByZXZQcm9wcyA9PT0gbmV4dFByb3BzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFwcmV2UHJvcHMpIHtcclxuICAgICAgICAgICAgcmV0dXJuICEhbmV4dFByb3BzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIW5leHRQcm9wcykge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGhhc1Byb3BzQ2hhbmdlZChwcmV2UHJvcHMsIG5leHRQcm9wcyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuZnVuY3Rpb24gaGFzUHJvcHNDaGFuZ2VkKHByZXZQcm9wcywgbmV4dFByb3BzKSB7XHJcbiAgICBjb25zdCBuZXh0S2V5cyA9IE9iamVjdC5rZXlzKG5leHRQcm9wcyk7XHJcbiAgICBpZiAobmV4dEtleXMubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhwcmV2UHJvcHMpLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXh0S2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGtleSA9IG5leHRLZXlzW2ldO1xyXG4gICAgICAgIGlmIChuZXh0UHJvcHNba2V5XSAhPT0gcHJldlByb3BzW2tleV0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG59XHJcbmZ1bmN0aW9uIHVwZGF0ZUhPQ0hvc3RFbCh7IHZub2RlLCBwYXJlbnQgfSwgZWwgLy8gSG9zdE5vZGVcclxuKSB7XHJcbiAgICB3aGlsZSAocGFyZW50ICYmIHBhcmVudC5zdWJUcmVlID09PSB2bm9kZSkge1xyXG4gICAgICAgICh2bm9kZSA9IHBhcmVudC52bm9kZSkuZWwgPSBlbDtcclxuICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xyXG4gICAgfVxyXG59XG5cbmNvbnN0IGlzU3VzcGVuc2UgPSAodHlwZSkgPT4gdHlwZS5fX2lzU3VzcGVuc2U7XHJcbi8vIFN1c3BlbnNlIGV4cG9zZXMgYSBjb21wb25lbnQtbGlrZSBBUEksIGFuZCBpcyB0cmVhdGVkIGxpa2UgYSBjb21wb25lbnRcclxuLy8gaW4gdGhlIGNvbXBpbGVyLCBidXQgaW50ZXJuYWxseSBpdCdzIGEgc3BlY2lhbCBidWlsdC1pbiB0eXBlIHRoYXQgaG9va3NcclxuLy8gZGlyZWN0bHkgaW50byB0aGUgcmVuZGVyZXIuXHJcbmNvbnN0IFN1c3BlbnNlSW1wbCA9IHtcclxuICAgIC8vIEluIG9yZGVyIHRvIG1ha2UgU3VzcGVuc2UgdHJlZS1zaGFrYWJsZSwgd2UgbmVlZCB0byBhdm9pZCBpbXBvcnRpbmcgaXRcclxuICAgIC8vIGRpcmVjdGx5IGluIHRoZSByZW5kZXJlci4gVGhlIHJlbmRlcmVyIGNoZWNrcyBmb3IgdGhlIF9faXNTdXNwZW5zZSBmbGFnXHJcbiAgICAvLyBvbiBhIHZub2RlJ3MgdHlwZSBhbmQgY2FsbHMgdGhlIGBwcm9jZXNzYCBtZXRob2QsIHBhc3NpbmcgaW4gcmVuZGVyZXJcclxuICAgIC8vIGludGVybmFscy5cclxuICAgIF9faXNTdXNwZW5zZTogdHJ1ZSxcclxuICAgIHByb2Nlc3MobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCwgXHJcbiAgICAvLyBwbGF0Zm9ybS1zcGVjaWZpYyBpbXBsIHBhc3NlZCBmcm9tIHJlbmRlcmVyXHJcbiAgICByZW5kZXJlckludGVybmFscykge1xyXG4gICAgICAgIGlmIChuMSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIG1vdW50U3VzcGVuc2UobjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBwYXRjaFN1c3BlbnNlKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgaXNTVkcsIG9wdGltaXplZCwgcmVuZGVyZXJJbnRlcm5hbHMpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBoeWRyYXRlOiBoeWRyYXRlU3VzcGVuc2VcclxufTtcclxuLy8gRm9yY2UtY2FzdGVkIHB1YmxpYyB0eXBpbmcgZm9yIGggYW5kIFRTWCBwcm9wcyBpbmZlcmVuY2VcclxuY29uc3QgU3VzcGVuc2UgPSAoIFN1c3BlbnNlSW1wbFxyXG4gICAgKTtcclxuZnVuY3Rpb24gbW91bnRTdXNwZW5zZShuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQsIHJlbmRlcmVySW50ZXJuYWxzKSB7XHJcbiAgICBjb25zdCB7IHA6IHBhdGNoLCBvOiB7IGNyZWF0ZUVsZW1lbnQgfSB9ID0gcmVuZGVyZXJJbnRlcm5hbHM7XHJcbiAgICBjb25zdCBoaWRkZW5Db250YWluZXIgPSBjcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgIGNvbnN0IHN1c3BlbnNlID0gKG4yLnN1c3BlbnNlID0gY3JlYXRlU3VzcGVuc2VCb3VuZGFyeShuMiwgcGFyZW50U3VzcGVuc2UsIHBhcmVudENvbXBvbmVudCwgY29udGFpbmVyLCBoaWRkZW5Db250YWluZXIsIGFuY2hvciwgaXNTVkcsIG9wdGltaXplZCwgcmVuZGVyZXJJbnRlcm5hbHMpKTtcclxuICAgIC8vIHN0YXJ0IG1vdW50aW5nIHRoZSBjb250ZW50IHN1YnRyZWUgaW4gYW4gb2ZmLWRvbSBjb250YWluZXJcclxuICAgIHBhdGNoKG51bGwsIHN1c3BlbnNlLnN1YlRyZWUsIGhpZGRlbkNvbnRhaW5lciwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCBzdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAvLyBub3cgY2hlY2sgaWYgd2UgaGF2ZSBlbmNvdW50ZXJlZCBhbnkgYXN5bmMgZGVwc1xyXG4gICAgaWYgKHN1c3BlbnNlLmRlcHMgPiAwKSB7XHJcbiAgICAgICAgLy8gbW91bnQgdGhlIGZhbGxiYWNrIHRyZWVcclxuICAgICAgICBwYXRjaChudWxsLCBzdXNwZW5zZS5mYWxsYmFja1RyZWUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIG51bGwsIC8vIGZhbGxiYWNrIHRyZWUgd2lsbCBub3QgaGF2ZSBzdXNwZW5zZSBjb250ZXh0XHJcbiAgICAgICAgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgbjIuZWwgPSBzdXNwZW5zZS5mYWxsYmFja1RyZWUuZWw7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICAvLyBTdXNwZW5zZSBoYXMgbm8gYXN5bmMgZGVwcy4gSnVzdCByZXNvbHZlLlxyXG4gICAgICAgIHN1c3BlbnNlLnJlc29sdmUoKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBwYXRjaFN1c3BlbnNlKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgaXNTVkcsIG9wdGltaXplZCwgeyBwOiBwYXRjaCB9KSB7XHJcbiAgICBjb25zdCBzdXNwZW5zZSA9IChuMi5zdXNwZW5zZSA9IG4xLnN1c3BlbnNlKTtcclxuICAgIHN1c3BlbnNlLnZub2RlID0gbjI7XHJcbiAgICBjb25zdCB7IGNvbnRlbnQsIGZhbGxiYWNrIH0gPSBub3JtYWxpemVTdXNwZW5zZUNoaWxkcmVuKG4yKTtcclxuICAgIGNvbnN0IG9sZFN1YlRyZWUgPSBzdXNwZW5zZS5zdWJUcmVlO1xyXG4gICAgY29uc3Qgb2xkRmFsbGJhY2tUcmVlID0gc3VzcGVuc2UuZmFsbGJhY2tUcmVlO1xyXG4gICAgaWYgKCFzdXNwZW5zZS5pc1Jlc29sdmVkKSB7XHJcbiAgICAgICAgcGF0Y2gob2xkU3ViVHJlZSwgY29udGVudCwgc3VzcGVuc2UuaGlkZGVuQ29udGFpbmVyLCBudWxsLCBwYXJlbnRDb21wb25lbnQsIHN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICBpZiAoc3VzcGVuc2UuZGVwcyA+IDApIHtcclxuICAgICAgICAgICAgLy8gc3RpbGwgcGVuZGluZy4gcGF0Y2ggdGhlIGZhbGxiYWNrIHRyZWUuXHJcbiAgICAgICAgICAgIHBhdGNoKG9sZEZhbGxiYWNrVHJlZSwgZmFsbGJhY2ssIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIG51bGwsIC8vIGZhbGxiYWNrIHRyZWUgd2lsbCBub3QgaGF2ZSBzdXNwZW5zZSBjb250ZXh0XHJcbiAgICAgICAgICAgIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICBuMi5lbCA9IGZhbGxiYWNrLmVsO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBJZiBkZXBzIHNvbWVob3cgYmVjb21lcyAwIGFmdGVyIHRoZSBwYXRjaCBpdCBtZWFucyB0aGUgcGF0Y2ggY2F1c2VkIGFuXHJcbiAgICAgICAgLy8gYXN5bmMgZGVwIGNvbXBvbmVudCB0byB1bm1vdW50IGFuZCByZW1vdmVkIGl0cyBkZXAuIEl0IHdpbGwgY2F1c2UgdGhlXHJcbiAgICAgICAgLy8gc3VzcGVuc2UgdG8gcmVzb2x2ZSBhbmQgd2UgZG9uJ3QgbmVlZCB0byBkbyBhbnl0aGluZyBoZXJlLlxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8ganVzdCBub3JtYWwgcGF0Y2ggaW5uZXIgY29udGVudCBhcyBhIGZyYWdtZW50XHJcbiAgICAgICAgcGF0Y2gob2xkU3ViVHJlZSwgY29udGVudCwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgc3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgIG4yLmVsID0gY29udGVudC5lbDtcclxuICAgIH1cclxuICAgIHN1c3BlbnNlLnN1YlRyZWUgPSBjb250ZW50O1xyXG4gICAgc3VzcGVuc2UuZmFsbGJhY2tUcmVlID0gZmFsbGJhY2s7XHJcbn1cclxubGV0IGhhc1dhcm5lZCA9IGZhbHNlO1xyXG5mdW5jdGlvbiBjcmVhdGVTdXNwZW5zZUJvdW5kYXJ5KHZub2RlLCBwYXJlbnQsIHBhcmVudENvbXBvbmVudCwgY29udGFpbmVyLCBoaWRkZW5Db250YWluZXIsIGFuY2hvciwgaXNTVkcsIG9wdGltaXplZCwgcmVuZGVyZXJJbnRlcm5hbHMsIGlzSHlkcmF0aW5nID0gZmFsc2UpIHtcclxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhZmFsc2UgJiYgIWhhc1dhcm5lZCkge1xyXG4gICAgICAgIGhhc1dhcm5lZCA9IHRydWU7XHJcbiAgICAgICAgLy8gQHRzLWlnbm9yZSBgY29uc29sZS5pbmZvYCBjYW5ub3QgYmUgbnVsbCBlcnJvclxyXG4gICAgICAgIGNvbnNvbGVbY29uc29sZS5pbmZvID8gJ2luZm8nIDogJ2xvZyddKGA8U3VzcGVuc2U+IGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIGFuZCBpdHMgQVBJIHdpbGwgbGlrZWx5IGNoYW5nZS5gKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHsgcDogcGF0Y2gsIG06IG1vdmUsIHVtOiB1bm1vdW50LCBuOiBuZXh0LCBvOiB7IHBhcmVudE5vZGUgfSB9ID0gcmVuZGVyZXJJbnRlcm5hbHM7XHJcbiAgICBjb25zdCBnZXRDdXJyZW50VHJlZSA9ICgpID0+IHN1c3BlbnNlLmlzUmVzb2x2ZWQgfHwgc3VzcGVuc2UuaXNIeWRyYXRpbmdcclxuICAgICAgICA/IHN1c3BlbnNlLnN1YlRyZWVcclxuICAgICAgICA6IHN1c3BlbnNlLmZhbGxiYWNrVHJlZTtcclxuICAgIGNvbnN0IHsgY29udGVudCwgZmFsbGJhY2sgfSA9IG5vcm1hbGl6ZVN1c3BlbnNlQ2hpbGRyZW4odm5vZGUpO1xyXG4gICAgY29uc3Qgc3VzcGVuc2UgPSB7XHJcbiAgICAgICAgdm5vZGUsXHJcbiAgICAgICAgcGFyZW50LFxyXG4gICAgICAgIHBhcmVudENvbXBvbmVudCxcclxuICAgICAgICBpc1NWRyxcclxuICAgICAgICBvcHRpbWl6ZWQsXHJcbiAgICAgICAgY29udGFpbmVyLFxyXG4gICAgICAgIGhpZGRlbkNvbnRhaW5lcixcclxuICAgICAgICBhbmNob3IsXHJcbiAgICAgICAgZGVwczogMCxcclxuICAgICAgICBzdWJUcmVlOiBjb250ZW50LFxyXG4gICAgICAgIGZhbGxiYWNrVHJlZTogZmFsbGJhY2ssXHJcbiAgICAgICAgaXNIeWRyYXRpbmcsXHJcbiAgICAgICAgaXNSZXNvbHZlZDogZmFsc2UsXHJcbiAgICAgICAgaXNVbm1vdW50ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGVmZmVjdHM6IFtdLFxyXG4gICAgICAgIHJlc29sdmUoKSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzdXNwZW5zZS5pc1Jlc29sdmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGByZXNvbHZlU3VzcGVuc2UoKSBpcyBjYWxsZWQgb24gYW4gYWxyZWFkeSByZXNvbHZlZCBzdXNwZW5zZSBib3VuZGFyeS5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChzdXNwZW5zZS5pc1VubW91bnRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgcmVzb2x2ZVN1c3BlbnNlKCkgaXMgY2FsbGVkIG9uIGFuIGFscmVhZHkgdW5tb3VudGVkIHN1c3BlbnNlIGJvdW5kYXJ5LmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IHsgdm5vZGUsIHN1YlRyZWUsIGZhbGxiYWNrVHJlZSwgZWZmZWN0cywgcGFyZW50Q29tcG9uZW50LCBjb250YWluZXIgfSA9IHN1c3BlbnNlO1xyXG4gICAgICAgICAgICBpZiAoc3VzcGVuc2UuaXNIeWRyYXRpbmcpIHtcclxuICAgICAgICAgICAgICAgIHN1c3BlbnNlLmlzSHlkcmF0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGluaXRpYWwgYW5jaG9yIG9uIG1vdW50XHJcbiAgICAgICAgICAgICAgICBsZXQgeyBhbmNob3IgfSA9IHN1c3BlbnNlO1xyXG4gICAgICAgICAgICAgICAgLy8gdW5tb3VudCBmYWxsYmFjayB0cmVlXHJcbiAgICAgICAgICAgICAgICBpZiAoZmFsbGJhY2tUcmVlLmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIGZhbGxiYWNrIHRyZWUgd2FzIG1vdW50ZWQsIGl0IG1heSBoYXZlIGJlZW4gbW92ZWRcclxuICAgICAgICAgICAgICAgICAgICAvLyBhcyBwYXJ0IG9mIGEgcGFyZW50IHN1c3BlbnNlLiBnZXQgdGhlIGxhdGVzdCBhbmNob3IgZm9yIGluc2VydGlvblxyXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvciA9IG5leHQoZmFsbGJhY2tUcmVlKTtcclxuICAgICAgICAgICAgICAgICAgICB1bm1vdW50KGZhbGxiYWNrVHJlZSwgcGFyZW50Q29tcG9uZW50LCBzdXNwZW5zZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBtb3ZlIGNvbnRlbnQgZnJvbSBvZmYtZG9tIGNvbnRhaW5lciB0byBhY3R1YWwgY29udGFpbmVyXHJcbiAgICAgICAgICAgICAgICBtb3ZlKHN1YlRyZWUsIGNvbnRhaW5lciwgYW5jaG9yLCAwIC8qIEVOVEVSICovKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBlbCA9ICh2bm9kZS5lbCA9IHN1YlRyZWUuZWwpO1xyXG4gICAgICAgICAgICAvLyBzdXNwZW5zZSBhcyB0aGUgcm9vdCBub2RlIG9mIGEgY29tcG9uZW50Li4uXHJcbiAgICAgICAgICAgIGlmIChwYXJlbnRDb21wb25lbnQgJiYgcGFyZW50Q29tcG9uZW50LnN1YlRyZWUgPT09IHZub2RlKSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRDb21wb25lbnQudm5vZGUuZWwgPSBlbDtcclxuICAgICAgICAgICAgICAgIHVwZGF0ZUhPQ0hvc3RFbChwYXJlbnRDb21wb25lbnQsIGVsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhIHBlbmRpbmcgcGFyZW50IHN1c3BlbnNlXHJcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSBzdXNwZW5zZS5wYXJlbnQ7XHJcbiAgICAgICAgICAgIGxldCBoYXNVbnJlc29sdmVkQW5jZXN0b3IgPSBmYWxzZTtcclxuICAgICAgICAgICAgd2hpbGUgKHBhcmVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwYXJlbnQuaXNSZXNvbHZlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGZvdW5kIGEgcGVuZGluZyBwYXJlbnQgc3VzcGVuc2UsIG1lcmdlIGJ1ZmZlcmVkIHBvc3Qgam9ic1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGludG8gdGhhdCBwYXJlbnRcclxuICAgICAgICAgICAgICAgICAgICBwYXJlbnQuZWZmZWN0cy5wdXNoKC4uLmVmZmVjdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhc1VucmVzb2x2ZWRBbmNlc3RvciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIG5vIHBlbmRpbmcgcGFyZW50IHN1c3BlbnNlLCBmbHVzaCBhbGwgam9ic1xyXG4gICAgICAgICAgICBpZiAoIWhhc1VucmVzb2x2ZWRBbmNlc3Rvcikge1xyXG4gICAgICAgICAgICAgICAgcXVldWVQb3N0Rmx1c2hDYihlZmZlY3RzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzdXNwZW5zZS5pc1Jlc29sdmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgc3VzcGVuc2UuZWZmZWN0cyA9IFtdO1xyXG4gICAgICAgICAgICAvLyBpbnZva2UgQHJlc29sdmUgZXZlbnRcclxuICAgICAgICAgICAgY29uc3Qgb25SZXNvbHZlID0gdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMub25SZXNvbHZlO1xyXG4gICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihvblJlc29sdmUpKSB7XHJcbiAgICAgICAgICAgICAgICBvblJlc29sdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcmVjZWRlKCkge1xyXG4gICAgICAgICAgICBzdXNwZW5zZS5pc1Jlc29sdmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGNvbnN0IHsgdm5vZGUsIHN1YlRyZWUsIGZhbGxiYWNrVHJlZSwgcGFyZW50Q29tcG9uZW50LCBjb250YWluZXIsIGhpZGRlbkNvbnRhaW5lciwgaXNTVkcsIG9wdGltaXplZCB9ID0gc3VzcGVuc2U7XHJcbiAgICAgICAgICAgIC8vIG1vdmUgY29udGVudCB0cmVlIGJhY2sgdG8gdGhlIG9mZi1kb20gY29udGFpbmVyXHJcbiAgICAgICAgICAgIGNvbnN0IGFuY2hvciA9IG5leHQoc3ViVHJlZSk7XHJcbiAgICAgICAgICAgIG1vdmUoc3ViVHJlZSwgaGlkZGVuQ29udGFpbmVyLCBudWxsLCAxIC8qIExFQVZFICovKTtcclxuICAgICAgICAgICAgLy8gcmVtb3VudCB0aGUgZmFsbGJhY2sgdHJlZVxyXG4gICAgICAgICAgICBwYXRjaChudWxsLCBmYWxsYmFja1RyZWUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIG51bGwsIC8vIGZhbGxiYWNrIHRyZWUgd2lsbCBub3QgaGF2ZSBzdXNwZW5zZSBjb250ZXh0XHJcbiAgICAgICAgICAgIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICBjb25zdCBlbCA9ICh2bm9kZS5lbCA9IGZhbGxiYWNrVHJlZS5lbCk7XHJcbiAgICAgICAgICAgIC8vIHN1c3BlbnNlIGFzIHRoZSByb290IG5vZGUgb2YgYSBjb21wb25lbnQuLi5cclxuICAgICAgICAgICAgaWYgKHBhcmVudENvbXBvbmVudCAmJiBwYXJlbnRDb21wb25lbnQuc3ViVHJlZSA9PT0gdm5vZGUpIHtcclxuICAgICAgICAgICAgICAgIHBhcmVudENvbXBvbmVudC52bm9kZS5lbCA9IGVsO1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlSE9DSG9zdEVsKHBhcmVudENvbXBvbmVudCwgZWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGludm9rZSBAcmVjZWRlIGV2ZW50XHJcbiAgICAgICAgICAgIGNvbnN0IG9uUmVjZWRlID0gdm5vZGUucHJvcHMgJiYgdm5vZGUucHJvcHMub25SZWNlZGU7XHJcbiAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKG9uUmVjZWRlKSkge1xyXG4gICAgICAgICAgICAgICAgb25SZWNlZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbW92ZShjb250YWluZXIsIGFuY2hvciwgdHlwZSkge1xyXG4gICAgICAgICAgICBtb3ZlKGdldEN1cnJlbnRUcmVlKCksIGNvbnRhaW5lciwgYW5jaG9yLCB0eXBlKTtcclxuICAgICAgICAgICAgc3VzcGVuc2UuY29udGFpbmVyID0gY29udGFpbmVyO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgbmV4dCgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5leHQoZ2V0Q3VycmVudFRyZWUoKSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICByZWdpc3RlckRlcChpbnN0YW5jZSwgc2V0dXBSZW5kZXJFZmZlY3QpIHtcclxuICAgICAgICAgICAgLy8gc3VzcGVuc2UgaXMgYWxyZWFkeSByZXNvbHZlZCwgbmVlZCB0byByZWNlZGUuXHJcbiAgICAgICAgICAgIC8vIHVzZSBxdWV1ZUpvYiBzbyBpdCdzIGhhbmRsZWQgc3luY2hyb25vdXNseSBhZnRlciBwYXRjaGluZyB0aGUgY3VycmVudFxyXG4gICAgICAgICAgICAvLyBzdXNwZW5zZSB0cmVlXHJcbiAgICAgICAgICAgIGlmIChzdXNwZW5zZS5pc1Jlc29sdmVkKSB7XHJcbiAgICAgICAgICAgICAgICBxdWV1ZUpvYigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3VzcGVuc2UucmVjZWRlKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBoeWRyYXRlZEVsID0gaW5zdGFuY2Uudm5vZGUuZWw7XHJcbiAgICAgICAgICAgIHN1c3BlbnNlLmRlcHMrKztcclxuICAgICAgICAgICAgaW5zdGFuY2VcclxuICAgICAgICAgICAgICAgIC5hc3luY0RlcC5jYXRjaChlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBpbnN0YW5jZSwgMCAvKiBTRVRVUF9GVU5DVElPTiAqLyk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAudGhlbihhc3luY1NldHVwUmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIHJldHJ5IHdoZW4gdGhlIHNldHVwKCkgcHJvbWlzZSByZXNvbHZlcy5cclxuICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudCBtYXkgaGF2ZSBiZWVuIHVubW91bnRlZCBiZWZvcmUgcmVzb2x2ZS5cclxuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5pc1VubW91bnRlZCB8fCBzdXNwZW5zZS5pc1VubW91bnRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHN1c3BlbnNlLmRlcHMtLTtcclxuICAgICAgICAgICAgICAgIC8vIHJldHJ5IGZyb20gdGhpcyBjb21wb25lbnRcclxuICAgICAgICAgICAgICAgIGluc3RhbmNlLmFzeW5jUmVzb2x2ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgeyB2bm9kZSB9ID0gaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHVzaFdhcm5pbmdDb250ZXh0KHZub2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBhc3luY1NldHVwUmVzdWx0KTtcclxuICAgICAgICAgICAgICAgIGlmIChoeWRyYXRlZEVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdm5vZGUgbWF5IGhhdmUgYmVlbiByZXBsYWNlZCBpZiBhbiB1cGRhdGUgaGFwcGVuZWQgYmVmb3JlIHRoZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFzeW5jIGRlcCBpcyByZXNvbHZlZC5cclxuICAgICAgICAgICAgICAgICAgICB2bm9kZS5lbCA9IGh5ZHJhdGVkRWw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBzZXR1cFJlbmRlckVmZmVjdChpbnN0YW5jZSwgdm5vZGUsIFxyXG4gICAgICAgICAgICAgICAgLy8gY29tcG9uZW50IG1heSBoYXZlIGJlZW4gbW92ZWQgYmVmb3JlIHJlc29sdmUuXHJcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGlzIG5vdCBhIGh5ZHJhdGlvbiwgaW5zdGFuY2Uuc3ViVHJlZSB3aWxsIGJlIHRoZSBjb21tZW50XHJcbiAgICAgICAgICAgICAgICAvLyBwbGFjZWhvbGRlci5cclxuICAgICAgICAgICAgICAgIGh5ZHJhdGVkRWxcclxuICAgICAgICAgICAgICAgICAgICA/IHBhcmVudE5vZGUoaHlkcmF0ZWRFbClcclxuICAgICAgICAgICAgICAgICAgICA6IHBhcmVudE5vZGUoaW5zdGFuY2Uuc3ViVHJlZS5lbCksIFxyXG4gICAgICAgICAgICAgICAgLy8gYW5jaG9yIHdpbGwgbm90IGJlIHVzZWQgaWYgdGhpcyBpcyBoeWRyYXRpb24sIHNvIG9ubHkgbmVlZCB0b1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc2lkZXIgdGhlIGNvbW1lbnQgcGxhY2Vob2xkZXIgY2FzZS5cclxuICAgICAgICAgICAgICAgIGh5ZHJhdGVkRWwgPyBudWxsIDogbmV4dChpbnN0YW5jZS5zdWJUcmVlKSwgc3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlSE9DSG9zdEVsKGluc3RhbmNlLCB2bm9kZS5lbCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9wV2FybmluZ0NvbnRleHQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChzdXNwZW5zZS5kZXBzID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHVubW91bnQocGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKSB7XHJcbiAgICAgICAgICAgIHN1c3BlbnNlLmlzVW5tb3VudGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdW5tb3VudChzdXNwZW5zZS5zdWJUcmVlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7XHJcbiAgICAgICAgICAgIGlmICghc3VzcGVuc2UuaXNSZXNvbHZlZCkge1xyXG4gICAgICAgICAgICAgICAgdW5tb3VudChzdXNwZW5zZS5mYWxsYmFja1RyZWUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gc3VzcGVuc2U7XHJcbn1cclxuZnVuY3Rpb24gaHlkcmF0ZVN1c3BlbnNlKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscywgaHlkcmF0ZU5vZGUpIHtcclxuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscyAqL1xyXG4gICAgY29uc3Qgc3VzcGVuc2UgPSAodm5vZGUuc3VzcGVuc2UgPSBjcmVhdGVTdXNwZW5zZUJvdW5kYXJ5KHZub2RlLCBwYXJlbnRTdXNwZW5zZSwgcGFyZW50Q29tcG9uZW50LCBub2RlLnBhcmVudE5vZGUsIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLCBudWxsLCBpc1NWRywgb3B0aW1pemVkLCByZW5kZXJlckludGVybmFscywgdHJ1ZSAvKiBoeWRyYXRpbmcgKi8pKTtcclxuICAgIC8vIHRoZXJlIGFyZSB0d28gcG9zc2libGUgc2NlbmFyaW9zIGZvciBzZXJ2ZXItcmVuZGVyZWQgc3VzcGVuc2U6XHJcbiAgICAvLyAtIHN1Y2Nlc3M6IHNzciBjb250ZW50IHNob3VsZCBiZSBmdWxseSByZXNvbHZlZFxyXG4gICAgLy8gLSBmYWlsdXJlOiBzc3IgY29udGVudCBzaG91bGQgYmUgdGhlIGZhbGxiYWNrIGJyYW5jaC5cclxuICAgIC8vIGhvd2V2ZXIsIG9uIHRoZSBjbGllbnQgd2UgZG9uJ3QgcmVhbGx5IGtub3cgaWYgaXQgaGFzIGZhaWxlZCBvciBub3RcclxuICAgIC8vIGF0dGVtcHQgdG8gaHlkcmF0ZSB0aGUgRE9NIGFzc3VtaW5nIGl0IGhhcyBzdWNjZWVkZWQsIGJ1dCB3ZSBzdGlsbFxyXG4gICAgLy8gbmVlZCB0byBjb25zdHJ1Y3QgYSBzdXNwZW5zZSBib3VuZGFyeSBmaXJzdFxyXG4gICAgY29uc3QgcmVzdWx0ID0gaHlkcmF0ZU5vZGUobm9kZSwgc3VzcGVuc2Uuc3ViVHJlZSwgcGFyZW50Q29tcG9uZW50LCBzdXNwZW5zZSwgb3B0aW1pemVkKTtcclxuICAgIGlmIChzdXNwZW5zZS5kZXBzID09PSAwKSB7XHJcbiAgICAgICAgc3VzcGVuc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIC8qIGVzbGludC1lbmFibGUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzICovXHJcbn1cclxuZnVuY3Rpb24gbm9ybWFsaXplU3VzcGVuc2VDaGlsZHJlbih2bm9kZSkge1xyXG4gICAgY29uc3QgeyBzaGFwZUZsYWcsIGNoaWxkcmVuIH0gPSB2bm9kZTtcclxuICAgIGlmIChzaGFwZUZsYWcgJiAzMiAvKiBTTE9UU19DSElMRFJFTiAqLykge1xyXG4gICAgICAgIGNvbnN0IHsgZGVmYXVsdDogZCwgZmFsbGJhY2sgfSA9IGNoaWxkcmVuO1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGNvbnRlbnQ6IG5vcm1hbGl6ZVZOb2RlKGlzRnVuY3Rpb24oZCkgPyBkKCkgOiBkKSxcclxuICAgICAgICAgICAgZmFsbGJhY2s6IG5vcm1hbGl6ZVZOb2RlKGlzRnVuY3Rpb24oZmFsbGJhY2spID8gZmFsbGJhY2soKSA6IGZhbGxiYWNrKVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBjb250ZW50OiBub3JtYWxpemVWTm9kZShjaGlsZHJlbiksXHJcbiAgICAgICAgICAgIGZhbGxiYWNrOiBub3JtYWxpemVWTm9kZShudWxsKVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UoZm4sIHN1c3BlbnNlKSB7XHJcbiAgICBpZiAoc3VzcGVuc2UgJiYgIXN1c3BlbnNlLmlzUmVzb2x2ZWQpIHtcclxuICAgICAgICBpZiAoaXNBcnJheShmbikpIHtcclxuICAgICAgICAgICAgc3VzcGVuc2UuZWZmZWN0cy5wdXNoKC4uLmZuKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHN1c3BlbnNlLmVmZmVjdHMucHVzaChmbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcXVldWVQb3N0Rmx1c2hDYihmbik7XHJcbiAgICB9XHJcbn1cblxubGV0IGlzUmVuZGVyaW5nQ29tcGlsZWRTbG90ID0gMDtcclxuY29uc3Qgc2V0Q29tcGlsZWRTbG90UmVuZGVyaW5nID0gKG4pID0+IChpc1JlbmRlcmluZ0NvbXBpbGVkU2xvdCArPSBuKTtcclxuLyoqXHJcbiAqIENvbXBpbGVyIHJ1bnRpbWUgaGVscGVyIGZvciByZW5kZXJpbmcgYDxzbG90Lz5gXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5mdW5jdGlvbiByZW5kZXJTbG90KHNsb3RzLCBuYW1lLCBwcm9wcyA9IHt9LCBcclxuLy8gdGhpcyBpcyBub3QgYSB1c2VyLWZhY2luZyBmdW5jdGlvbiwgc28gdGhlIGZhbGxiYWNrIGlzIGFsd2F5cyBnZW5lcmF0ZWQgYnlcclxuLy8gdGhlIGNvbXBpbGVyIGFuZCBndWFyYW50ZWVkIHRvIGJlIGEgZnVuY3Rpb24gcmV0dXJuaW5nIGFuIGFycmF5XHJcbmZhbGxiYWNrKSB7XHJcbiAgICBsZXQgc2xvdCA9IHNsb3RzW25hbWVdO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBzbG90ICYmIHNsb3QubGVuZ3RoID4gMSkge1xyXG4gICAgICAgIHdhcm4oYFNTUi1vcHRpbWl6ZWQgc2xvdCBmdW5jdGlvbiBkZXRlY3RlZCBpbiBhIG5vbi1TU1Itb3B0aW1pemVkIHJlbmRlciBgICtcclxuICAgICAgICAgICAgYGZ1bmN0aW9uLiBZb3UgbmVlZCB0byBtYXJrIHRoaXMgY29tcG9uZW50IHdpdGggJGR5bmFtaWMtc2xvdHMgaW4gdGhlIGAgK1xyXG4gICAgICAgICAgICBgcGFyZW50IHRlbXBsYXRlLmApO1xyXG4gICAgICAgIHNsb3QgPSAoKSA9PiBbXTtcclxuICAgIH1cclxuICAgIC8vIGEgY29tcGlsZWQgc2xvdCBkaXNhYmxlcyBibG9jayB0cmFja2luZyBieSBkZWZhdWx0IHRvIGF2b2lkIG1hbnVhbFxyXG4gICAgLy8gaW52b2NhdGlvbiBpbnRlcmZlcmluZyB3aXRoIHRlbXBsYXRlLWJhc2VkIGJsb2NrIHRyYWNraW5nLCBidXQgaW5cclxuICAgIC8vIGByZW5kZXJTbG90YCB3ZSBjYW4gYmUgc3VyZSB0aGF0IGl0J3MgdGVtcGxhdGUtYmFzZWQgc28gd2UgY2FuIGZvcmNlXHJcbiAgICAvLyBlbmFibGUgaXQuXHJcbiAgICBpc1JlbmRlcmluZ0NvbXBpbGVkU2xvdCsrO1xyXG4gICAgY29uc3QgcmVuZGVyZWQgPSAob3BlbkJsb2NrKCksXHJcbiAgICAgICAgY3JlYXRlQmxvY2soRnJhZ21lbnQsIHsga2V5OiBwcm9wcy5rZXkgfSwgc2xvdCA/IHNsb3QocHJvcHMpIDogZmFsbGJhY2sgPyBmYWxsYmFjaygpIDogW10sIHNsb3RzLl8gPT09IDEgLyogU1RBQkxFICovXHJcbiAgICAgICAgICAgID8gNjQgLyogU1RBQkxFX0ZSQUdNRU5UICovXHJcbiAgICAgICAgICAgIDogLTIgLyogQkFJTCAqLykpO1xyXG4gICAgaXNSZW5kZXJpbmdDb21waWxlZFNsb3QtLTtcclxuICAgIHJldHVybiByZW5kZXJlZDtcclxufVxuXG4vKipcclxuICogV3JhcCBhIHNsb3QgZnVuY3Rpb24gdG8gbWVtb2l6ZSBjdXJyZW50IHJlbmRlcmluZyBpbnN0YW5jZVxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gd2l0aEN0eChmbiwgY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlKSB7XHJcbiAgICBpZiAoIWN0eClcclxuICAgICAgICByZXR1cm4gZm47XHJcbiAgICBjb25zdCByZW5kZXJGbldpdGhDb250ZXh0ID0gKC4uLmFyZ3MpID0+IHtcclxuICAgICAgICAvLyBJZiBhIHVzZXIgY2FsbHMgYSBjb21waWxlZCBzbG90IGluc2lkZSBhIHRlbXBsYXRlIGV4cHJlc3Npb24gKCMxNzQ1KSwgaXRcclxuICAgICAgICAvLyBjYW4gbWVzcyB1cCBibG9jayB0cmFja2luZywgc28gYnkgZGVmYXVsdCB3ZSBuZWVkIHRvIHB1c2ggYSBudWxsIGJsb2NrIHRvXHJcbiAgICAgICAgLy8gYXZvaWQgdGhhdC4gVGhpcyBpc24ndCBuZWNlc3NhcnkgaWYgcmVuZGVyaW5nIGEgY29tcGlsZWQgYDxzbG90PmAuXHJcbiAgICAgICAgaWYgKCFpc1JlbmRlcmluZ0NvbXBpbGVkU2xvdCkge1xyXG4gICAgICAgICAgICBvcGVuQmxvY2sodHJ1ZSAvKiBudWxsIGJsb2NrIHRoYXQgZGlzYWJsZXMgdHJhY2tpbmcgKi8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBvd25lciA9IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTtcclxuICAgICAgICBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UoY3R4KTtcclxuICAgICAgICBjb25zdCByZXMgPSBmbiguLi5hcmdzKTtcclxuICAgICAgICBzZXRDdXJyZW50UmVuZGVyaW5nSW5zdGFuY2Uob3duZXIpO1xyXG4gICAgICAgIGlmICghaXNSZW5kZXJpbmdDb21waWxlZFNsb3QpIHtcclxuICAgICAgICAgICAgY2xvc2VCbG9jaygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfTtcclxuICAgIHJlbmRlckZuV2l0aENvbnRleHQuX2MgPSB0cnVlO1xyXG4gICAgcmV0dXJuIHJlbmRlckZuV2l0aENvbnRleHQ7XHJcbn1cblxuLy8gU0ZDIHNjb3BlZCBzdHlsZSBJRCBtYW5hZ2VtZW50LlxyXG5sZXQgY3VycmVudFNjb3BlSWQgPSBudWxsO1xyXG5jb25zdCBzY29wZUlkU3RhY2sgPSBbXTtcclxuLyoqXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5mdW5jdGlvbiBwdXNoU2NvcGVJZChpZCkge1xyXG4gICAgc2NvcGVJZFN0YWNrLnB1c2goKGN1cnJlbnRTY29wZUlkID0gaWQpKTtcclxufVxyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIHBvcFNjb3BlSWQoKSB7XHJcbiAgICBzY29wZUlkU3RhY2sucG9wKCk7XHJcbiAgICBjdXJyZW50U2NvcGVJZCA9IHNjb3BlSWRTdGFja1tzY29wZUlkU3RhY2subGVuZ3RoIC0gMV0gfHwgbnVsbDtcclxufVxyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIHdpdGhTY29wZUlkKGlkKSB7XHJcbiAgICByZXR1cm4gKChmbikgPT4gd2l0aEN0eChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcHVzaFNjb3BlSWQoaWQpO1xyXG4gICAgICAgIGNvbnN0IHJlcyA9IGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgICAgICAgcG9wU2NvcGVJZCgpO1xyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9KSk7XHJcbn1cblxuY29uc3QgaXNUZWxlcG9ydCA9ICh0eXBlKSA9PiB0eXBlLl9faXNUZWxlcG9ydDtcclxuY29uc3QgaXNUZWxlcG9ydERpc2FibGVkID0gKHByb3BzKSA9PiBwcm9wcyAmJiAocHJvcHMuZGlzYWJsZWQgfHwgcHJvcHMuZGlzYWJsZWQgPT09ICcnKTtcclxuY29uc3QgcmVzb2x2ZVRhcmdldCA9IChwcm9wcywgc2VsZWN0KSA9PiB7XHJcbiAgICBjb25zdCB0YXJnZXRTZWxlY3RvciA9IHByb3BzICYmIHByb3BzLnRvO1xyXG4gICAgaWYgKGlzU3RyaW5nKHRhcmdldFNlbGVjdG9yKSkge1xyXG4gICAgICAgIGlmICghc2VsZWN0KSB7XHJcbiAgICAgICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICAgICAgd2FybihgQ3VycmVudCByZW5kZXJlciBkb2VzIG5vdCBzdXBwb3J0IHN0cmluZyB0YXJnZXQgZm9yIFRlbGVwb3J0cy4gYCArXHJcbiAgICAgICAgICAgICAgICAgICAgYChtaXNzaW5nIHF1ZXJ5U2VsZWN0b3IgcmVuZGVyZXIgb3B0aW9uKWApO1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHNlbGVjdCh0YXJnZXRTZWxlY3Rvcik7XHJcbiAgICAgICAgICAgIGlmICghdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBGYWlsZWQgdG8gbG9jYXRlIFRlbGVwb3J0IHRhcmdldCB3aXRoIHNlbGVjdG9yIFwiJHt0YXJnZXRTZWxlY3Rvcn1cIi4gYCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBOb3RlIHRoZSB0YXJnZXQgZWxlbWVudCBtdXN0IGV4aXN0IGJlZm9yZSB0aGUgY29tcG9uZW50IGlzIG1vdW50ZWQgLSBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYGkuZS4gdGhlIHRhcmdldCBjYW5ub3QgYmUgcmVuZGVyZWQgYnkgdGhlIGNvbXBvbmVudCBpdHNlbGYsIGFuZCBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYGlkZWFsbHkgc2hvdWxkIGJlIG91dHNpZGUgb2YgdGhlIGVudGlyZSBWdWUgY29tcG9uZW50IHRyZWUuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICF0YXJnZXRTZWxlY3RvciAmJiAhaXNUZWxlcG9ydERpc2FibGVkKHByb3BzKSkge1xyXG4gICAgICAgICAgICB3YXJuKGBJbnZhbGlkIFRlbGVwb3J0IHRhcmdldDogJHt0YXJnZXRTZWxlY3Rvcn1gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldFNlbGVjdG9yO1xyXG4gICAgfVxyXG59O1xyXG5jb25zdCBUZWxlcG9ydEltcGwgPSB7XHJcbiAgICBfX2lzVGVsZXBvcnQ6IHRydWUsXHJcbiAgICBwcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQsIGludGVybmFscykge1xyXG4gICAgICAgIGNvbnN0IHsgbWM6IG1vdW50Q2hpbGRyZW4sIHBjOiBwYXRjaENoaWxkcmVuLCBwYmM6IHBhdGNoQmxvY2tDaGlsZHJlbiwgbzogeyBpbnNlcnQsIHF1ZXJ5U2VsZWN0b3IsIGNyZWF0ZVRleHQsIGNyZWF0ZUNvbW1lbnQgfSB9ID0gaW50ZXJuYWxzO1xyXG4gICAgICAgIGNvbnN0IGRpc2FibGVkID0gaXNUZWxlcG9ydERpc2FibGVkKG4yLnByb3BzKTtcclxuICAgICAgICBjb25zdCB7IHNoYXBlRmxhZywgY2hpbGRyZW4gfSA9IG4yO1xyXG4gICAgICAgIGlmIChuMSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIC8vIGluc2VydCBhbmNob3JzIGluIHRoZSBtYWluIHZpZXdcclxuICAgICAgICAgICAgY29uc3QgcGxhY2Vob2xkZXIgPSAobjIuZWwgPSAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJylcclxuICAgICAgICAgICAgICAgID8gY3JlYXRlQ29tbWVudCgndGVsZXBvcnQgc3RhcnQnKVxyXG4gICAgICAgICAgICAgICAgOiBjcmVhdGVUZXh0KCcnKSk7XHJcbiAgICAgICAgICAgIGNvbnN0IG1haW5BbmNob3IgPSAobjIuYW5jaG9yID0gKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpXHJcbiAgICAgICAgICAgICAgICA/IGNyZWF0ZUNvbW1lbnQoJ3RlbGVwb3J0IGVuZCcpXHJcbiAgICAgICAgICAgICAgICA6IGNyZWF0ZVRleHQoJycpKTtcclxuICAgICAgICAgICAgaW5zZXJ0KHBsYWNlaG9sZGVyLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgIGluc2VydChtYWluQW5jaG9yLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IChuMi50YXJnZXQgPSByZXNvbHZlVGFyZ2V0KG4yLnByb3BzLCBxdWVyeVNlbGVjdG9yKSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldEFuY2hvciA9IChuMi50YXJnZXRBbmNob3IgPSBjcmVhdGVUZXh0KCcnKSk7XHJcbiAgICAgICAgICAgIGlmICh0YXJnZXQpIHtcclxuICAgICAgICAgICAgICAgIGluc2VydCh0YXJnZXRBbmNob3IsIHRhcmdldCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFkaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgd2FybignSW52YWxpZCBUZWxlcG9ydCB0YXJnZXQgb24gbW91bnQ6JywgdGFyZ2V0LCBgKCR7dHlwZW9mIHRhcmdldH0pYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgbW91bnQgPSAoY29udGFpbmVyLCBhbmNob3IpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIFRlbGVwb3J0ICphbHdheXMqIGhhcyBBcnJheSBjaGlsZHJlbi4gVGhpcyBpcyBlbmZvcmNlZCBpbiBib3RoIHRoZVxyXG4gICAgICAgICAgICAgICAgLy8gY29tcGlsZXIgYW5kIHZub2RlIGNoaWxkcmVuIG5vcm1hbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYgLyogQVJSQVlfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBtb3VudENoaWxkcmVuKGNoaWxkcmVuLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGlmIChkaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgbW91bnQoY29udGFpbmVyLCBtYWluQW5jaG9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh0YXJnZXQpIHtcclxuICAgICAgICAgICAgICAgIG1vdW50KHRhcmdldCwgdGFyZ2V0QW5jaG9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gdXBkYXRlIGNvbnRlbnRcclxuICAgICAgICAgICAgbjIuZWwgPSBuMS5lbDtcclxuICAgICAgICAgICAgY29uc3QgbWFpbkFuY2hvciA9IChuMi5hbmNob3IgPSBuMS5hbmNob3IpO1xyXG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgPSAobjIudGFyZ2V0ID0gbjEudGFyZ2V0KTtcclxuICAgICAgICAgICAgY29uc3QgdGFyZ2V0QW5jaG9yID0gKG4yLnRhcmdldEFuY2hvciA9IG4xLnRhcmdldEFuY2hvcik7XHJcbiAgICAgICAgICAgIGNvbnN0IHdhc0Rpc2FibGVkID0gaXNUZWxlcG9ydERpc2FibGVkKG4xLnByb3BzKTtcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudENvbnRhaW5lciA9IHdhc0Rpc2FibGVkID8gY29udGFpbmVyIDogdGFyZ2V0O1xyXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50QW5jaG9yID0gd2FzRGlzYWJsZWQgPyBtYWluQW5jaG9yIDogdGFyZ2V0QW5jaG9yO1xyXG4gICAgICAgICAgICBpZiAobjIuZHluYW1pY0NoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBmYXN0IHBhdGggd2hlbiB0aGUgdGVsZXBvcnQgaGFwcGVucyB0byBiZSBhIGJsb2NrIHJvb3RcclxuICAgICAgICAgICAgICAgIHBhdGNoQmxvY2tDaGlsZHJlbihuMS5keW5hbWljQ2hpbGRyZW4sIG4yLmR5bmFtaWNDaGlsZHJlbiwgY3VycmVudENvbnRhaW5lciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcpO1xyXG4gICAgICAgICAgICAgICAgLy8gZXZlbiBpbiBibG9jayB0cmVlIG1vZGUgd2UgbmVlZCB0byBtYWtlIHN1cmUgYWxsIHJvb3QtbGV2ZWwgbm9kZXNcclxuICAgICAgICAgICAgICAgIC8vIGluIHRoZSB0ZWxlcG9ydCBpbmhlcml0IHByZXZpb3VzIERPTSByZWZlcmVuY2VzIHNvIHRoYXQgdGhleSBjYW5cclxuICAgICAgICAgICAgICAgIC8vIGJlIG1vdmVkIGluIGZ1dHVyZSBwYXRjaGVzLlxyXG4gICAgICAgICAgICAgICAgaWYgKG4yLnNoYXBlRmxhZyAmIDE2IC8qIEFSUkFZX0NISUxEUkVOICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkQ2hpbGRyZW4gPSBuMS5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IG4yLmNoaWxkcmVuO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25seSBpbmhlcml0IGZvciBub24tcGF0Y2hlZCBub2RlcyAoaS5lLiBzdGF0aWMgb25lcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbltpXS5lbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baV0uZWwgPSBvbGRDaGlsZHJlbltpXS5lbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICghb3B0aW1pemVkKSB7XHJcbiAgICAgICAgICAgICAgICBwYXRjaENoaWxkcmVuKG4xLCBuMiwgY3VycmVudENvbnRhaW5lciwgY3VycmVudEFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChkaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF3YXNEaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGVuYWJsZWQgLT4gZGlzYWJsZWRcclxuICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIGludG8gbWFpbiBjb250YWluZXJcclxuICAgICAgICAgICAgICAgICAgICBtb3ZlVGVsZXBvcnQobjIsIGNvbnRhaW5lciwgbWFpbkFuY2hvciwgaW50ZXJuYWxzLCAxIC8qIFRPR0dMRSAqLyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyB0YXJnZXQgY2hhbmdlZFxyXG4gICAgICAgICAgICAgICAgaWYgKChuMi5wcm9wcyAmJiBuMi5wcm9wcy50bykgIT09IChuMS5wcm9wcyAmJiBuMS5wcm9wcy50bykpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0VGFyZ2V0ID0gKG4yLnRhcmdldCA9IHJlc29sdmVUYXJnZXQobjIucHJvcHMsIHF1ZXJ5U2VsZWN0b3IpKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFRhcmdldCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3ZlVGVsZXBvcnQobjIsIG5leHRUYXJnZXQsIG51bGwsIGludGVybmFscywgMCAvKiBUQVJHRVRfQ0hBTkdFICovKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4oJ0ludmFsaWQgVGVsZXBvcnQgdGFyZ2V0IG9uIHVwZGF0ZTonLCB0YXJnZXQsIGAoJHt0eXBlb2YgdGFyZ2V0fSlgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh3YXNEaXNhYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGRpc2FibGVkIC0+IGVuYWJsZWRcclxuICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIGludG8gdGVsZXBvcnQgdGFyZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgbW92ZVRlbGVwb3J0KG4yLCB0YXJnZXQsIHRhcmdldEFuY2hvciwgaW50ZXJuYWxzLCAxIC8qIFRPR0dMRSAqLyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlKHZub2RlLCB7IHI6IHJlbW92ZSwgbzogeyByZW1vdmU6IGhvc3RSZW1vdmUgfSB9KSB7XHJcbiAgICAgICAgY29uc3QgeyBzaGFwZUZsYWcsIGNoaWxkcmVuLCBhbmNob3IgfSA9IHZub2RlO1xyXG4gICAgICAgIGhvc3RSZW1vdmUoYW5jaG9yKTtcclxuICAgICAgICBpZiAoc2hhcGVGbGFnICYgMTYgLyogQVJSQVlfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlKGNoaWxkcmVuW2ldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBtb3ZlOiBtb3ZlVGVsZXBvcnQsXHJcbiAgICBoeWRyYXRlOiBoeWRyYXRlVGVsZXBvcnRcclxufTtcclxuZnVuY3Rpb24gbW92ZVRlbGVwb3J0KHZub2RlLCBjb250YWluZXIsIHBhcmVudEFuY2hvciwgeyBvOiB7IGluc2VydCB9LCBtOiBtb3ZlIH0sIG1vdmVUeXBlID0gMiAvKiBSRU9SREVSICovKSB7XHJcbiAgICAvLyBtb3ZlIHRhcmdldCBhbmNob3IgaWYgdGhpcyBpcyBhIHRhcmdldCBjaGFuZ2UuXHJcbiAgICBpZiAobW92ZVR5cGUgPT09IDAgLyogVEFSR0VUX0NIQU5HRSAqLykge1xyXG4gICAgICAgIGluc2VydCh2bm9kZS50YXJnZXRBbmNob3IsIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHsgZWwsIGFuY2hvciwgc2hhcGVGbGFnLCBjaGlsZHJlbiwgcHJvcHMgfSA9IHZub2RlO1xyXG4gICAgY29uc3QgaXNSZW9yZGVyID0gbW92ZVR5cGUgPT09IDIgLyogUkVPUkRFUiAqLztcclxuICAgIC8vIG1vdmUgbWFpbiB2aWV3IGFuY2hvciBpZiB0aGlzIGlzIGEgcmUtb3JkZXIuXHJcbiAgICBpZiAoaXNSZW9yZGVyKSB7XHJcbiAgICAgICAgaW5zZXJ0KGVsLCBjb250YWluZXIsIHBhcmVudEFuY2hvcik7XHJcbiAgICB9XHJcbiAgICAvLyBpZiB0aGlzIGlzIGEgcmUtb3JkZXIgYW5kIHRlbGVwb3J0IGlzIGVuYWJsZWQgKGNvbnRlbnQgaXMgaW4gdGFyZ2V0KVxyXG4gICAgLy8gZG8gbm90IG1vdmUgY2hpbGRyZW4uIFNvIHRoZSBvcHBvc2l0ZSBpczogb25seSBtb3ZlIGNoaWxkcmVuIGlmIHRoaXNcclxuICAgIC8vIGlzIG5vdCBhIHJlb3JkZXIsIG9yIHRoZSB0ZWxlcG9ydCBpcyBkaXNhYmxlZFxyXG4gICAgaWYgKCFpc1Jlb3JkZXIgfHwgaXNUZWxlcG9ydERpc2FibGVkKHByb3BzKSkge1xyXG4gICAgICAgIC8vIFRlbGVwb3J0IGhhcyBlaXRoZXIgQXJyYXkgY2hpbGRyZW4gb3Igbm8gY2hpbGRyZW4uXHJcbiAgICAgICAgaWYgKHNoYXBlRmxhZyAmIDE2IC8qIEFSUkFZX0NISUxEUkVOICovKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIG1vdmUoY2hpbGRyZW5baV0sIGNvbnRhaW5lciwgcGFyZW50QW5jaG9yLCAyIC8qIFJFT1JERVIgKi8pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gbW92ZSBtYWluIHZpZXcgYW5jaG9yIGlmIHRoaXMgaXMgYSByZS1vcmRlci5cclxuICAgIGlmIChpc1Jlb3JkZXIpIHtcclxuICAgICAgICBpbnNlcnQoYW5jaG9yLCBjb250YWluZXIsIHBhcmVudEFuY2hvcik7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gaHlkcmF0ZVRlbGVwb3J0KG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQsIHsgbzogeyBuZXh0U2libGluZywgcGFyZW50Tm9kZSwgcXVlcnlTZWxlY3RvciB9IH0sIGh5ZHJhdGVDaGlsZHJlbikge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gKHZub2RlLnRhcmdldCA9IHJlc29sdmVUYXJnZXQodm5vZGUucHJvcHMsIHF1ZXJ5U2VsZWN0b3IpKTtcclxuICAgIGlmICh0YXJnZXQpIHtcclxuICAgICAgICAvLyBpZiBtdWx0aXBsZSB0ZWxlcG9ydHMgcmVuZGVyZWQgdG8gdGhlIHNhbWUgdGFyZ2V0IGVsZW1lbnQsIHdlIG5lZWQgdG9cclxuICAgICAgICAvLyBwaWNrIHVwIGZyb20gd2hlcmUgdGhlIGxhc3QgdGVsZXBvcnQgZmluaXNoZWQgaW5zdGVhZCBvZiB0aGUgZmlyc3Qgbm9kZVxyXG4gICAgICAgIGNvbnN0IHRhcmdldE5vZGUgPSB0YXJnZXQuX2xwYSB8fCB0YXJnZXQuZmlyc3RDaGlsZDtcclxuICAgICAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMTYgLyogQVJSQVlfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICAgICAgaWYgKGlzVGVsZXBvcnREaXNhYmxlZCh2bm9kZS5wcm9wcykpIHtcclxuICAgICAgICAgICAgICAgIHZub2RlLmFuY2hvciA9IGh5ZHJhdGVDaGlsZHJlbihuZXh0U2libGluZyhub2RlKSwgdm5vZGUsIHBhcmVudE5vZGUobm9kZSksIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgPSB0YXJnZXROb2RlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdm5vZGUuYW5jaG9yID0gbmV4dFNpYmxpbmcobm9kZSk7XHJcbiAgICAgICAgICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgPSBoeWRyYXRlQ2hpbGRyZW4odGFyZ2V0Tm9kZSwgdm5vZGUsIHRhcmdldCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0YXJnZXQuX2xwYSA9XHJcbiAgICAgICAgICAgICAgICB2bm9kZS50YXJnZXRBbmNob3IgJiYgbmV4dFNpYmxpbmcodm5vZGUudGFyZ2V0QW5jaG9yKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdm5vZGUuYW5jaG9yICYmIG5leHRTaWJsaW5nKHZub2RlLmFuY2hvcik7XHJcbn1cclxuLy8gRm9yY2UtY2FzdGVkIHB1YmxpYyB0eXBpbmcgZm9yIGggYW5kIFRTWCBwcm9wcyBpbmZlcmVuY2VcclxuY29uc3QgVGVsZXBvcnQgPSBUZWxlcG9ydEltcGw7XG5cbmNvbnN0IENPTVBPTkVOVFMgPSAnY29tcG9uZW50cyc7XHJcbmNvbnN0IERJUkVDVElWRVMgPSAnZGlyZWN0aXZlcyc7XHJcbi8qKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gcmVzb2x2ZUNvbXBvbmVudChuYW1lKSB7XHJcbiAgICByZXR1cm4gcmVzb2x2ZUFzc2V0KENPTVBPTkVOVFMsIG5hbWUpIHx8IG5hbWU7XHJcbn1cclxuY29uc3QgTlVMTF9EWU5BTUlDX0NPTVBPTkVOVCA9IFN5bWJvbCgpO1xyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIHJlc29sdmVEeW5hbWljQ29tcG9uZW50KGNvbXBvbmVudCkge1xyXG4gICAgaWYgKGlzU3RyaW5nKGNvbXBvbmVudCkpIHtcclxuICAgICAgICByZXR1cm4gcmVzb2x2ZUFzc2V0KENPTVBPTkVOVFMsIGNvbXBvbmVudCwgZmFsc2UpIHx8IGNvbXBvbmVudDtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIGludmFsaWQgdHlwZXMgd2lsbCBmYWxsdGhyb3VnaCB0byBjcmVhdGVWTm9kZSBhbmQgcmFpc2Ugd2FybmluZ1xyXG4gICAgICAgIHJldHVybiAoY29tcG9uZW50IHx8IE5VTExfRFlOQU1JQ19DT01QT05FTlQpO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gcmVzb2x2ZURpcmVjdGl2ZShuYW1lKSB7XHJcbiAgICByZXR1cm4gcmVzb2x2ZUFzc2V0KERJUkVDVElWRVMsIG5hbWUpO1xyXG59XHJcbi8vIGltcGxlbWVudGF0aW9uXHJcbmZ1bmN0aW9uIHJlc29sdmVBc3NldCh0eXBlLCBuYW1lLCB3YXJuTWlzc2luZyA9IHRydWUpIHtcclxuICAgIGNvbnN0IGluc3RhbmNlID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlIHx8IGN1cnJlbnRJbnN0YW5jZTtcclxuICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgIGNvbnN0IENvbXBvbmVudCA9IGluc3RhbmNlLnR5cGU7XHJcbiAgICAgICAgLy8gc2VsZiBuYW1lIGhhcyBoaWdoZXN0IHByaW9yaXR5XHJcbiAgICAgICAgaWYgKHR5cGUgPT09IENPTVBPTkVOVFMpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZk5hbWUgPSBDb21wb25lbnQuZGlzcGxheU5hbWUgfHwgQ29tcG9uZW50Lm5hbWU7XHJcbiAgICAgICAgICAgIGlmIChzZWxmTmFtZSAmJlxyXG4gICAgICAgICAgICAgICAgKHNlbGZOYW1lID09PSBuYW1lIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZk5hbWUgPT09IGNhbWVsaXplKG5hbWUpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZk5hbWUgPT09IGNhcGl0YWxpemUoY2FtZWxpemUobmFtZSkpKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIENvbXBvbmVudDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCByZXMgPSBcclxuICAgICAgICAvLyBsb2NhbCByZWdpc3RyYXRpb25cclxuICAgICAgICAvLyBjaGVjayBpbnN0YW5jZVt0eXBlXSBmaXJzdCBmb3IgY29tcG9uZW50cyB3aXRoIG1peGluIG9yIGV4dGVuZHMuXHJcbiAgICAgICAgcmVzb2x2ZShpbnN0YW5jZVt0eXBlXSB8fCBDb21wb25lbnRbdHlwZV0sIG5hbWUpIHx8XHJcbiAgICAgICAgICAgIC8vIGdsb2JhbCByZWdpc3RyYXRpb25cclxuICAgICAgICAgICAgcmVzb2x2ZShpbnN0YW5jZS5hcHBDb250ZXh0W3R5cGVdLCBuYW1lKTtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHdhcm5NaXNzaW5nICYmICFyZXMpIHtcclxuICAgICAgICAgICAgd2FybihgRmFpbGVkIHRvIHJlc29sdmUgJHt0eXBlLnNsaWNlKDAsIC0xKX06ICR7bmFtZX1gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHJlcztcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIHdhcm4oYHJlc29sdmUke2NhcGl0YWxpemUodHlwZS5zbGljZSgwLCAtMSkpfSBgICtcclxuICAgICAgICAgICAgYGNhbiBvbmx5IGJlIHVzZWQgaW4gcmVuZGVyKCkgb3Igc2V0dXAoKS5gKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiByZXNvbHZlKHJlZ2lzdHJ5LCBuYW1lKSB7XHJcbiAgICByZXR1cm4gKHJlZ2lzdHJ5ICYmXHJcbiAgICAgICAgKHJlZ2lzdHJ5W25hbWVdIHx8XHJcbiAgICAgICAgICAgIHJlZ2lzdHJ5W2NhbWVsaXplKG5hbWUpXSB8fFxyXG4gICAgICAgICAgICByZWdpc3RyeVtjYXBpdGFsaXplKGNhbWVsaXplKG5hbWUpKV0pKTtcclxufVxuXG5jb25zdCBGcmFnbWVudCA9IFN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAnRnJhZ21lbnQnIDogdW5kZWZpbmVkKTtcclxuY29uc3QgVGV4dCA9IFN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAnVGV4dCcgOiB1bmRlZmluZWQpO1xyXG5jb25zdCBDb21tZW50ID0gU3ltYm9sKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/ICdDb21tZW50JyA6IHVuZGVmaW5lZCk7XHJcbmNvbnN0IFN0YXRpYyA9IFN5bWJvbCgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyAnU3RhdGljJyA6IHVuZGVmaW5lZCk7XHJcbi8vIFNpbmNlIHYtaWYgYW5kIHYtZm9yIGFyZSB0aGUgdHdvIHBvc3NpYmxlIHdheXMgbm9kZSBzdHJ1Y3R1cmUgY2FuIGR5bmFtaWNhbGx5XHJcbi8vIGNoYW5nZSwgb25jZSB3ZSBjb25zaWRlciB2LWlmIGJyYW5jaGVzIGFuZCBlYWNoIHYtZm9yIGZyYWdtZW50IGEgYmxvY2ssIHdlXHJcbi8vIGNhbiBkaXZpZGUgYSB0ZW1wbGF0ZSBpbnRvIG5lc3RlZCBibG9ja3MsIGFuZCB3aXRoaW4gZWFjaCBibG9jayB0aGUgbm9kZVxyXG4vLyBzdHJ1Y3R1cmUgd291bGQgYmUgc3RhYmxlLiBUaGlzIGFsbG93cyB1cyB0byBza2lwIG1vc3QgY2hpbGRyZW4gZGlmZmluZ1xyXG4vLyBhbmQgb25seSB3b3JyeSBhYm91dCB0aGUgZHluYW1pYyBub2RlcyAoaW5kaWNhdGVkIGJ5IHBhdGNoIGZsYWdzKS5cclxuY29uc3QgYmxvY2tTdGFjayA9IFtdO1xyXG5sZXQgY3VycmVudEJsb2NrID0gbnVsbDtcclxuLyoqXHJcbiAqIE9wZW4gYSBibG9jay5cclxuICogVGhpcyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgYGNyZWF0ZUJsb2NrYC4gSXQgY2Fubm90IGJlIHBhcnQgb2YgYGNyZWF0ZUJsb2NrYFxyXG4gKiBiZWNhdXNlIHRoZSBjaGlsZHJlbiBvZiB0aGUgYmxvY2sgYXJlIGV2YWx1YXRlZCBiZWZvcmUgYGNyZWF0ZUJsb2NrYCBpdHNlbGZcclxuICogaXMgY2FsbGVkLiBUaGUgZ2VuZXJhdGVkIGNvZGUgdHlwaWNhbGx5IGxvb2tzIGxpa2UgdGhpczpcclxuICpcclxuICogYGBganNcclxuICogZnVuY3Rpb24gcmVuZGVyKCkge1xyXG4gKiAgIHJldHVybiAob3BlbkJsb2NrKCksY3JlYXRlQmxvY2soJ2RpdicsIG51bGwsIFsuLi5dKSlcclxuICogfVxyXG4gKiBgYGBcclxuICogZGlzYWJsZVRyYWNraW5nIGlzIHRydWUgd2hlbiBjcmVhdGluZyBhIHYtZm9yIGZyYWdtZW50IGJsb2NrLCBzaW5jZSBhIHYtZm9yXHJcbiAqIGZyYWdtZW50IGFsd2F5cyBkaWZmcyBpdHMgY2hpbGRyZW4uXHJcbiAqXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5mdW5jdGlvbiBvcGVuQmxvY2soZGlzYWJsZVRyYWNraW5nID0gZmFsc2UpIHtcclxuICAgIGJsb2NrU3RhY2sucHVzaCgoY3VycmVudEJsb2NrID0gZGlzYWJsZVRyYWNraW5nID8gbnVsbCA6IFtdKSk7XHJcbn1cclxuZnVuY3Rpb24gY2xvc2VCbG9jaygpIHtcclxuICAgIGJsb2NrU3RhY2sucG9wKCk7XHJcbiAgICBjdXJyZW50QmxvY2sgPSBibG9ja1N0YWNrW2Jsb2NrU3RhY2subGVuZ3RoIC0gMV0gfHwgbnVsbDtcclxufVxyXG4vLyBXaGV0aGVyIHdlIHNob3VsZCBiZSB0cmFja2luZyBkeW5hbWljIGNoaWxkIG5vZGVzIGluc2lkZSBhIGJsb2NrLlxyXG4vLyBPbmx5IHRyYWNrcyB3aGVuIHRoaXMgdmFsdWUgaXMgPiAwXHJcbi8vIFdlIGFyZSBub3QgdXNpbmcgYSBzaW1wbGUgYm9vbGVhbiBiZWNhdXNlIHRoaXMgdmFsdWUgbWF5IG5lZWQgdG8gYmVcclxuLy8gaW5jcmVtZW50ZWQvZGVjcmVtZW50ZWQgYnkgbmVzdGVkIHVzYWdlIG9mIHYtb25jZSAoc2VlIGJlbG93KVxyXG5sZXQgc2hvdWxkVHJhY2sgPSAxO1xyXG4vKipcclxuICogQmxvY2sgdHJhY2tpbmcgc29tZXRpbWVzIG5lZWRzIHRvIGJlIGRpc2FibGVkLCBmb3IgZXhhbXBsZSBkdXJpbmcgdGhlXHJcbiAqIGNyZWF0aW9uIG9mIGEgdHJlZSB0aGF0IG5lZWRzIHRvIGJlIGNhY2hlZCBieSB2LW9uY2UuIFRoZSBjb21waWxlciBnZW5lcmF0ZXNcclxuICogY29kZSBsaWtlIHRoaXM6XHJcbiAqXHJcbiAqIGBgYCBqc1xyXG4gKiBfY2FjaGVbMV0gfHwgKFxyXG4gKiAgIHNldEJsb2NrVHJhY2tpbmcoLTEpLFxyXG4gKiAgIF9jYWNoZVsxXSA9IGNyZWF0ZVZOb2RlKC4uLiksXHJcbiAqICAgc2V0QmxvY2tUcmFja2luZygxKSxcclxuICogICBfY2FjaGVbMV1cclxuICogKVxyXG4gKiBgYGBcclxuICpcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIHNldEJsb2NrVHJhY2tpbmcodmFsdWUpIHtcclxuICAgIHNob3VsZFRyYWNrICs9IHZhbHVlO1xyXG59XHJcbi8qKlxyXG4gKiBDcmVhdGUgYSBibG9jayByb290IHZub2RlLiBUYWtlcyB0aGUgc2FtZSBleGFjdCBhcmd1bWVudHMgYXMgYGNyZWF0ZVZOb2RlYC5cclxuICogQSBibG9jayByb290IGtlZXBzIHRyYWNrIG9mIGR5bmFtaWMgbm9kZXMgd2l0aGluIHRoZSBibG9jayBpbiB0aGVcclxuICogYGR5bmFtaWNDaGlsZHJlbmAgYXJyYXkuXHJcbiAqXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVCbG9jayh0eXBlLCBwcm9wcywgY2hpbGRyZW4sIHBhdGNoRmxhZywgZHluYW1pY1Byb3BzKSB7XHJcbiAgICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKHR5cGUsIHByb3BzLCBjaGlsZHJlbiwgcGF0Y2hGbGFnLCBkeW5hbWljUHJvcHMsIHRydWUgLyogaXNCbG9jazogcHJldmVudCBhIGJsb2NrIGZyb20gdHJhY2tpbmcgaXRzZWxmICovKTtcclxuICAgIC8vIHNhdmUgY3VycmVudCBibG9jayBjaGlsZHJlbiBvbiB0aGUgYmxvY2sgdm5vZGVcclxuICAgIHZub2RlLmR5bmFtaWNDaGlsZHJlbiA9IGN1cnJlbnRCbG9jayB8fCBFTVBUWV9BUlI7XHJcbiAgICAvLyBjbG9zZSBibG9ja1xyXG4gICAgY2xvc2VCbG9jaygpO1xyXG4gICAgLy8gYSBibG9jayBpcyBhbHdheXMgZ29pbmcgdG8gYmUgcGF0Y2hlZCwgc28gdHJhY2sgaXQgYXMgYSBjaGlsZCBvZiBpdHNcclxuICAgIC8vIHBhcmVudCBibG9ja1xyXG4gICAgaWYgKHNob3VsZFRyYWNrID4gMCAmJiBjdXJyZW50QmxvY2spIHtcclxuICAgICAgICBjdXJyZW50QmxvY2sucHVzaCh2bm9kZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdm5vZGU7XHJcbn1cclxuZnVuY3Rpb24gaXNWTm9kZSh2YWx1ZSkge1xyXG4gICAgcmV0dXJuIHZhbHVlID8gdmFsdWUuX192X2lzVk5vZGUgPT09IHRydWUgOiBmYWxzZTtcclxufVxyXG5mdW5jdGlvbiBpc1NhbWVWTm9kZVR5cGUobjEsIG4yKSB7XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgbjIuc2hhcGVGbGFnICYgNiAvKiBDT01QT05FTlQgKi8gJiZcclxuICAgICAgICBobXJEaXJ0eUNvbXBvbmVudHMuaGFzKG4yLnR5cGUpKSB7XHJcbiAgICAgICAgLy8gSE1SIG9ubHk6IGlmIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gaG90LXVwZGF0ZWQsIGZvcmNlIGEgcmVsb2FkLlxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiBuMS50eXBlID09PSBuMi50eXBlICYmIG4xLmtleSA9PT0gbjIua2V5O1xyXG59XHJcbmxldCB2bm9kZUFyZ3NUcmFuc2Zvcm1lcjtcclxuLyoqXHJcbiAqIEludGVybmFsIEFQSSBmb3IgcmVnaXN0ZXJpbmcgYW4gYXJndW1lbnRzIHRyYW5zZm9ybSBmb3IgY3JlYXRlVk5vZGVcclxuICogdXNlZCBmb3IgY3JlYXRpbmcgc3R1YnMgaW4gdGhlIHRlc3QtdXRpbHNcclxuICogSXQgaXMgKmludGVybmFsKiBidXQgbmVlZHMgdG8gYmUgZXhwb3NlZCBmb3IgdGVzdC11dGlscyB0byBwaWNrIHVwIHByb3BlclxyXG4gKiB0eXBpbmdzXHJcbiAqL1xyXG5mdW5jdGlvbiB0cmFuc2Zvcm1WTm9kZUFyZ3ModHJhbnNmb3JtZXIpIHtcclxuICAgIHZub2RlQXJnc1RyYW5zZm9ybWVyID0gdHJhbnNmb3JtZXI7XHJcbn1cclxuY29uc3QgY3JlYXRlVk5vZGVXaXRoQXJnc1RyYW5zZm9ybSA9ICguLi5hcmdzKSA9PiB7XHJcbiAgICByZXR1cm4gX2NyZWF0ZVZOb2RlKC4uLih2bm9kZUFyZ3NUcmFuc2Zvcm1lclxyXG4gICAgICAgID8gdm5vZGVBcmdzVHJhbnNmb3JtZXIoYXJncywgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlKVxyXG4gICAgICAgIDogYXJncykpO1xyXG59O1xyXG5jb25zdCBJbnRlcm5hbE9iamVjdEtleSA9IGBfX3ZJbnRlcm5hbGA7XHJcbmNvbnN0IG5vcm1hbGl6ZUtleSA9ICh7IGtleSB9KSA9PiBrZXkgIT0gbnVsbCA/IGtleSA6IG51bGw7XHJcbmNvbnN0IG5vcm1hbGl6ZVJlZiA9ICh7IHJlZiB9KSA9PiB7XHJcbiAgICByZXR1cm4gKHJlZiAhPSBudWxsXHJcbiAgICAgICAgPyBpc0FycmF5KHJlZilcclxuICAgICAgICAgICAgPyByZWZcclxuICAgICAgICAgICAgOiBbY3VycmVudFJlbmRlcmluZ0luc3RhbmNlLCByZWZdXHJcbiAgICAgICAgOiBudWxsKTtcclxufTtcclxuY29uc3QgY3JlYXRlVk5vZGUgPSAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpXHJcbiAgICA/IGNyZWF0ZVZOb2RlV2l0aEFyZ3NUcmFuc2Zvcm1cclxuICAgIDogX2NyZWF0ZVZOb2RlKTtcclxuZnVuY3Rpb24gX2NyZWF0ZVZOb2RlKHR5cGUsIHByb3BzID0gbnVsbCwgY2hpbGRyZW4gPSBudWxsLCBwYXRjaEZsYWcgPSAwLCBkeW5hbWljUHJvcHMgPSBudWxsLCBpc0Jsb2NrTm9kZSA9IGZhbHNlKSB7XHJcbiAgICBpZiAoIXR5cGUgfHwgdHlwZSA9PT0gTlVMTF9EWU5BTUlDX0NPTVBPTkVOVCkge1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIXR5cGUpIHtcclxuICAgICAgICAgICAgd2FybihgSW52YWxpZCB2bm9kZSB0eXBlIHdoZW4gY3JlYXRpbmcgdm5vZGU6ICR7dHlwZX0uYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHR5cGUgPSBDb21tZW50O1xyXG4gICAgfVxyXG4gICAgaWYgKGlzVk5vZGUodHlwZSkpIHtcclxuICAgICAgICBjb25zdCBjbG9uZWQgPSBjbG9uZVZOb2RlKHR5cGUsIHByb3BzKTtcclxuICAgICAgICBpZiAoY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgbm9ybWFsaXplQ2hpbGRyZW4oY2xvbmVkLCBjaGlsZHJlbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjbG9uZWQ7XHJcbiAgICB9XHJcbiAgICAvLyBjbGFzcyBjb21wb25lbnQgbm9ybWFsaXphdGlvbi5cclxuICAgIGlmIChpc0Z1bmN0aW9uKHR5cGUpICYmICdfX3ZjY09wdHMnIGluIHR5cGUpIHtcclxuICAgICAgICB0eXBlID0gdHlwZS5fX3ZjY09wdHM7XHJcbiAgICB9XHJcbiAgICAvLyBjbGFzcyAmIHN0eWxlIG5vcm1hbGl6YXRpb24uXHJcbiAgICBpZiAocHJvcHMpIHtcclxuICAgICAgICAvLyBmb3IgcmVhY3RpdmUgb3IgcHJveHkgb2JqZWN0cywgd2UgbmVlZCB0byBjbG9uZSBpdCB0byBlbmFibGUgbXV0YXRpb24uXHJcbiAgICAgICAgaWYgKGlzUHJveHkocHJvcHMpIHx8IEludGVybmFsT2JqZWN0S2V5IGluIHByb3BzKSB7XHJcbiAgICAgICAgICAgIHByb3BzID0gZXh0ZW5kKHt9LCBwcm9wcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCB7IGNsYXNzOiBrbGFzcywgc3R5bGUgfSA9IHByb3BzO1xyXG4gICAgICAgIGlmIChrbGFzcyAmJiAhaXNTdHJpbmcoa2xhc3MpKSB7XHJcbiAgICAgICAgICAgIHByb3BzLmNsYXNzID0gbm9ybWFsaXplQ2xhc3Moa2xhc3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNPYmplY3Qoc3R5bGUpKSB7XHJcbiAgICAgICAgICAgIC8vIHJlYWN0aXZlIHN0YXRlIG9iamVjdHMgbmVlZCB0byBiZSBjbG9uZWQgc2luY2UgdGhleSBhcmUgbGlrZWx5IHRvIGJlXHJcbiAgICAgICAgICAgIC8vIG11dGF0ZWRcclxuICAgICAgICAgICAgaWYgKGlzUHJveHkoc3R5bGUpICYmICFpc0FycmF5KHN0eWxlKSkge1xyXG4gICAgICAgICAgICAgICAgc3R5bGUgPSBleHRlbmQoe30sIHN0eWxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwcm9wcy5zdHlsZSA9IG5vcm1hbGl6ZVN0eWxlKHN0eWxlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBlbmNvZGUgdGhlIHZub2RlIHR5cGUgaW5mb3JtYXRpb24gaW50byBhIGJpdG1hcFxyXG4gICAgY29uc3Qgc2hhcGVGbGFnID0gaXNTdHJpbmcodHlwZSlcclxuICAgICAgICA/IDEgLyogRUxFTUVOVCAqL1xyXG4gICAgICAgIDogIGlzU3VzcGVuc2UodHlwZSlcclxuICAgICAgICAgICAgPyAxMjggLyogU1VTUEVOU0UgKi9cclxuICAgICAgICAgICAgOiBpc1RlbGVwb3J0KHR5cGUpXHJcbiAgICAgICAgICAgICAgICA/IDY0IC8qIFRFTEVQT1JUICovXHJcbiAgICAgICAgICAgICAgICA6IGlzT2JqZWN0KHR5cGUpXHJcbiAgICAgICAgICAgICAgICAgICAgPyA0IC8qIFNUQVRFRlVMX0NPTVBPTkVOVCAqL1xyXG4gICAgICAgICAgICAgICAgICAgIDogaXNGdW5jdGlvbih0eXBlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IDIgLyogRlVOQ1RJT05BTF9DT01QT05FTlQgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgOiAwO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBzaGFwZUZsYWcgJiA0IC8qIFNUQVRFRlVMX0NPTVBPTkVOVCAqLyAmJiBpc1Byb3h5KHR5cGUpKSB7XHJcbiAgICAgICAgdHlwZSA9IHRvUmF3KHR5cGUpO1xyXG4gICAgICAgIHdhcm4oYFZ1ZSByZWNlaXZlZCBhIENvbXBvbmVudCB3aGljaCB3YXMgbWFkZSBhIHJlYWN0aXZlIG9iamVjdC4gVGhpcyBjYW4gYCArXHJcbiAgICAgICAgICAgIGBsZWFkIHRvIHVubmVjZXNzYXJ5IHBlcmZvcm1hbmNlIG92ZXJoZWFkLCBhbmQgc2hvdWxkIGJlIGF2b2lkZWQgYnkgYCArXHJcbiAgICAgICAgICAgIGBtYXJraW5nIHRoZSBjb21wb25lbnQgd2l0aCBcXGBtYXJrUmF3XFxgIG9yIHVzaW5nIFxcYHNoYWxsb3dSZWZcXGAgYCArXHJcbiAgICAgICAgICAgIGBpbnN0ZWFkIG9mIFxcYHJlZlxcYC5gLCBgXFxuQ29tcG9uZW50IHRoYXQgd2FzIG1hZGUgcmVhY3RpdmU6IGAsIHR5cGUpO1xyXG4gICAgfVxyXG4gICAgY29uc3Qgdm5vZGUgPSB7XHJcbiAgICAgICAgX192X2lzVk5vZGU6IHRydWUsXHJcbiAgICAgICAgW1wiX192X3NraXBcIiAvKiBTS0lQICovXTogdHJ1ZSxcclxuICAgICAgICB0eXBlLFxyXG4gICAgICAgIHByb3BzLFxyXG4gICAgICAgIGtleTogcHJvcHMgJiYgbm9ybWFsaXplS2V5KHByb3BzKSxcclxuICAgICAgICByZWY6IHByb3BzICYmIG5vcm1hbGl6ZVJlZihwcm9wcyksXHJcbiAgICAgICAgc2NvcGVJZDogY3VycmVudFNjb3BlSWQsXHJcbiAgICAgICAgY2hpbGRyZW46IG51bGwsXHJcbiAgICAgICAgY29tcG9uZW50OiBudWxsLFxyXG4gICAgICAgIHN1c3BlbnNlOiBudWxsLFxyXG4gICAgICAgIGRpcnM6IG51bGwsXHJcbiAgICAgICAgdHJhbnNpdGlvbjogbnVsbCxcclxuICAgICAgICBlbDogbnVsbCxcclxuICAgICAgICBhbmNob3I6IG51bGwsXHJcbiAgICAgICAgdGFyZ2V0OiBudWxsLFxyXG4gICAgICAgIHRhcmdldEFuY2hvcjogbnVsbCxcclxuICAgICAgICBzdGF0aWNDb3VudDogMCxcclxuICAgICAgICBzaGFwZUZsYWcsXHJcbiAgICAgICAgcGF0Y2hGbGFnLFxyXG4gICAgICAgIGR5bmFtaWNQcm9wcyxcclxuICAgICAgICBkeW5hbWljQ2hpbGRyZW46IG51bGwsXHJcbiAgICAgICAgYXBwQ29udGV4dDogbnVsbFxyXG4gICAgfTtcclxuICAgIC8vIHZhbGlkYXRlIGtleVxyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB2bm9kZS5rZXkgIT09IHZub2RlLmtleSkge1xyXG4gICAgICAgIHdhcm4oYFZOb2RlIGNyZWF0ZWQgd2l0aCBpbnZhbGlkIGtleSAoTmFOKS4gVk5vZGUgdHlwZTpgLCB2bm9kZS50eXBlKTtcclxuICAgIH1cclxuICAgIG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlLCBjaGlsZHJlbik7XHJcbiAgICBpZiAoc2hvdWxkVHJhY2sgPiAwICYmXHJcbiAgICAgICAgLy8gYXZvaWQgYSBibG9jayBub2RlIGZyb20gdHJhY2tpbmcgaXRzZWxmXHJcbiAgICAgICAgIWlzQmxvY2tOb2RlICYmXHJcbiAgICAgICAgLy8gaGFzIGN1cnJlbnQgcGFyZW50IGJsb2NrXHJcbiAgICAgICAgY3VycmVudEJsb2NrICYmXHJcbiAgICAgICAgLy8gcHJlc2VuY2Ugb2YgYSBwYXRjaCBmbGFnIGluZGljYXRlcyB0aGlzIG5vZGUgbmVlZHMgcGF0Y2hpbmcgb24gdXBkYXRlcy5cclxuICAgICAgICAvLyBjb21wb25lbnQgbm9kZXMgYWxzbyBzaG91bGQgYWx3YXlzIGJlIHBhdGNoZWQsIGJlY2F1c2UgZXZlbiBpZiB0aGVcclxuICAgICAgICAvLyBjb21wb25lbnQgZG9lc24ndCBuZWVkIHRvIHVwZGF0ZSwgaXQgbmVlZHMgdG8gcGVyc2lzdCB0aGUgaW5zdGFuY2Ugb24gdG9cclxuICAgICAgICAvLyB0aGUgbmV4dCB2bm9kZSBzbyB0aGF0IGl0IGNhbiBiZSBwcm9wZXJseSB1bm1vdW50ZWQgbGF0ZXIuXHJcbiAgICAgICAgKHBhdGNoRmxhZyA+IDAgfHwgc2hhcGVGbGFnICYgNiAvKiBDT01QT05FTlQgKi8pICYmXHJcbiAgICAgICAgLy8gdGhlIEVWRU5UUyBmbGFnIGlzIG9ubHkgZm9yIGh5ZHJhdGlvbiBhbmQgaWYgaXQgaXMgdGhlIG9ubHkgZmxhZywgdGhlXHJcbiAgICAgICAgLy8gdm5vZGUgc2hvdWxkIG5vdCBiZSBjb25zaWRlcmVkIGR5bmFtaWMgZHVlIHRvIGhhbmRsZXIgY2FjaGluZy5cclxuICAgICAgICBwYXRjaEZsYWcgIT09IDMyIC8qIEhZRFJBVEVfRVZFTlRTICovKSB7XHJcbiAgICAgICAgY3VycmVudEJsb2NrLnB1c2godm5vZGUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZub2RlO1xyXG59XHJcbmZ1bmN0aW9uIGNsb25lVk5vZGUodm5vZGUsIGV4dHJhUHJvcHMpIHtcclxuICAgIC8vIFRoaXMgaXMgaW50ZW50aW9uYWxseSBOT1QgdXNpbmcgc3ByZWFkIG9yIGV4dGVuZCB0byBhdm9pZCB0aGUgcnVudGltZVxyXG4gICAgLy8ga2V5IGVudW1lcmF0aW9uIGNvc3QuXHJcbiAgICBjb25zdCB7IHByb3BzLCBwYXRjaEZsYWcgfSA9IHZub2RlO1xyXG4gICAgY29uc3QgbWVyZ2VkUHJvcHMgPSBleHRyYVByb3BzID8gbWVyZ2VQcm9wcyhwcm9wcyB8fCB7fSwgZXh0cmFQcm9wcykgOiBwcm9wcztcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgX192X2lzVk5vZGU6IHRydWUsXHJcbiAgICAgICAgW1wiX192X3NraXBcIiAvKiBTS0lQICovXTogdHJ1ZSxcclxuICAgICAgICB0eXBlOiB2bm9kZS50eXBlLFxyXG4gICAgICAgIHByb3BzOiBtZXJnZWRQcm9wcyxcclxuICAgICAgICBrZXk6IG1lcmdlZFByb3BzICYmIG5vcm1hbGl6ZUtleShtZXJnZWRQcm9wcyksXHJcbiAgICAgICAgcmVmOiBleHRyYVByb3BzICYmIGV4dHJhUHJvcHMucmVmID8gbm9ybWFsaXplUmVmKGV4dHJhUHJvcHMpIDogdm5vZGUucmVmLFxyXG4gICAgICAgIHNjb3BlSWQ6IHZub2RlLnNjb3BlSWQsXHJcbiAgICAgICAgY2hpbGRyZW46IHZub2RlLmNoaWxkcmVuLFxyXG4gICAgICAgIHRhcmdldDogdm5vZGUudGFyZ2V0LFxyXG4gICAgICAgIHRhcmdldEFuY2hvcjogdm5vZGUudGFyZ2V0QW5jaG9yLFxyXG4gICAgICAgIHN0YXRpY0NvdW50OiB2bm9kZS5zdGF0aWNDb3VudCxcclxuICAgICAgICBzaGFwZUZsYWc6IHZub2RlLnNoYXBlRmxhZyxcclxuICAgICAgICAvLyBpZiB0aGUgdm5vZGUgaXMgY2xvbmVkIHdpdGggZXh0cmEgcHJvcHMsIHdlIGNhbiBubyBsb25nZXIgYXNzdW1lIGl0c1xyXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhdGNoIGZsYWcgdG8gYmUgcmVsaWFibGUgYW5kIG5lZWQgdG8gYWRkIHRoZSBGVUxMX1BST1BTIGZsYWcuXHJcbiAgICAgICAgLy8gbm90ZTogcGVyc2VydmUgZmxhZyBmb3IgZnJhZ21lbnRzIHNpbmNlIHRoZXkgdXNlIHRoZSBmbGFnIGZvciBjaGlsZHJlblxyXG4gICAgICAgIC8vIGZhc3QgcGF0aHMgb25seS5cclxuICAgICAgICBwYXRjaEZsYWc6IGV4dHJhUHJvcHMgJiYgdm5vZGUudHlwZSAhPT0gRnJhZ21lbnRcclxuICAgICAgICAgICAgPyBwYXRjaEZsYWcgPT09IC0xIC8vIGhvaXN0ZWQgbm9kZVxyXG4gICAgICAgICAgICAgICAgPyAxNiAvKiBGVUxMX1BST1BTICovXHJcbiAgICAgICAgICAgICAgICA6IHBhdGNoRmxhZyB8IDE2IC8qIEZVTExfUFJPUFMgKi9cclxuICAgICAgICAgICAgOiBwYXRjaEZsYWcsXHJcbiAgICAgICAgZHluYW1pY1Byb3BzOiB2bm9kZS5keW5hbWljUHJvcHMsXHJcbiAgICAgICAgZHluYW1pY0NoaWxkcmVuOiB2bm9kZS5keW5hbWljQ2hpbGRyZW4sXHJcbiAgICAgICAgYXBwQ29udGV4dDogdm5vZGUuYXBwQ29udGV4dCxcclxuICAgICAgICBkaXJzOiB2bm9kZS5kaXJzLFxyXG4gICAgICAgIHRyYW5zaXRpb246IHZub2RlLnRyYW5zaXRpb24sXHJcbiAgICAgICAgLy8gVGhlc2Ugc2hvdWxkIHRlY2huaWNhbGx5IG9ubHkgYmUgbm9uLW51bGwgb24gbW91bnRlZCBWTm9kZXMuIEhvd2V2ZXIsXHJcbiAgICAgICAgLy8gdGhleSAqc2hvdWxkKiBiZSBjb3BpZWQgZm9yIGtlcHQtYWxpdmUgdm5vZGVzLiBTbyB3ZSBqdXN0IGFsd2F5cyBjb3B5XHJcbiAgICAgICAgLy8gdGhlbSBzaW5jZSB0aGVtIGJlaW5nIG5vbi1udWxsIGR1cmluZyBhIG1vdW50IGRvZXNuJ3QgYWZmZWN0IHRoZSBsb2dpYyBhc1xyXG4gICAgICAgIC8vIHRoZXkgd2lsbCBzaW1wbHkgYmUgb3ZlcndyaXR0ZW4uXHJcbiAgICAgICAgY29tcG9uZW50OiB2bm9kZS5jb21wb25lbnQsXHJcbiAgICAgICAgc3VzcGVuc2U6IHZub2RlLnN1c3BlbnNlLFxyXG4gICAgICAgIGVsOiB2bm9kZS5lbCxcclxuICAgICAgICBhbmNob3I6IHZub2RlLmFuY2hvclxyXG4gICAgfTtcclxufVxyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVRleHRWTm9kZSh0ZXh0ID0gJyAnLCBmbGFnID0gMCkge1xyXG4gICAgcmV0dXJuIGNyZWF0ZVZOb2RlKFRleHQsIG51bGwsIHRleHQsIGZsYWcpO1xyXG59XHJcbi8qKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlU3RhdGljVk5vZGUoY29udGVudCwgbnVtYmVyT2ZOb2Rlcykge1xyXG4gICAgLy8gQSBzdGF0aWMgdm5vZGUgY2FuIGNvbnRhaW4gbXVsdGlwbGUgc3RyaW5naWZpZWQgZWxlbWVudHMsIGFuZCB0aGUgbnVtYmVyXHJcbiAgICAvLyBvZiBlbGVtZW50cyBpcyBuZWNlc3NhcnkgZm9yIGh5ZHJhdGlvbi5cclxuICAgIGNvbnN0IHZub2RlID0gY3JlYXRlVk5vZGUoU3RhdGljLCBudWxsLCBjb250ZW50KTtcclxuICAgIHZub2RlLnN0YXRpY0NvdW50ID0gbnVtYmVyT2ZOb2RlcztcclxuICAgIHJldHVybiB2bm9kZTtcclxufVxyXG4vKipcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUNvbW1lbnRWTm9kZSh0ZXh0ID0gJycsIFxyXG4vLyB3aGVuIHVzZWQgYXMgdGhlIHYtZWxzZSBicmFuY2gsIHRoZSBjb21tZW50IG5vZGUgbXVzdCBiZSBjcmVhdGVkIGFzIGFcclxuLy8gYmxvY2sgdG8gZW5zdXJlIGNvcnJlY3QgdXBkYXRlcy5cclxuYXNCbG9jayA9IGZhbHNlKSB7XHJcbiAgICByZXR1cm4gYXNCbG9ja1xyXG4gICAgICAgID8gKG9wZW5CbG9jaygpLCBjcmVhdGVCbG9jayhDb21tZW50LCBudWxsLCB0ZXh0KSlcclxuICAgICAgICA6IGNyZWF0ZVZOb2RlKENvbW1lbnQsIG51bGwsIHRleHQpO1xyXG59XHJcbmZ1bmN0aW9uIG5vcm1hbGl6ZVZOb2RlKGNoaWxkKSB7XHJcbiAgICBpZiAoY2hpbGQgPT0gbnVsbCB8fCB0eXBlb2YgY2hpbGQgPT09ICdib29sZWFuJykge1xyXG4gICAgICAgIC8vIGVtcHR5IHBsYWNlaG9sZGVyXHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZVZOb2RlKENvbW1lbnQpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNBcnJheShjaGlsZCkpIHtcclxuICAgICAgICAvLyBmcmFnbWVudFxyXG4gICAgICAgIHJldHVybiBjcmVhdGVWTm9kZShGcmFnbWVudCwgbnVsbCwgY2hpbGQpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodHlwZW9mIGNoaWxkID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIC8vIGFscmVhZHkgdm5vZGUsIHRoaXMgc2hvdWxkIGJlIHRoZSBtb3N0IGNvbW1vbiBzaW5jZSBjb21waWxlZCB0ZW1wbGF0ZXNcclxuICAgICAgICAvLyBhbHdheXMgcHJvZHVjZSBhbGwtdm5vZGUgY2hpbGRyZW4gYXJyYXlzXHJcbiAgICAgICAgcmV0dXJuIGNoaWxkLmVsID09PSBudWxsID8gY2hpbGQgOiBjbG9uZVZOb2RlKGNoaWxkKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIHN0cmluZ3MgYW5kIG51bWJlcnNcclxuICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUoVGV4dCwgbnVsbCwgU3RyaW5nKGNoaWxkKSk7XHJcbiAgICB9XHJcbn1cclxuLy8gb3B0aW1pemVkIG5vcm1hbGl6YXRpb24gZm9yIHRlbXBsYXRlLWNvbXBpbGVkIHJlbmRlciBmbnNcclxuZnVuY3Rpb24gY2xvbmVJZk1vdW50ZWQoY2hpbGQpIHtcclxuICAgIHJldHVybiBjaGlsZC5lbCA9PT0gbnVsbCA/IGNoaWxkIDogY2xvbmVWTm9kZShjaGlsZCk7XHJcbn1cclxuZnVuY3Rpb24gbm9ybWFsaXplQ2hpbGRyZW4odm5vZGUsIGNoaWxkcmVuKSB7XHJcbiAgICBsZXQgdHlwZSA9IDA7XHJcbiAgICBjb25zdCB7IHNoYXBlRmxhZyB9ID0gdm5vZGU7XHJcbiAgICBpZiAoY2hpbGRyZW4gPT0gbnVsbCkge1xyXG4gICAgICAgIGNoaWxkcmVuID0gbnVsbDtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzQXJyYXkoY2hpbGRyZW4pKSB7XHJcbiAgICAgICAgdHlwZSA9IDE2IC8qIEFSUkFZX0NISUxEUkVOICovO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodHlwZW9mIGNoaWxkcmVuID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgIGlmIChzaGFwZUZsYWcgJiAxIC8qIEVMRU1FTlQgKi8gfHwgc2hhcGVGbGFnICYgNjQgLyogVEVMRVBPUlQgKi8pIHtcclxuICAgICAgICAgICAgLy8gTm9ybWFsaXplIHNsb3QgdG8gcGxhaW4gY2hpbGRyZW4gZm9yIHBsYWluIGVsZW1lbnQgYW5kIFRlbGVwb3J0XHJcbiAgICAgICAgICAgIGNvbnN0IHNsb3QgPSBjaGlsZHJlbi5kZWZhdWx0O1xyXG4gICAgICAgICAgICBpZiAoc2xvdCkge1xyXG4gICAgICAgICAgICAgICAgLy8gX2MgbWFya2VyIGlzIGFkZGVkIGJ5IHdpdGhDdHgoKSBpbmRpY2F0aW5nIHRoaXMgaXMgYSBjb21waWxlZCBzbG90XHJcbiAgICAgICAgICAgICAgICBzbG90Ll9jICYmIHNldENvbXBpbGVkU2xvdFJlbmRlcmluZygxKTtcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZUNoaWxkcmVuKHZub2RlLCBzbG90KCkpO1xyXG4gICAgICAgICAgICAgICAgc2xvdC5fYyAmJiBzZXRDb21waWxlZFNsb3RSZW5kZXJpbmcoLTEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHR5cGUgPSAzMiAvKiBTTE9UU19DSElMRFJFTiAqLztcclxuICAgICAgICAgICAgY29uc3Qgc2xvdEZsYWcgPSBjaGlsZHJlbi5fO1xyXG4gICAgICAgICAgICBpZiAoIXNsb3RGbGFnICYmICEoSW50ZXJuYWxPYmplY3RLZXkgaW4gY2hpbGRyZW4pKSB7XHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5fY3R4ID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHNsb3RGbGFnID09PSAzIC8qIEZPUldBUkRFRCAqLyAmJiBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2UpIHtcclxuICAgICAgICAgICAgICAgIC8vIGEgY2hpbGQgY29tcG9uZW50IHJlY2VpdmVzIGZvcndhcmRlZCBzbG90cyBmcm9tIHRoZSBwYXJlbnQuXHJcbiAgICAgICAgICAgICAgICAvLyBpdHMgc2xvdCB0eXBlIGlzIGRldGVybWluZWQgYnkgaXRzIHBhcmVudCdzIHNsb3QgdHlwZS5cclxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2Uudm5vZGUucGF0Y2hGbGFnICYgMTAyNCAvKiBEWU5BTUlDX1NMT1RTICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4uXyA9IDIgLyogRFlOQU1JQyAqLztcclxuICAgICAgICAgICAgICAgICAgICB2bm9kZS5wYXRjaEZsYWcgfD0gMTAyNCAvKiBEWU5BTUlDX1NMT1RTICovO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4uXyA9IDEgLyogU1RBQkxFICovO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNGdW5jdGlvbihjaGlsZHJlbikpIHtcclxuICAgICAgICBjaGlsZHJlbiA9IHsgZGVmYXVsdDogY2hpbGRyZW4sIF9jdHg6IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZSB9O1xyXG4gICAgICAgIHR5cGUgPSAzMiAvKiBTTE9UU19DSElMRFJFTiAqLztcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGNoaWxkcmVuID0gU3RyaW5nKGNoaWxkcmVuKTtcclxuICAgICAgICAvLyBmb3JjZSB0ZWxlcG9ydCBjaGlsZHJlbiB0byBhcnJheSBzbyBpdCBjYW4gYmUgbW92ZWQgYXJvdW5kXHJcbiAgICAgICAgaWYgKHNoYXBlRmxhZyAmIDY0IC8qIFRFTEVQT1JUICovKSB7XHJcbiAgICAgICAgICAgIHR5cGUgPSAxNiAvKiBBUlJBWV9DSElMRFJFTiAqLztcclxuICAgICAgICAgICAgY2hpbGRyZW4gPSBbY3JlYXRlVGV4dFZOb2RlKGNoaWxkcmVuKV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0eXBlID0gOCAvKiBURVhUX0NISUxEUkVOICovO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHZub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47XHJcbiAgICB2bm9kZS5zaGFwZUZsYWcgfD0gdHlwZTtcclxufVxyXG5mdW5jdGlvbiBtZXJnZVByb3BzKC4uLmFyZ3MpIHtcclxuICAgIGNvbnN0IHJldCA9IGV4dGVuZCh7fSwgYXJnc1swXSk7XHJcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCB0b01lcmdlID0gYXJnc1tpXTtcclxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiB0b01lcmdlKSB7XHJcbiAgICAgICAgICAgIGlmIChrZXkgPT09ICdjbGFzcycpIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZXQuY2xhc3MgIT09IHRvTWVyZ2UuY2xhc3MpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXQuY2xhc3MgPSBub3JtYWxpemVDbGFzcyhbcmV0LmNsYXNzLCB0b01lcmdlLmNsYXNzXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoa2V5ID09PSAnc3R5bGUnKSB7XHJcbiAgICAgICAgICAgICAgICByZXQuc3R5bGUgPSBub3JtYWxpemVTdHlsZShbcmV0LnN0eWxlLCB0b01lcmdlLnN0eWxlXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoaXNPbihrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZyA9IHJldFtrZXldO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaW5jb21pbmcgPSB0b01lcmdlW2tleV07XHJcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmcgIT09IGluY29taW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0W2tleV0gPSBleGlzdGluZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFtdLmNvbmNhdChleGlzdGluZywgdG9NZXJnZVtrZXldKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGluY29taW5nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0W2tleV0gPSB0b01lcmdlW2tleV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmV0O1xyXG59XG5cbmxldCBkZXZ0b29scztcclxuZnVuY3Rpb24gc2V0RGV2dG9vbHNIb29rKGhvb2spIHtcclxuICAgIGRldnRvb2xzID0gaG9vaztcclxufVxyXG5mdW5jdGlvbiBkZXZ0b29sc0luaXRBcHAoYXBwLCB2ZXJzaW9uKSB7XHJcbiAgICAvLyBUT0RPIHF1ZXVlIGlmIGRldnRvb2xzIGlzIHVuZGVmaW5lZFxyXG4gICAgaWYgKCFkZXZ0b29scylcclxuICAgICAgICByZXR1cm47XHJcbiAgICBkZXZ0b29scy5lbWl0KFwiYXBwOmluaXRcIiAvKiBBUFBfSU5JVCAqLywgYXBwLCB2ZXJzaW9uLCB7XHJcbiAgICAgICAgRnJhZ21lbnQsXHJcbiAgICAgICAgVGV4dCxcclxuICAgICAgICBDb21tZW50LFxyXG4gICAgICAgIFN0YXRpY1xyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gZGV2dG9vbHNVbm1vdW50QXBwKGFwcCkge1xyXG4gICAgaWYgKCFkZXZ0b29scylcclxuICAgICAgICByZXR1cm47XHJcbiAgICBkZXZ0b29scy5lbWl0KFwiYXBwOnVubW91bnRcIiAvKiBBUFBfVU5NT1VOVCAqLywgYXBwKTtcclxufVxyXG5jb25zdCBkZXZ0b29sc0NvbXBvbmVudEFkZGVkID0gLyojX19QVVJFX18qLyBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soXCJjb21wb25lbnQ6YWRkZWRcIiAvKiBDT01QT05FTlRfQURERUQgKi8pO1xyXG5jb25zdCBkZXZ0b29sc0NvbXBvbmVudFVwZGF0ZWQgPSAvKiNfX1BVUkVfXyovIGNyZWF0ZURldnRvb2xzQ29tcG9uZW50SG9vayhcImNvbXBvbmVudDp1cGRhdGVkXCIgLyogQ09NUE9ORU5UX1VQREFURUQgKi8pO1xyXG5jb25zdCBkZXZ0b29sc0NvbXBvbmVudFJlbW92ZWQgPSAvKiNfX1BVUkVfXyovIGNyZWF0ZURldnRvb2xzQ29tcG9uZW50SG9vayhcImNvbXBvbmVudDpyZW1vdmVkXCIgLyogQ09NUE9ORU5UX1JFTU9WRUQgKi8pO1xyXG5mdW5jdGlvbiBjcmVhdGVEZXZ0b29sc0NvbXBvbmVudEhvb2soaG9vaykge1xyXG4gICAgcmV0dXJuIChjb21wb25lbnQpID0+IHtcclxuICAgICAgICBpZiAoIWRldnRvb2xzKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgZGV2dG9vbHMuZW1pdChob29rLCBjb21wb25lbnQuYXBwQ29udGV4dC5hcHAsIGNvbXBvbmVudC51aWQsIGNvbXBvbmVudC5wYXJlbnQgPyBjb21wb25lbnQucGFyZW50LnVpZCA6IHVuZGVmaW5lZCk7XHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIGRldnRvb2xzQ29tcG9uZW50RW1pdChjb21wb25lbnQsIGV2ZW50LCBwYXJhbXMpIHtcclxuICAgIGlmICghZGV2dG9vbHMpXHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgZGV2dG9vbHMuZW1pdChcImNvbXBvbmVudDplbWl0XCIgLyogQ09NUE9ORU5UX0VNSVQgKi8sIGNvbXBvbmVudC5hcHBDb250ZXh0LmFwcCwgY29tcG9uZW50LCBldmVudCwgcGFyYW1zKTtcclxufVxuXG5mdW5jdGlvbiBlbWl0KGluc3RhbmNlLCBldmVudCwgLi4uYXJncykge1xyXG4gICAgY29uc3QgcHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wcyB8fCBFTVBUWV9PQko7XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgY29uc3QgeyBlbWl0c09wdGlvbnMsIHByb3BzT3B0aW9uczogW3Byb3BzT3B0aW9uc10gfSA9IGluc3RhbmNlO1xyXG4gICAgICAgIGlmIChlbWl0c09wdGlvbnMpIHtcclxuICAgICAgICAgICAgaWYgKCEoZXZlbnQgaW4gZW1pdHNPcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFwcm9wc09wdGlvbnMgfHwgIShgb25gICsgY2FwaXRhbGl6ZShldmVudCkgaW4gcHJvcHNPcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBlbWl0dGVkIGV2ZW50IFwiJHtldmVudH1cIiBidXQgaXQgaXMgbmVpdGhlciBkZWNsYXJlZCBpbiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYHRoZSBlbWl0cyBvcHRpb24gbm9yIGFzIGFuIFwib24ke2NhcGl0YWxpemUoZXZlbnQpfVwiIHByb3AuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0b3IgPSBlbWl0c09wdGlvbnNbZXZlbnRdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24odmFsaWRhdG9yKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzVmFsaWQgPSB2YWxpZGF0b3IoLi4uYXJncyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4oYEludmFsaWQgZXZlbnQgYXJndW1lbnRzOiBldmVudCB2YWxpZGF0aW9uIGZhaWxlZCBmb3IgZXZlbnQgXCIke2V2ZW50fVwiLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSB7XHJcbiAgICAgICAgZGV2dG9vbHNDb21wb25lbnRFbWl0KGluc3RhbmNlLCBldmVudCwgYXJncyk7XHJcbiAgICB9XHJcbiAgICBsZXQgaGFuZGxlck5hbWUgPSBgb24ke2NhcGl0YWxpemUoZXZlbnQpfWA7XHJcbiAgICBsZXQgaGFuZGxlciA9IHByb3BzW2hhbmRsZXJOYW1lXTtcclxuICAgIC8vIGZvciB2LW1vZGVsIHVwZGF0ZTp4eHggZXZlbnRzLCBhbHNvIHRyaWdnZXIga2ViYWItY2FzZSBlcXVpdmFsZW50XHJcbiAgICAvLyBmb3IgcHJvcHMgcGFzc2VkIHZpYSBrZWJhYi1jYXNlXHJcbiAgICBpZiAoIWhhbmRsZXIgJiYgZXZlbnQuc3RhcnRzV2l0aCgndXBkYXRlOicpKSB7XHJcbiAgICAgICAgaGFuZGxlck5hbWUgPSBgb24ke2NhcGl0YWxpemUoaHlwaGVuYXRlKGV2ZW50KSl9YDtcclxuICAgICAgICBoYW5kbGVyID0gcHJvcHNbaGFuZGxlck5hbWVdO1xyXG4gICAgfVxyXG4gICAgaWYgKCFoYW5kbGVyKSB7XHJcbiAgICAgICAgaGFuZGxlciA9IHByb3BzW2hhbmRsZXJOYW1lICsgYE9uY2VgXTtcclxuICAgICAgICBpZiAoIWluc3RhbmNlLmVtaXR0ZWQpIHtcclxuICAgICAgICAgICAgKGluc3RhbmNlLmVtaXR0ZWQgPSB7fSlbaGFuZGxlck5hbWVdID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoaW5zdGFuY2UuZW1pdHRlZFtoYW5kbGVyTmFtZV0pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChoYW5kbGVyKSB7XHJcbiAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoaGFuZGxlciwgaW5zdGFuY2UsIDYgLyogQ09NUE9ORU5UX0VWRU5UX0hBTkRMRVIgKi8sIGFyZ3MpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyhjb21wLCBhcHBDb250ZXh0LCBhc01peGluID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IGFwcElkID0gYXBwQ29udGV4dC5hcHAgPyBhcHBDb250ZXh0LmFwcC5fdWlkIDogLTE7XHJcbiAgICBjb25zdCBjYWNoZSA9IGNvbXAuX19lbWl0cyB8fCAoY29tcC5fX2VtaXRzID0ge30pO1xyXG4gICAgY29uc3QgY2FjaGVkID0gY2FjaGVbYXBwSWRdO1xyXG4gICAgaWYgKGNhY2hlZCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgcmV0dXJuIGNhY2hlZDtcclxuICAgIH1cclxuICAgIGNvbnN0IHJhdyA9IGNvbXAuZW1pdHM7XHJcbiAgICBsZXQgbm9ybWFsaXplZCA9IHt9O1xyXG4gICAgLy8gYXBwbHkgbWl4aW4vZXh0ZW5kcyBwcm9wc1xyXG4gICAgbGV0IGhhc0V4dGVuZHMgPSBmYWxzZTtcclxuICAgIGlmIChfX1ZVRV9PUFRJT05TX0FQSV9fICYmICFpc0Z1bmN0aW9uKGNvbXApKSB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5kRW1pdHMgPSAocmF3KSA9PiB7XHJcbiAgICAgICAgICAgIGhhc0V4dGVuZHMgPSB0cnVlO1xyXG4gICAgICAgICAgICBleHRlbmQobm9ybWFsaXplZCwgbm9ybWFsaXplRW1pdHNPcHRpb25zKHJhdywgYXBwQ29udGV4dCwgdHJ1ZSkpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgaWYgKCFhc01peGluICYmIGFwcENvbnRleHQubWl4aW5zLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBhcHBDb250ZXh0Lm1peGlucy5mb3JFYWNoKGV4dGVuZEVtaXRzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNvbXAuZXh0ZW5kcykge1xyXG4gICAgICAgICAgICBleHRlbmRFbWl0cyhjb21wLmV4dGVuZHMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29tcC5taXhpbnMpIHtcclxuICAgICAgICAgICAgY29tcC5taXhpbnMuZm9yRWFjaChleHRlbmRFbWl0cyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKCFyYXcgJiYgIWhhc0V4dGVuZHMpIHtcclxuICAgICAgICByZXR1cm4gKGNhY2hlW2FwcElkXSA9IG51bGwpO1xyXG4gICAgfVxyXG4gICAgaWYgKGlzQXJyYXkocmF3KSkge1xyXG4gICAgICAgIHJhdy5mb3JFYWNoKGtleSA9PiAobm9ybWFsaXplZFtrZXldID0gbnVsbCkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgZXh0ZW5kKG5vcm1hbGl6ZWQsIHJhdyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gKGNhY2hlW2FwcElkXSA9IG5vcm1hbGl6ZWQpO1xyXG59XHJcbi8vIENoZWNrIGlmIGFuIGluY29taW5nIHByb3Aga2V5IGlzIGEgZGVjbGFyZWQgZW1pdCBldmVudCBsaXN0ZW5lci5cclxuLy8gZS5nLiBXaXRoIGBlbWl0czogeyBjbGljazogbnVsbCB9YCwgcHJvcHMgbmFtZWQgYG9uQ2xpY2tgIGFuZCBgb25jbGlja2AgYXJlXHJcbi8vIGJvdGggY29uc2lkZXJlZCBtYXRjaGVkIGxpc3RlbmVycy5cclxuZnVuY3Rpb24gaXNFbWl0TGlzdGVuZXIob3B0aW9ucywga2V5KSB7XHJcbiAgICBpZiAoIW9wdGlvbnMgfHwgIWlzT24oa2V5KSkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGtleSA9IGtleS5yZXBsYWNlKC9PbmNlJC8sICcnKTtcclxuICAgIHJldHVybiAoaGFzT3duKG9wdGlvbnMsIGtleVsyXS50b0xvd2VyQ2FzZSgpICsga2V5LnNsaWNlKDMpKSB8fFxyXG4gICAgICAgIGhhc093bihvcHRpb25zLCBrZXkuc2xpY2UoMikpKTtcclxufVxuXG5mdW5jdGlvbiBpbml0UHJvcHMoaW5zdGFuY2UsIHJhd1Byb3BzLCBpc1N0YXRlZnVsLCAvLyByZXN1bHQgb2YgYml0d2lzZSBmbGFnIGNvbXBhcmlzb25cclxuaXNTU1IgPSBmYWxzZSkge1xyXG4gICAgY29uc3QgcHJvcHMgPSB7fTtcclxuICAgIGNvbnN0IGF0dHJzID0ge307XHJcbiAgICBkZWYoYXR0cnMsIEludGVybmFsT2JqZWN0S2V5LCAxKTtcclxuICAgIHNldEZ1bGxQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHByb3BzLCBhdHRycyk7XHJcbiAgICAvLyB2YWxpZGF0aW9uXHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgdmFsaWRhdGVQcm9wcyhwcm9wcywgaW5zdGFuY2UpO1xyXG4gICAgfVxyXG4gICAgaWYgKGlzU3RhdGVmdWwpIHtcclxuICAgICAgICAvLyBzdGF0ZWZ1bFxyXG4gICAgICAgIGluc3RhbmNlLnByb3BzID0gaXNTU1IgPyBwcm9wcyA6IHNoYWxsb3dSZWFjdGl2ZShwcm9wcyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAoIWluc3RhbmNlLnR5cGUucHJvcHMpIHtcclxuICAgICAgICAgICAgLy8gZnVuY3Rpb25hbCB3LyBvcHRpb25hbCBwcm9wcywgcHJvcHMgPT09IGF0dHJzXHJcbiAgICAgICAgICAgIGluc3RhbmNlLnByb3BzID0gYXR0cnM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBmdW5jdGlvbmFsIHcvIGRlY2xhcmVkIHByb3BzXHJcbiAgICAgICAgICAgIGluc3RhbmNlLnByb3BzID0gcHJvcHM7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaW5zdGFuY2UuYXR0cnMgPSBhdHRycztcclxufVxyXG5mdW5jdGlvbiB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHJhd1ByZXZQcm9wcywgb3B0aW1pemVkKSB7XHJcbiAgICBjb25zdCB7IHByb3BzLCBhdHRycywgdm5vZGU6IHsgcGF0Y2hGbGFnIH0gfSA9IGluc3RhbmNlO1xyXG4gICAgY29uc3QgcmF3Q3VycmVudFByb3BzID0gdG9SYXcocHJvcHMpO1xyXG4gICAgY29uc3QgW29wdGlvbnNdID0gaW5zdGFuY2UucHJvcHNPcHRpb25zO1xyXG4gICAgaWYgKFxyXG4gICAgLy8gYWx3YXlzIGZvcmNlIGZ1bGwgZGlmZiBpZiBobXIgaXMgZW5hYmxlZFxyXG4gICAgISgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgaW5zdGFuY2UudHlwZS5fX2htcklkKSAmJlxyXG4gICAgICAgIChvcHRpbWl6ZWQgfHwgcGF0Y2hGbGFnID4gMCkgJiZcclxuICAgICAgICAhKHBhdGNoRmxhZyAmIDE2IC8qIEZVTExfUFJPUFMgKi8pKSB7XHJcbiAgICAgICAgaWYgKHBhdGNoRmxhZyAmIDggLyogUFJPUFMgKi8pIHtcclxuICAgICAgICAgICAgLy8gQ29tcGlsZXItZ2VuZXJhdGVkIHByb3BzICYgbm8ga2V5cyBjaGFuZ2UsIGp1c3Qgc2V0IHRoZSB1cGRhdGVkXHJcbiAgICAgICAgICAgIC8vIHRoZSBwcm9wcy5cclxuICAgICAgICAgICAgY29uc3QgcHJvcHNUb1VwZGF0ZSA9IGluc3RhbmNlLnZub2RlLmR5bmFtaWNQcm9wcztcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wc1RvVXBkYXRlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBwcm9wc1RvVXBkYXRlW2ldO1xyXG4gICAgICAgICAgICAgICAgLy8gUFJPUFMgZmxhZyBndWFyYW50ZWVzIHJhd1Byb3BzIHRvIGJlIG5vbi1udWxsXHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHJhd1Byb3BzW2tleV07XHJcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGF0dHIgLyBwcm9wcyBzZXBhcmF0aW9uIHdhcyBkb25lIG9uIGluaXQgYW5kIHdpbGwgYmUgY29uc2lzdGVudFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGluIHRoaXMgY29kZSBwYXRoLCBzbyBqdXN0IGNoZWNrIGlmIGF0dHJzIGhhdmUgaXQuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc093bihhdHRycywga2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyc1trZXldID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW1lbGl6ZWRLZXkgPSBjYW1lbGl6ZShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wc1tjYW1lbGl6ZWRLZXldID0gcmVzb2x2ZVByb3BWYWx1ZShvcHRpb25zLCByYXdDdXJyZW50UHJvcHMsIGNhbWVsaXplZEtleSwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJzW2tleV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIGZ1bGwgcHJvcHMgdXBkYXRlLlxyXG4gICAgICAgIHNldEZ1bGxQcm9wcyhpbnN0YW5jZSwgcmF3UHJvcHMsIHByb3BzLCBhdHRycyk7XHJcbiAgICAgICAgLy8gaW4gY2FzZSBvZiBkeW5hbWljIHByb3BzLCBjaGVjayBpZiB3ZSBuZWVkIHRvIGRlbGV0ZSBrZXlzIGZyb21cclxuICAgICAgICAvLyB0aGUgcHJvcHMgb2JqZWN0XHJcbiAgICAgICAgbGV0IGtlYmFiS2V5O1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJhd0N1cnJlbnRQcm9wcykge1xyXG4gICAgICAgICAgICBpZiAoIXJhd1Byb3BzIHx8XHJcbiAgICAgICAgICAgICAgICAvLyBmb3IgY2FtZWxDYXNlXHJcbiAgICAgICAgICAgICAgICAoIWhhc093bihyYXdQcm9wcywga2V5KSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGl0J3MgcG9zc2libGUgdGhlIG9yaWdpbmFsIHByb3BzIHdhcyBwYXNzZWQgaW4gYXMga2ViYWItY2FzZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFuZCBjb252ZXJ0ZWQgdG8gY2FtZWxDYXNlICgjOTU1KVxyXG4gICAgICAgICAgICAgICAgICAgICgoa2ViYWJLZXkgPSBoeXBoZW5hdGUoa2V5KSkgPT09IGtleSB8fCAhaGFzT3duKHJhd1Byb3BzLCBrZWJhYktleSkpKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmF3UHJldlByb3BzICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBjYW1lbENhc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHJhd1ByZXZQcm9wc1trZXldICE9PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvciBrZWJhYi1jYXNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdQcmV2UHJvcHNba2ViYWJLZXldICE9PSB1bmRlZmluZWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzW2tleV0gPSByZXNvbHZlUHJvcFZhbHVlKG9wdGlvbnMsIHJhd1Byb3BzIHx8IEVNUFRZX09CSiwga2V5LCB1bmRlZmluZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwcm9wc1trZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGluIHRoZSBjYXNlIG9mIGZ1bmN0aW9uYWwgY29tcG9uZW50IHcvbyBwcm9wcyBkZWNsYXJhdGlvbiwgcHJvcHMgYW5kXHJcbiAgICAgICAgLy8gYXR0cnMgcG9pbnQgdG8gdGhlIHNhbWUgb2JqZWN0IHNvIGl0IHNob3VsZCBhbHJlYWR5IGhhdmUgYmVlbiB1cGRhdGVkLlxyXG4gICAgICAgIGlmIChhdHRycyAhPT0gcmF3Q3VycmVudFByb3BzKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJhd1Byb3BzIHx8ICFoYXNPd24ocmF3UHJvcHMsIGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgYXR0cnNba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIHRyaWdnZXIgdXBkYXRlcyBmb3IgJGF0dHJzIGluIGNhc2UgaXQncyB1c2VkIGluIGNvbXBvbmVudCBzbG90c1xyXG4gICAgdHJpZ2dlcihpbnN0YW5jZSwgXCJzZXRcIiAvKiBTRVQgKi8sICckYXR0cnMnKTtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgcmF3UHJvcHMpIHtcclxuICAgICAgICB2YWxpZGF0ZVByb3BzKHByb3BzLCBpbnN0YW5jZSk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gc2V0RnVsbFByb3BzKGluc3RhbmNlLCByYXdQcm9wcywgcHJvcHMsIGF0dHJzKSB7XHJcbiAgICBjb25zdCBbb3B0aW9ucywgbmVlZENhc3RLZXlzXSA9IGluc3RhbmNlLnByb3BzT3B0aW9ucztcclxuICAgIGlmIChyYXdQcm9wcykge1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJhd1Byb3BzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gcmF3UHJvcHNba2V5XTtcclxuICAgICAgICAgICAgLy8ga2V5LCByZWYgYXJlIHJlc2VydmVkIGFuZCBuZXZlciBwYXNzZWQgZG93blxyXG4gICAgICAgICAgICBpZiAoaXNSZXNlcnZlZFByb3Aoa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcHJvcCBvcHRpb24gbmFtZXMgYXJlIGNhbWVsaXplZCBkdXJpbmcgbm9ybWFsaXphdGlvbiwgc28gdG8gc3VwcG9ydFxyXG4gICAgICAgICAgICAvLyBrZWJhYiAtPiBjYW1lbCBjb252ZXJzaW9uIGhlcmUgd2UgbmVlZCB0byBjYW1lbGl6ZSB0aGUga2V5LlxyXG4gICAgICAgICAgICBsZXQgY2FtZWxLZXk7XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zICYmIGhhc093bihvcHRpb25zLCAoY2FtZWxLZXkgPSBjYW1lbGl6ZShrZXkpKSkpIHtcclxuICAgICAgICAgICAgICAgIHByb3BzW2NhbWVsS2V5XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKCFpc0VtaXRMaXN0ZW5lcihpbnN0YW5jZS5lbWl0c09wdGlvbnMsIGtleSkpIHtcclxuICAgICAgICAgICAgICAgIC8vIEFueSBub24tZGVjbGFyZWQgKGVpdGhlciBhcyBhIHByb3Agb3IgYW4gZW1pdHRlZCBldmVudCkgcHJvcHMgYXJlIHB1dFxyXG4gICAgICAgICAgICAgICAgLy8gaW50byBhIHNlcGFyYXRlIGBhdHRyc2Agb2JqZWN0IGZvciBzcHJlYWRpbmcuIE1ha2Ugc3VyZSB0byBwcmVzZXJ2ZVxyXG4gICAgICAgICAgICAgICAgLy8gb3JpZ2luYWwga2V5IGNhc2luZ1xyXG4gICAgICAgICAgICAgICAgYXR0cnNba2V5XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKG5lZWRDYXN0S2V5cykge1xyXG4gICAgICAgIGNvbnN0IHJhd0N1cnJlbnRQcm9wcyA9IHRvUmF3KHByb3BzKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5lZWRDYXN0S2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBrZXkgPSBuZWVkQ2FzdEtleXNbaV07XHJcbiAgICAgICAgICAgIHByb3BzW2tleV0gPSByZXNvbHZlUHJvcFZhbHVlKG9wdGlvbnMsIHJhd0N1cnJlbnRQcm9wcywga2V5LCByYXdDdXJyZW50UHJvcHNba2V5XSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIHJlc29sdmVQcm9wVmFsdWUob3B0aW9ucywgcHJvcHMsIGtleSwgdmFsdWUpIHtcclxuICAgIGNvbnN0IG9wdCA9IG9wdGlvbnNba2V5XTtcclxuICAgIGlmIChvcHQgIT0gbnVsbCkge1xyXG4gICAgICAgIGNvbnN0IGhhc0RlZmF1bHQgPSBoYXNPd24ob3B0LCAnZGVmYXVsdCcpO1xyXG4gICAgICAgIC8vIGRlZmF1bHQgdmFsdWVzXHJcbiAgICAgICAgaWYgKGhhc0RlZmF1bHQgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBvcHQuZGVmYXVsdDtcclxuICAgICAgICAgICAgdmFsdWUgPVxyXG4gICAgICAgICAgICAgICAgb3B0LnR5cGUgIT09IEZ1bmN0aW9uICYmIGlzRnVuY3Rpb24oZGVmYXVsdFZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgID8gZGVmYXVsdFZhbHVlKHByb3BzKVxyXG4gICAgICAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBib29sZWFuIGNhc3RpbmdcclxuICAgICAgICBpZiAob3B0WzAgLyogc2hvdWxkQ2FzdCAqL10pIHtcclxuICAgICAgICAgICAgaWYgKCFoYXNPd24ocHJvcHMsIGtleSkgJiYgIWhhc0RlZmF1bHQpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAob3B0WzEgLyogc2hvdWxkQ2FzdFRydWUgKi9dICYmXHJcbiAgICAgICAgICAgICAgICAodmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSBoeXBoZW5hdGUoa2V5KSkpIHtcclxuICAgICAgICAgICAgICAgIHZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxufVxyXG5mdW5jdGlvbiBub3JtYWxpemVQcm9wc09wdGlvbnMoY29tcCwgYXBwQ29udGV4dCwgYXNNaXhpbiA9IGZhbHNlKSB7XHJcbiAgICBjb25zdCBhcHBJZCA9IGFwcENvbnRleHQuYXBwID8gYXBwQ29udGV4dC5hcHAuX3VpZCA6IC0xO1xyXG4gICAgY29uc3QgY2FjaGUgPSBjb21wLl9fcHJvcHMgfHwgKGNvbXAuX19wcm9wcyA9IHt9KTtcclxuICAgIGNvbnN0IGNhY2hlZCA9IGNhY2hlW2FwcElkXTtcclxuICAgIGlmIChjYWNoZWQpIHtcclxuICAgICAgICByZXR1cm4gY2FjaGVkO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmF3ID0gY29tcC5wcm9wcztcclxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fTtcclxuICAgIGNvbnN0IG5lZWRDYXN0S2V5cyA9IFtdO1xyXG4gICAgLy8gYXBwbHkgbWl4aW4vZXh0ZW5kcyBwcm9wc1xyXG4gICAgbGV0IGhhc0V4dGVuZHMgPSBmYWxzZTtcclxuICAgIGlmIChfX1ZVRV9PUFRJT05TX0FQSV9fICYmICFpc0Z1bmN0aW9uKGNvbXApKSB7XHJcbiAgICAgICAgY29uc3QgZXh0ZW5kUHJvcHMgPSAocmF3KSA9PiB7XHJcbiAgICAgICAgICAgIGhhc0V4dGVuZHMgPSB0cnVlO1xyXG4gICAgICAgICAgICBjb25zdCBbcHJvcHMsIGtleXNdID0gbm9ybWFsaXplUHJvcHNPcHRpb25zKHJhdywgYXBwQ29udGV4dCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGV4dGVuZChub3JtYWxpemVkLCBwcm9wcyk7XHJcbiAgICAgICAgICAgIGlmIChrZXlzKVxyXG4gICAgICAgICAgICAgICAgbmVlZENhc3RLZXlzLnB1c2goLi4ua2V5cyk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBpZiAoIWFzTWl4aW4gJiYgYXBwQ29udGV4dC5taXhpbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGFwcENvbnRleHQubWl4aW5zLmZvckVhY2goZXh0ZW5kUHJvcHMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29tcC5leHRlbmRzKSB7XHJcbiAgICAgICAgICAgIGV4dGVuZFByb3BzKGNvbXAuZXh0ZW5kcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjb21wLm1peGlucykge1xyXG4gICAgICAgICAgICBjb21wLm1peGlucy5mb3JFYWNoKGV4dGVuZFByb3BzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoIXJhdyAmJiAhaGFzRXh0ZW5kcykge1xyXG4gICAgICAgIHJldHVybiAoY2FjaGVbYXBwSWRdID0gRU1QVFlfQVJSKTtcclxuICAgIH1cclxuICAgIGlmIChpc0FycmF5KHJhdykpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFpc1N0cmluZyhyYXdbaV0pKSB7XHJcbiAgICAgICAgICAgICAgICB3YXJuKGBwcm9wcyBtdXN0IGJlIHN0cmluZ3Mgd2hlbiB1c2luZyBhcnJheSBzeW50YXguYCwgcmF3W2ldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0gY2FtZWxpemUocmF3W2ldKTtcclxuICAgICAgICAgICAgaWYgKHZhbGlkYXRlUHJvcE5hbWUobm9ybWFsaXplZEtleSkpIHtcclxuICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRbbm9ybWFsaXplZEtleV0gPSBFTVBUWV9PQko7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChyYXcpIHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFpc09iamVjdChyYXcpKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYGludmFsaWQgcHJvcHMgb3B0aW9uc2AsIHJhdyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJhdykge1xyXG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkS2V5ID0gY2FtZWxpemUoa2V5KTtcclxuICAgICAgICAgICAgaWYgKHZhbGlkYXRlUHJvcE5hbWUobm9ybWFsaXplZEtleSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9wdCA9IHJhd1trZXldO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcCA9IChub3JtYWxpemVkW25vcm1hbGl6ZWRLZXldID1cclxuICAgICAgICAgICAgICAgICAgICBpc0FycmF5KG9wdCkgfHwgaXNGdW5jdGlvbihvcHQpID8geyB0eXBlOiBvcHQgfSA6IG9wdCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJvcCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvb2xlYW5JbmRleCA9IGdldFR5cGVJbmRleChCb29sZWFuLCBwcm9wLnR5cGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZ0luZGV4ID0gZ2V0VHlwZUluZGV4KFN0cmluZywgcHJvcC50eXBlKTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9wWzAgLyogc2hvdWxkQ2FzdCAqL10gPSBib29sZWFuSW5kZXggPiAtMTtcclxuICAgICAgICAgICAgICAgICAgICBwcm9wWzEgLyogc2hvdWxkQ2FzdFRydWUgKi9dID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nSW5kZXggPCAwIHx8IGJvb2xlYW5JbmRleCA8IHN0cmluZ0luZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBwcm9wIG5lZWRzIGJvb2xlYW4gY2FzdGluZyBvciBkZWZhdWx0IHZhbHVlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJvb2xlYW5JbmRleCA+IC0xIHx8IGhhc093bihwcm9wLCAnZGVmYXVsdCcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRDYXN0S2V5cy5wdXNoKG5vcm1hbGl6ZWRLZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiAoY2FjaGVbYXBwSWRdID0gW25vcm1hbGl6ZWQsIG5lZWRDYXN0S2V5c10pO1xyXG59XHJcbi8vIHVzZSBmdW5jdGlvbiBzdHJpbmcgbmFtZSB0byBjaGVjayB0eXBlIGNvbnN0cnVjdG9yc1xyXG4vLyBzbyB0aGF0IGl0IHdvcmtzIGFjcm9zcyB2bXMgLyBpZnJhbWVzLlxyXG5mdW5jdGlvbiBnZXRUeXBlKGN0b3IpIHtcclxuICAgIGNvbnN0IG1hdGNoID0gY3RvciAmJiBjdG9yLnRvU3RyaW5nKCkubWF0Y2goL15cXHMqZnVuY3Rpb24gKFxcdyspLyk7XHJcbiAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6ICcnO1xyXG59XHJcbmZ1bmN0aW9uIGlzU2FtZVR5cGUoYSwgYikge1xyXG4gICAgcmV0dXJuIGdldFR5cGUoYSkgPT09IGdldFR5cGUoYik7XHJcbn1cclxuZnVuY3Rpb24gZ2V0VHlwZUluZGV4KHR5cGUsIGV4cGVjdGVkVHlwZXMpIHtcclxuICAgIGlmIChpc0FycmF5KGV4cGVjdGVkVHlwZXMpKSB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGV4cGVjdGVkVHlwZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGlzU2FtZVR5cGUoZXhwZWN0ZWRUeXBlc1tpXSwgdHlwZSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNGdW5jdGlvbihleHBlY3RlZFR5cGVzKSkge1xyXG4gICAgICAgIHJldHVybiBpc1NhbWVUeXBlKGV4cGVjdGVkVHlwZXMsIHR5cGUpID8gMCA6IC0xO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIC0xO1xyXG59XHJcbi8qKlxyXG4gKiBkZXYgb25seVxyXG4gKi9cclxuZnVuY3Rpb24gdmFsaWRhdGVQcm9wcyhwcm9wcywgaW5zdGFuY2UpIHtcclxuICAgIGNvbnN0IHJhd1ZhbHVlcyA9IHRvUmF3KHByb3BzKTtcclxuICAgIGNvbnN0IG9wdGlvbnMgPSBpbnN0YW5jZS5wcm9wc09wdGlvbnNbMF07XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvcHRpb25zKSB7XHJcbiAgICAgICAgbGV0IG9wdCA9IG9wdGlvbnNba2V5XTtcclxuICAgICAgICBpZiAob3B0ID09IG51bGwpXHJcbiAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIHZhbGlkYXRlUHJvcChrZXksIHJhd1ZhbHVlc1trZXldLCBvcHQsICFoYXNPd24ocmF3VmFsdWVzLCBrZXkpKTtcclxuICAgIH1cclxufVxyXG4vKipcclxuICogZGV2IG9ubHlcclxuICovXHJcbmZ1bmN0aW9uIHZhbGlkYXRlUHJvcE5hbWUoa2V5KSB7XHJcbiAgICBpZiAoa2V5WzBdICE9PSAnJCcpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIHdhcm4oYEludmFsaWQgcHJvcCBuYW1lOiBcIiR7a2V5fVwiIGlzIGEgcmVzZXJ2ZWQgcHJvcGVydHkuYCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuLyoqXHJcbiAqIGRldiBvbmx5XHJcbiAqL1xyXG5mdW5jdGlvbiB2YWxpZGF0ZVByb3AobmFtZSwgdmFsdWUsIHByb3AsIGlzQWJzZW50KSB7XHJcbiAgICBjb25zdCB7IHR5cGUsIHJlcXVpcmVkLCB2YWxpZGF0b3IgfSA9IHByb3A7XHJcbiAgICAvLyByZXF1aXJlZCFcclxuICAgIGlmIChyZXF1aXJlZCAmJiBpc0Fic2VudCkge1xyXG4gICAgICAgIHdhcm4oJ01pc3NpbmcgcmVxdWlyZWQgcHJvcDogXCInICsgbmFtZSArICdcIicpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIC8vIG1pc3NpbmcgYnV0IG9wdGlvbmFsXHJcbiAgICBpZiAodmFsdWUgPT0gbnVsbCAmJiAhcHJvcC5yZXF1aXJlZCkge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIC8vIHR5cGUgY2hlY2tcclxuICAgIGlmICh0eXBlICE9IG51bGwgJiYgdHlwZSAhPT0gdHJ1ZSkge1xyXG4gICAgICAgIGxldCBpc1ZhbGlkID0gZmFsc2U7XHJcbiAgICAgICAgY29uc3QgdHlwZXMgPSBpc0FycmF5KHR5cGUpID8gdHlwZSA6IFt0eXBlXTtcclxuICAgICAgICBjb25zdCBleHBlY3RlZFR5cGVzID0gW107XHJcbiAgICAgICAgLy8gdmFsdWUgaXMgdmFsaWQgYXMgbG9uZyBhcyBvbmUgb2YgdGhlIHNwZWNpZmllZCB0eXBlcyBtYXRjaFxyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoICYmICFpc1ZhbGlkOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgeyB2YWxpZCwgZXhwZWN0ZWRUeXBlIH0gPSBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlc1tpXSk7XHJcbiAgICAgICAgICAgIGV4cGVjdGVkVHlwZXMucHVzaChleHBlY3RlZFR5cGUgfHwgJycpO1xyXG4gICAgICAgICAgICBpc1ZhbGlkID0gdmFsaWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghaXNWYWxpZCkge1xyXG4gICAgICAgICAgICB3YXJuKGdldEludmFsaWRUeXBlTWVzc2FnZShuYW1lLCB2YWx1ZSwgZXhwZWN0ZWRUeXBlcykpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gY3VzdG9tIHZhbGlkYXRvclxyXG4gICAgaWYgKHZhbGlkYXRvciAmJiAhdmFsaWRhdG9yKHZhbHVlKSkge1xyXG4gICAgICAgIHdhcm4oJ0ludmFsaWQgcHJvcDogY3VzdG9tIHZhbGlkYXRvciBjaGVjayBmYWlsZWQgZm9yIHByb3AgXCInICsgbmFtZSArICdcIi4nKTtcclxuICAgIH1cclxufVxyXG5jb25zdCBpc1NpbXBsZVR5cGUgPSAvKiNfX1BVUkVfXyovIG1ha2VNYXAoJ1N0cmluZyxOdW1iZXIsQm9vbGVhbixGdW5jdGlvbixTeW1ib2wnKTtcclxuLyoqXHJcbiAqIGRldiBvbmx5XHJcbiAqL1xyXG5mdW5jdGlvbiBhc3NlcnRUeXBlKHZhbHVlLCB0eXBlKSB7XHJcbiAgICBsZXQgdmFsaWQ7XHJcbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBnZXRUeXBlKHR5cGUpO1xyXG4gICAgaWYgKGlzU2ltcGxlVHlwZShleHBlY3RlZFR5cGUpKSB7XHJcbiAgICAgICAgY29uc3QgdCA9IHR5cGVvZiB2YWx1ZTtcclxuICAgICAgICB2YWxpZCA9IHQgPT09IGV4cGVjdGVkVHlwZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIC8vIGZvciBwcmltaXRpdmUgd3JhcHBlciBvYmplY3RzXHJcbiAgICAgICAgaWYgKCF2YWxpZCAmJiB0ID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICB2YWxpZCA9IHZhbHVlIGluc3RhbmNlb2YgdHlwZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdPYmplY3QnKSB7XHJcbiAgICAgICAgdmFsaWQgPSBpc09iamVjdCh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09ICdBcnJheScpIHtcclxuICAgICAgICB2YWxpZCA9IGlzQXJyYXkodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHZhbGlkLFxyXG4gICAgICAgIGV4cGVjdGVkVHlwZVxyXG4gICAgfTtcclxufVxyXG4vKipcclxuICogZGV2IG9ubHlcclxuICovXHJcbmZ1bmN0aW9uIGdldEludmFsaWRUeXBlTWVzc2FnZShuYW1lLCB2YWx1ZSwgZXhwZWN0ZWRUeXBlcykge1xyXG4gICAgbGV0IG1lc3NhZ2UgPSBgSW52YWxpZCBwcm9wOiB0eXBlIGNoZWNrIGZhaWxlZCBmb3IgcHJvcCBcIiR7bmFtZX1cIi5gICtcclxuICAgICAgICBgIEV4cGVjdGVkICR7ZXhwZWN0ZWRUeXBlcy5tYXAoY2FwaXRhbGl6ZSkuam9pbignLCAnKX1gO1xyXG4gICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gZXhwZWN0ZWRUeXBlc1swXTtcclxuICAgIGNvbnN0IHJlY2VpdmVkVHlwZSA9IHRvUmF3VHlwZSh2YWx1ZSk7XHJcbiAgICBjb25zdCBleHBlY3RlZFZhbHVlID0gc3R5bGVWYWx1ZSh2YWx1ZSwgZXhwZWN0ZWRUeXBlKTtcclxuICAgIGNvbnN0IHJlY2VpdmVkVmFsdWUgPSBzdHlsZVZhbHVlKHZhbHVlLCByZWNlaXZlZFR5cGUpO1xyXG4gICAgLy8gY2hlY2sgaWYgd2UgbmVlZCB0byBzcGVjaWZ5IGV4cGVjdGVkIHZhbHVlXHJcbiAgICBpZiAoZXhwZWN0ZWRUeXBlcy5sZW5ndGggPT09IDEgJiZcclxuICAgICAgICBpc0V4cGxpY2FibGUoZXhwZWN0ZWRUeXBlKSAmJlxyXG4gICAgICAgICFpc0Jvb2xlYW4oZXhwZWN0ZWRUeXBlLCByZWNlaXZlZFR5cGUpKSB7XHJcbiAgICAgICAgbWVzc2FnZSArPSBgIHdpdGggdmFsdWUgJHtleHBlY3RlZFZhbHVlfWA7XHJcbiAgICB9XHJcbiAgICBtZXNzYWdlICs9IGAsIGdvdCAke3JlY2VpdmVkVHlwZX0gYDtcclxuICAgIC8vIGNoZWNrIGlmIHdlIG5lZWQgdG8gc3BlY2lmeSByZWNlaXZlZCB2YWx1ZVxyXG4gICAgaWYgKGlzRXhwbGljYWJsZShyZWNlaXZlZFR5cGUpKSB7XHJcbiAgICAgICAgbWVzc2FnZSArPSBgd2l0aCB2YWx1ZSAke3JlY2VpdmVkVmFsdWV9LmA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbWVzc2FnZTtcclxufVxyXG4vKipcclxuICogZGV2IG9ubHlcclxuICovXHJcbmZ1bmN0aW9uIHN0eWxlVmFsdWUodmFsdWUsIHR5cGUpIHtcclxuICAgIGlmICh0eXBlID09PSAnU3RyaW5nJykge1xyXG4gICAgICAgIHJldHVybiBgXCIke3ZhbHVlfVwiYDtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHR5cGUgPT09ICdOdW1iZXInKSB7XHJcbiAgICAgICAgcmV0dXJuIGAke051bWJlcih2YWx1ZSl9YDtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBgJHt2YWx1ZX1gO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBkZXYgb25seVxyXG4gKi9cclxuZnVuY3Rpb24gaXNFeHBsaWNhYmxlKHR5cGUpIHtcclxuICAgIGNvbnN0IGV4cGxpY2l0VHlwZXMgPSBbJ3N0cmluZycsICdudW1iZXInLCAnYm9vbGVhbiddO1xyXG4gICAgcmV0dXJuIGV4cGxpY2l0VHlwZXMuc29tZShlbGVtID0+IHR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZWxlbSk7XHJcbn1cclxuLyoqXHJcbiAqIGRldiBvbmx5XHJcbiAqL1xyXG5mdW5jdGlvbiBpc0Jvb2xlYW4oLi4uYXJncykge1xyXG4gICAgcmV0dXJuIGFyZ3Muc29tZShlbGVtID0+IGVsZW0udG9Mb3dlckNhc2UoKSA9PT0gJ2Jvb2xlYW4nKTtcclxufVxuXG5mdW5jdGlvbiBpbmplY3RIb29rKHR5cGUsIGhvb2ssIHRhcmdldCA9IGN1cnJlbnRJbnN0YW5jZSwgcHJlcGVuZCA9IGZhbHNlKSB7XHJcbiAgICBpZiAodGFyZ2V0KSB7XHJcbiAgICAgICAgY29uc3QgaG9va3MgPSB0YXJnZXRbdHlwZV0gfHwgKHRhcmdldFt0eXBlXSA9IFtdKTtcclxuICAgICAgICAvLyBjYWNoZSB0aGUgZXJyb3IgaGFuZGxpbmcgd3JhcHBlciBmb3IgaW5qZWN0ZWQgaG9va3Mgc28gdGhlIHNhbWUgaG9va1xyXG4gICAgICAgIC8vIGNhbiBiZSBwcm9wZXJseSBkZWR1cGVkIGJ5IHRoZSBzY2hlZHVsZXIuIFwiX193ZWhcIiBzdGFuZHMgZm9yIFwid2l0aCBlcnJvclxyXG4gICAgICAgIC8vIGhhbmRsaW5nXCIuXHJcbiAgICAgICAgY29uc3Qgd3JhcHBlZEhvb2sgPSBob29rLl9fd2VoIHx8XHJcbiAgICAgICAgICAgIChob29rLl9fd2VoID0gKC4uLmFyZ3MpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuaXNVbm1vdW50ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBkaXNhYmxlIHRyYWNraW5nIGluc2lkZSBhbGwgbGlmZWN5Y2xlIGhvb2tzXHJcbiAgICAgICAgICAgICAgICAvLyBzaW5jZSB0aGV5IGNhbiBwb3RlbnRpYWxseSBiZSBjYWxsZWQgaW5zaWRlIGVmZmVjdHMuXHJcbiAgICAgICAgICAgICAgICBwYXVzZVRyYWNraW5nKCk7XHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgY3VycmVudEluc3RhbmNlIGR1cmluZyBob29rIGludm9jYXRpb24uXHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGFzc3VtZXMgdGhlIGhvb2sgZG9lcyBub3Qgc3luY2hyb25vdXNseSB0cmlnZ2VyIG90aGVyIGhvb2tzLCB3aGljaFxyXG4gICAgICAgICAgICAgICAgLy8gY2FuIG9ubHkgYmUgZmFsc2Ugd2hlbiB0aGUgdXNlciBkb2VzIHNvbWV0aGluZyByZWFsbHkgZnVua3kuXHJcbiAgICAgICAgICAgICAgICBzZXRDdXJyZW50SW5zdGFuY2UodGFyZ2V0KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nKGhvb2ssIHRhcmdldCwgdHlwZSwgYXJncyk7XHJcbiAgICAgICAgICAgICAgICBzZXRDdXJyZW50SW5zdGFuY2UobnVsbCk7XHJcbiAgICAgICAgICAgICAgICByZXNldFRyYWNraW5nKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICBpZiAocHJlcGVuZCkge1xyXG4gICAgICAgICAgICBob29rcy51bnNoaWZ0KHdyYXBwZWRIb29rKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGhvb2tzLnB1c2god3JhcHBlZEhvb2spO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gd3JhcHBlZEhvb2s7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICBjb25zdCBhcGlOYW1lID0gYG9uJHtjYXBpdGFsaXplKEVycm9yVHlwZVN0cmluZ3NbdHlwZV0ucmVwbGFjZSgvIGhvb2skLywgJycpKX1gO1xyXG4gICAgICAgIHdhcm4oYCR7YXBpTmFtZX0gaXMgY2FsbGVkIHdoZW4gdGhlcmUgaXMgbm8gYWN0aXZlIGNvbXBvbmVudCBpbnN0YW5jZSB0byBiZSBgICtcclxuICAgICAgICAgICAgYGFzc29jaWF0ZWQgd2l0aC4gYCArXHJcbiAgICAgICAgICAgIGBMaWZlY3ljbGUgaW5qZWN0aW9uIEFQSXMgY2FuIG9ubHkgYmUgdXNlZCBkdXJpbmcgZXhlY3V0aW9uIG9mIHNldHVwKCkuYCArXHJcbiAgICAgICAgICAgICggYCBJZiB5b3UgYXJlIHVzaW5nIGFzeW5jIHNldHVwKCksIG1ha2Ugc3VyZSB0byByZWdpc3RlciBsaWZlY3ljbGUgYCArXHJcbiAgICAgICAgICAgICAgICAgICAgYGhvb2tzIGJlZm9yZSB0aGUgZmlyc3QgYXdhaXQgc3RhdGVtZW50LmBcclxuICAgICAgICAgICAgICAgICkpO1xyXG4gICAgfVxyXG59XHJcbmNvbnN0IGNyZWF0ZUhvb2sgPSAobGlmZWN5Y2xlKSA9PiAoaG9vaywgdGFyZ2V0ID0gY3VycmVudEluc3RhbmNlKSA9PiBcclxuLy8gcG9zdC1jcmVhdGUgbGlmZWN5Y2xlIHJlZ2lzdHJhdGlvbnMgYXJlIG5vb3BzIGR1cmluZyBTU1JcclxuIWlzSW5TU1JDb21wb25lbnRTZXR1cCAmJiBpbmplY3RIb29rKGxpZmVjeWNsZSwgaG9vaywgdGFyZ2V0KTtcclxuY29uc3Qgb25CZWZvcmVNb3VudCA9IGNyZWF0ZUhvb2soXCJibVwiIC8qIEJFRk9SRV9NT1VOVCAqLyk7XHJcbmNvbnN0IG9uTW91bnRlZCA9IGNyZWF0ZUhvb2soXCJtXCIgLyogTU9VTlRFRCAqLyk7XHJcbmNvbnN0IG9uQmVmb3JlVXBkYXRlID0gY3JlYXRlSG9vayhcImJ1XCIgLyogQkVGT1JFX1VQREFURSAqLyk7XHJcbmNvbnN0IG9uVXBkYXRlZCA9IGNyZWF0ZUhvb2soXCJ1XCIgLyogVVBEQVRFRCAqLyk7XHJcbmNvbnN0IG9uQmVmb3JlVW5tb3VudCA9IGNyZWF0ZUhvb2soXCJidW1cIiAvKiBCRUZPUkVfVU5NT1VOVCAqLyk7XHJcbmNvbnN0IG9uVW5tb3VudGVkID0gY3JlYXRlSG9vayhcInVtXCIgLyogVU5NT1VOVEVEICovKTtcclxuY29uc3Qgb25SZW5kZXJUcmlnZ2VyZWQgPSBjcmVhdGVIb29rKFwicnRnXCIgLyogUkVOREVSX1RSSUdHRVJFRCAqLyk7XHJcbmNvbnN0IG9uUmVuZGVyVHJhY2tlZCA9IGNyZWF0ZUhvb2soXCJydGNcIiAvKiBSRU5ERVJfVFJBQ0tFRCAqLyk7XHJcbmNvbnN0IG9uRXJyb3JDYXB0dXJlZCA9IChob29rLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpID0+IHtcclxuICAgIGluamVjdEhvb2soXCJlY1wiIC8qIEVSUk9SX0NBUFRVUkVEICovLCBob29rLCB0YXJnZXQpO1xyXG59O1xuXG5mdW5jdGlvbiB1c2VUcmFuc2l0aW9uU3RhdGUoKSB7XHJcbiAgICBjb25zdCBzdGF0ZSA9IHtcclxuICAgICAgICBpc01vdW50ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGlzTGVhdmluZzogZmFsc2UsXHJcbiAgICAgICAgaXNVbm1vdW50aW5nOiBmYWxzZSxcclxuICAgICAgICBsZWF2aW5nVk5vZGVzOiBuZXcgTWFwKClcclxuICAgIH07XHJcbiAgICBvbk1vdW50ZWQoKCkgPT4ge1xyXG4gICAgICAgIHN0YXRlLmlzTW91bnRlZCA9IHRydWU7XHJcbiAgICB9KTtcclxuICAgIG9uQmVmb3JlVW5tb3VudCgoKSA9PiB7XHJcbiAgICAgICAgc3RhdGUuaXNVbm1vdW50aW5nID0gdHJ1ZTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHN0YXRlO1xyXG59XHJcbmNvbnN0IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yID0gW0Z1bmN0aW9uLCBBcnJheV07XHJcbmNvbnN0IEJhc2VUcmFuc2l0aW9uSW1wbCA9IHtcclxuICAgIG5hbWU6IGBCYXNlVHJhbnNpdGlvbmAsXHJcbiAgICBwcm9wczoge1xyXG4gICAgICAgIG1vZGU6IFN0cmluZyxcclxuICAgICAgICBhcHBlYXI6IEJvb2xlYW4sXHJcbiAgICAgICAgcGVyc2lzdGVkOiBCb29sZWFuLFxyXG4gICAgICAgIC8vIGVudGVyXHJcbiAgICAgICAgb25CZWZvcmVFbnRlcjogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsXHJcbiAgICAgICAgb25FbnRlcjogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsXHJcbiAgICAgICAgb25BZnRlckVudGVyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvcixcclxuICAgICAgICBvbkVudGVyQ2FuY2VsbGVkOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvcixcclxuICAgICAgICAvLyBsZWF2ZVxyXG4gICAgICAgIG9uQmVmb3JlTGVhdmU6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLFxyXG4gICAgICAgIG9uTGVhdmU6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLFxyXG4gICAgICAgIG9uQWZ0ZXJMZWF2ZTogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsXHJcbiAgICAgICAgb25MZWF2ZUNhbmNlbGxlZDogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3IsXHJcbiAgICAgICAgLy8gYXBwZWFyXHJcbiAgICAgICAgb25CZWZvcmVBcHBlYXI6IFRyYW5zaXRpb25Ib29rVmFsaWRhdG9yLFxyXG4gICAgICAgIG9uQXBwZWFyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvcixcclxuICAgICAgICBvbkFmdGVyQXBwZWFyOiBUcmFuc2l0aW9uSG9va1ZhbGlkYXRvcixcclxuICAgICAgICBvbkFwcGVhckNhbmNlbGxlZDogVHJhbnNpdGlvbkhvb2tWYWxpZGF0b3JcclxuICAgIH0sXHJcbiAgICBzZXR1cChwcm9wcywgeyBzbG90cyB9KSB7XHJcbiAgICAgICAgY29uc3QgaW5zdGFuY2UgPSBnZXRDdXJyZW50SW5zdGFuY2UoKTtcclxuICAgICAgICBjb25zdCBzdGF0ZSA9IHVzZVRyYW5zaXRpb25TdGF0ZSgpO1xyXG4gICAgICAgIGxldCBwcmV2VHJhbnNpdGlvbktleTtcclxuICAgICAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHNsb3RzLmRlZmF1bHQgJiYgZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKHNsb3RzLmRlZmF1bHQoKSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgIWNoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHdhcm4gbXVsdGlwbGUgZWxlbWVudHNcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBjaGlsZHJlbi5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgICAgICB3YXJuKCc8dHJhbnNpdGlvbj4gY2FuIG9ubHkgYmUgdXNlZCBvbiBhIHNpbmdsZSBlbGVtZW50IG9yIGNvbXBvbmVudC4gVXNlICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICc8dHJhbnNpdGlvbi1ncm91cD4gZm9yIGxpc3RzLicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHRoZXJlJ3Mgbm8gbmVlZCB0byB0cmFjayByZWFjdGl2aXR5IGZvciB0aGVzZSBwcm9wcyBzbyB1c2UgdGhlIHJhd1xyXG4gICAgICAgICAgICAvLyBwcm9wcyBmb3IgYSBiaXQgYmV0dGVyIHBlcmZcclxuICAgICAgICAgICAgY29uc3QgcmF3UHJvcHMgPSB0b1Jhdyhwcm9wcyk7XHJcbiAgICAgICAgICAgIGNvbnN0IHsgbW9kZSB9ID0gcmF3UHJvcHM7XHJcbiAgICAgICAgICAgIC8vIGNoZWNrIG1vZGVcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBtb2RlICYmICFbJ2luLW91dCcsICdvdXQtaW4nLCAnZGVmYXVsdCddLmluY2x1ZGVzKG1vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICB3YXJuKGBpbnZhbGlkIDx0cmFuc2l0aW9uPiBtb2RlOiAke21vZGV9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gYXQgdGhpcyBwb2ludCBjaGlsZHJlbiBoYXMgYSBndWFyYW50ZWVkIGxlbmd0aCBvZiAxLlxyXG4gICAgICAgICAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuWzBdO1xyXG4gICAgICAgICAgICBpZiAoc3RhdGUuaXNMZWF2aW5nKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZW1wdHlQbGFjZWhvbGRlcihjaGlsZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gaW4gdGhlIGNhc2Ugb2YgPHRyYW5zaXRpb24+PGtlZXAtYWxpdmUvPjwvdHJhbnNpdGlvbj4sIHdlIG5lZWQgdG9cclxuICAgICAgICAgICAgLy8gY29tcGFyZSB0aGUgdHlwZSBvZiB0aGUga2VwdC1hbGl2ZSBjaGlsZHJlbi5cclxuICAgICAgICAgICAgY29uc3QgaW5uZXJDaGlsZCA9IGdldEtlZXBBbGl2ZUNoaWxkKGNoaWxkKTtcclxuICAgICAgICAgICAgaWYgKCFpbm5lckNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZW1wdHlQbGFjZWhvbGRlcihjaGlsZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgZW50ZXJIb29rcyA9IChpbm5lckNoaWxkLnRyYW5zaXRpb24gPSByZXNvbHZlVHJhbnNpdGlvbkhvb2tzKGlubmVyQ2hpbGQsIHJhd1Byb3BzLCBzdGF0ZSwgaW5zdGFuY2UpKTtcclxuICAgICAgICAgICAgY29uc3Qgb2xkQ2hpbGQgPSBpbnN0YW5jZS5zdWJUcmVlO1xyXG4gICAgICAgICAgICBjb25zdCBvbGRJbm5lckNoaWxkID0gb2xkQ2hpbGQgJiYgZ2V0S2VlcEFsaXZlQ2hpbGQob2xkQ2hpbGQpO1xyXG4gICAgICAgICAgICBsZXQgdHJhbnNpdGlvbktleUNoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgY29uc3QgeyBnZXRUcmFuc2l0aW9uS2V5IH0gPSBpbm5lckNoaWxkLnR5cGU7XHJcbiAgICAgICAgICAgIGlmIChnZXRUcmFuc2l0aW9uS2V5KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSBnZXRUcmFuc2l0aW9uS2V5KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJldlRyYW5zaXRpb25LZXkgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHByZXZUcmFuc2l0aW9uS2V5ID0ga2V5O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoa2V5ICE9PSBwcmV2VHJhbnNpdGlvbktleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHByZXZUcmFuc2l0aW9uS2V5ID0ga2V5O1xyXG4gICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25LZXlDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBoYW5kbGUgbW9kZVxyXG4gICAgICAgICAgICBpZiAob2xkSW5uZXJDaGlsZCAmJlxyXG4gICAgICAgICAgICAgICAgb2xkSW5uZXJDaGlsZC50eXBlICE9PSBDb21tZW50ICYmXHJcbiAgICAgICAgICAgICAgICAoIWlzU2FtZVZOb2RlVHlwZShpbm5lckNoaWxkLCBvbGRJbm5lckNoaWxkKSB8fCB0cmFuc2l0aW9uS2V5Q2hhbmdlZCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGxlYXZpbmdIb29rcyA9IHJlc29sdmVUcmFuc2l0aW9uSG9va3Mob2xkSW5uZXJDaGlsZCwgcmF3UHJvcHMsIHN0YXRlLCBpbnN0YW5jZSk7XHJcbiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgb2xkIHRyZWUncyBob29rcyBpbiBjYXNlIG9mIGR5bmFtaWMgdHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKG9sZElubmVyQ2hpbGQsIGxlYXZpbmdIb29rcyk7XHJcbiAgICAgICAgICAgICAgICAvLyBzd2l0Y2hpbmcgYmV0d2VlbiBkaWZmZXJlbnQgdmlld3NcclxuICAgICAgICAgICAgICAgIGlmIChtb2RlID09PSAnb3V0LWluJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmlzTGVhdmluZyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuIHBsYWNlaG9sZGVyIG5vZGUgYW5kIHF1ZXVlIHVwZGF0ZSB3aGVuIGxlYXZlIGZpbmlzaGVzXHJcbiAgICAgICAgICAgICAgICAgICAgbGVhdmluZ0hvb2tzLmFmdGVyTGVhdmUgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmlzTGVhdmluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS51cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbXB0eVBsYWNlaG9sZGVyKGNoaWxkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1vZGUgPT09ICdpbi1vdXQnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVhdmluZ0hvb2tzLmRlbGF5TGVhdmUgPSAoZWwsIGVhcmx5UmVtb3ZlLCBkZWxheWVkTGVhdmUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gZ2V0TGVhdmluZ05vZGVzRm9yVHlwZShzdGF0ZSwgb2xkSW5uZXJDaGlsZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlYXZpbmdWTm9kZXNDYWNoZVtTdHJpbmcob2xkSW5uZXJDaGlsZC5rZXkpXSA9IG9sZElubmVyQ2hpbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVhcmx5IHJlbW92YWwgY2FsbGJhY2tcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwuX2xlYXZlQ2IgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXJseVJlbW92ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuX2xlYXZlQ2IgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZW50ZXJIb29rcy5kZWxheWVkTGVhdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudGVySG9va3MuZGVsYXllZExlYXZlID0gZGVsYXllZExlYXZlO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGNoaWxkO1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcbi8vIGV4cG9ydCB0aGUgcHVibGljIHR5cGUgZm9yIGgvdHN4IGluZmVyZW5jZVxyXG4vLyBhbHNvIHRvIGF2b2lkIGlubGluZSBpbXBvcnQoKSBpbiBnZW5lcmF0ZWQgZC50cyBmaWxlc1xyXG5jb25zdCBCYXNlVHJhbnNpdGlvbiA9IEJhc2VUcmFuc2l0aW9uSW1wbDtcclxuZnVuY3Rpb24gZ2V0TGVhdmluZ05vZGVzRm9yVHlwZShzdGF0ZSwgdm5vZGUpIHtcclxuICAgIGNvbnN0IHsgbGVhdmluZ1ZOb2RlcyB9ID0gc3RhdGU7XHJcbiAgICBsZXQgbGVhdmluZ1ZOb2Rlc0NhY2hlID0gbGVhdmluZ1ZOb2Rlcy5nZXQodm5vZGUudHlwZSk7XHJcbiAgICBpZiAoIWxlYXZpbmdWTm9kZXNDYWNoZSkge1xyXG4gICAgICAgIGxlYXZpbmdWTm9kZXNDYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XHJcbiAgICAgICAgbGVhdmluZ1ZOb2Rlcy5zZXQodm5vZGUudHlwZSwgbGVhdmluZ1ZOb2Rlc0NhY2hlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBsZWF2aW5nVk5vZGVzQ2FjaGU7XHJcbn1cclxuLy8gVGhlIHRyYW5zaXRpb24gaG9va3MgYXJlIGF0dGFjaGVkIHRvIHRoZSB2bm9kZSBhcyB2bm9kZS50cmFuc2l0aW9uXHJcbi8vIGFuZCB3aWxsIGJlIGNhbGxlZCBhdCBhcHByb3ByaWF0ZSB0aW1pbmcgaW4gdGhlIHJlbmRlcmVyLlxyXG5mdW5jdGlvbiByZXNvbHZlVHJhbnNpdGlvbkhvb2tzKHZub2RlLCB7IGFwcGVhciwgcGVyc2lzdGVkID0gZmFsc2UsIG9uQmVmb3JlRW50ZXIsIG9uRW50ZXIsIG9uQWZ0ZXJFbnRlciwgb25FbnRlckNhbmNlbGxlZCwgb25CZWZvcmVMZWF2ZSwgb25MZWF2ZSwgb25BZnRlckxlYXZlLCBvbkxlYXZlQ2FuY2VsbGVkLCBvbkJlZm9yZUFwcGVhciwgb25BcHBlYXIsIG9uQWZ0ZXJBcHBlYXIsIG9uQXBwZWFyQ2FuY2VsbGVkIH0sIHN0YXRlLCBpbnN0YW5jZSkge1xyXG4gICAgY29uc3Qga2V5ID0gU3RyaW5nKHZub2RlLmtleSk7XHJcbiAgICBjb25zdCBsZWF2aW5nVk5vZGVzQ2FjaGUgPSBnZXRMZWF2aW5nTm9kZXNGb3JUeXBlKHN0YXRlLCB2bm9kZSk7XHJcbiAgICBjb25zdCBjYWxsSG9vayA9IChob29rLCBhcmdzKSA9PiB7XHJcbiAgICAgICAgaG9vayAmJlxyXG4gICAgICAgICAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhob29rLCBpbnN0YW5jZSwgOSAvKiBUUkFOU0lUSU9OX0hPT0sgKi8sIGFyZ3MpO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IGhvb2tzID0ge1xyXG4gICAgICAgIHBlcnNpc3RlZCxcclxuICAgICAgICBiZWZvcmVFbnRlcihlbCkge1xyXG4gICAgICAgICAgICBsZXQgaG9vayA9IG9uQmVmb3JlRW50ZXI7XHJcbiAgICAgICAgICAgIGlmICghc3RhdGUuaXNNb3VudGVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXBwZWFyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG9vayA9IG9uQmVmb3JlQXBwZWFyIHx8IG9uQmVmb3JlRW50ZXI7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gZm9yIHNhbWUgZWxlbWVudCAodi1zaG93KVxyXG4gICAgICAgICAgICBpZiAoZWwuX2xlYXZlQ2IpIHtcclxuICAgICAgICAgICAgICAgIGVsLl9sZWF2ZUNiKHRydWUgLyogY2FuY2VsbGVkICovKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBmb3IgdG9nZ2xlZCBlbGVtZW50IHdpdGggc2FtZSBrZXkgKHYtaWYpXHJcbiAgICAgICAgICAgIGNvbnN0IGxlYXZpbmdWTm9kZSA9IGxlYXZpbmdWTm9kZXNDYWNoZVtrZXldO1xyXG4gICAgICAgICAgICBpZiAobGVhdmluZ1ZOb2RlICYmXHJcbiAgICAgICAgICAgICAgICBpc1NhbWVWTm9kZVR5cGUodm5vZGUsIGxlYXZpbmdWTm9kZSkgJiZcclxuICAgICAgICAgICAgICAgIGxlYXZpbmdWTm9kZS5lbC5fbGVhdmVDYikge1xyXG4gICAgICAgICAgICAgICAgLy8gZm9yY2UgZWFybHkgcmVtb3ZhbCAobm90IGNhbmNlbGxlZClcclxuICAgICAgICAgICAgICAgIGxlYXZpbmdWTm9kZS5lbC5fbGVhdmVDYigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhbGxIb29rKGhvb2ssIFtlbF0pO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW50ZXIoZWwpIHtcclxuICAgICAgICAgICAgbGV0IGhvb2sgPSBvbkVudGVyO1xyXG4gICAgICAgICAgICBsZXQgYWZ0ZXJIb29rID0gb25BZnRlckVudGVyO1xyXG4gICAgICAgICAgICBsZXQgY2FuY2VsSG9vayA9IG9uRW50ZXJDYW5jZWxsZWQ7XHJcbiAgICAgICAgICAgIGlmICghc3RhdGUuaXNNb3VudGVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXBwZWFyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG9vayA9IG9uQXBwZWFyIHx8IG9uRW50ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgYWZ0ZXJIb29rID0gb25BZnRlckFwcGVhciB8fCBvbkFmdGVyRW50ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FuY2VsSG9vayA9IG9uQXBwZWFyQ2FuY2VsbGVkIHx8IG9uRW50ZXJDYW5jZWxsZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbGV0IGNhbGxlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjb25zdCBkb25lID0gKGVsLl9lbnRlckNiID0gKGNhbmNlbGxlZCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhbGxlZClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBjYWxsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhbmNlbGxlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNhbGxIb29rKGNhbmNlbEhvb2ssIFtlbF0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FsbEhvb2soYWZ0ZXJIb29rLCBbZWxdKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChob29rcy5kZWxheWVkTGVhdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBob29rcy5kZWxheWVkTGVhdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsLl9lbnRlckNiID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYgKGhvb2spIHtcclxuICAgICAgICAgICAgICAgIGhvb2soZWwsIGRvbmUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGhvb2subGVuZ3RoIDw9IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBkb25lKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGxlYXZlKGVsLCByZW1vdmUpIHtcclxuICAgICAgICAgICAgY29uc3Qga2V5ID0gU3RyaW5nKHZub2RlLmtleSk7XHJcbiAgICAgICAgICAgIGlmIChlbC5fZW50ZXJDYikge1xyXG4gICAgICAgICAgICAgICAgZWwuX2VudGVyQ2IodHJ1ZSAvKiBjYW5jZWxsZWQgKi8pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5pc1VubW91bnRpbmcpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYWxsSG9vayhvbkJlZm9yZUxlYXZlLCBbZWxdKTtcclxuICAgICAgICAgICAgbGV0IGNhbGxlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjb25zdCBkb25lID0gKGVsLl9sZWF2ZUNiID0gKGNhbmNlbGxlZCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhbGxlZClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBjYWxsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FuY2VsbGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FsbEhvb2sob25MZWF2ZUNhbmNlbGxlZCwgW2VsXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjYWxsSG9vayhvbkFmdGVyTGVhdmUsIFtlbF0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWwuX2xlYXZlQ2IgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBpZiAobGVhdmluZ1ZOb2Rlc0NhY2hlW2tleV0gPT09IHZub2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGxlYXZpbmdWTm9kZXNDYWNoZVtrZXldO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgbGVhdmluZ1ZOb2Rlc0NhY2hlW2tleV0gPSB2bm9kZTtcclxuICAgICAgICAgICAgaWYgKG9uTGVhdmUpIHtcclxuICAgICAgICAgICAgICAgIG9uTGVhdmUoZWwsIGRvbmUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKG9uTGVhdmUubGVuZ3RoIDw9IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBkb25lKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIGhvb2tzO1xyXG59XHJcbi8vIHRoZSBwbGFjZWhvbGRlciByZWFsbHkgb25seSBoYW5kbGVzIG9uZSBzcGVjaWFsIGNhc2U6IEtlZXBBbGl2ZVxyXG4vLyBpbiB0aGUgY2FzZSBvZiBhIEtlZXBBbGl2ZSBpbiBhIGxlYXZlIHBoYXNlIHdlIG5lZWQgdG8gcmV0dXJuIGEgS2VlcEFsaXZlXHJcbi8vIHBsYWNlaG9sZGVyIHdpdGggZW1wdHkgY29udGVudCB0byBhdm9pZCB0aGUgS2VlcEFsaXZlIGluc3RhbmNlIGZyb20gYmVpbmdcclxuLy8gdW5tb3VudGVkLlxyXG5mdW5jdGlvbiBlbXB0eVBsYWNlaG9sZGVyKHZub2RlKSB7XHJcbiAgICBpZiAoaXNLZWVwQWxpdmUodm5vZGUpKSB7XHJcbiAgICAgICAgdm5vZGUgPSBjbG9uZVZOb2RlKHZub2RlKTtcclxuICAgICAgICB2bm9kZS5jaGlsZHJlbiA9IG51bGw7XHJcbiAgICAgICAgcmV0dXJuIHZub2RlO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGdldEtlZXBBbGl2ZUNoaWxkKHZub2RlKSB7XHJcbiAgICByZXR1cm4gaXNLZWVwQWxpdmUodm5vZGUpXHJcbiAgICAgICAgPyB2bm9kZS5jaGlsZHJlblxyXG4gICAgICAgICAgICA/IHZub2RlLmNoaWxkcmVuWzBdXHJcbiAgICAgICAgICAgIDogdW5kZWZpbmVkXHJcbiAgICAgICAgOiB2bm9kZTtcclxufVxyXG5mdW5jdGlvbiBzZXRUcmFuc2l0aW9uSG9va3Modm5vZGUsIGhvb2tzKSB7XHJcbiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNiAvKiBDT01QT05FTlQgKi8gJiYgdm5vZGUuY29tcG9uZW50KSB7XHJcbiAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKHZub2RlLmNvbXBvbmVudC5zdWJUcmVlLCBob29rcyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICB2bm9kZS50cmFuc2l0aW9uID0gaG9va3M7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKGNoaWxkcmVuLCBrZWVwQ29tbWVudCA9IGZhbHNlKSB7XHJcbiAgICBsZXQgcmV0ID0gW107XHJcbiAgICBsZXQga2V5ZWRGcmFnbWVudENvdW50ID0gMDtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldO1xyXG4gICAgICAgIC8vIGhhbmRsZSBmcmFnbWVudCBjaGlsZHJlbiBjYXNlLCBlLmcuIHYtZm9yXHJcbiAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT09IEZyYWdtZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChjaGlsZC5wYXRjaEZsYWcgJiAxMjggLyogS0VZRURfRlJBR01FTlQgKi8pXHJcbiAgICAgICAgICAgICAgICBrZXllZEZyYWdtZW50Q291bnQrKztcclxuICAgICAgICAgICAgcmV0ID0gcmV0LmNvbmNhdChnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4oY2hpbGQuY2hpbGRyZW4sIGtlZXBDb21tZW50KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNvbW1lbnQgcGxhY2Vob2xkZXJzIHNob3VsZCBiZSBza2lwcGVkLCBlLmcuIHYtaWZcclxuICAgICAgICBlbHNlIGlmIChrZWVwQ29tbWVudCB8fCBjaGlsZC50eXBlICE9PSBDb21tZW50KSB7XHJcbiAgICAgICAgICAgIHJldC5wdXNoKGNoaWxkKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyAjMTEyNiBpZiBhIHRyYW5zaXRpb24gY2hpbGRyZW4gbGlzdCBjb250YWlucyBtdWx0aXBsZSBzdWIgZnJhZ21lbnRzLCB0aGVzZVxyXG4gICAgLy8gZnJhZ21lbnRzIHdpbGwgYmUgbWVyZ2VkIGludG8gYSBmbGF0IGNoaWxkcmVuIGFycmF5LiBTaW5jZSBlYWNoIHYtZm9yXHJcbiAgICAvLyBmcmFnbWVudCBtYXkgY29udGFpbiBkaWZmZXJlbnQgc3RhdGljIGJpbmRpbmdzIGluc2lkZSwgd2UgbmVlZCB0byBkZS10b3BcclxuICAgIC8vIHRoZXNlIGNoaWxkcmVuIHRvIGZvcmNlIGZ1bGwgZGlmZnMgdG8gZW5zdXJlIGNvcnJlY3QgYmVoYXZpb3IuXHJcbiAgICBpZiAoa2V5ZWRGcmFnbWVudENvdW50ID4gMSkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHJldFtpXS5wYXRjaEZsYWcgPSAtMiAvKiBCQUlMICovO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXQ7XHJcbn1cblxuY29uc3QgaXNLZWVwQWxpdmUgPSAodm5vZGUpID0+IHZub2RlLnR5cGUuX19pc0tlZXBBbGl2ZTtcclxuY29uc3QgS2VlcEFsaXZlSW1wbCA9IHtcclxuICAgIG5hbWU6IGBLZWVwQWxpdmVgLFxyXG4gICAgLy8gTWFya2VyIGZvciBzcGVjaWFsIGhhbmRsaW5nIGluc2lkZSB0aGUgcmVuZGVyZXIuIFdlIGFyZSBub3QgdXNpbmcgYSA9PT1cclxuICAgIC8vIGNoZWNrIGRpcmVjdGx5IG9uIEtlZXBBbGl2ZSBpbiB0aGUgcmVuZGVyZXIsIGJlY2F1c2UgaW1wb3J0aW5nIGl0IGRpcmVjdGx5XHJcbiAgICAvLyB3b3VsZCBwcmV2ZW50IGl0IGZyb20gYmVpbmcgdHJlZS1zaGFrZW4uXHJcbiAgICBfX2lzS2VlcEFsaXZlOiB0cnVlLFxyXG4gICAgaW5oZXJpdFJlZjogdHJ1ZSxcclxuICAgIHByb3BzOiB7XHJcbiAgICAgICAgaW5jbHVkZTogW1N0cmluZywgUmVnRXhwLCBBcnJheV0sXHJcbiAgICAgICAgZXhjbHVkZTogW1N0cmluZywgUmVnRXhwLCBBcnJheV0sXHJcbiAgICAgICAgbWF4OiBbU3RyaW5nLCBOdW1iZXJdXHJcbiAgICB9LFxyXG4gICAgc2V0dXAocHJvcHMsIHsgc2xvdHMgfSkge1xyXG4gICAgICAgIGNvbnN0IGNhY2hlID0gbmV3IE1hcCgpO1xyXG4gICAgICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KCk7XHJcbiAgICAgICAgbGV0IGN1cnJlbnQgPSBudWxsO1xyXG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7XHJcbiAgICAgICAgY29uc3QgcGFyZW50U3VzcGVuc2UgPSBpbnN0YW5jZS5zdXNwZW5zZTtcclxuICAgICAgICAvLyBLZWVwQWxpdmUgY29tbXVuaWNhdGVzIHdpdGggdGhlIGluc3RhbnRpYXRlZCByZW5kZXJlciB2aWEgdGhlXHJcbiAgICAgICAgLy8gY3R4IHdoZXJlIHRoZSByZW5kZXJlciBwYXNzZXMgaW4gaXRzIGludGVybmFscyxcclxuICAgICAgICAvLyBhbmQgdGhlIEtlZXBBbGl2ZSBpbnN0YW5jZSBleHBvc2VzIGFjdGl2YXRlL2RlYWN0aXZhdGUgaW1wbGVtZW50YXRpb25zLlxyXG4gICAgICAgIC8vIFRoZSB3aG9sZSBwb2ludCBvZiB0aGlzIGlzIHRvIGF2b2lkIGltcG9ydGluZyBLZWVwQWxpdmUgZGlyZWN0bHkgaW4gdGhlXHJcbiAgICAgICAgLy8gcmVuZGVyZXIgdG8gZmFjaWxpdGF0ZSB0cmVlLXNoYWtpbmcuXHJcbiAgICAgICAgY29uc3Qgc2hhcmVkQ29udGV4dCA9IGluc3RhbmNlLmN0eDtcclxuICAgICAgICBjb25zdCB7IHJlbmRlcmVyOiB7IHA6IHBhdGNoLCBtOiBtb3ZlLCB1bTogX3VubW91bnQsIG86IHsgY3JlYXRlRWxlbWVudCB9IH0gfSA9IHNoYXJlZENvbnRleHQ7XHJcbiAgICAgICAgY29uc3Qgc3RvcmFnZUNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgICAgIHNoYXJlZENvbnRleHQuYWN0aXZhdGUgPSAodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBpc1NWRywgb3B0aW1pemVkKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gdm5vZGUuY29tcG9uZW50O1xyXG4gICAgICAgICAgICBtb3ZlKHZub2RlLCBjb250YWluZXIsIGFuY2hvciwgMCAvKiBFTlRFUiAqLywgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgICAgICAvLyBpbiBjYXNlIHByb3BzIGhhdmUgY2hhbmdlZFxyXG4gICAgICAgICAgICBwYXRjaChpbnN0YW5jZS52bm9kZSwgdm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaW5zdGFuY2UuaXNEZWFjdGl2YXRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnZva2VBcnJheUZucyhpbnN0YW5jZS5hKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IHZub2RlSG9vayA9IHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLm9uVm5vZGVNb3VudGVkO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZub2RlSG9vaykge1xyXG4gICAgICAgICAgICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIGluc3RhbmNlLnBhcmVudCwgdm5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBzaGFyZWRDb250ZXh0LmRlYWN0aXZhdGUgPSAodm5vZGUpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgaW5zdGFuY2UgPSB2bm9kZS5jb21wb25lbnQ7XHJcbiAgICAgICAgICAgIG1vdmUodm5vZGUsIHN0b3JhZ2VDb250YWluZXIsIG51bGwsIDEgLyogTEVBVkUgKi8sIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZS5kYSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGludm9rZUFycmF5Rm5zKGluc3RhbmNlLmRhKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IHZub2RlSG9vayA9IHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLm9uVm5vZGVVbm1vdW50ZWQ7XHJcbiAgICAgICAgICAgICAgICBpZiAodm5vZGVIb29rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgaW5zdGFuY2UucGFyZW50LCB2bm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5pc0RlYWN0aXZhdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgfSwgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgZnVuY3Rpb24gdW5tb3VudCh2bm9kZSkge1xyXG4gICAgICAgICAgICAvLyByZXNldCB0aGUgc2hhcGVGbGFnIHNvIGl0IGNhbiBiZSBwcm9wZXJseSB1bm1vdW50ZWRcclxuICAgICAgICAgICAgcmVzZXRTaGFwZUZsYWcodm5vZGUpO1xyXG4gICAgICAgICAgICBfdW5tb3VudCh2bm9kZSwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gcHJ1bmVDYWNoZShmaWx0ZXIpIHtcclxuICAgICAgICAgICAgY2FjaGUuZm9yRWFjaCgodm5vZGUsIGtleSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IGdldE5hbWUodm5vZGUudHlwZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobmFtZSAmJiAoIWZpbHRlciB8fCAhZmlsdGVyKG5hbWUpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBydW5lQ2FjaGVFbnRyeShrZXkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gcHJ1bmVDYWNoZUVudHJ5KGtleSkge1xyXG4gICAgICAgICAgICBjb25zdCBjYWNoZWQgPSBjYWNoZS5nZXQoa2V5KTtcclxuICAgICAgICAgICAgaWYgKCFjdXJyZW50IHx8IGNhY2hlZC50eXBlICE9PSBjdXJyZW50LnR5cGUpIHtcclxuICAgICAgICAgICAgICAgIHVubW91bnQoY2FjaGVkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50KSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjdXJyZW50IGFjdGl2ZSBpbnN0YW5jZSBzaG91bGQgbm8gbG9uZ2VyIGJlIGtlcHQtYWxpdmUuXHJcbiAgICAgICAgICAgICAgICAvLyB3ZSBjYW4ndCB1bm1vdW50IGl0IG5vdyBidXQgaXQgbWlnaHQgYmUgbGF0ZXIsIHNvIHJlc2V0IGl0cyBmbGFnIG5vdy5cclxuICAgICAgICAgICAgICAgIHJlc2V0U2hhcGVGbGFnKGN1cnJlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhY2hlLmRlbGV0ZShrZXkpO1xyXG4gICAgICAgICAgICBrZXlzLmRlbGV0ZShrZXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB3YXRjaCgoKSA9PiBbcHJvcHMuaW5jbHVkZSwgcHJvcHMuZXhjbHVkZV0sIChbaW5jbHVkZSwgZXhjbHVkZV0pID0+IHtcclxuICAgICAgICAgICAgaW5jbHVkZSAmJiBwcnVuZUNhY2hlKG5hbWUgPT4gbWF0Y2hlcyhpbmNsdWRlLCBuYW1lKSk7XHJcbiAgICAgICAgICAgIGV4Y2x1ZGUgJiYgcHJ1bmVDYWNoZShuYW1lID0+IG1hdGNoZXMoZXhjbHVkZSwgbmFtZSkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIGNhY2hlIHN1YiB0cmVlIGluIGJlZm9yZU1vdW50L1VwZGF0ZSAoaS5lLiByaWdodCBhZnRlciB0aGUgcmVuZGVyKVxyXG4gICAgICAgIGxldCBwZW5kaW5nQ2FjaGVLZXkgPSBudWxsO1xyXG4gICAgICAgIGNvbnN0IGNhY2hlU3VidHJlZSA9ICgpID0+IHtcclxuICAgICAgICAgICAgLy8gZml4ICMxNjIxLCB0aGUgcGVuZGluZ0NhY2hlS2V5IGNvdWxkIGJlIDBcclxuICAgICAgICAgICAgaWYgKHBlbmRpbmdDYWNoZUtleSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBjYWNoZS5zZXQocGVuZGluZ0NhY2hlS2V5LCBpbnN0YW5jZS5zdWJUcmVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgb25CZWZvcmVNb3VudChjYWNoZVN1YnRyZWUpO1xyXG4gICAgICAgIG9uQmVmb3JlVXBkYXRlKGNhY2hlU3VidHJlZSk7XHJcbiAgICAgICAgb25CZWZvcmVVbm1vdW50KCgpID0+IHtcclxuICAgICAgICAgICAgY2FjaGUuZm9yRWFjaChjYWNoZWQgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgeyBzdWJUcmVlLCBzdXNwZW5zZSB9ID0gaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkLnR5cGUgPT09IHN1YlRyZWUudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGN1cnJlbnQgaW5zdGFuY2Ugd2lsbCBiZSB1bm1vdW50ZWQgYXMgcGFydCBvZiBrZWVwLWFsaXZlJ3MgdW5tb3VudFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc2V0U2hhcGVGbGFnKHN1YlRyZWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBpbnZva2UgaXRzIGRlYWN0aXZhdGVkIGhvb2sgaGVyZVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhID0gc3ViVHJlZS5jb21wb25lbnQuZGE7XHJcbiAgICAgICAgICAgICAgICAgICAgZGEgJiYgcXVldWVQb3N0UmVuZGVyRWZmZWN0KGRhLCBzdXNwZW5zZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdW5tb3VudChjYWNoZWQpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICAgICAgICBwZW5kaW5nQ2FjaGVLZXkgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAoIXNsb3RzLmRlZmF1bHQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuID0gc2xvdHMuZGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBsZXQgdm5vZGUgPSBjaGlsZHJlblswXTtcclxuICAgICAgICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBLZWVwQWxpdmUgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSBvbmUgY29tcG9uZW50IGNoaWxkLmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGRyZW47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoIWlzVk5vZGUodm5vZGUpIHx8XHJcbiAgICAgICAgICAgICAgICAhKHZub2RlLnNoYXBlRmxhZyAmIDQgLyogU1RBVEVGVUxfQ09NUE9ORU5UICovKSkge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdm5vZGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgY29tcCA9IHZub2RlLnR5cGU7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBnZXROYW1lKGNvbXApO1xyXG4gICAgICAgICAgICBjb25zdCB7IGluY2x1ZGUsIGV4Y2x1ZGUsIG1heCB9ID0gcHJvcHM7XHJcbiAgICAgICAgICAgIGlmICgoaW5jbHVkZSAmJiAoIW5hbWUgfHwgIW1hdGNoZXMoaW5jbHVkZSwgbmFtZSkpKSB8fFxyXG4gICAgICAgICAgICAgICAgKGV4Y2x1ZGUgJiYgbmFtZSAmJiBtYXRjaGVzKGV4Y2x1ZGUsIG5hbWUpKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIChjdXJyZW50ID0gdm5vZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGtleSA9IHZub2RlLmtleSA9PSBudWxsID8gY29tcCA6IHZub2RlLmtleTtcclxuICAgICAgICAgICAgY29uc3QgY2FjaGVkVk5vZGUgPSBjYWNoZS5nZXQoa2V5KTtcclxuICAgICAgICAgICAgLy8gY2xvbmUgdm5vZGUgaWYgaXQncyByZXVzZWQgYmVjYXVzZSB3ZSBhcmUgZ29pbmcgdG8gbXV0YXRlIGl0XHJcbiAgICAgICAgICAgIGlmICh2bm9kZS5lbCkge1xyXG4gICAgICAgICAgICAgICAgdm5vZGUgPSBjbG9uZVZOb2RlKHZub2RlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyAjMTUxMyBpdCdzIHBvc3NpYmxlIGZvciB0aGUgcmV0dXJuZWQgdm5vZGUgdG8gYmUgY2xvbmVkIGR1ZSB0byBhdHRyXHJcbiAgICAgICAgICAgIC8vIGZhbGx0aHJvdWdoIG9yIHNjb3BlSWQsIHNvIHRoZSB2bm9kZSBoZXJlIG1heSBub3QgYmUgdGhlIGZpbmFsIHZub2RlXHJcbiAgICAgICAgICAgIC8vIHRoYXQgaXMgbW91bnRlZC4gSW5zdGVhZCBvZiBjYWNoaW5nIGl0IGRpcmVjdGx5LCB3ZSBzdG9yZSB0aGUgcGVuZGluZ1xyXG4gICAgICAgICAgICAvLyBrZXkgYW5kIGNhY2hlIGBpbnN0YW5jZS5zdWJUcmVlYCAodGhlIG5vcm1hbGl6ZWQgdm5vZGUpIGluXHJcbiAgICAgICAgICAgIC8vIGJlZm9yZU1vdW50L2JlZm9yZVVwZGF0ZSBob29rcy5cclxuICAgICAgICAgICAgcGVuZGluZ0NhY2hlS2V5ID0ga2V5O1xyXG4gICAgICAgICAgICBpZiAoY2FjaGVkVk5vZGUpIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvcHkgb3ZlciBtb3VudGVkIHN0YXRlXHJcbiAgICAgICAgICAgICAgICB2bm9kZS5lbCA9IGNhY2hlZFZOb2RlLmVsO1xyXG4gICAgICAgICAgICAgICAgdm5vZGUuY29tcG9uZW50ID0gY2FjaGVkVk5vZGUuY29tcG9uZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKHZub2RlLnRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZWN1cnNpdmVseSB1cGRhdGUgdHJhbnNpdGlvbiBob29rcyBvbiBzdWJUcmVlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VHJhbnNpdGlvbkhvb2tzKHZub2RlLCB2bm9kZS50cmFuc2l0aW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGF2b2lkIHZub2RlIGJlaW5nIG1vdW50ZWQgYXMgZnJlc2hcclxuICAgICAgICAgICAgICAgIHZub2RlLnNoYXBlRmxhZyB8PSA1MTIgLyogQ09NUE9ORU5UX0tFUFRfQUxJVkUgKi87XHJcbiAgICAgICAgICAgICAgICAvLyBtYWtlIHRoaXMga2V5IHRoZSBmcmVzaGVzdFxyXG4gICAgICAgICAgICAgICAga2V5cy5kZWxldGUoa2V5KTtcclxuICAgICAgICAgICAgICAgIGtleXMuYWRkKGtleSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBrZXlzLmFkZChrZXkpO1xyXG4gICAgICAgICAgICAgICAgLy8gcHJ1bmUgb2xkZXN0IGVudHJ5XHJcbiAgICAgICAgICAgICAgICBpZiAobWF4ICYmIGtleXMuc2l6ZSA+IHBhcnNlSW50KG1heCwgMTApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJ1bmVDYWNoZUVudHJ5KGtleXMudmFsdWVzKCkubmV4dCgpLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBhdm9pZCB2bm9kZSBiZWluZyB1bm1vdW50ZWRcclxuICAgICAgICAgICAgdm5vZGUuc2hhcGVGbGFnIHw9IDI1NiAvKiBDT01QT05FTlRfU0hPVUxEX0tFRVBfQUxJVkUgKi87XHJcbiAgICAgICAgICAgIGN1cnJlbnQgPSB2bm9kZTtcclxuICAgICAgICAgICAgcmV0dXJuIHZub2RlO1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcbi8vIGV4cG9ydCB0aGUgcHVibGljIHR5cGUgZm9yIGgvdHN4IGluZmVyZW5jZVxyXG4vLyBhbHNvIHRvIGF2b2lkIGlubGluZSBpbXBvcnQoKSBpbiBnZW5lcmF0ZWQgZC50cyBmaWxlc1xyXG5jb25zdCBLZWVwQWxpdmUgPSBLZWVwQWxpdmVJbXBsO1xyXG5mdW5jdGlvbiBnZXROYW1lKGNvbXApIHtcclxuICAgIHJldHVybiBjb21wLmRpc3BsYXlOYW1lIHx8IGNvbXAubmFtZTtcclxufVxyXG5mdW5jdGlvbiBtYXRjaGVzKHBhdHRlcm4sIG5hbWUpIHtcclxuICAgIGlmIChpc0FycmF5KHBhdHRlcm4pKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4uc29tZSgocCkgPT4gbWF0Y2hlcyhwLCBuYW1lKSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChpc1N0cmluZyhwYXR0ZXJuKSkge1xyXG4gICAgICAgIHJldHVybiBwYXR0ZXJuLnNwbGl0KCcsJykuaW5kZXhPZihuYW1lKSA+IC0xO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAocGF0dGVybi50ZXN0KSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4udGVzdChuYW1lKTtcclxuICAgIH1cclxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbn1cclxuZnVuY3Rpb24gb25BY3RpdmF0ZWQoaG9vaywgdGFyZ2V0KSB7XHJcbiAgICByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgXCJhXCIgLyogQUNUSVZBVEVEICovLCB0YXJnZXQpO1xyXG59XHJcbmZ1bmN0aW9uIG9uRGVhY3RpdmF0ZWQoaG9vaywgdGFyZ2V0KSB7XHJcbiAgICByZWdpc3RlcktlZXBBbGl2ZUhvb2soaG9vaywgXCJkYVwiIC8qIERFQUNUSVZBVEVEICovLCB0YXJnZXQpO1xyXG59XHJcbmZ1bmN0aW9uIHJlZ2lzdGVyS2VlcEFsaXZlSG9vayhob29rLCB0eXBlLCB0YXJnZXQgPSBjdXJyZW50SW5zdGFuY2UpIHtcclxuICAgIC8vIGNhY2hlIHRoZSBkZWFjdGl2YXRlIGJyYW5jaCBjaGVjayB3cmFwcGVyIGZvciBpbmplY3RlZCBob29rcyBzbyB0aGUgc2FtZVxyXG4gICAgLy8gaG9vayBjYW4gYmUgcHJvcGVybHkgZGVkdXBlZCBieSB0aGUgc2NoZWR1bGVyLiBcIl9fd2RjXCIgc3RhbmRzIGZvciBcIndpdGhcclxuICAgIC8vIGRlYWN0aXZhdGlvbiBjaGVja1wiLlxyXG4gICAgY29uc3Qgd3JhcHBlZEhvb2sgPSBob29rLl9fd2RjIHx8XHJcbiAgICAgICAgKGhvb2suX193ZGMgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgIC8vIG9ubHkgZmlyZSB0aGUgaG9vayBpZiB0aGUgdGFyZ2V0IGluc3RhbmNlIGlzIE5PVCBpbiBhIGRlYWN0aXZhdGVkIGJyYW5jaC5cclxuICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSB0YXJnZXQ7XHJcbiAgICAgICAgICAgIHdoaWxlIChjdXJyZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudC5pc0RlYWN0aXZhdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGhvb2soKTtcclxuICAgICAgICB9KTtcclxuICAgIGluamVjdEhvb2sodHlwZSwgd3JhcHBlZEhvb2ssIHRhcmdldCk7XHJcbiAgICAvLyBJbiBhZGRpdGlvbiB0byByZWdpc3RlcmluZyBpdCBvbiB0aGUgdGFyZ2V0IGluc3RhbmNlLCB3ZSB3YWxrIHVwIHRoZSBwYXJlbnRcclxuICAgIC8vIGNoYWluIGFuZCByZWdpc3RlciBpdCBvbiBhbGwgYW5jZXN0b3IgaW5zdGFuY2VzIHRoYXQgYXJlIGtlZXAtYWxpdmUgcm9vdHMuXHJcbiAgICAvLyBUaGlzIGF2b2lkcyB0aGUgbmVlZCB0byB3YWxrIHRoZSBlbnRpcmUgY29tcG9uZW50IHRyZWUgd2hlbiBpbnZva2luZyB0aGVzZVxyXG4gICAgLy8gaG9va3MsIGFuZCBtb3JlIGltcG9ydGFudGx5LCBhdm9pZHMgdGhlIG5lZWQgdG8gdHJhY2sgY2hpbGQgY29tcG9uZW50cyBpblxyXG4gICAgLy8gYXJyYXlzLlxyXG4gICAgaWYgKHRhcmdldCkge1xyXG4gICAgICAgIGxldCBjdXJyZW50ID0gdGFyZ2V0LnBhcmVudDtcclxuICAgICAgICB3aGlsZSAoY3VycmVudCAmJiBjdXJyZW50LnBhcmVudCkge1xyXG4gICAgICAgICAgICBpZiAoaXNLZWVwQWxpdmUoY3VycmVudC5wYXJlbnQudm5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBpbmplY3RUb0tlZXBBbGl2ZVJvb3Qod3JhcHBlZEhvb2ssIHR5cGUsIHRhcmdldCwgY3VycmVudCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBpbmplY3RUb0tlZXBBbGl2ZVJvb3QoaG9vaywgdHlwZSwgdGFyZ2V0LCBrZWVwQWxpdmVSb290KSB7XHJcbiAgICAvLyBpbmplY3RIb29rIHdyYXBzIHRoZSBvcmlnaW5hbCBmb3IgZXJyb3IgaGFuZGxpbmcsIHNvIG1ha2Ugc3VyZSB0byByZW1vdmVcclxuICAgIC8vIHRoZSB3cmFwcGVkIHZlcnNpb24uXHJcbiAgICBjb25zdCBpbmplY3RlZCA9IGluamVjdEhvb2sodHlwZSwgaG9vaywga2VlcEFsaXZlUm9vdCwgdHJ1ZSAvKiBwcmVwZW5kICovKTtcclxuICAgIG9uVW5tb3VudGVkKCgpID0+IHtcclxuICAgICAgICByZW1vdmUoa2VlcEFsaXZlUm9vdFt0eXBlXSwgaW5qZWN0ZWQpO1xyXG4gICAgfSwgdGFyZ2V0KTtcclxufVxyXG5mdW5jdGlvbiByZXNldFNoYXBlRmxhZyh2bm9kZSkge1xyXG4gICAgbGV0IHNoYXBlRmxhZyA9IHZub2RlLnNoYXBlRmxhZztcclxuICAgIGlmIChzaGFwZUZsYWcgJiAyNTYgLyogQ09NUE9ORU5UX1NIT1VMRF9LRUVQX0FMSVZFICovKSB7XHJcbiAgICAgICAgc2hhcGVGbGFnIC09IDI1NiAvKiBDT01QT05FTlRfU0hPVUxEX0tFRVBfQUxJVkUgKi87XHJcbiAgICB9XHJcbiAgICBpZiAoc2hhcGVGbGFnICYgNTEyIC8qIENPTVBPTkVOVF9LRVBUX0FMSVZFICovKSB7XHJcbiAgICAgICAgc2hhcGVGbGFnIC09IDUxMiAvKiBDT01QT05FTlRfS0VQVF9BTElWRSAqLztcclxuICAgIH1cclxuICAgIHZub2RlLnNoYXBlRmxhZyA9IHNoYXBlRmxhZztcclxufVxuXG5jb25zdCBpc0ludGVybmFsS2V5ID0gKGtleSkgPT4ga2V5WzBdID09PSAnXycgfHwga2V5ID09PSAnJHN0YWJsZSc7XHJcbmNvbnN0IG5vcm1hbGl6ZVNsb3RWYWx1ZSA9ICh2YWx1ZSkgPT4gaXNBcnJheSh2YWx1ZSlcclxuICAgID8gdmFsdWUubWFwKG5vcm1hbGl6ZVZOb2RlKVxyXG4gICAgOiBbbm9ybWFsaXplVk5vZGUodmFsdWUpXTtcclxuY29uc3Qgbm9ybWFsaXplU2xvdCA9IChrZXksIHJhd1Nsb3QsIGN0eCkgPT4gd2l0aEN0eCgocHJvcHMpID0+IHtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgY3VycmVudEluc3RhbmNlKSB7XHJcbiAgICAgICAgd2FybihgU2xvdCBcIiR7a2V5fVwiIGludm9rZWQgb3V0c2lkZSBvZiB0aGUgcmVuZGVyIGZ1bmN0aW9uOiBgICtcclxuICAgICAgICAgICAgYHRoaXMgd2lsbCBub3QgdHJhY2sgZGVwZW5kZW5jaWVzIHVzZWQgaW4gdGhlIHNsb3QuIGAgK1xyXG4gICAgICAgICAgICBgSW52b2tlIHRoZSBzbG90IGZ1bmN0aW9uIGluc2lkZSB0aGUgcmVuZGVyIGZ1bmN0aW9uIGluc3RlYWQuYCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbm9ybWFsaXplU2xvdFZhbHVlKHJhd1Nsb3QocHJvcHMpKTtcclxufSwgY3R4KTtcclxuY29uc3Qgbm9ybWFsaXplT2JqZWN0U2xvdHMgPSAocmF3U2xvdHMsIHNsb3RzKSA9PiB7XHJcbiAgICBjb25zdCBjdHggPSByYXdTbG90cy5fY3R4O1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcmF3U2xvdHMpIHtcclxuICAgICAgICBpZiAoaXNJbnRlcm5hbEtleShrZXkpKVxyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHJhd1Nsb3RzW2tleV07XHJcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHNsb3RzW2tleV0gPSBub3JtYWxpemVTbG90KGtleSwgdmFsdWUsIGN0eCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHZhbHVlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgTm9uLWZ1bmN0aW9uIHZhbHVlIGVuY291bnRlcmVkIGZvciBzbG90IFwiJHtrZXl9XCIuIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgIGBQcmVmZXIgZnVuY3Rpb24gc2xvdHMgZm9yIGJldHRlciBwZXJmb3JtYW5jZS5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplU2xvdFZhbHVlKHZhbHVlKTtcclxuICAgICAgICAgICAgc2xvdHNba2V5XSA9ICgpID0+IG5vcm1hbGl6ZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5jb25zdCBub3JtYWxpemVWTm9kZVNsb3RzID0gKGluc3RhbmNlLCBjaGlsZHJlbikgPT4ge1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhaXNLZWVwQWxpdmUoaW5zdGFuY2Uudm5vZGUpKSB7XHJcbiAgICAgICAgd2FybihgTm9uLWZ1bmN0aW9uIHZhbHVlIGVuY291bnRlcmVkIGZvciBkZWZhdWx0IHNsb3QuIGAgK1xyXG4gICAgICAgICAgICBgUHJlZmVyIGZ1bmN0aW9uIHNsb3RzIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuYCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplU2xvdFZhbHVlKGNoaWxkcmVuKTtcclxuICAgIGluc3RhbmNlLnNsb3RzLmRlZmF1bHQgPSAoKSA9PiBub3JtYWxpemVkO1xyXG59O1xyXG5jb25zdCBpbml0U2xvdHMgPSAoaW5zdGFuY2UsIGNoaWxkcmVuKSA9PiB7XHJcbiAgICBpZiAoaW5zdGFuY2Uudm5vZGUuc2hhcGVGbGFnICYgMzIgLyogU0xPVFNfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICBjb25zdCB0eXBlID0gY2hpbGRyZW4uXztcclxuICAgICAgICBpZiAodHlwZSkge1xyXG4gICAgICAgICAgICBpbnN0YW5jZS5zbG90cyA9IGNoaWxkcmVuO1xyXG4gICAgICAgICAgICAvLyBtYWtlIGNvbXBpbGVyIG1hcmtlciBub24tZW51bWVyYWJsZVxyXG4gICAgICAgICAgICBkZWYoY2hpbGRyZW4sICdfJywgdHlwZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBub3JtYWxpemVPYmplY3RTbG90cyhjaGlsZHJlbiwgKGluc3RhbmNlLnNsb3RzID0ge30pKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpbnN0YW5jZS5zbG90cyA9IHt9O1xyXG4gICAgICAgIGlmIChjaGlsZHJlbikge1xyXG4gICAgICAgICAgICBub3JtYWxpemVWTm9kZVNsb3RzKGluc3RhbmNlLCBjaGlsZHJlbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZGVmKGluc3RhbmNlLnNsb3RzLCBJbnRlcm5hbE9iamVjdEtleSwgMSk7XHJcbn07XHJcbmNvbnN0IHVwZGF0ZVNsb3RzID0gKGluc3RhbmNlLCBjaGlsZHJlbikgPT4ge1xyXG4gICAgY29uc3QgeyB2bm9kZSwgc2xvdHMgfSA9IGluc3RhbmNlO1xyXG4gICAgbGV0IG5lZWREZWxldGlvbkNoZWNrID0gdHJ1ZTtcclxuICAgIGxldCBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQgPSBFTVBUWV9PQko7XHJcbiAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMzIgLyogU0xPVFNfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICBjb25zdCB0eXBlID0gY2hpbGRyZW4uXztcclxuICAgICAgICBpZiAodHlwZSkge1xyXG4gICAgICAgICAgICAvLyBjb21waWxlZCBzbG90cy5cclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBpc0htclVwZGF0aW5nKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBQYXJlbnQgd2FzIEhNUiB1cGRhdGVkIHNvIHNsb3QgY29udGVudCBtYXkgaGF2ZSBjaGFuZ2VkLlxyXG4gICAgICAgICAgICAgICAgLy8gZm9yY2UgdXBkYXRlIHNsb3RzIGFuZCBtYXJrIGluc3RhbmNlIGZvciBobXIgYXMgd2VsbFxyXG4gICAgICAgICAgICAgICAgZXh0ZW5kKHNsb3RzLCBjaGlsZHJlbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gMSAvKiBTVEFCTEUgKi8pIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbXBpbGVkIEFORCBzdGFibGUuXHJcbiAgICAgICAgICAgICAgICAvLyBubyBuZWVkIHRvIHVwZGF0ZSwgYW5kIHNraXAgc3RhbGUgc2xvdHMgcmVtb3ZhbC5cclxuICAgICAgICAgICAgICAgIG5lZWREZWxldGlvbkNoZWNrID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjb21waWxlZCBidXQgZHluYW1pYyAodi1pZi92LWZvciBvbiBzbG90cykgLSB1cGRhdGUgc2xvdHMsIGJ1dCBza2lwXHJcbiAgICAgICAgICAgICAgICAvLyBub3JtYWxpemF0aW9uLlxyXG4gICAgICAgICAgICAgICAgZXh0ZW5kKHNsb3RzLCBjaGlsZHJlbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG5lZWREZWxldGlvbkNoZWNrID0gIWNoaWxkcmVuLiRzdGFibGU7XHJcbiAgICAgICAgICAgIG5vcm1hbGl6ZU9iamVjdFNsb3RzKGNoaWxkcmVuLCBzbG90cyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRlbGV0aW9uQ29tcGFyaXNvblRhcmdldCA9IGNoaWxkcmVuO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoY2hpbGRyZW4pIHtcclxuICAgICAgICAvLyBub24gc2xvdCBvYmplY3QgY2hpbGRyZW4gKGRpcmVjdCB2YWx1ZSkgcGFzc2VkIHRvIGEgY29tcG9uZW50XHJcbiAgICAgICAgbm9ybWFsaXplVk5vZGVTbG90cyhpbnN0YW5jZSwgY2hpbGRyZW4pO1xyXG4gICAgICAgIGRlbGV0aW9uQ29tcGFyaXNvblRhcmdldCA9IHsgZGVmYXVsdDogMSB9O1xyXG4gICAgfVxyXG4gICAgLy8gZGVsZXRlIHN0YWxlIHNsb3RzXHJcbiAgICBpZiAobmVlZERlbGV0aW9uQ2hlY2spIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzbG90cykge1xyXG4gICAgICAgICAgICBpZiAoIWlzSW50ZXJuYWxLZXkoa2V5KSAmJiAhKGtleSBpbiBkZWxldGlvbkNvbXBhcmlzb25UYXJnZXQpKSB7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgc2xvdHNba2V5XTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcblxuLyoqXHJcblJ1bnRpbWUgaGVscGVyIGZvciBhcHBseWluZyBkaXJlY3RpdmVzIHRvIGEgdm5vZGUuIEV4YW1wbGUgdXNhZ2U6XHJcblxuY29uc3QgY29tcCA9IHJlc29sdmVDb21wb25lbnQoJ2NvbXAnKVxyXG5jb25zdCBmb28gPSByZXNvbHZlRGlyZWN0aXZlKCdmb28nKVxyXG5jb25zdCBiYXIgPSByZXNvbHZlRGlyZWN0aXZlKCdiYXInKVxyXG5cbnJldHVybiB3aXRoRGlyZWN0aXZlcyhoKGNvbXApLCBbXHJcbiAgW2ZvbywgdGhpcy54XSxcclxuICBbYmFyLCB0aGlzLnldXHJcbl0pXHJcbiovXHJcbmNvbnN0IGlzQnVpbHRJbkRpcmVjdGl2ZSA9IC8qI19fUFVSRV9fKi8gbWFrZU1hcCgnYmluZCxjbG9hayxlbHNlLWlmLGVsc2UsZm9yLGh0bWwsaWYsbW9kZWwsb24sb25jZSxwcmUsc2hvdyxzbG90LHRleHQnKTtcclxuZnVuY3Rpb24gdmFsaWRhdGVEaXJlY3RpdmVOYW1lKG5hbWUpIHtcclxuICAgIGlmIChpc0J1aWx0SW5EaXJlY3RpdmUobmFtZSkpIHtcclxuICAgICAgICB3YXJuKCdEbyBub3QgdXNlIGJ1aWx0LWluIGRpcmVjdGl2ZSBpZHMgYXMgY3VzdG9tIGRpcmVjdGl2ZSBpZDogJyArIG5hbWUpO1xyXG4gICAgfVxyXG59XHJcbi8qKlxyXG4gKiBBZGRzIGRpcmVjdGl2ZXMgdG8gYSBWTm9kZS5cclxuICovXHJcbmZ1bmN0aW9uIHdpdGhEaXJlY3RpdmVzKHZub2RlLCBkaXJlY3RpdmVzKSB7XHJcbiAgICBjb25zdCBpbnRlcm5hbEluc3RhbmNlID0gY3VycmVudFJlbmRlcmluZ0luc3RhbmNlO1xyXG4gICAgaWYgKGludGVybmFsSW5zdGFuY2UgPT09IG51bGwpIHtcclxuICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgd2Fybihgd2l0aERpcmVjdGl2ZXMgY2FuIG9ubHkgYmUgdXNlZCBpbnNpZGUgcmVuZGVyIGZ1bmN0aW9ucy5gKTtcclxuICAgICAgICByZXR1cm4gdm5vZGU7XHJcbiAgICB9XHJcbiAgICBjb25zdCBpbnN0YW5jZSA9IGludGVybmFsSW5zdGFuY2UucHJveHk7XHJcbiAgICBjb25zdCBiaW5kaW5ncyA9IHZub2RlLmRpcnMgfHwgKHZub2RlLmRpcnMgPSBbXSk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpcmVjdGl2ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBsZXQgW2RpciwgdmFsdWUsIGFyZywgbW9kaWZpZXJzID0gRU1QVFlfT0JKXSA9IGRpcmVjdGl2ZXNbaV07XHJcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oZGlyKSkge1xyXG4gICAgICAgICAgICBkaXIgPSB7XHJcbiAgICAgICAgICAgICAgICBtb3VudGVkOiBkaXIsXHJcbiAgICAgICAgICAgICAgICB1cGRhdGVkOiBkaXJcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYmluZGluZ3MucHVzaCh7XHJcbiAgICAgICAgICAgIGRpcixcclxuICAgICAgICAgICAgaW5zdGFuY2UsXHJcbiAgICAgICAgICAgIHZhbHVlLFxyXG4gICAgICAgICAgICBvbGRWYWx1ZTogdm9pZCAwLFxyXG4gICAgICAgICAgICBhcmcsXHJcbiAgICAgICAgICAgIG1vZGlmaWVyc1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZub2RlO1xyXG59XHJcbmZ1bmN0aW9uIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIHByZXZWTm9kZSwgaW5zdGFuY2UsIG5hbWUpIHtcclxuICAgIGNvbnN0IGJpbmRpbmdzID0gdm5vZGUuZGlycztcclxuICAgIGNvbnN0IG9sZEJpbmRpbmdzID0gcHJldlZOb2RlICYmIHByZXZWTm9kZS5kaXJzO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBiaW5kaW5ncy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSBiaW5kaW5nc1tpXTtcclxuICAgICAgICBpZiAob2xkQmluZGluZ3MpIHtcclxuICAgICAgICAgICAgYmluZGluZy5vbGRWYWx1ZSA9IG9sZEJpbmRpbmdzW2ldLnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBob29rID0gYmluZGluZy5kaXJbbmFtZV07XHJcbiAgICAgICAgaWYgKGhvb2spIHtcclxuICAgICAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoaG9vaywgaW5zdGFuY2UsIDggLyogRElSRUNUSVZFX0hPT0sgKi8sIFtcclxuICAgICAgICAgICAgICAgIHZub2RlLmVsLFxyXG4gICAgICAgICAgICAgICAgYmluZGluZyxcclxuICAgICAgICAgICAgICAgIHZub2RlLFxyXG4gICAgICAgICAgICAgICAgcHJldlZOb2RlXHJcbiAgICAgICAgICAgIF0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxuXG5mdW5jdGlvbiBjcmVhdGVBcHBDb250ZXh0KCkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBhcHA6IG51bGwsXHJcbiAgICAgICAgY29uZmlnOiB7XHJcbiAgICAgICAgICAgIGlzTmF0aXZlVGFnOiBOTyxcclxuICAgICAgICAgICAgcGVyZm9ybWFuY2U6IGZhbHNlLFxyXG4gICAgICAgICAgICBnbG9iYWxQcm9wZXJ0aWVzOiB7fSxcclxuICAgICAgICAgICAgb3B0aW9uTWVyZ2VTdHJhdGVnaWVzOiB7fSxcclxuICAgICAgICAgICAgaXNDdXN0b21FbGVtZW50OiBOTyxcclxuICAgICAgICAgICAgZXJyb3JIYW5kbGVyOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHdhcm5IYW5kbGVyOiB1bmRlZmluZWRcclxuICAgICAgICB9LFxyXG4gICAgICAgIG1peGluczogW10sXHJcbiAgICAgICAgY29tcG9uZW50czoge30sXHJcbiAgICAgICAgZGlyZWN0aXZlczoge30sXHJcbiAgICAgICAgcHJvdmlkZXM6IE9iamVjdC5jcmVhdGUobnVsbClcclxuICAgIH07XHJcbn1cclxubGV0IHVpZCA9IDA7XHJcbmZ1bmN0aW9uIGNyZWF0ZUFwcEFQSShyZW5kZXIsIGh5ZHJhdGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVBcHAocm9vdENvbXBvbmVudCwgcm9vdFByb3BzID0gbnVsbCkge1xyXG4gICAgICAgIGlmIChyb290UHJvcHMgIT0gbnVsbCAmJiAhaXNPYmplY3Qocm9vdFByb3BzKSkge1xyXG4gICAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgd2Fybihgcm9vdCBwcm9wcyBwYXNzZWQgdG8gYXBwLm1vdW50KCkgbXVzdCBiZSBhbiBvYmplY3QuYCk7XHJcbiAgICAgICAgICAgIHJvb3RQcm9wcyA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBjcmVhdGVBcHBDb250ZXh0KCk7XHJcbiAgICAgICAgY29uc3QgaW5zdGFsbGVkUGx1Z2lucyA9IG5ldyBTZXQoKTtcclxuICAgICAgICBsZXQgaXNNb3VudGVkID0gZmFsc2U7XHJcbiAgICAgICAgY29uc3QgYXBwID0gKGNvbnRleHQuYXBwID0ge1xyXG4gICAgICAgICAgICBfdWlkOiB1aWQrKyxcclxuICAgICAgICAgICAgX2NvbXBvbmVudDogcm9vdENvbXBvbmVudCxcclxuICAgICAgICAgICAgX3Byb3BzOiByb290UHJvcHMsXHJcbiAgICAgICAgICAgIF9jb250YWluZXI6IG51bGwsXHJcbiAgICAgICAgICAgIF9jb250ZXh0OiBjb250ZXh0LFxyXG4gICAgICAgICAgICB2ZXJzaW9uLFxyXG4gICAgICAgICAgICBnZXQgY29uZmlnKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuY29uZmlnO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBzZXQgY29uZmlnKHYpIHtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBhcHAuY29uZmlnIGNhbm5vdCBiZSByZXBsYWNlZC4gTW9kaWZ5IGluZGl2aWR1YWwgb3B0aW9ucyBpbnN0ZWFkLmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB1c2UocGx1Z2luLCAuLi5vcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFsbGVkUGx1Z2lucy5oYXMocGx1Z2luKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuKGBQbHVnaW4gaGFzIGFscmVhZHkgYmVlbiBhcHBsaWVkIHRvIHRhcmdldCBhcHAuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChwbHVnaW4gJiYgaXNGdW5jdGlvbihwbHVnaW4uaW5zdGFsbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsZWRQbHVnaW5zLmFkZChwbHVnaW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIHBsdWdpbi5pbnN0YWxsKGFwcCwgLi4ub3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChpc0Z1bmN0aW9uKHBsdWdpbikpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnN0YWxsZWRQbHVnaW5zLmFkZChwbHVnaW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIHBsdWdpbihhcHAsIC4uLm9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgQSBwbHVnaW4gbXVzdCBlaXRoZXIgYmUgYSBmdW5jdGlvbiBvciBhbiBvYmplY3Qgd2l0aCBhbiBcImluc3RhbGxcIiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYGZ1bmN0aW9uLmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwcDtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgbWl4aW4obWl4aW4pIHtcclxuICAgICAgICAgICAgICAgIGlmIChfX1ZVRV9PUFRJT05TX0FQSV9fKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb250ZXh0Lm1peGlucy5pbmNsdWRlcyhtaXhpbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5taXhpbnMucHVzaChtaXhpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKCdNaXhpbiBoYXMgYWxyZWFkeSBiZWVuIGFwcGxpZWQgdG8gdGFyZ2V0IGFwcCcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG1peGluLm5hbWUgPyBgOiAke21peGluLm5hbWV9YCA6ICcnKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybignTWl4aW5zIGFyZSBvbmx5IGF2YWlsYWJsZSBpbiBidWlsZHMgc3VwcG9ydGluZyBPcHRpb25zIEFQSScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwcDtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY29tcG9uZW50KG5hbWUsIGNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlQ29tcG9uZW50TmFtZShuYW1lLCBjb250ZXh0LmNvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIWNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmNvbXBvbmVudHNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENvbXBvbmVudCBcIiR7bmFtZX1cIiBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQgaW4gdGFyZ2V0IGFwcC5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnRleHQuY29tcG9uZW50c1tuYW1lXSA9IGNvbXBvbmVudDtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGRpcmVjdGl2ZShuYW1lLCBkaXJlY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZURpcmVjdGl2ZU5hbWUobmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIWRpcmVjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmRpcmVjdGl2ZXNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGNvbnRleHQuZGlyZWN0aXZlc1tuYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYERpcmVjdGl2ZSBcIiR7bmFtZX1cIiBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQgaW4gdGFyZ2V0IGFwcC5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnRleHQuZGlyZWN0aXZlc1tuYW1lXSA9IGRpcmVjdGl2ZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG1vdW50KHJvb3RDb250YWluZXIsIGlzSHlkcmF0ZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpc01vdW50ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2bm9kZSA9IGNyZWF0ZVZOb2RlKHJvb3RDb21wb25lbnQsIHJvb3RQcm9wcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RvcmUgYXBwIGNvbnRleHQgb24gdGhlIHJvb3QgVk5vZGUuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyB3aWxsIGJlIHNldCBvbiB0aGUgcm9vdCBpbnN0YW5jZSBvbiBpbml0aWFsIG1vdW50LlxyXG4gICAgICAgICAgICAgICAgICAgIHZub2RlLmFwcENvbnRleHQgPSBjb250ZXh0O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEhNUiByb290IHJlbG9hZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5yZWxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW5kZXIoY2xvbmVWTm9kZSh2bm9kZSksIHJvb3RDb250YWluZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNIeWRyYXRlICYmIGh5ZHJhdGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaHlkcmF0ZSh2bm9kZSwgcm9vdENvbnRhaW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXIodm5vZGUsIHJvb3RDb250YWluZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpc01vdW50ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGFwcC5fY29udGFpbmVyID0gcm9vdENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgICAgICByb290Q29udGFpbmVyLl9fdnVlX2FwcF9fID0gYXBwO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRldnRvb2xzSW5pdEFwcChhcHAsIHZlcnNpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdm5vZGUuY29tcG9uZW50LnByb3h5O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgQXBwIGhhcyBhbHJlYWR5IGJlZW4gbW91bnRlZC5cXG5gICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYElmIHlvdSB3YW50IHRvIHJlbW91bnQgdGhlIHNhbWUgYXBwLCBtb3ZlIHlvdXIgYXBwIGNyZWF0aW9uIGxvZ2ljIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgaW50byBhIGZhY3RvcnkgZnVuY3Rpb24gYW5kIGNyZWF0ZSBmcmVzaCBhcHAgaW5zdGFuY2VzIGZvciBlYWNoIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgbW91bnQgLSBlLmcuIFxcYGNvbnN0IGNyZWF0ZU15QXBwID0gKCkgPT4gY3JlYXRlQXBwKEFwcClcXGBgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgdW5tb3VudCgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc01vdW50ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZW5kZXIobnVsbCwgYXBwLl9jb250YWluZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRldnRvb2xzVW5tb3VudEFwcChhcHApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYENhbm5vdCB1bm1vdW50IGFuIGFwcCB0aGF0IGlzIG5vdCBtb3VudGVkLmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBwcm92aWRlKGtleSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYga2V5IGluIGNvbnRleHQucHJvdmlkZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKGBBcHAgYWxyZWFkeSBwcm92aWRlcyBwcm9wZXJ0eSB3aXRoIGtleSBcIiR7U3RyaW5nKGtleSl9XCIuIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgSXQgd2lsbCBiZSBvdmVyd3JpdHRlbiB3aXRoIHRoZSBuZXcgdmFsdWUuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBUeXBlU2NyaXB0IGRvZXNuJ3QgYWxsb3cgc3ltYm9scyBhcyBpbmRleCB0eXBlXHJcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vTWljcm9zb2Z0L1R5cGVTY3JpcHQvaXNzdWVzLzI0NTg3XHJcbiAgICAgICAgICAgICAgICBjb250ZXh0LnByb3ZpZGVzW2tleV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhcHA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gYXBwO1xyXG4gICAgfTtcclxufVxuXG5sZXQgaGFzTWlzbWF0Y2ggPSBmYWxzZTtcclxuY29uc3QgaXNTVkdDb250YWluZXIgPSAoY29udGFpbmVyKSA9PiAvc3ZnLy50ZXN0KGNvbnRhaW5lci5uYW1lc3BhY2VVUkkpICYmIGNvbnRhaW5lci50YWdOYW1lICE9PSAnZm9yZWlnbk9iamVjdCc7XHJcbmNvbnN0IGlzQ29tbWVudCA9IChub2RlKSA9PiBub2RlLm5vZGVUeXBlID09PSA4IC8qIENPTU1FTlQgKi87XHJcbi8vIE5vdGU6IGh5ZHJhdGlvbiBpcyBET00tc3BlY2lmaWNcclxuLy8gQnV0IHdlIGhhdmUgdG8gcGxhY2UgaXQgaW4gY29yZSBkdWUgdG8gdGlnaHQgY291cGxpbmcgd2l0aCBjb3JlIC0gc3BsaXR0aW5nXHJcbi8vIGl0IG91dCBjcmVhdGVzIGEgdG9uIG9mIHVubmVjZXNzYXJ5IGNvbXBsZXhpdHkuXHJcbi8vIEh5ZHJhdGlvbiBhbHNvIGRlcGVuZHMgb24gc29tZSByZW5kZXJlciBpbnRlcm5hbCBsb2dpYyB3aGljaCBuZWVkcyB0byBiZVxyXG4vLyBwYXNzZWQgaW4gdmlhIGFyZ3VtZW50cy5cclxuZnVuY3Rpb24gY3JlYXRlSHlkcmF0aW9uRnVuY3Rpb25zKHJlbmRlcmVySW50ZXJuYWxzKSB7XHJcbiAgICBjb25zdCB7IG10OiBtb3VudENvbXBvbmVudCwgcDogcGF0Y2gsIG86IHsgcGF0Y2hQcm9wLCBuZXh0U2libGluZywgcGFyZW50Tm9kZSwgcmVtb3ZlLCBpbnNlcnQsIGNyZWF0ZUNvbW1lbnQgfSB9ID0gcmVuZGVyZXJJbnRlcm5hbHM7XHJcbiAgICBjb25zdCBoeWRyYXRlID0gKHZub2RlLCBjb250YWluZXIpID0+IHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFjb250YWluZXIuaGFzQ2hpbGROb2RlcygpKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYEF0dGVtcHRpbmcgdG8gaHlkcmF0ZSBleGlzdGluZyBtYXJrdXAgYnV0IGNvbnRhaW5lciBpcyBlbXB0eS4gYCArXHJcbiAgICAgICAgICAgICAgICBgUGVyZm9ybWluZyBmdWxsIG1vdW50IGluc3RlYWQuYCk7XHJcbiAgICAgICAgICAgIHBhdGNoKG51bGwsIHZub2RlLCBjb250YWluZXIpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGhhc01pc21hdGNoID0gZmFsc2U7XHJcbiAgICAgICAgaHlkcmF0ZU5vZGUoY29udGFpbmVyLmZpcnN0Q2hpbGQsIHZub2RlLCBudWxsLCBudWxsKTtcclxuICAgICAgICBmbHVzaFBvc3RGbHVzaENicygpO1xyXG4gICAgICAgIGlmIChoYXNNaXNtYXRjaCAmJiAhZmFsc2UpIHtcclxuICAgICAgICAgICAgLy8gdGhpcyBlcnJvciBzaG91bGQgc2hvdyB1cCBpbiBwcm9kdWN0aW9uXHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEh5ZHJhdGlvbiBjb21wbGV0ZWQgYnV0IGNvbnRhaW5zIG1pc21hdGNoZXMuYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IGh5ZHJhdGVOb2RlID0gKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQgPSBmYWxzZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGlzRnJhZ21lbnRTdGFydCA9IGlzQ29tbWVudChub2RlKSAmJiBub2RlLmRhdGEgPT09ICdbJztcclxuICAgICAgICBjb25zdCBvbk1pc21hdGNoID0gKCkgPT4gaGFuZGxlTWlzbWF0Y2gobm9kZSwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzRnJhZ21lbnRTdGFydCk7XHJcbiAgICAgICAgY29uc3QgeyB0eXBlLCByZWYsIHNoYXBlRmxhZyB9ID0gdm5vZGU7XHJcbiAgICAgICAgY29uc3QgZG9tVHlwZSA9IG5vZGUubm9kZVR5cGU7XHJcbiAgICAgICAgdm5vZGUuZWwgPSBub2RlO1xyXG4gICAgICAgIGxldCBuZXh0Tm9kZSA9IG51bGw7XHJcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgVGV4dDpcclxuICAgICAgICAgICAgICAgIGlmIChkb21UeXBlICE9PSAzIC8qIFRFWFQgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IG9uTWlzbWF0Y2goKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmRhdGEgIT09IHZub2RlLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc01pc21hdGNoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBIeWRyYXRpb24gdGV4dCBtaXNtYXRjaDpgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgXFxuLSBDbGllbnQ6ICR7SlNPTi5zdHJpbmdpZnkobm9kZS5kYXRhKX1gICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgXFxuLSBTZXJ2ZXI6ICR7SlNPTi5zdHJpbmdpZnkodm5vZGUuY2hpbGRyZW4pfWApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLmRhdGEgPSB2bm9kZS5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBuZXh0U2libGluZyhub2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIENvbW1lbnQ6XHJcbiAgICAgICAgICAgICAgICBpZiAoZG9tVHlwZSAhPT0gOCAvKiBDT01NRU5UICovIHx8IGlzRnJhZ21lbnRTdGFydCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5leHROb2RlID0gb25NaXNtYXRjaCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBuZXh0U2libGluZyhub2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFN0YXRpYzpcclxuICAgICAgICAgICAgICAgIGlmIChkb21UeXBlICE9PSAxIC8qIEVMRU1FTlQgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IG9uTWlzbWF0Y2goKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGRldGVybWluZSBhbmNob3IsIGFkb3B0IGNvbnRlbnRcclxuICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IG5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHN0YXRpYyB2bm9kZSBoYXMgaXRzIGNvbnRlbnQgc3RyaXBwZWQgZHVyaW5nIGJ1aWxkLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFkb3B0IGl0IGZyb20gdGhlIHNlcnZlci1yZW5kZXJlZCBIVE1MLlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZWRUb0Fkb3B0Q29udGVudCA9ICF2bm9kZS5jaGlsZHJlbi5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2bm9kZS5zdGF0aWNDb3VudDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZWVkVG9BZG9wdENvbnRlbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2bm9kZS5jaGlsZHJlbiArPSBuZXh0Tm9kZS5vdXRlckhUTUw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID09PSB2bm9kZS5zdGF0aWNDb3VudCAtIDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZub2RlLmFuY2hvciA9IG5leHROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHROb2RlID0gbmV4dFNpYmxpbmcobmV4dE5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dE5vZGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBGcmFnbWVudDpcclxuICAgICAgICAgICAgICAgIGlmICghaXNGcmFnbWVudFN0YXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IGh5ZHJhdGVGcmFnbWVudChub2RlLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgaWYgKHNoYXBlRmxhZyAmIDEgLyogRUxFTUVOVCAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChkb21UeXBlICE9PSAxIC8qIEVMRU1FTlQgKi8gfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdm5vZGUudHlwZSAhPT0gbm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBvbk1pc21hdGNoKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IGh5ZHJhdGVFbGVtZW50KG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNoYXBlRmxhZyAmIDYgLyogQ09NUE9ORU5UICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gd2hlbiBzZXR0aW5nIHVwIHRoZSByZW5kZXIgZWZmZWN0LCBpZiB0aGUgaW5pdGlhbCB2bm9kZSBhbHJlYWR5XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaGFzIC5lbCBzZXQsIHRoZSBjb21wb25lbnQgd2lsbCBwZXJmb3JtIGh5ZHJhdGlvbiBpbnN0ZWFkIG9mIG1vdW50XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gb24gaXRzIHN1Yi10cmVlLlxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHBhcmVudE5vZGUobm9kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaHlkcmF0ZUNvbXBvbmVudCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91bnRDb21wb25lbnQodm5vZGUsIGNvbnRhaW5lciwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkdDb250YWluZXIoY29udGFpbmVyKSwgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFzeW5jIGNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvYWRBc3luYyA9IHZub2RlLnR5cGUuX19hc3luY0xvYWRlcjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobG9hZEFzeW5jKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRBc3luYygpLnRoZW4oaHlkcmF0ZUNvbXBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoeWRyYXRlQ29tcG9uZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbXBvbmVudCBtYXkgYmUgYXN5bmMsIHNvIGluIHRoZSBjYXNlIG9mIGZyYWdtZW50cyB3ZSBjYW5ub3QgcmVseVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG9uIGNvbXBvbmVudCdzIHJlbmRlcmVkIG91dHB1dCB0byBkZXRlcm1pbmUgdGhlIGVuZCBvZiB0aGUgZnJhZ21lbnRcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbnN0ZWFkLCB3ZSBkbyBhIGxvb2thaGVhZCB0byBmaW5kIHRoZSBlbmQgYW5jaG9yIG5vZGUuXHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dE5vZGUgPSBpc0ZyYWdtZW50U3RhcnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBsb2NhdGVDbG9zaW5nQXN5bmNBbmNob3Iobm9kZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBuZXh0U2libGluZyhub2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNoYXBlRmxhZyAmIDY0IC8qIFRFTEVQT1JUICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbVR5cGUgIT09IDggLyogQ09NTUVOVCAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IG9uTWlzbWF0Y2goKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHROb2RlID0gdm5vZGUudHlwZS5oeWRyYXRlKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQsIHJlbmRlcmVySW50ZXJuYWxzLCBoeWRyYXRlQ2hpbGRyZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBzaGFwZUZsYWcgJiAxMjggLyogU1VTUEVOU0UgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0Tm9kZSA9IHZub2RlLnR5cGUuaHlkcmF0ZShub2RlLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkdDb250YWluZXIocGFyZW50Tm9kZShub2RlKSksIG9wdGltaXplZCwgcmVuZGVyZXJJbnRlcm5hbHMsIGh5ZHJhdGVOb2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oJ0ludmFsaWQgSG9zdFZOb2RlIHR5cGU6JywgdHlwZSwgYCgke3R5cGVvZiB0eXBlfSlgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlZiAhPSBudWxsICYmIHBhcmVudENvbXBvbmVudCkge1xyXG4gICAgICAgICAgICBzZXRSZWYocmVmLCBudWxsLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB2bm9kZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZXh0Tm9kZTtcclxuICAgIH07XHJcbiAgICBjb25zdCBoeWRyYXRlRWxlbWVudCA9IChlbCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIG9wdGltaXplZCkgPT4ge1xyXG4gICAgICAgIG9wdGltaXplZCA9IG9wdGltaXplZCB8fCAhIXZub2RlLmR5bmFtaWNDaGlsZHJlbjtcclxuICAgICAgICBjb25zdCB7IHByb3BzLCBwYXRjaEZsYWcsIHNoYXBlRmxhZywgZGlycyB9ID0gdm5vZGU7XHJcbiAgICAgICAgLy8gc2tpcCBwcm9wcyAmIGNoaWxkcmVuIGlmIHRoaXMgaXMgaG9pc3RlZCBzdGF0aWMgbm9kZXNcclxuICAgICAgICBpZiAocGF0Y2hGbGFnICE9PSAtMSAvKiBIT0lTVEVEICovKSB7XHJcbiAgICAgICAgICAgIGlmIChkaXJzKSB7XHJcbiAgICAgICAgICAgICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICdjcmVhdGVkJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gcHJvcHNcclxuICAgICAgICAgICAgaWYgKHByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW9wdGltaXplZCB8fFxyXG4gICAgICAgICAgICAgICAgICAgIChwYXRjaEZsYWcgJiAxNiAvKiBGVUxMX1BST1BTICovIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoRmxhZyAmIDMyIC8qIEhZRFJBVEVfRVZFTlRTICovKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNSZXNlcnZlZFByb3Aoa2V5KSAmJiBpc09uKGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoUHJvcChlbCwga2V5LCBudWxsLCBwcm9wc1trZXldKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHByb3BzLm9uQ2xpY2spIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBGYXN0IHBhdGggZm9yIGNsaWNrIGxpc3RlbmVycyAod2hpY2ggaXMgbW9zdCBvZnRlbikgdG8gYXZvaWRcclxuICAgICAgICAgICAgICAgICAgICAvLyBpdGVyYXRpbmcgdGhyb3VnaCBwcm9wcy5cclxuICAgICAgICAgICAgICAgICAgICBwYXRjaFByb3AoZWwsICdvbkNsaWNrJywgbnVsbCwgcHJvcHMub25DbGljayk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdm5vZGUgLyBkaXJlY3RpdmUgaG9va3NcclxuICAgICAgICAgICAgbGV0IHZub2RlSG9va3M7XHJcbiAgICAgICAgICAgIGlmICgodm5vZGVIb29rcyA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVCZWZvcmVNb3VudCkpIHtcclxuICAgICAgICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2tzLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZGlycykge1xyXG4gICAgICAgICAgICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAnYmVmb3JlTW91bnQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoKHZub2RlSG9va3MgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlTW91bnRlZCkgfHwgZGlycykge1xyXG4gICAgICAgICAgICAgICAgcXVldWVFZmZlY3RXaXRoU3VzcGVuc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHZub2RlSG9va3MgJiYgaW52b2tlVk5vZGVIb29rKHZub2RlSG9va3MsIHBhcmVudENvbXBvbmVudCwgdm5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRpcnMgJiYgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAnbW91bnRlZCcpO1xyXG4gICAgICAgICAgICAgICAgfSwgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGNoaWxkcmVuXHJcbiAgICAgICAgICAgIGlmIChzaGFwZUZsYWcgJiAxNiAvKiBBUlJBWV9DSElMRFJFTiAqLyAmJlxyXG4gICAgICAgICAgICAgICAgLy8gc2tpcCBpZiBlbGVtZW50IGhhcyBpbm5lckhUTUwgLyB0ZXh0Q29udGVudFxyXG4gICAgICAgICAgICAgICAgIShwcm9wcyAmJiAocHJvcHMuaW5uZXJIVE1MIHx8IHByb3BzLnRleHRDb250ZW50KSkpIHtcclxuICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gaHlkcmF0ZUNoaWxkcmVuKGVsLmZpcnN0Q2hpbGQsIHZub2RlLCBlbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIGxldCBoYXNXYXJuZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaGFzTWlzbWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWhhc1dhcm5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBIeWRyYXRpb24gY2hpbGRyZW4gbWlzbWF0Y2ggaW4gPCR7dm5vZGUudHlwZX0+OiBgICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBzZXJ2ZXIgcmVuZGVyZWQgZWxlbWVudCBjb250YWlucyBtb3JlIGNoaWxkIG5vZGVzIHRoYW4gY2xpZW50IHZkb20uYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc1dhcm5lZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBTU1JlZCBET00gY29udGFpbnMgbW9yZSBub2RlcyB0aGFuIGl0IHNob3VsZC4gUmVtb3ZlIHRoZW0uXHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VyID0gbmV4dDtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5uZXh0U2libGluZztcclxuICAgICAgICAgICAgICAgICAgICByZW1vdmUoY3VyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChzaGFwZUZsYWcgJiA4IC8qIFRFWFRfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICAgICAgICAgIGlmIChlbC50ZXh0Q29udGVudCAhPT0gdm5vZGUuY2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICBoYXNNaXNtYXRjaCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm4oYEh5ZHJhdGlvbiB0ZXh0IGNvbnRlbnQgbWlzbWF0Y2ggaW4gPCR7dm5vZGUudHlwZX0+OlxcbmAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0gQ2xpZW50OiAke2VsLnRleHRDb250ZW50fVxcbmAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYC0gU2VydmVyOiAke3Zub2RlLmNoaWxkcmVufWApO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsLnRleHRDb250ZW50ID0gdm5vZGUuY2hpbGRyZW47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGVsLm5leHRTaWJsaW5nO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IGh5ZHJhdGVDaGlsZHJlbiA9IChub2RlLCB2bm9kZSwgY29udGFpbmVyLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQpID0+IHtcclxuICAgICAgICBvcHRpbWl6ZWQgPSBvcHRpbWl6ZWQgfHwgISF2bm9kZS5keW5hbWljQ2hpbGRyZW47XHJcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSB2bm9kZS5jaGlsZHJlbjtcclxuICAgICAgICBjb25zdCBsID0gY2hpbGRyZW4ubGVuZ3RoO1xyXG4gICAgICAgIGxldCBoYXNXYXJuZWQgPSBmYWxzZTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCB2bm9kZSA9IG9wdGltaXplZFxyXG4gICAgICAgICAgICAgICAgPyBjaGlsZHJlbltpXVxyXG4gICAgICAgICAgICAgICAgOiAoY2hpbGRyZW5baV0gPSBub3JtYWxpemVWTm9kZShjaGlsZHJlbltpXSkpO1xyXG4gICAgICAgICAgICBpZiAobm9kZSkge1xyXG4gICAgICAgICAgICAgICAgbm9kZSA9IGh5ZHJhdGVOb2RlKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaGFzTWlzbWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhaGFzV2FybmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgSHlkcmF0aW9uIGNoaWxkcmVuIG1pc21hdGNoIGluIDwke2NvbnRhaW5lci50YWdOYW1lLnRvTG93ZXJDYXNlKCl9PjogYCArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGBzZXJ2ZXIgcmVuZGVyZWQgZWxlbWVudCBjb250YWlucyBmZXdlciBjaGlsZCBub2RlcyB0aGFuIGNsaWVudCB2ZG9tLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhc1dhcm5lZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgU1NSZWQgRE9NIGRpZG4ndCBjb250YWluIGVub3VnaCBub2Rlcy4gTW91bnQgdGhlIG1pc3Npbmcgb25lcy5cclxuICAgICAgICAgICAgICAgIHBhdGNoKG51bGwsIHZub2RlLCBjb250YWluZXIsIG51bGwsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHQ29udGFpbmVyKGNvbnRhaW5lcikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IGh5ZHJhdGVGcmFnbWVudCA9IChub2RlLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgb3B0aW1pemVkKSA9PiB7XHJcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gcGFyZW50Tm9kZShub2RlKTtcclxuICAgICAgICBjb25zdCBuZXh0ID0gaHlkcmF0ZUNoaWxkcmVuKG5leHRTaWJsaW5nKG5vZGUpLCB2bm9kZSwgY29udGFpbmVyLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgIGlmIChuZXh0ICYmIGlzQ29tbWVudChuZXh0KSAmJiBuZXh0LmRhdGEgPT09ICddJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV4dFNpYmxpbmcoKHZub2RlLmFuY2hvciA9IG5leHQpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGZyYWdtZW50IGRpZG4ndCBoeWRyYXRlIHN1Y2Nlc3NmdWxseSwgc2luY2Ugd2UgZGlkbid0IGdldCBhIGVuZCBhbmNob3JcclxuICAgICAgICAgICAgLy8gYmFjay4gVGhpcyBzaG91bGQgaGF2ZSBsZWQgdG8gbm9kZS9jaGlsZHJlbiBtaXNtYXRjaCB3YXJuaW5ncy5cclxuICAgICAgICAgICAgaGFzTWlzbWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgICAgICAvLyBzaW5jZSB0aGUgYW5jaG9yIGlzIG1pc3NpbmcsIHdlIG5lZWQgdG8gY3JlYXRlIG9uZSBhbmQgaW5zZXJ0IGl0XHJcbiAgICAgICAgICAgIGluc2VydCgodm5vZGUuYW5jaG9yID0gY3JlYXRlQ29tbWVudChgXWApKSwgY29udGFpbmVyLCBuZXh0KTtcclxuICAgICAgICAgICAgcmV0dXJuIG5leHQ7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IGhhbmRsZU1pc21hdGNoID0gKG5vZGUsIHZub2RlLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc0ZyYWdtZW50KSA9PiB7XHJcbiAgICAgICAgaGFzTWlzbWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICB3YXJuKGBIeWRyYXRpb24gbm9kZSBtaXNtYXRjaDpcXG4tIENsaWVudCB2bm9kZTpgLCB2bm9kZS50eXBlLCBgXFxuLSBTZXJ2ZXIgcmVuZGVyZWQgRE9NOmAsIG5vZGUsIG5vZGUubm9kZVR5cGUgPT09IDMgLyogVEVYVCAqL1xyXG4gICAgICAgICAgICAgICAgPyBgKHRleHQpYFxyXG4gICAgICAgICAgICAgICAgOiBpc0NvbW1lbnQobm9kZSkgJiYgbm9kZS5kYXRhID09PSAnWydcclxuICAgICAgICAgICAgICAgICAgICA/IGAoc3RhcnQgb2YgZnJhZ21lbnQpYFxyXG4gICAgICAgICAgICAgICAgICAgIDogYGApO1xyXG4gICAgICAgIHZub2RlLmVsID0gbnVsbDtcclxuICAgICAgICBpZiAoaXNGcmFnbWVudCkge1xyXG4gICAgICAgICAgICAvLyByZW1vdmUgZXhjZXNzaXZlIGZyYWdtZW50IG5vZGVzXHJcbiAgICAgICAgICAgIGNvbnN0IGVuZCA9IGxvY2F0ZUNsb3NpbmdBc3luY0FuY2hvcihub2RlKTtcclxuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5leHQgPSBuZXh0U2libGluZyhub2RlKTtcclxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQgIT09IGVuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZShuZXh0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG5leHQgPSBuZXh0U2libGluZyhub2RlKTtcclxuICAgICAgICBjb25zdCBjb250YWluZXIgPSBwYXJlbnROb2RlKG5vZGUpO1xyXG4gICAgICAgIHJlbW92ZShub2RlKTtcclxuICAgICAgICBwYXRjaChudWxsLCB2bm9kZSwgY29udGFpbmVyLCBuZXh0LCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWR0NvbnRhaW5lcihjb250YWluZXIpKTtcclxuICAgICAgICByZXR1cm4gbmV4dDtcclxuICAgIH07XHJcbiAgICBjb25zdCBsb2NhdGVDbG9zaW5nQXN5bmNBbmNob3IgPSAobm9kZSkgPT4ge1xyXG4gICAgICAgIGxldCBtYXRjaCA9IDA7XHJcbiAgICAgICAgd2hpbGUgKG5vZGUpIHtcclxuICAgICAgICAgICAgbm9kZSA9IG5leHRTaWJsaW5nKG5vZGUpO1xyXG4gICAgICAgICAgICBpZiAobm9kZSAmJiBpc0NvbW1lbnQobm9kZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChub2RlLmRhdGEgPT09ICdbJylcclxuICAgICAgICAgICAgICAgICAgICBtYXRjaCsrO1xyXG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZGF0YSA9PT0gJ10nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0U2libGluZyhub2RlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoLS07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBbaHlkcmF0ZSwgaHlkcmF0ZU5vZGVdO1xyXG59XG5cbmxldCBzdXBwb3J0ZWQ7XHJcbmxldCBwZXJmO1xyXG5mdW5jdGlvbiBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIHR5cGUpIHtcclxuICAgIGlmIChpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5wZXJmb3JtYW5jZSAmJiBpc1N1cHBvcnRlZCgpKSB7XHJcbiAgICAgICAgcGVyZi5tYXJrKGB2dWUtJHt0eXBlfS0ke2luc3RhbmNlLnVpZH1gKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBlbmRNZWFzdXJlKGluc3RhbmNlLCB0eXBlKSB7XHJcbiAgICBpZiAoaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcucGVyZm9ybWFuY2UgJiYgaXNTdXBwb3J0ZWQoKSkge1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0VGFnID0gYHZ1ZS0ke3R5cGV9LSR7aW5zdGFuY2UudWlkfWA7XHJcbiAgICAgICAgY29uc3QgZW5kVGFnID0gc3RhcnRUYWcgKyBgOmVuZGA7XHJcbiAgICAgICAgcGVyZi5tYXJrKGVuZFRhZyk7XHJcbiAgICAgICAgcGVyZi5tZWFzdXJlKGA8JHtmb3JtYXRDb21wb25lbnROYW1lKGluc3RhbmNlLCBpbnN0YW5jZS50eXBlKX0+ICR7dHlwZX1gLCBzdGFydFRhZywgZW5kVGFnKTtcclxuICAgICAgICBwZXJmLmNsZWFyTWFya3Moc3RhcnRUYWcpO1xyXG4gICAgICAgIHBlcmYuY2xlYXJNYXJrcyhlbmRUYWcpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGlzU3VwcG9ydGVkKCkge1xyXG4gICAgaWYgKHN1cHBvcnRlZCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgcmV0dXJuIHN1cHBvcnRlZDtcclxuICAgIH1cclxuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscyAqL1xyXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5wZXJmb3JtYW5jZSkge1xyXG4gICAgICAgIHN1cHBvcnRlZCA9IHRydWU7XHJcbiAgICAgICAgcGVyZiA9IHdpbmRvdy5wZXJmb3JtYW5jZTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHN1cHBvcnRlZCA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1yZXN0cmljdGVkLWdsb2JhbHMgKi9cclxuICAgIHJldHVybiBzdXBwb3J0ZWQ7XHJcbn1cblxuLyoqXHJcbiAqIFRoaXMgaXMgb25seSBjYWxsZWQgaW4gZXNtLWJ1bmRsZXIgYnVpbGRzLlxyXG4gKiBJdCBpcyBjYWxsZWQgd2hlbiBhIHJlbmRlcmVyIGlzIGNyZWF0ZWQsIGluIGBiYXNlQ3JlYXRlUmVuZGVyZXJgIHNvIHRoYXRcclxuICogaW1wb3J0aW5nIHJ1bnRpbWUtY29yZSBpcyBzaWRlLWVmZmVjdHMgZnJlZS5cclxuICpcclxuICogaXN0YW5idWwtaWdub3JlLW5leHRcclxuICovXHJcbmZ1bmN0aW9uIGluaXRGZWF0dXJlRmxhZ3MoKSB7XHJcbiAgICBsZXQgbmVlZFdhcm4gPSBmYWxzZTtcclxuICAgIGlmICh0eXBlb2YgX19WVUVfT1BUSU9OU19BUElfXyAhPT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgbmVlZFdhcm4gPSB0cnVlO1xyXG4gICAgICAgIGdldEdsb2JhbFRoaXMoKS5fX1ZVRV9PUFRJT05TX0FQSV9fID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2YgX19WVUVfUFJPRF9ERVZUT09MU19fICE9PSAnYm9vbGVhbicpIHtcclxuICAgICAgICBuZWVkV2FybiA9IHRydWU7XHJcbiAgICAgICAgZ2V0R2xvYmFsVGhpcygpLl9fVlVFX1BST0RfREVWVE9PTFNfXyA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBuZWVkV2Fybikge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihgWW91IGFyZSBydW5uaW5nIHRoZSBlc20tYnVuZGxlciBidWlsZCBvZiBWdWUuIEl0IGlzIHJlY29tbWVuZGVkIHRvIGAgK1xyXG4gICAgICAgICAgICBgY29uZmlndXJlIHlvdXIgYnVuZGxlciB0byBleHBsaWNpdGx5IHJlcGxhY2UgZmVhdHVyZSBmbGFnIGdsb2JhbHMgYCArXHJcbiAgICAgICAgICAgIGB3aXRoIGJvb2xlYW4gbGl0ZXJhbHMgdG8gZ2V0IHByb3BlciB0cmVlLXNoYWtpbmcgaW4gdGhlIGZpbmFsIGJ1bmRsZS4gYCArXHJcbiAgICAgICAgICAgIGBTZWUgaHR0cDovL2xpbmsudnVlanMub3JnL2ZlYXR1cmUtZmxhZ3MgZm9yIG1vcmUgZGV0YWlscy5gKTtcclxuICAgIH1cclxufVxuXG5jb25zdCBwcm9kRWZmZWN0T3B0aW9ucyA9IHtcclxuICAgIHNjaGVkdWxlcjogcXVldWVKb2JcclxufTtcclxuZnVuY3Rpb24gY3JlYXRlRGV2RWZmZWN0T3B0aW9ucyhpbnN0YW5jZSkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBzY2hlZHVsZXI6IHF1ZXVlSm9iLFxyXG4gICAgICAgIG9uVHJhY2s6IGluc3RhbmNlLnJ0YyA/IGUgPT4gaW52b2tlQXJyYXlGbnMoaW5zdGFuY2UucnRjLCBlKSA6IHZvaWQgMCxcclxuICAgICAgICBvblRyaWdnZXI6IGluc3RhbmNlLnJ0ZyA/IGUgPT4gaW52b2tlQXJyYXlGbnMoaW5zdGFuY2UucnRnLCBlKSA6IHZvaWQgMFxyXG4gICAgfTtcclxufVxyXG5jb25zdCBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QgPSAgcXVldWVFZmZlY3RXaXRoU3VzcGVuc2VcclxuICAgIDtcclxuY29uc3Qgc2V0UmVmID0gKHJhd1JlZiwgb2xkUmF3UmVmLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB2bm9kZSkgPT4ge1xyXG4gICAgbGV0IHZhbHVlO1xyXG4gICAgaWYgKCF2bm9kZSkge1xyXG4gICAgICAgIHZhbHVlID0gbnVsbDtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiA0IC8qIFNUQVRFRlVMX0NPTVBPTkVOVCAqLykge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZub2RlLmNvbXBvbmVudC5wcm94eTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gdm5vZGUuZWw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgW293bmVyLCByZWZdID0gcmF3UmVmO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhb3duZXIpIHtcclxuICAgICAgICB3YXJuKGBNaXNzaW5nIHJlZiBvd25lciBjb250ZXh0LiByZWYgY2Fubm90IGJlIHVzZWQgb24gaG9pc3RlZCB2bm9kZXMuIGAgK1xyXG4gICAgICAgICAgICBgQSB2bm9kZSB3aXRoIHJlZiBtdXN0IGJlIGNyZWF0ZWQgaW5zaWRlIHRoZSByZW5kZXIgZnVuY3Rpb24uYCk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgY29uc3Qgb2xkUmVmID0gb2xkUmF3UmVmICYmIG9sZFJhd1JlZlsxXTtcclxuICAgIGNvbnN0IHJlZnMgPSBvd25lci5yZWZzID09PSBFTVBUWV9PQkogPyAob3duZXIucmVmcyA9IHt9KSA6IG93bmVyLnJlZnM7XHJcbiAgICBjb25zdCBzZXR1cFN0YXRlID0gb3duZXIuc2V0dXBTdGF0ZTtcclxuICAgIC8vIHVuc2V0IG9sZCByZWZcclxuICAgIGlmIChvbGRSZWYgIT0gbnVsbCAmJiBvbGRSZWYgIT09IHJlZikge1xyXG4gICAgICAgIGlmIChpc1N0cmluZyhvbGRSZWYpKSB7XHJcbiAgICAgICAgICAgIHJlZnNbb2xkUmVmXSA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmIChoYXNPd24oc2V0dXBTdGF0ZSwgb2xkUmVmKSkge1xyXG4gICAgICAgICAgICAgICAgc2V0dXBTdGF0ZVtvbGRSZWZdID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChpc1JlZihvbGRSZWYpKSB7XHJcbiAgICAgICAgICAgIG9sZFJlZi52YWx1ZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGlzU3RyaW5nKHJlZikpIHtcclxuICAgICAgICBjb25zdCBkb1NldCA9ICgpID0+IHtcclxuICAgICAgICAgICAgcmVmc1tyZWZdID0gdmFsdWU7XHJcbiAgICAgICAgICAgIGlmIChoYXNPd24oc2V0dXBTdGF0ZSwgcmVmKSkge1xyXG4gICAgICAgICAgICAgICAgc2V0dXBTdGF0ZVtyZWZdID0gdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vICMxNzg5OiBmb3Igbm9uLW51bGwgdmFsdWVzLCBzZXQgdGhlbSBhZnRlciByZW5kZXJcclxuICAgICAgICAvLyBudWxsIHZhbHVlcyBtZWFucyB0aGlzIGlzIHVubW91bnQgYW5kIGl0IHNob3VsZCBub3Qgb3ZlcndyaXRlIGFub3RoZXJcclxuICAgICAgICAvLyByZWYgd2l0aCB0aGUgc2FtZSBrZXlcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgZG9TZXQuaWQgPSAtMTtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KGRvU2V0LCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBkb1NldCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzUmVmKHJlZikpIHtcclxuICAgICAgICBjb25zdCBkb1NldCA9ICgpID0+IHtcclxuICAgICAgICAgICAgcmVmLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgZG9TZXQuaWQgPSAtMTtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KGRvU2V0LCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBkb1NldCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzRnVuY3Rpb24ocmVmKSkge1xyXG4gICAgICAgIGNhbGxXaXRoRXJyb3JIYW5kbGluZyhyZWYsIHBhcmVudENvbXBvbmVudCwgMTIgLyogRlVOQ1RJT05fUkVGICovLCBbXHJcbiAgICAgICAgICAgIHZhbHVlLFxyXG4gICAgICAgICAgICByZWZzXHJcbiAgICAgICAgXSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICB3YXJuKCdJbnZhbGlkIHRlbXBsYXRlIHJlZiB0eXBlOicsIHZhbHVlLCBgKCR7dHlwZW9mIHZhbHVlfSlgKTtcclxuICAgIH1cclxufTtcclxuLyoqXHJcbiAqIFRoZSBjcmVhdGVSZW5kZXJlciBmdW5jdGlvbiBhY2NlcHRzIHR3byBnZW5lcmljIGFyZ3VtZW50czpcclxuICogSG9zdE5vZGUgYW5kIEhvc3RFbGVtZW50LCBjb3JyZXNwb25kaW5nIHRvIE5vZGUgYW5kIEVsZW1lbnQgdHlwZXMgaW4gdGhlXHJcbiAqIGhvc3QgZW52aXJvbm1lbnQuIEZvciBleGFtcGxlLCBmb3IgcnVudGltZS1kb20sIEhvc3ROb2RlIHdvdWxkIGJlIHRoZSBET01cclxuICogYE5vZGVgIGludGVyZmFjZSBhbmQgSG9zdEVsZW1lbnQgd291bGQgYmUgdGhlIERPTSBgRWxlbWVudGAgaW50ZXJmYWNlLlxyXG4gKlxyXG4gKiBDdXN0b20gcmVuZGVyZXJzIGNhbiBwYXNzIGluIHRoZSBwbGF0Zm9ybSBzcGVjaWZpYyB0eXBlcyBsaWtlIHRoaXM6XHJcbiAqXHJcbiAqIGBgYCBqc1xyXG4gKiBjb25zdCB7IHJlbmRlciwgY3JlYXRlQXBwIH0gPSBjcmVhdGVSZW5kZXJlcjxOb2RlLCBFbGVtZW50Pih7XHJcbiAqICAgcGF0Y2hQcm9wLFxyXG4gKiAgIC4uLm5vZGVPcHNcclxuICogfSlcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVSZW5kZXJlcihvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMpO1xyXG59XHJcbi8vIFNlcGFyYXRlIEFQSSBmb3IgY3JlYXRpbmcgaHlkcmF0aW9uLWVuYWJsZWQgcmVuZGVyZXIuXHJcbi8vIEh5ZHJhdGlvbiBsb2dpYyBpcyBvbmx5IHVzZWQgd2hlbiBjYWxsaW5nIHRoaXMgZnVuY3Rpb24sIG1ha2luZyBpdFxyXG4vLyB0cmVlLXNoYWthYmxlLlxyXG5mdW5jdGlvbiBjcmVhdGVIeWRyYXRpb25SZW5kZXJlcihvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMsIGNyZWF0ZUh5ZHJhdGlvbkZ1bmN0aW9ucyk7XHJcbn1cclxuLy8gaW1wbGVtZW50YXRpb25cclxuZnVuY3Rpb24gYmFzZUNyZWF0ZVJlbmRlcmVyKG9wdGlvbnMsIGNyZWF0ZUh5ZHJhdGlvbkZucykge1xyXG4gICAgLy8gY29tcGlsZS10aW1lIGZlYXR1cmUgZmxhZ3MgY2hlY2tcclxuICAgIHtcclxuICAgICAgICBpbml0RmVhdHVyZUZsYWdzKCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCB7IGluc2VydDogaG9zdEluc2VydCwgcmVtb3ZlOiBob3N0UmVtb3ZlLCBwYXRjaFByb3A6IGhvc3RQYXRjaFByb3AsIGZvcmNlUGF0Y2hQcm9wOiBob3N0Rm9yY2VQYXRjaFByb3AsIGNyZWF0ZUVsZW1lbnQ6IGhvc3RDcmVhdGVFbGVtZW50LCBjcmVhdGVUZXh0OiBob3N0Q3JlYXRlVGV4dCwgY3JlYXRlQ29tbWVudDogaG9zdENyZWF0ZUNvbW1lbnQsIHNldFRleHQ6IGhvc3RTZXRUZXh0LCBzZXRFbGVtZW50VGV4dDogaG9zdFNldEVsZW1lbnRUZXh0LCBwYXJlbnROb2RlOiBob3N0UGFyZW50Tm9kZSwgbmV4dFNpYmxpbmc6IGhvc3ROZXh0U2libGluZywgc2V0U2NvcGVJZDogaG9zdFNldFNjb3BlSWQgPSBOT09QLCBjbG9uZU5vZGU6IGhvc3RDbG9uZU5vZGUsIGluc2VydFN0YXRpY0NvbnRlbnQ6IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50IH0gPSBvcHRpb25zO1xyXG4gICAgLy8gTm90ZTogZnVuY3Rpb25zIGluc2lkZSB0aGlzIGNsb3N1cmUgc2hvdWxkIHVzZSBgY29uc3QgeHh4ID0gKCkgPT4ge31gXHJcbiAgICAvLyBzdHlsZSBpbiBvcmRlciB0byBwcmV2ZW50IGJlaW5nIGlubGluZWQgYnkgbWluaWZpZXJzLlxyXG4gICAgY29uc3QgcGF0Y2ggPSAobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciA9IG51bGwsIHBhcmVudENvbXBvbmVudCA9IG51bGwsIHBhcmVudFN1c3BlbnNlID0gbnVsbCwgaXNTVkcgPSBmYWxzZSwgb3B0aW1pemVkID0gZmFsc2UpID0+IHtcclxuICAgICAgICAvLyBwYXRjaGluZyAmIG5vdCBzYW1lIHR5cGUsIHVubW91bnQgb2xkIHRyZWVcclxuICAgICAgICBpZiAobjEgJiYgIWlzU2FtZVZOb2RlVHlwZShuMSwgbjIpKSB7XHJcbiAgICAgICAgICAgIGFuY2hvciA9IGdldE5leHRIb3N0Tm9kZShuMSk7XHJcbiAgICAgICAgICAgIHVubW91bnQobjEsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHRydWUpO1xyXG4gICAgICAgICAgICBuMSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChuMi5wYXRjaEZsYWcgPT09IC0yIC8qIEJBSUwgKi8pIHtcclxuICAgICAgICAgICAgb3B0aW1pemVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIG4yLmR5bmFtaWNDaGlsZHJlbiA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHsgdHlwZSwgcmVmLCBzaGFwZUZsYWcgfSA9IG4yO1xyXG4gICAgICAgIHN3aXRjaCAodHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIFRleHQ6XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzVGV4dChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIENvbW1lbnQ6XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobjEsIG4yLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBTdGF0aWM6XHJcbiAgICAgICAgICAgICAgICBpZiAobjEgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG1vdW50U3RhdGljTm9kZShuMiwgY29udGFpbmVyLCBhbmNob3IsIGlzU1ZHKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhdGNoU3RhdGljTm9kZShuMSwgbjIsIGNvbnRhaW5lciwgaXNTVkcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgRnJhZ21lbnQ6XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzRnJhZ21lbnQobjEsIG4yLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIGlmIChzaGFwZUZsYWcgJiAxIC8qIEVMRU1FTlQgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzRWxlbWVudChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNoYXBlRmxhZyAmIDYgLyogQ09NUE9ORU5UICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0NvbXBvbmVudChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNoYXBlRmxhZyAmIDY0IC8qIFRFTEVQT1JUICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZS5wcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQsIGludGVybmFscyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICggc2hhcGVGbGFnICYgMTI4IC8qIFNVU1BFTlNFICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZS5wcm9jZXNzKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQsIGludGVybmFscyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKCdJbnZhbGlkIFZOb2RlIHR5cGU6JywgdHlwZSwgYCgke3R5cGVvZiB0eXBlfSlgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0IHJlZlxyXG4gICAgICAgIGlmIChyZWYgIT0gbnVsbCAmJiBwYXJlbnRDb21wb25lbnQpIHtcclxuICAgICAgICAgICAgc2V0UmVmKHJlZiwgbjEgJiYgbjEucmVmLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBuMik7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IHByb2Nlc3NUZXh0ID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IpID0+IHtcclxuICAgICAgICBpZiAobjEgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBob3N0SW5zZXJ0KChuMi5lbCA9IGhvc3RDcmVhdGVUZXh0KG4yLmNoaWxkcmVuKSksIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsID0gKG4yLmVsID0gbjEuZWwpO1xyXG4gICAgICAgICAgICBpZiAobjIuY2hpbGRyZW4gIT09IG4xLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICBob3N0U2V0VGV4dChlbCwgbjIuY2hpbGRyZW4pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IHByb2Nlc3NDb21tZW50Tm9kZSA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yKSA9PiB7XHJcbiAgICAgICAgaWYgKG4xID09IG51bGwpIHtcclxuICAgICAgICAgICAgaG9zdEluc2VydCgobjIuZWwgPSBob3N0Q3JlYXRlQ29tbWVudChuMi5jaGlsZHJlbiB8fCAnJykpLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyB0aGVyZSdzIG5vIHN1cHBvcnQgZm9yIGR5bmFtaWMgY29tbWVudHNcclxuICAgICAgICAgICAgbjIuZWwgPSBuMS5lbDtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3QgbW91bnRTdGF0aWNOb2RlID0gKG4yLCBjb250YWluZXIsIGFuY2hvciwgaXNTVkcpID0+IHtcclxuICAgICAgICBbbjIuZWwsIG4yLmFuY2hvcl0gPSBob3N0SW5zZXJ0U3RhdGljQ29udGVudChuMi5jaGlsZHJlbiwgY29udGFpbmVyLCBhbmNob3IsIGlzU1ZHKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERldiAvIEhNUiBvbmx5XHJcbiAgICAgKi9cclxuICAgIGNvbnN0IHBhdGNoU3RhdGljTm9kZSA9IChuMSwgbjIsIGNvbnRhaW5lciwgaXNTVkcpID0+IHtcclxuICAgICAgICAvLyBzdGF0aWMgbm9kZXMgYXJlIG9ubHkgcGF0Y2hlZCBkdXJpbmcgZGV2IGZvciBITVJcclxuICAgICAgICBpZiAobjIuY2hpbGRyZW4gIT09IG4xLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFuY2hvciA9IGhvc3ROZXh0U2libGluZyhuMS5hbmNob3IpO1xyXG4gICAgICAgICAgICAvLyByZW1vdmUgZXhpc3RpbmdcclxuICAgICAgICAgICAgcmVtb3ZlU3RhdGljTm9kZShuMSk7XHJcbiAgICAgICAgICAgIFtuMi5lbCwgbjIuYW5jaG9yXSA9IGhvc3RJbnNlcnRTdGF0aWNDb250ZW50KG4yLmNoaWxkcmVuLCBjb250YWluZXIsIGFuY2hvciwgaXNTVkcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbjIuZWwgPSBuMS5lbDtcclxuICAgICAgICAgICAgbjIuYW5jaG9yID0gbjEuYW5jaG9yO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERldiAvIEhNUiBvbmx5XHJcbiAgICAgKi9cclxuICAgIGNvbnN0IG1vdmVTdGF0aWNOb2RlID0gKHZub2RlLCBjb250YWluZXIsIGFuY2hvcikgPT4ge1xyXG4gICAgICAgIGxldCBjdXIgPSB2bm9kZS5lbDtcclxuICAgICAgICBjb25zdCBlbmQgPSB2bm9kZS5hbmNob3I7XHJcbiAgICAgICAgd2hpbGUgKGN1ciAmJiBjdXIgIT09IGVuZCkge1xyXG4gICAgICAgICAgICBjb25zdCBuZXh0ID0gaG9zdE5leHRTaWJsaW5nKGN1cik7XHJcbiAgICAgICAgICAgIGhvc3RJbnNlcnQoY3VyLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgIGN1ciA9IG5leHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGhvc3RJbnNlcnQoZW5kLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXYgLyBITVIgb25seVxyXG4gICAgICovXHJcbiAgICBjb25zdCByZW1vdmVTdGF0aWNOb2RlID0gKHZub2RlKSA9PiB7XHJcbiAgICAgICAgbGV0IGN1ciA9IHZub2RlLmVsO1xyXG4gICAgICAgIHdoaWxlIChjdXIgJiYgY3VyICE9PSB2bm9kZS5hbmNob3IpIHtcclxuICAgICAgICAgICAgY29uc3QgbmV4dCA9IGhvc3ROZXh0U2libGluZyhjdXIpO1xyXG4gICAgICAgICAgICBob3N0UmVtb3ZlKGN1cik7XHJcbiAgICAgICAgICAgIGN1ciA9IG5leHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGhvc3RSZW1vdmUodm5vZGUuYW5jaG9yKTtcclxuICAgIH07XHJcbiAgICBjb25zdCBwcm9jZXNzRWxlbWVudCA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKSA9PiB7XHJcbiAgICAgICAgaXNTVkcgPSBpc1NWRyB8fCBuMi50eXBlID09PSAnc3ZnJztcclxuICAgICAgICBpZiAobjEgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBtb3VudEVsZW1lbnQobjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHBhdGNoRWxlbWVudChuMSwgbjIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCBtb3VudEVsZW1lbnQgPSAodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKSA9PiB7XHJcbiAgICAgICAgbGV0IGVsO1xyXG4gICAgICAgIGxldCB2bm9kZUhvb2s7XHJcbiAgICAgICAgY29uc3QgeyB0eXBlLCBwcm9wcywgc2hhcGVGbGFnLCB0cmFuc2l0aW9uLCBzY29wZUlkLCBwYXRjaEZsYWcsIGRpcnMgfSA9IHZub2RlO1xyXG4gICAgICAgIGlmICghKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgIHZub2RlLmVsICYmXHJcbiAgICAgICAgICAgIGhvc3RDbG9uZU5vZGUgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICAgICBwYXRjaEZsYWcgPT09IC0xIC8qIEhPSVNURUQgKi8pIHtcclxuICAgICAgICAgICAgLy8gSWYgYSB2bm9kZSBoYXMgbm9uLW51bGwgZWwsIGl0IG1lYW5zIGl0J3MgYmVpbmcgcmV1c2VkLlxyXG4gICAgICAgICAgICAvLyBPbmx5IHN0YXRpYyB2bm9kZXMgY2FuIGJlIHJldXNlZCwgc28gaXRzIG1vdW50ZWQgRE9NIG5vZGVzIHNob3VsZCBiZVxyXG4gICAgICAgICAgICAvLyBleGFjdGx5IHRoZSBzYW1lLCBhbmQgd2UgY2FuIHNpbXBseSBkbyBhIGNsb25lIGhlcmUuXHJcbiAgICAgICAgICAgIC8vIG9ubHkgZG8gdGhpcyBpbiBwcm9kdWN0aW9uIHNpbmNlIGNsb25lZCB0cmVlcyBjYW5ub3QgYmUgSE1SIHVwZGF0ZWQuXHJcbiAgICAgICAgICAgIGVsID0gdm5vZGUuZWwgPSBob3N0Q2xvbmVOb2RlKHZub2RlLmVsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGVsID0gdm5vZGUuZWwgPSBob3N0Q3JlYXRlRWxlbWVudCh2bm9kZS50eXBlLCBpc1NWRywgcHJvcHMgJiYgcHJvcHMuaXMpO1xyXG4gICAgICAgICAgICAvLyBtb3VudCBjaGlsZHJlbiBmaXJzdCwgc2luY2Ugc29tZSBwcm9wcyBtYXkgcmVseSBvbiBjaGlsZCBjb250ZW50XHJcbiAgICAgICAgICAgIC8vIGJlaW5nIGFscmVhZHkgcmVuZGVyZWQsIGUuZy4gYDxzZWxlY3QgdmFsdWU+YFxyXG4gICAgICAgICAgICBpZiAoc2hhcGVGbGFnICYgOCAvKiBURVhUX0NISUxEUkVOICovKSB7XHJcbiAgICAgICAgICAgICAgICBob3N0U2V0RWxlbWVudFRleHQoZWwsIHZub2RlLmNoaWxkcmVuKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChzaGFwZUZsYWcgJiAxNiAvKiBBUlJBWV9DSElMRFJFTiAqLykge1xyXG4gICAgICAgICAgICAgICAgbW91bnRDaGlsZHJlbih2bm9kZS5jaGlsZHJlbiwgZWwsIG51bGwsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHICYmIHR5cGUgIT09ICdmb3JlaWduT2JqZWN0Jywgb3B0aW1pemVkIHx8ICEhdm5vZGUuZHluYW1pY0NoaWxkcmVuKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZGlycykge1xyXG4gICAgICAgICAgICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayh2bm9kZSwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCAnY3JlYXRlZCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIHByb3BzXHJcbiAgICAgICAgICAgIGlmIChwcm9wcykge1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcHJvcHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzUmVzZXJ2ZWRQcm9wKGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBudWxsLCBwcm9wc1trZXldLCBpc1NWRywgdm5vZGUuY2hpbGRyZW4sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHVubW91bnRDaGlsZHJlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCh2bm9kZUhvb2sgPSBwcm9wcy5vblZub2RlQmVmb3JlTW91bnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gc2NvcGVJZFxyXG4gICAgICAgICAgICBzZXRTY29wZUlkKGVsLCBzY29wZUlkLCB2bm9kZSwgcGFyZW50Q29tcG9uZW50KTtcclxuICAgICAgICAgICAgLy8gaWYgKHNjb3BlSWQpIHtcclxuICAgICAgICAgICAgLy8gICBob3N0U2V0U2NvcGVJZChlbCwgc2NvcGVJZClcclxuICAgICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgICAvLyBpZiAocGFyZW50Q29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgIC8vICAgY29uc3QgdHJlZU93bmVySWQgPSBwYXJlbnRDb21wb25lbnQudHlwZS5fX3Njb3BlSWRcclxuICAgICAgICAgICAgLy8gICAvLyB2bm9kZSdzIG93biBzY29wZUlkIGFuZCB0aGUgY3VycmVudCBwYXRjaGVkIGNvbXBvbmVudCdzIHNjb3BlSWQgaXNcclxuICAgICAgICAgICAgLy8gICAvLyBkaWZmZXJlbnQgLSB0aGlzIGlzIGEgc2xvdCBjb250ZW50IG5vZGUuXHJcbiAgICAgICAgICAgIC8vICAgaWYgKHRyZWVPd25lcklkICYmIHRyZWVPd25lcklkICE9PSBzY29wZUlkKSB7XHJcbiAgICAgICAgICAgIC8vICAgICBob3N0U2V0U2NvcGVJZChlbCwgdHJlZU93bmVySWQgKyAnLXMnKVxyXG4gICAgICAgICAgICAvLyAgIH1cclxuICAgICAgICAgICAgLy8gICBjb25zdCBwYXJlbnRTY29wZUlkID1cclxuICAgICAgICAgICAgLy8gICAgIHZub2RlID09PSBwYXJlbnRDb21wb25lbnQuc3ViVHJlZSAmJiBwYXJlbnRDb21wb25lbnQudm5vZGUuc2NvcGVJZFxyXG4gICAgICAgICAgICAvLyAgIGlmIChwYXJlbnRTY29wZUlkKSB7XHJcbiAgICAgICAgICAgIC8vICAgICBob3N0U2V0U2NvcGVJZChlbCwgcGFyZW50U2NvcGVJZClcclxuICAgICAgICAgICAgLy8gICAgIGlmIChwYXJlbnRDb21wb25lbnQucGFyZW50KSB7XHJcbiAgICAgICAgICAgIC8vICAgICAgIGNvbnN0IHRyZWVPd25lcklkID0gcGFyZW50Q29tcG9uZW50LnBhcmVudC50eXBlLl9fc2NvcGVJZFxyXG4gICAgICAgICAgICAvLyAgICAgICAvLyB2bm9kZSdzIG93biBzY29wZUlkIGFuZCB0aGUgY3VycmVudCBwYXRjaGVkIGNvbXBvbmVudCdzIHNjb3BlSWQgaXNcclxuICAgICAgICAgICAgLy8gICAgICAgLy8gZGlmZmVyZW50IC0gdGhpcyBpcyBhIHNsb3QgY29udGVudCBub2RlLlxyXG4gICAgICAgICAgICAvLyAgICAgICBpZiAodHJlZU93bmVySWQgJiYgdHJlZU93bmVySWQgIT09IHBhcmVudFNjb3BlSWQpIHtcclxuICAgICAgICAgICAgLy8gICAgICAgICBob3N0U2V0U2NvcGVJZChlbCwgdHJlZU93bmVySWQgKyAnLXMnKVxyXG4gICAgICAgICAgICAvLyAgICAgICB9XHJcbiAgICAgICAgICAgIC8vICAgICB9XHJcbiAgICAgICAgICAgIC8vICAgfVxyXG4gICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlbCwgJ19fdm5vZGUnLCB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogdm5vZGUsXHJcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGVsLCAnX192dWVQYXJlbnRDb21wb25lbnQnLCB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZTogcGFyZW50Q29tcG9uZW50LFxyXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2VcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXJzKSB7XHJcbiAgICAgICAgICAgIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgJ2JlZm9yZU1vdW50Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vICMxNTgzIEZvciBpbnNpZGUgc3VzcGVuc2UgKyBzdXNwZW5zZSBub3QgcmVzb2x2ZWQgY2FzZSwgZW50ZXIgaG9vayBzaG91bGQgY2FsbCB3aGVuIHN1c3BlbnNlIHJlc29sdmVkXHJcbiAgICAgICAgLy8gIzE2ODkgRm9yIGluc2lkZSBzdXNwZW5zZSArIHN1c3BlbnNlIHJlc29sdmVkIGNhc2UsIGp1c3QgY2FsbCBpdFxyXG4gICAgICAgIGNvbnN0IG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzID0gKCFwYXJlbnRTdXNwZW5zZSB8fCAocGFyZW50U3VzcGVuc2UgJiYgcGFyZW50U3VzcGVuc2UuaXNSZXNvbHZlZCkpICYmXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24gJiZcclxuICAgICAgICAgICAgIXRyYW5zaXRpb24ucGVyc2lzdGVkO1xyXG4gICAgICAgIGlmIChuZWVkQ2FsbFRyYW5zaXRpb25Ib29rcykge1xyXG4gICAgICAgICAgICB0cmFuc2l0aW9uLmJlZm9yZUVudGVyKGVsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaG9zdEluc2VydChlbCwgY29udGFpbmVyLCBhbmNob3IpO1xyXG4gICAgICAgIGlmICgodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpIHx8XHJcbiAgICAgICAgICAgIG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzIHx8XHJcbiAgICAgICAgICAgIGRpcnMpIHtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHZub2RlSG9vayAmJiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTtcclxuICAgICAgICAgICAgICAgIG5lZWRDYWxsVHJhbnNpdGlvbkhvb2tzICYmIHRyYW5zaXRpb24uZW50ZXIoZWwpO1xyXG4gICAgICAgICAgICAgICAgZGlycyAmJiBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICdtb3VudGVkJyk7XHJcbiAgICAgICAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3Qgc2V0U2NvcGVJZCA9IChlbCwgc2NvcGVJZCwgdm5vZGUsIHBhcmVudENvbXBvbmVudCkgPT4ge1xyXG4gICAgICAgIGlmIChzY29wZUlkKSB7XHJcbiAgICAgICAgICAgIGhvc3RTZXRTY29wZUlkKGVsLCBzY29wZUlkKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHBhcmVudENvbXBvbmVudCkge1xyXG4gICAgICAgICAgICBjb25zdCB0cmVlT3duZXJJZCA9IHBhcmVudENvbXBvbmVudC50eXBlLl9fc2NvcGVJZDtcclxuICAgICAgICAgICAgLy8gdm5vZGUncyBvd24gc2NvcGVJZCBhbmQgdGhlIGN1cnJlbnQgcGF0Y2hlZCBjb21wb25lbnQncyBzY29wZUlkIGlzXHJcbiAgICAgICAgICAgIC8vIGRpZmZlcmVudCAtIHRoaXMgaXMgYSBzbG90IGNvbnRlbnQgbm9kZS5cclxuICAgICAgICAgICAgaWYgKHRyZWVPd25lcklkICYmIHRyZWVPd25lcklkICE9PSBzY29wZUlkKSB7XHJcbiAgICAgICAgICAgICAgICBob3N0U2V0U2NvcGVJZChlbCwgdHJlZU93bmVySWQgKyAnLXMnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodm5vZGUgPT09IHBhcmVudENvbXBvbmVudC5zdWJUcmVlKSB7XHJcbiAgICAgICAgICAgICAgICBzZXRTY29wZUlkKGVsLCBwYXJlbnRDb21wb25lbnQudm5vZGUuc2NvcGVJZCwgcGFyZW50Q29tcG9uZW50LnZub2RlLCBwYXJlbnRDb21wb25lbnQucGFyZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCBtb3VudENoaWxkcmVuID0gKGNoaWxkcmVuLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCwgc3RhcnQgPSAwKSA9PiB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgY2hpbGQgPSAoY2hpbGRyZW5baV0gPSBvcHRpbWl6ZWRcclxuICAgICAgICAgICAgICAgID8gY2xvbmVJZk1vdW50ZWQoY2hpbGRyZW5baV0pXHJcbiAgICAgICAgICAgICAgICA6IG5vcm1hbGl6ZVZOb2RlKGNoaWxkcmVuW2ldKSk7XHJcbiAgICAgICAgICAgIHBhdGNoKG51bGwsIGNoaWxkLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IHBhdGNoRWxlbWVudCA9IChuMSwgbjIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpID0+IHtcclxuICAgICAgICBjb25zdCBlbCA9IChuMi5lbCA9IG4xLmVsKTtcclxuICAgICAgICBsZXQgeyBwYXRjaEZsYWcsIGR5bmFtaWNDaGlsZHJlbiwgZGlycyB9ID0gbjI7XHJcbiAgICAgICAgLy8gIzE0MjYgdGFrZSB0aGUgb2xkIHZub2RlJ3MgcGF0Y2ggZmxhZyBpbnRvIGFjY291bnQgc2luY2UgdXNlciBtYXkgY2xvbmUgYVxyXG4gICAgICAgIC8vIGNvbXBpbGVyLWdlbmVyYXRlZCB2bm9kZSwgd2hpY2ggZGUtb3B0cyB0byBGVUxMX1BST1BTXHJcbiAgICAgICAgcGF0Y2hGbGFnIHw9IG4xLnBhdGNoRmxhZyAmIDE2IC8qIEZVTExfUFJPUFMgKi87XHJcbiAgICAgICAgY29uc3Qgb2xkUHJvcHMgPSBuMS5wcm9wcyB8fCBFTVBUWV9PQko7XHJcbiAgICAgICAgY29uc3QgbmV3UHJvcHMgPSBuMi5wcm9wcyB8fCBFTVBUWV9PQko7XHJcbiAgICAgICAgbGV0IHZub2RlSG9vaztcclxuICAgICAgICBpZiAoKHZub2RlSG9vayA9IG5ld1Byb3BzLm9uVm5vZGVCZWZvcmVVcGRhdGUpKSB7XHJcbiAgICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudENvbXBvbmVudCwgbjIsIG4xKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGRpcnMpIHtcclxuICAgICAgICAgICAgaW52b2tlRGlyZWN0aXZlSG9vayhuMiwgbjEsIHBhcmVudENvbXBvbmVudCwgJ2JlZm9yZVVwZGF0ZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGlzSG1yVXBkYXRpbmcpIHtcclxuICAgICAgICAgICAgLy8gSE1SIHVwZGF0ZWQsIGZvcmNlIGZ1bGwgZGlmZlxyXG4gICAgICAgICAgICBwYXRjaEZsYWcgPSAwO1xyXG4gICAgICAgICAgICBvcHRpbWl6ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgZHluYW1pY0NoaWxkcmVuID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHBhdGNoRmxhZyA+IDApIHtcclxuICAgICAgICAgICAgLy8gdGhlIHByZXNlbmNlIG9mIGEgcGF0Y2hGbGFnIG1lYW5zIHRoaXMgZWxlbWVudCdzIHJlbmRlciBjb2RlIHdhc1xyXG4gICAgICAgICAgICAvLyBnZW5lcmF0ZWQgYnkgdGhlIGNvbXBpbGVyIGFuZCBjYW4gdGFrZSB0aGUgZmFzdCBwYXRoLlxyXG4gICAgICAgICAgICAvLyBpbiB0aGlzIHBhdGggb2xkIG5vZGUgYW5kIG5ldyBub2RlIGFyZSBndWFyYW50ZWVkIHRvIGhhdmUgdGhlIHNhbWUgc2hhcGVcclxuICAgICAgICAgICAgLy8gKGkuZS4gYXQgdGhlIGV4YWN0IHNhbWUgcG9zaXRpb24gaW4gdGhlIHNvdXJjZSB0ZW1wbGF0ZSlcclxuICAgICAgICAgICAgaWYgKHBhdGNoRmxhZyAmIDE2IC8qIEZVTExfUFJPUFMgKi8pIHtcclxuICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQgcHJvcHMgY29udGFpbiBkeW5hbWljIGtleXMsIGZ1bGwgZGlmZiBuZWVkZWRcclxuICAgICAgICAgICAgICAgIHBhdGNoUHJvcHMoZWwsIG4yLCBvbGRQcm9wcywgbmV3UHJvcHMsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIGNsYXNzXHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGZsYWcgaXMgbWF0Y2hlZCB3aGVuIHRoZSBlbGVtZW50IGhhcyBkeW5hbWljIGNsYXNzIGJpbmRpbmdzLlxyXG4gICAgICAgICAgICAgICAgaWYgKHBhdGNoRmxhZyAmIDIgLyogQ0xBU1MgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2xkUHJvcHMuY2xhc3MgIT09IG5ld1Byb3BzLmNsYXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RQYXRjaFByb3AoZWwsICdjbGFzcycsIG51bGwsIG5ld1Byb3BzLmNsYXNzLCBpc1NWRyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gc3R5bGVcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMgZmxhZyBpcyBtYXRjaGVkIHdoZW4gdGhlIGVsZW1lbnQgaGFzIGR5bmFtaWMgc3R5bGUgYmluZGluZ3NcclxuICAgICAgICAgICAgICAgIGlmIChwYXRjaEZsYWcgJiA0IC8qIFNUWUxFICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwgJ3N0eWxlJywgb2xkUHJvcHMuc3R5bGUsIG5ld1Byb3BzLnN0eWxlLCBpc1NWRyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBwcm9wc1xyXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBmbGFnIGlzIG1hdGNoZWQgd2hlbiB0aGUgZWxlbWVudCBoYXMgZHluYW1pYyBwcm9wL2F0dHIgYmluZGluZ3NcclxuICAgICAgICAgICAgICAgIC8vIG90aGVyIHRoYW4gY2xhc3MgYW5kIHN0eWxlLiBUaGUga2V5cyBvZiBkeW5hbWljIHByb3AvYXR0cnMgYXJlIHNhdmVkIGZvclxyXG4gICAgICAgICAgICAgICAgLy8gZmFzdGVyIGl0ZXJhdGlvbi5cclxuICAgICAgICAgICAgICAgIC8vIE5vdGUgZHluYW1pYyBrZXlzIGxpa2UgOltmb29dPVwiYmFyXCIgd2lsbCBjYXVzZSB0aGlzIG9wdGltaXphdGlvbiB0b1xyXG4gICAgICAgICAgICAgICAgLy8gYmFpbCBvdXQgYW5kIGdvIHRocm91Z2ggYSBmdWxsIGRpZmYgYmVjYXVzZSB3ZSBuZWVkIHRvIHVuc2V0IHRoZSBvbGQga2V5XHJcbiAgICAgICAgICAgICAgICBpZiAocGF0Y2hGbGFnICYgOCAvKiBQUk9QUyAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBmbGFnIGlzIHByZXNlbnQgdGhlbiBkeW5hbWljUHJvcHMgbXVzdCBiZSBub24tbnVsbFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb3BzVG9VcGRhdGUgPSBuMi5keW5hbWljUHJvcHM7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wc1RvVXBkYXRlLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IHByb3BzVG9VcGRhdGVbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXYgPSBvbGRQcm9wc1trZXldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0ID0gbmV3UHJvcHNba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQgIT09IHByZXYgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChob3N0Rm9yY2VQYXRjaFByb3AgJiYgaG9zdEZvcmNlUGF0Y2hQcm9wKGVsLCBrZXkpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBwcmV2LCBuZXh0LCBpc1NWRywgbjEuY2hpbGRyZW4sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHVubW91bnRDaGlsZHJlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gdGV4dFxyXG4gICAgICAgICAgICAvLyBUaGlzIGZsYWcgaXMgbWF0Y2hlZCB3aGVuIHRoZSBlbGVtZW50IGhhcyBvbmx5IGR5bmFtaWMgdGV4dCBjaGlsZHJlbi5cclxuICAgICAgICAgICAgaWYgKHBhdGNoRmxhZyAmIDEgLyogVEVYVCAqLykge1xyXG4gICAgICAgICAgICAgICAgaWYgKG4xLmNoaWxkcmVuICE9PSBuMi5jaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChlbCwgbjIuY2hpbGRyZW4pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKCFvcHRpbWl6ZWQgJiYgZHluYW1pY0NoaWxkcmVuID09IG51bGwpIHtcclxuICAgICAgICAgICAgLy8gdW5vcHRpbWl6ZWQsIGZ1bGwgZGlmZlxyXG4gICAgICAgICAgICBwYXRjaFByb3BzKGVsLCBuMiwgb2xkUHJvcHMsIG5ld1Byb3BzLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGFyZUNoaWxkcmVuU1ZHID0gaXNTVkcgJiYgbjIudHlwZSAhPT0gJ2ZvcmVpZ25PYmplY3QnO1xyXG4gICAgICAgIGlmIChkeW5hbWljQ2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgcGF0Y2hCbG9ja0NoaWxkcmVuKG4xLmR5bmFtaWNDaGlsZHJlbiwgZHluYW1pY0NoaWxkcmVuLCBlbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgYXJlQ2hpbGRyZW5TVkcpO1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHBhcmVudENvbXBvbmVudCAmJiBwYXJlbnRDb21wb25lbnQudHlwZS5fX2htcklkKSB7XHJcbiAgICAgICAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKG4xLCBuMik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoIW9wdGltaXplZCkge1xyXG4gICAgICAgICAgICAvLyBmdWxsIGRpZmZcclxuICAgICAgICAgICAgcGF0Y2hDaGlsZHJlbihuMSwgbjIsIGVsLCBudWxsLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBhcmVDaGlsZHJlblNWRyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgodm5vZGVIb29rID0gbmV3UHJvcHMub25Wbm9kZVVwZGF0ZWQpIHx8IGRpcnMpIHtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHZub2RlSG9vayAmJiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIG4yLCBuMSk7XHJcbiAgICAgICAgICAgICAgICBkaXJzICYmIGludm9rZURpcmVjdGl2ZUhvb2sobjIsIG4xLCBwYXJlbnRDb21wb25lbnQsICd1cGRhdGVkJyk7XHJcbiAgICAgICAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLy8gVGhlIGZhc3QgcGF0aCBmb3IgYmxvY2tzLlxyXG4gICAgY29uc3QgcGF0Y2hCbG9ja0NoaWxkcmVuID0gKG9sZENoaWxkcmVuLCBuZXdDaGlsZHJlbiwgZmFsbGJhY2tDb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHKSA9PiB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdDaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBvbGRWTm9kZSA9IG9sZENoaWxkcmVuW2ldO1xyXG4gICAgICAgICAgICBjb25zdCBuZXdWTm9kZSA9IG5ld0NoaWxkcmVuW2ldO1xyXG4gICAgICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGNvbnRhaW5lciAocGFyZW50IGVsZW1lbnQpIGZvciB0aGUgcGF0Y2guXHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IFxyXG4gICAgICAgICAgICAvLyAtIEluIHRoZSBjYXNlIG9mIGEgRnJhZ21lbnQsIHdlIG5lZWQgdG8gcHJvdmlkZSB0aGUgYWN0dWFsIHBhcmVudFxyXG4gICAgICAgICAgICAvLyBvZiB0aGUgRnJhZ21lbnQgaXRzZWxmIHNvIGl0IGNhbiBtb3ZlIGl0cyBjaGlsZHJlbi5cclxuICAgICAgICAgICAgb2xkVk5vZGUudHlwZSA9PT0gRnJhZ21lbnQgfHxcclxuICAgICAgICAgICAgICAgIC8vIC0gSW4gdGhlIGNhc2Ugb2YgZGlmZmVyZW50IG5vZGVzLCB0aGVyZSBpcyBnb2luZyB0byBiZSBhIHJlcGxhY2VtZW50XHJcbiAgICAgICAgICAgICAgICAvLyB3aGljaCBhbHNvIHJlcXVpcmVzIHRoZSBjb3JyZWN0IHBhcmVudCBjb250YWluZXJcclxuICAgICAgICAgICAgICAgICFpc1NhbWVWTm9kZVR5cGUob2xkVk5vZGUsIG5ld1ZOb2RlKSB8fFxyXG4gICAgICAgICAgICAgICAgLy8gLSBJbiB0aGUgY2FzZSBvZiBhIGNvbXBvbmVudCwgaXQgY291bGQgY29udGFpbiBhbnl0aGluZy5cclxuICAgICAgICAgICAgICAgIG9sZFZOb2RlLnNoYXBlRmxhZyAmIDYgLyogQ09NUE9ORU5UICovIHx8XHJcbiAgICAgICAgICAgICAgICBvbGRWTm9kZS5zaGFwZUZsYWcgJiA2NCAvKiBURUxFUE9SVCAqL1xyXG4gICAgICAgICAgICAgICAgPyBob3N0UGFyZW50Tm9kZShvbGRWTm9kZS5lbClcclxuICAgICAgICAgICAgICAgIDogLy8gSW4gb3RoZXIgY2FzZXMsIHRoZSBwYXJlbnQgY29udGFpbmVyIGlzIG5vdCBhY3R1YWxseSB1c2VkIHNvIHdlXHJcbiAgICAgICAgICAgICAgICAgICAgLy8ganVzdCBwYXNzIHRoZSBibG9jayBlbGVtZW50IGhlcmUgdG8gYXZvaWQgYSBET00gcGFyZW50Tm9kZSBjYWxsLlxyXG4gICAgICAgICAgICAgICAgICAgIGZhbGxiYWNrQ29udGFpbmVyO1xyXG4gICAgICAgICAgICBwYXRjaChvbGRWTm9kZSwgbmV3Vk5vZGUsIGNvbnRhaW5lciwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCBwYXRjaFByb3BzID0gKGVsLCB2bm9kZSwgb2xkUHJvcHMsIG5ld1Byb3BzLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRykgPT4ge1xyXG4gICAgICAgIGlmIChvbGRQcm9wcyAhPT0gbmV3UHJvcHMpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gbmV3UHJvcHMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc1Jlc2VydmVkUHJvcChrZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dCA9IG5ld1Byb3BzW2tleV07XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2ID0gb2xkUHJvcHNba2V5XTtcclxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICE9PSBwcmV2IHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKGhvc3RGb3JjZVBhdGNoUHJvcCAmJiBob3N0Rm9yY2VQYXRjaFByb3AoZWwsIGtleSkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG9zdFBhdGNoUHJvcChlbCwga2V5LCBwcmV2LCBuZXh0LCBpc1NWRywgdm5vZGUuY2hpbGRyZW4sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHVubW91bnRDaGlsZHJlbik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9sZFByb3BzICE9PSBFTVBUWV9PQkopIHtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIG9sZFByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc1Jlc2VydmVkUHJvcChrZXkpICYmICEoa2V5IGluIG5ld1Byb3BzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBob3N0UGF0Y2hQcm9wKGVsLCBrZXksIG9sZFByb3BzW2tleV0sIG51bGwsIGlzU1ZHLCB2bm9kZS5jaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdW5tb3VudENoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3QgcHJvY2Vzc0ZyYWdtZW50ID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpID0+IHtcclxuICAgICAgICBjb25zdCBmcmFnbWVudFN0YXJ0QW5jaG9yID0gKG4yLmVsID0gbjEgPyBuMS5lbCA6IGhvc3RDcmVhdGVUZXh0KCcnKSk7XHJcbiAgICAgICAgY29uc3QgZnJhZ21lbnRFbmRBbmNob3IgPSAobjIuYW5jaG9yID0gbjEgPyBuMS5hbmNob3IgOiBob3N0Q3JlYXRlVGV4dCgnJykpO1xyXG4gICAgICAgIGxldCB7IHBhdGNoRmxhZywgZHluYW1pY0NoaWxkcmVuIH0gPSBuMjtcclxuICAgICAgICBpZiAocGF0Y2hGbGFnID4gMCkge1xyXG4gICAgICAgICAgICBvcHRpbWl6ZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGlzSG1yVXBkYXRpbmcpIHtcclxuICAgICAgICAgICAgLy8gSE1SIHVwZGF0ZWQsIGZvcmNlIGZ1bGwgZGlmZlxyXG4gICAgICAgICAgICBwYXRjaEZsYWcgPSAwO1xyXG4gICAgICAgICAgICBvcHRpbWl6ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgZHluYW1pY0NoaWxkcmVuID0gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKG4xID09IG51bGwpIHtcclxuICAgICAgICAgICAgaG9zdEluc2VydChmcmFnbWVudFN0YXJ0QW5jaG9yLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgIGhvc3RJbnNlcnQoZnJhZ21lbnRFbmRBbmNob3IsIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICAgICAgLy8gYSBmcmFnbWVudCBjYW4gb25seSBoYXZlIGFycmF5IGNoaWxkcmVuXHJcbiAgICAgICAgICAgIC8vIHNpbmNlIHRoZXkgYXJlIGVpdGhlciBnZW5lcmF0ZWQgYnkgdGhlIGNvbXBpbGVyLCBvciBpbXBsaWNpdGx5IGNyZWF0ZWRcclxuICAgICAgICAgICAgLy8gZnJvbSBhcnJheXMuXHJcbiAgICAgICAgICAgIG1vdW50Q2hpbGRyZW4objIuY2hpbGRyZW4sIGNvbnRhaW5lciwgZnJhZ21lbnRFbmRBbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHBhdGNoRmxhZyA+IDAgJiZcclxuICAgICAgICAgICAgICAgIHBhdGNoRmxhZyAmIDY0IC8qIFNUQUJMRV9GUkFHTUVOVCAqLyAmJlxyXG4gICAgICAgICAgICAgICAgZHluYW1pY0NoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhIHN0YWJsZSBmcmFnbWVudCAodGVtcGxhdGUgcm9vdCBvciA8dGVtcGxhdGUgdi1mb3I+KSBkb2Vzbid0IG5lZWQgdG9cclxuICAgICAgICAgICAgICAgIC8vIHBhdGNoIGNoaWxkcmVuIG9yZGVyLCBidXQgaXQgbWF5IGNvbnRhaW4gZHluYW1pY0NoaWxkcmVuLlxyXG4gICAgICAgICAgICAgICAgcGF0Y2hCbG9ja0NoaWxkcmVuKG4xLmR5bmFtaWNDaGlsZHJlbiwgZHluYW1pY0NoaWxkcmVuLCBjb250YWluZXIsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHKTtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgcGFyZW50Q29tcG9uZW50ICYmIHBhcmVudENvbXBvbmVudC50eXBlLl9faG1ySWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuKG4xLCBuMik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBrZXllZCAvIHVua2V5ZWQsIG9yIG1hbnVhbCBmcmFnbWVudHMuXHJcbiAgICAgICAgICAgICAgICAvLyBmb3Iga2V5ZWQgJiB1bmtleWVkLCBzaW5jZSB0aGV5IGFyZSBjb21waWxlciBnZW5lcmF0ZWQgZnJvbSB2LWZvcixcclxuICAgICAgICAgICAgICAgIC8vIGVhY2ggY2hpbGQgaXMgZ3VhcmFudGVlZCB0byBiZSBhIGJsb2NrIHNvIHRoZSBmcmFnbWVudCB3aWxsIG5ldmVyXHJcbiAgICAgICAgICAgICAgICAvLyBoYXZlIGR5bmFtaWNDaGlsZHJlbi5cclxuICAgICAgICAgICAgICAgIHBhdGNoQ2hpbGRyZW4objEsIG4yLCBjb250YWluZXIsIGZyYWdtZW50RW5kQW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCBwcm9jZXNzQ29tcG9uZW50ID0gKG4xLCBuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpID0+IHtcclxuICAgICAgICBpZiAobjEgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBpZiAobjIuc2hhcGVGbGFnICYgNTEyIC8qIENPTVBPTkVOVF9LRVBUX0FMSVZFICovKSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRDb21wb25lbnQuY3R4LmFjdGl2YXRlKG4yLCBjb250YWluZXIsIGFuY2hvciwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBtb3VudENvbXBvbmVudChuMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB1cGRhdGVDb21wb25lbnQobjEsIG4yLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCBtb3VudENvbXBvbmVudCA9IChpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKSA9PiB7XHJcbiAgICAgICAgY29uc3QgaW5zdGFuY2UgPSAoaW5pdGlhbFZOb2RlLmNvbXBvbmVudCA9IGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKGluaXRpYWxWTm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSkpO1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgaW5zdGFuY2UudHlwZS5fX2htcklkKSB7XHJcbiAgICAgICAgICAgIHJlZ2lzdGVySE1SKGluc3RhbmNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICBwdXNoV2FybmluZ0NvbnRleHQoaW5pdGlhbFZOb2RlKTtcclxuICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgbW91bnRgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaW5qZWN0IHJlbmRlcmVyIGludGVybmFscyBmb3Iga2VlcEFsaXZlXHJcbiAgICAgICAgaWYgKGlzS2VlcEFsaXZlKGluaXRpYWxWTm9kZSkpIHtcclxuICAgICAgICAgICAgaW5zdGFuY2UuY3R4LnJlbmRlcmVyID0gaW50ZXJuYWxzO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyByZXNvbHZlIHByb3BzIGFuZCBzbG90cyBmb3Igc2V0dXAgY29udGV4dFxyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzZXR1cENvbXBvbmVudChpbnN0YW5jZSk7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgaW5pdGApO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzZXR1cCgpIGlzIGFzeW5jLiBUaGlzIGNvbXBvbmVudCByZWxpZXMgb24gYXN5bmMgbG9naWMgdG8gYmUgcmVzb2x2ZWRcclxuICAgICAgICAvLyBiZWZvcmUgcHJvY2VlZGluZ1xyXG4gICAgICAgIGlmICggaW5zdGFuY2UuYXN5bmNEZXApIHtcclxuICAgICAgICAgICAgaWYgKCFwYXJlbnRTdXNwZW5zZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSlcclxuICAgICAgICAgICAgICAgICAgICB3YXJuKCdhc3luYyBzZXR1cCgpIGlzIHVzZWQgd2l0aG91dCBhIHN1c3BlbnNlIGJvdW5kYXJ5IScpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlLnJlZ2lzdGVyRGVwKGluc3RhbmNlLCBzZXR1cFJlbmRlckVmZmVjdCk7XHJcbiAgICAgICAgICAgIC8vIEdpdmUgaXQgYSBwbGFjZWhvbGRlciBpZiB0aGlzIGlzIG5vdCBoeWRyYXRpb25cclxuICAgICAgICAgICAgaWYgKCFpbml0aWFsVk5vZGUuZWwpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gKGluc3RhbmNlLnN1YlRyZWUgPSBjcmVhdGVWTm9kZShDb21tZW50KSk7XHJcbiAgICAgICAgICAgICAgICBwcm9jZXNzQ29tbWVudE5vZGUobnVsbCwgcGxhY2Vob2xkZXIsIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNldHVwUmVuZGVyRWZmZWN0KGluc3RhbmNlLCBpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICBwb3BXYXJuaW5nQ29udGV4dCgpO1xyXG4gICAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgbW91bnRgKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3QgdXBkYXRlQ29tcG9uZW50ID0gKG4xLCBuMiwgb3B0aW1pemVkKSA9PiB7XHJcbiAgICAgICAgY29uc3QgaW5zdGFuY2UgPSAobjIuY29tcG9uZW50ID0gbjEuY29tcG9uZW50KTtcclxuICAgICAgICBpZiAoc2hvdWxkVXBkYXRlQ29tcG9uZW50KG4xLCBuMiwgb3B0aW1pemVkKSkge1xyXG4gICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5hc3luY0RlcCAmJlxyXG4gICAgICAgICAgICAgICAgIWluc3RhbmNlLmFzeW5jUmVzb2x2ZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIGFzeW5jICYgc3RpbGwgcGVuZGluZyAtIGp1c3QgdXBkYXRlIHByb3BzIGFuZCBzbG90c1xyXG4gICAgICAgICAgICAgICAgLy8gc2luY2UgdGhlIGNvbXBvbmVudCdzIHJlYWN0aXZlIGVmZmVjdCBmb3IgcmVuZGVyIGlzbid0IHNldC11cCB5ZXRcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBwdXNoV2FybmluZ0NvbnRleHQobjIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyKGluc3RhbmNlLCBuMiwgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBwb3BXYXJuaW5nQ29udGV4dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gbm9ybWFsIHVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgaW5zdGFuY2UubmV4dCA9IG4yO1xyXG4gICAgICAgICAgICAgICAgLy8gaW4gY2FzZSB0aGUgY2hpbGQgY29tcG9uZW50IGlzIGFsc28gcXVldWVkLCByZW1vdmUgaXQgdG8gYXZvaWRcclxuICAgICAgICAgICAgICAgIC8vIGRvdWJsZSB1cGRhdGluZyB0aGUgc2FtZSBjaGlsZCBjb21wb25lbnQgaW4gdGhlIHNhbWUgZmx1c2guXHJcbiAgICAgICAgICAgICAgICBpbnZhbGlkYXRlSm9iKGluc3RhbmNlLnVwZGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAvLyBpbnN0YW5jZS51cGRhdGUgaXMgdGhlIHJlYWN0aXZlIGVmZmVjdCBydW5uZXIuXHJcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS51cGRhdGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gbm8gdXBkYXRlIG5lZWRlZC4ganVzdCBjb3B5IG92ZXIgcHJvcGVydGllc1xyXG4gICAgICAgICAgICBuMi5jb21wb25lbnQgPSBuMS5jb21wb25lbnQ7XHJcbiAgICAgICAgICAgIG4yLmVsID0gbjEuZWw7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLnZub2RlID0gbjI7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IHNldHVwUmVuZGVyRWZmZWN0ID0gKGluc3RhbmNlLCBpbml0aWFsVk5vZGUsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCkgPT4ge1xyXG4gICAgICAgIC8vIGNyZWF0ZSByZWFjdGl2ZSBlZmZlY3QgZm9yIHJlbmRlcmluZ1xyXG4gICAgICAgIGluc3RhbmNlLnVwZGF0ZSA9IGVmZmVjdChmdW5jdGlvbiBjb21wb25lbnRFZmZlY3QoKSB7XHJcbiAgICAgICAgICAgIGlmICghaW5zdGFuY2UuaXNNb3VudGVkKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdm5vZGVIb29rO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgeyBlbCwgcHJvcHMgfSA9IGluaXRpYWxWTm9kZTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHsgYm0sIG0sIHBhcmVudCB9ID0gaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAvLyBiZWZvcmVNb3VudCBob29rXHJcbiAgICAgICAgICAgICAgICBpZiAoYm0pIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnZva2VBcnJheUZucyhibSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBvblZub2RlQmVmb3JlTW91bnRcclxuICAgICAgICAgICAgICAgIGlmICgodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZUJlZm9yZU1vdW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgaW5pdGlhbFZOb2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHJlbmRlclxyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYHJlbmRlcmApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3ViVHJlZSA9IChpbnN0YW5jZS5zdWJUcmVlID0gcmVuZGVyQ29tcG9uZW50Um9vdChpbnN0YW5jZSkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChlbCAmJiBoeWRyYXRlTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgaHlkcmF0ZWApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyB2bm9kZSBoYXMgYWRvcHRlZCBob3N0IG5vZGUgLSBwZXJmb3JtIGh5ZHJhdGlvbiBpbnN0ZWFkIG9mIG1vdW50LlxyXG4gICAgICAgICAgICAgICAgICAgIGh5ZHJhdGVOb2RlKGluaXRpYWxWTm9kZS5lbCwgc3ViVHJlZSwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGBoeWRyYXRlYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydE1lYXN1cmUoaW5zdGFuY2UsIGBwYXRjaGApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBwYXRjaChudWxsLCBzdWJUcmVlLCBjb250YWluZXIsIGFuY2hvciwgaW5zdGFuY2UsIHBhcmVudFN1c3BlbnNlLCBpc1NWRyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgcGF0Y2hgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaW5pdGlhbFZOb2RlLmVsID0gc3ViVHJlZS5lbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIG1vdW50ZWQgaG9va1xyXG4gICAgICAgICAgICAgICAgaWYgKG0pIHtcclxuICAgICAgICAgICAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QobSwgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gb25Wbm9kZU1vdW50ZWRcclxuICAgICAgICAgICAgICAgIGlmICgodm5vZGVIb29rID0gcHJvcHMgJiYgcHJvcHMub25Wbm9kZU1vdW50ZWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50LCBpbml0aWFsVk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGFjdGl2YXRlZCBob29rIGZvciBrZWVwLWFsaXZlIHJvb3RzLlxyXG4gICAgICAgICAgICAgICAgLy8gIzE3NDIgYWN0aXZhdGVkIGhvb2sgbXVzdCBiZSBhY2Nlc3NlZCBhZnRlciBmaXJzdCByZW5kZXJcclxuICAgICAgICAgICAgICAgIC8vIHNpbmNlIHRoZSBob29rIG1heSBiZSBpbmplY3RlZCBieSBhIGNoaWxkIGtlZXAtYWxpdmVcclxuICAgICAgICAgICAgICAgIGNvbnN0IHsgYSB9ID0gaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICBpZiAoYSAmJlxyXG4gICAgICAgICAgICAgICAgICAgIGluaXRpYWxWTm9kZS5zaGFwZUZsYWcgJiAyNTYgLyogQ09NUE9ORU5UX1NIT1VMRF9LRUVQX0FMSVZFICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KGEsIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGluc3RhbmNlLmlzTW91bnRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyB1cGRhdGVDb21wb25lbnRcclxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdHJpZ2dlcmVkIGJ5IG11dGF0aW9uIG9mIGNvbXBvbmVudCdzIG93biBzdGF0ZSAobmV4dDogbnVsbClcclxuICAgICAgICAgICAgICAgIC8vIE9SIHBhcmVudCBjYWxsaW5nIHByb2Nlc3NDb21wb25lbnQgKG5leHQ6IFZOb2RlKVxyXG4gICAgICAgICAgICAgICAgbGV0IHsgbmV4dCwgYnUsIHUsIHBhcmVudCwgdm5vZGUgfSA9IGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgbGV0IG9yaWdpbk5leHQgPSBuZXh0O1xyXG4gICAgICAgICAgICAgICAgbGV0IHZub2RlSG9vaztcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBwdXNoV2FybmluZ0NvbnRleHQobmV4dCB8fCBpbnN0YW5jZS52bm9kZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAobmV4dCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUNvbXBvbmVudFByZVJlbmRlcihpbnN0YW5jZSwgbmV4dCwgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG5leHQgPSB2bm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG5leHQuZWwgPSB2bm9kZS5lbDtcclxuICAgICAgICAgICAgICAgIC8vIGJlZm9yZVVwZGF0ZSBob29rXHJcbiAgICAgICAgICAgICAgICBpZiAoYnUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbnZva2VBcnJheUZucyhidSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBvblZub2RlQmVmb3JlVXBkYXRlXHJcbiAgICAgICAgICAgICAgICBpZiAoKHZub2RlSG9vayA9IG5leHQucHJvcHMgJiYgbmV4dC5wcm9wcy5vblZub2RlQmVmb3JlVXBkYXRlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgbmV4dCwgdm5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gcmVuZGVyXHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRNZWFzdXJlKGluc3RhbmNlLCBgcmVuZGVyYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0VHJlZSA9IHJlbmRlckNvbXBvbmVudFJvb3QoaW5zdGFuY2UpO1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGByZW5kZXJgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZUcmVlID0gaW5zdGFuY2Uuc3ViVHJlZTtcclxuICAgICAgICAgICAgICAgIGluc3RhbmNlLnN1YlRyZWUgPSBuZXh0VHJlZTtcclxuICAgICAgICAgICAgICAgIC8vIHJlc2V0IHJlZnNcclxuICAgICAgICAgICAgICAgIC8vIG9ubHkgbmVlZGVkIGlmIHByZXZpb3VzIHBhdGNoIGhhZCByZWZzXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UucmVmcyAhPT0gRU1QVFlfT0JKKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UucmVmcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYHBhdGNoYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBwYXRjaChwcmV2VHJlZSwgbmV4dFRyZWUsIFxyXG4gICAgICAgICAgICAgICAgLy8gcGFyZW50IG1heSBoYXZlIGNoYW5nZWQgaWYgaXQncyBpbiBhIHRlbGVwb3J0XHJcbiAgICAgICAgICAgICAgICBob3N0UGFyZW50Tm9kZShwcmV2VHJlZS5lbCksIFxyXG4gICAgICAgICAgICAgICAgLy8gYW5jaG9yIG1heSBoYXZlIGNoYW5nZWQgaWYgaXQncyBpbiBhIGZyYWdtZW50XHJcbiAgICAgICAgICAgICAgICBnZXROZXh0SG9zdE5vZGUocHJldlRyZWUpLCBpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHKTtcclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbmRNZWFzdXJlKGluc3RhbmNlLCBgcGF0Y2hgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG5leHQuZWwgPSBuZXh0VHJlZS5lbDtcclxuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5OZXh0ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gc2VsZi10cmlnZ2VyZWQgdXBkYXRlLiBJbiBjYXNlIG9mIEhPQywgdXBkYXRlIHBhcmVudCBjb21wb25lbnRcclxuICAgICAgICAgICAgICAgICAgICAvLyB2bm9kZSBlbC4gSE9DIGlzIGluZGljYXRlZCBieSBwYXJlbnQgaW5zdGFuY2UncyBzdWJUcmVlIHBvaW50aW5nXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdG8gY2hpbGQgY29tcG9uZW50J3Mgdm5vZGVcclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVIT0NIb3N0RWwoaW5zdGFuY2UsIG5leHRUcmVlLmVsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIHVwZGF0ZWQgaG9va1xyXG4gICAgICAgICAgICAgICAgaWYgKHUpIHtcclxuICAgICAgICAgICAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QodSwgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gb25Wbm9kZVVwZGF0ZWRcclxuICAgICAgICAgICAgICAgIGlmICgodm5vZGVIb29rID0gbmV4dC5wcm9wcyAmJiBuZXh0LnByb3BzLm9uVm5vZGVVcGRhdGVkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGludm9rZVZOb2RlSG9vayh2bm9kZUhvb2ssIHBhcmVudCwgbmV4dCwgdm5vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGV2dG9vbHNDb21wb25lbnRVcGRhdGVkKGluc3RhbmNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBwb3BXYXJuaW5nQ29udGV4dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gY3JlYXRlRGV2RWZmZWN0T3B0aW9ucyhpbnN0YW5jZSkgOiBwcm9kRWZmZWN0T3B0aW9ucyk7XHJcbiAgICAgICAgaW5zdGFuY2UudXBkYXRlLmFsbG93UmVjdXJzZSA9IHRydWU7XHJcbiAgICB9O1xyXG4gICAgY29uc3QgdXBkYXRlQ29tcG9uZW50UHJlUmVuZGVyID0gKGluc3RhbmNlLCBuZXh0Vk5vZGUsIG9wdGltaXplZCkgPT4ge1xyXG4gICAgICAgIG5leHRWTm9kZS5jb21wb25lbnQgPSBpbnN0YW5jZTtcclxuICAgICAgICBjb25zdCBwcmV2UHJvcHMgPSBpbnN0YW5jZS52bm9kZS5wcm9wcztcclxuICAgICAgICBpbnN0YW5jZS52bm9kZSA9IG5leHRWTm9kZTtcclxuICAgICAgICBpbnN0YW5jZS5uZXh0ID0gbnVsbDtcclxuICAgICAgICB1cGRhdGVQcm9wcyhpbnN0YW5jZSwgbmV4dFZOb2RlLnByb3BzLCBwcmV2UHJvcHMsIG9wdGltaXplZCk7XHJcbiAgICAgICAgdXBkYXRlU2xvdHMoaW5zdGFuY2UsIG5leHRWTm9kZS5jaGlsZHJlbik7XHJcbiAgICAgICAgLy8gcHJvcHMgdXBkYXRlIG1heSBoYXZlIHRyaWdnZXJlZCBwcmUtZmx1c2ggd2F0Y2hlcnMuXHJcbiAgICAgICAgLy8gZmx1c2ggdGhlbSBiZWZvcmUgdGhlIHJlbmRlciB1cGRhdGUuXHJcbiAgICAgICAgZmx1c2hQcmVGbHVzaENicyh1bmRlZmluZWQsIGluc3RhbmNlLnVwZGF0ZSk7XHJcbiAgICB9O1xyXG4gICAgY29uc3QgcGF0Y2hDaGlsZHJlbiA9IChuMSwgbjIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkID0gZmFsc2UpID0+IHtcclxuICAgICAgICBjb25zdCBjMSA9IG4xICYmIG4xLmNoaWxkcmVuO1xyXG4gICAgICAgIGNvbnN0IHByZXZTaGFwZUZsYWcgPSBuMSA/IG4xLnNoYXBlRmxhZyA6IDA7XHJcbiAgICAgICAgY29uc3QgYzIgPSBuMi5jaGlsZHJlbjtcclxuICAgICAgICBjb25zdCB7IHBhdGNoRmxhZywgc2hhcGVGbGFnIH0gPSBuMjtcclxuICAgICAgICAvLyBmYXN0IHBhdGhcclxuICAgICAgICBpZiAocGF0Y2hGbGFnID4gMCkge1xyXG4gICAgICAgICAgICBpZiAocGF0Y2hGbGFnICYgMTI4IC8qIEtFWUVEX0ZSQUdNRU5UICovKSB7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGNvdWxkIGJlIGVpdGhlciBmdWxseS1rZXllZCBvciBtaXhlZCAoc29tZSBrZXllZCBzb21lIG5vdClcclxuICAgICAgICAgICAgICAgIC8vIHByZXNlbmNlIG9mIHBhdGNoRmxhZyBtZWFucyBjaGlsZHJlbiBhcmUgZ3VhcmFudGVlZCB0byBiZSBhcnJheXNcclxuICAgICAgICAgICAgICAgIHBhdGNoS2V5ZWRDaGlsZHJlbihjMSwgYzIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChwYXRjaEZsYWcgJiAyNTYgLyogVU5LRVlFRF9GUkFHTUVOVCAqLykge1xyXG4gICAgICAgICAgICAgICAgLy8gdW5rZXllZFxyXG4gICAgICAgICAgICAgICAgcGF0Y2hVbmtleWVkQ2hpbGRyZW4oYzEsIGMyLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY2hpbGRyZW4gaGFzIDMgcG9zc2liaWxpdGllczogdGV4dCwgYXJyYXkgb3Igbm8gY2hpbGRyZW4uXHJcbiAgICAgICAgaWYgKHNoYXBlRmxhZyAmIDggLyogVEVYVF9DSElMRFJFTiAqLykge1xyXG4gICAgICAgICAgICAvLyB0ZXh0IGNoaWxkcmVuIGZhc3QgcGF0aFxyXG4gICAgICAgICAgICBpZiAocHJldlNoYXBlRmxhZyAmIDE2IC8qIEFSUkFZX0NISUxEUkVOICovKSB7XHJcbiAgICAgICAgICAgICAgICB1bm1vdW50Q2hpbGRyZW4oYzEsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChjMiAhPT0gYzEpIHtcclxuICAgICAgICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsIGMyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHByZXZTaGFwZUZsYWcgJiAxNiAvKiBBUlJBWV9DSElMRFJFTiAqLykge1xyXG4gICAgICAgICAgICAgICAgLy8gcHJldiBjaGlsZHJlbiB3YXMgYXJyYXlcclxuICAgICAgICAgICAgICAgIGlmIChzaGFwZUZsYWcgJiAxNiAvKiBBUlJBWV9DSElMRFJFTiAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHR3byBhcnJheXMsIGNhbm5vdCBhc3N1bWUgYW55dGhpbmcsIGRvIGZ1bGwgZGlmZlxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGNoS2V5ZWRDaGlsZHJlbihjMSwgYzIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIG5vIG5ldyBjaGlsZHJlbiwganVzdCB1bm1vdW50IG9sZFxyXG4gICAgICAgICAgICAgICAgICAgIHVubW91bnRDaGlsZHJlbihjMSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBwcmV2IGNoaWxkcmVuIHdhcyB0ZXh0IE9SIG51bGxcclxuICAgICAgICAgICAgICAgIC8vIG5ldyBjaGlsZHJlbiBpcyBhcnJheSBPUiBudWxsXHJcbiAgICAgICAgICAgICAgICBpZiAocHJldlNoYXBlRmxhZyAmIDggLyogVEVYVF9DSElMRFJFTiAqLykge1xyXG4gICAgICAgICAgICAgICAgICAgIGhvc3RTZXRFbGVtZW50VGV4dChjb250YWluZXIsICcnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIG1vdW50IG5ldyBpZiBhcnJheVxyXG4gICAgICAgICAgICAgICAgaWYgKHNoYXBlRmxhZyAmIDE2IC8qIEFSUkFZX0NISUxEUkVOICovKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbW91bnRDaGlsZHJlbihjMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IHBhdGNoVW5rZXllZENoaWxkcmVuID0gKGMxLCBjMiwgY29udGFpbmVyLCBhbmNob3IsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpID0+IHtcclxuICAgICAgICBjMSA9IGMxIHx8IEVNUFRZX0FSUjtcclxuICAgICAgICBjMiA9IGMyIHx8IEVNUFRZX0FSUjtcclxuICAgICAgICBjb25zdCBvbGRMZW5ndGggPSBjMS5sZW5ndGg7XHJcbiAgICAgICAgY29uc3QgbmV3TGVuZ3RoID0gYzIubGVuZ3RoO1xyXG4gICAgICAgIGNvbnN0IGNvbW1vbkxlbmd0aCA9IE1hdGgubWluKG9sZExlbmd0aCwgbmV3TGVuZ3RoKTtcclxuICAgICAgICBsZXQgaTtcclxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29tbW9uTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgbmV4dENoaWxkID0gKGMyW2ldID0gb3B0aW1pemVkXHJcbiAgICAgICAgICAgICAgICA/IGNsb25lSWZNb3VudGVkKGMyW2ldKVxyXG4gICAgICAgICAgICAgICAgOiBub3JtYWxpemVWTm9kZShjMltpXSkpO1xyXG4gICAgICAgICAgICBwYXRjaChjMVtpXSwgbmV4dENoaWxkLCBjb250YWluZXIsIG51bGwsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAob2xkTGVuZ3RoID4gbmV3TGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIC8vIHJlbW92ZSBvbGRcclxuICAgICAgICAgICAgdW5tb3VudENoaWxkcmVuKGMxLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB0cnVlLCBjb21tb25MZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gbW91bnQgbmV3XHJcbiAgICAgICAgICAgIG1vdW50Q2hpbGRyZW4oYzIsIGNvbnRhaW5lciwgYW5jaG9yLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBpc1NWRywgb3B0aW1pemVkLCBjb21tb25MZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvLyBjYW4gYmUgYWxsLWtleWVkIG9yIG1peGVkXHJcbiAgICBjb25zdCBwYXRjaEtleWVkQ2hpbGRyZW4gPSAoYzEsIGMyLCBjb250YWluZXIsIHBhcmVudEFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCkgPT4ge1xyXG4gICAgICAgIGxldCBpID0gMDtcclxuICAgICAgICBjb25zdCBsMiA9IGMyLmxlbmd0aDtcclxuICAgICAgICBsZXQgZTEgPSBjMS5sZW5ndGggLSAxOyAvLyBwcmV2IGVuZGluZyBpbmRleFxyXG4gICAgICAgIGxldCBlMiA9IGwyIC0gMTsgLy8gbmV4dCBlbmRpbmcgaW5kZXhcclxuICAgICAgICAvLyAxLiBzeW5jIGZyb20gc3RhcnRcclxuICAgICAgICAvLyAoYSBiKSBjXHJcbiAgICAgICAgLy8gKGEgYikgZCBlXHJcbiAgICAgICAgd2hpbGUgKGkgPD0gZTEgJiYgaSA8PSBlMikge1xyXG4gICAgICAgICAgICBjb25zdCBuMSA9IGMxW2ldO1xyXG4gICAgICAgICAgICBjb25zdCBuMiA9IChjMltpXSA9IG9wdGltaXplZFxyXG4gICAgICAgICAgICAgICAgPyBjbG9uZUlmTW91bnRlZChjMltpXSlcclxuICAgICAgICAgICAgICAgIDogbm9ybWFsaXplVk5vZGUoYzJbaV0pKTtcclxuICAgICAgICAgICAgaWYgKGlzU2FtZVZOb2RlVHlwZShuMSwgbjIpKSB7XHJcbiAgICAgICAgICAgICAgICBwYXRjaChuMSwgbjIsIGNvbnRhaW5lciwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpKys7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIDIuIHN5bmMgZnJvbSBlbmRcclxuICAgICAgICAvLyBhIChiIGMpXHJcbiAgICAgICAgLy8gZCBlIChiIGMpXHJcbiAgICAgICAgd2hpbGUgKGkgPD0gZTEgJiYgaSA8PSBlMikge1xyXG4gICAgICAgICAgICBjb25zdCBuMSA9IGMxW2UxXTtcclxuICAgICAgICAgICAgY29uc3QgbjIgPSAoYzJbZTJdID0gb3B0aW1pemVkXHJcbiAgICAgICAgICAgICAgICA/IGNsb25lSWZNb3VudGVkKGMyW2UyXSlcclxuICAgICAgICAgICAgICAgIDogbm9ybWFsaXplVk5vZGUoYzJbZTJdKSk7XHJcbiAgICAgICAgICAgIGlmIChpc1NhbWVWTm9kZVR5cGUobjEsIG4yKSkge1xyXG4gICAgICAgICAgICAgICAgcGF0Y2gobjEsIG4yLCBjb250YWluZXIsIG51bGwsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGlzU1ZHLCBvcHRpbWl6ZWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZTEtLTtcclxuICAgICAgICAgICAgZTItLTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gMy4gY29tbW9uIHNlcXVlbmNlICsgbW91bnRcclxuICAgICAgICAvLyAoYSBiKVxyXG4gICAgICAgIC8vIChhIGIpIGNcclxuICAgICAgICAvLyBpID0gMiwgZTEgPSAxLCBlMiA9IDJcclxuICAgICAgICAvLyAoYSBiKVxyXG4gICAgICAgIC8vIGMgKGEgYilcclxuICAgICAgICAvLyBpID0gMCwgZTEgPSAtMSwgZTIgPSAwXHJcbiAgICAgICAgaWYgKGkgPiBlMSkge1xyXG4gICAgICAgICAgICBpZiAoaSA8PSBlMikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dFBvcyA9IGUyICsgMTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGFuY2hvciA9IG5leHRQb3MgPCBsMiA/IGMyW25leHRQb3NdLmVsIDogcGFyZW50QW5jaG9yO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKGkgPD0gZTIpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYXRjaChudWxsLCAoYzJbaV0gPSBvcHRpbWl6ZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBjbG9uZUlmTW91bnRlZChjMltpXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBub3JtYWxpemVWTm9kZShjMltpXSkpLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcpO1xyXG4gICAgICAgICAgICAgICAgICAgIGkrKztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyA0LiBjb21tb24gc2VxdWVuY2UgKyB1bm1vdW50XHJcbiAgICAgICAgLy8gKGEgYikgY1xyXG4gICAgICAgIC8vIChhIGIpXHJcbiAgICAgICAgLy8gaSA9IDIsIGUxID0gMiwgZTIgPSAxXHJcbiAgICAgICAgLy8gYSAoYiBjKVxyXG4gICAgICAgIC8vIChiIGMpXHJcbiAgICAgICAgLy8gaSA9IDAsIGUxID0gMCwgZTIgPSAtMVxyXG4gICAgICAgIGVsc2UgaWYgKGkgPiBlMikge1xyXG4gICAgICAgICAgICB3aGlsZSAoaSA8PSBlMSkge1xyXG4gICAgICAgICAgICAgICAgdW5tb3VudChjMVtpXSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICBpKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gNS4gdW5rbm93biBzZXF1ZW5jZVxyXG4gICAgICAgIC8vIFtpIC4uLiBlMSArIDFdOiBhIGIgW2MgZCBlXSBmIGdcclxuICAgICAgICAvLyBbaSAuLi4gZTIgKyAxXTogYSBiIFtlIGQgYyBoXSBmIGdcclxuICAgICAgICAvLyBpID0gMiwgZTEgPSA0LCBlMiA9IDVcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgczEgPSBpOyAvLyBwcmV2IHN0YXJ0aW5nIGluZGV4XHJcbiAgICAgICAgICAgIGNvbnN0IHMyID0gaTsgLy8gbmV4dCBzdGFydGluZyBpbmRleFxyXG4gICAgICAgICAgICAvLyA1LjEgYnVpbGQga2V5OmluZGV4IG1hcCBmb3IgbmV3Q2hpbGRyZW5cclxuICAgICAgICAgICAgY29uc3Qga2V5VG9OZXdJbmRleE1hcCA9IG5ldyBNYXAoKTtcclxuICAgICAgICAgICAgZm9yIChpID0gczI7IGkgPD0gZTI7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dENoaWxkID0gKGMyW2ldID0gb3B0aW1pemVkXHJcbiAgICAgICAgICAgICAgICAgICAgPyBjbG9uZUlmTW91bnRlZChjMltpXSlcclxuICAgICAgICAgICAgICAgICAgICA6IG5vcm1hbGl6ZVZOb2RlKGMyW2ldKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV4dENoaWxkLmtleSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBrZXlUb05ld0luZGV4TWFwLmhhcyhuZXh0Q2hpbGQua2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBEdXBsaWNhdGUga2V5cyBmb3VuZCBkdXJpbmcgdXBkYXRlOmAsIEpTT04uc3RyaW5naWZ5KG5leHRDaGlsZC5rZXkpLCBgTWFrZSBzdXJlIGtleXMgYXJlIHVuaXF1ZS5gKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAga2V5VG9OZXdJbmRleE1hcC5zZXQobmV4dENoaWxkLmtleSwgaSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gNS4yIGxvb3AgdGhyb3VnaCBvbGQgY2hpbGRyZW4gbGVmdCB0byBiZSBwYXRjaGVkIGFuZCB0cnkgdG8gcGF0Y2hcclxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgbm9kZXMgJiByZW1vdmUgbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIHByZXNlbnRcclxuICAgICAgICAgICAgbGV0IGo7XHJcbiAgICAgICAgICAgIGxldCBwYXRjaGVkID0gMDtcclxuICAgICAgICAgICAgY29uc3QgdG9CZVBhdGNoZWQgPSBlMiAtIHMyICsgMTtcclxuICAgICAgICAgICAgbGV0IG1vdmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIC8vIHVzZWQgdG8gdHJhY2sgd2hldGhlciBhbnkgbm9kZSBoYXMgbW92ZWRcclxuICAgICAgICAgICAgbGV0IG1heE5ld0luZGV4U29GYXIgPSAwO1xyXG4gICAgICAgICAgICAvLyB3b3JrcyBhcyBNYXA8bmV3SW5kZXgsIG9sZEluZGV4PlxyXG4gICAgICAgICAgICAvLyBOb3RlIHRoYXQgb2xkSW5kZXggaXMgb2Zmc2V0IGJ5ICsxXHJcbiAgICAgICAgICAgIC8vIGFuZCBvbGRJbmRleCA9IDAgaXMgYSBzcGVjaWFsIHZhbHVlIGluZGljYXRpbmcgdGhlIG5ldyBub2RlIGhhc1xyXG4gICAgICAgICAgICAvLyBubyBjb3JyZXNwb25kaW5nIG9sZCBub2RlLlxyXG4gICAgICAgICAgICAvLyB1c2VkIGZvciBkZXRlcm1pbmluZyBsb25nZXN0IHN0YWJsZSBzdWJzZXF1ZW5jZVxyXG4gICAgICAgICAgICBjb25zdCBuZXdJbmRleFRvT2xkSW5kZXhNYXAgPSBuZXcgQXJyYXkodG9CZVBhdGNoZWQpO1xyXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdG9CZVBhdGNoZWQ7IGkrKylcclxuICAgICAgICAgICAgICAgIG5ld0luZGV4VG9PbGRJbmRleE1hcFtpXSA9IDA7XHJcbiAgICAgICAgICAgIGZvciAoaSA9IHMxOyBpIDw9IGUxOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZDaGlsZCA9IGMxW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBhdGNoZWQgPj0gdG9CZVBhdGNoZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbmV3IGNoaWxkcmVuIGhhdmUgYmVlbiBwYXRjaGVkIHNvIHRoaXMgY2FuIG9ubHkgYmUgYSByZW1vdmFsXHJcbiAgICAgICAgICAgICAgICAgICAgdW5tb3VudChwcmV2Q2hpbGQsIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGV0IG5ld0luZGV4O1xyXG4gICAgICAgICAgICAgICAgaWYgKHByZXZDaGlsZC5rZXkgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0luZGV4ID0ga2V5VG9OZXdJbmRleE1hcC5nZXQocHJldkNoaWxkLmtleSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBrZXktbGVzcyBub2RlLCB0cnkgdG8gbG9jYXRlIGEga2V5LWxlc3Mgbm9kZSBvZiB0aGUgc2FtZSB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gczI7IGogPD0gZTI7IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3SW5kZXhUb09sZEluZGV4TWFwW2ogLSBzMl0gPT09IDAgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2FtZVZOb2RlVHlwZShwcmV2Q2hpbGQsIGMyW2pdKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5kZXggPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3SW5kZXggPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHVubW91bnQocHJldkNoaWxkLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0luZGV4VG9PbGRJbmRleE1hcFtuZXdJbmRleCAtIHMyXSA9IGkgKyAxO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXdJbmRleCA+PSBtYXhOZXdJbmRleFNvRmFyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heE5ld0luZGV4U29GYXIgPSBuZXdJbmRleDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0Y2gocHJldkNoaWxkLCBjMltuZXdJbmRleF0sIGNvbnRhaW5lciwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcsIG9wdGltaXplZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZCsrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIDUuMyBtb3ZlIGFuZCBtb3VudFxyXG4gICAgICAgICAgICAvLyBnZW5lcmF0ZSBsb25nZXN0IHN0YWJsZSBzdWJzZXF1ZW5jZSBvbmx5IHdoZW4gbm9kZXMgaGF2ZSBtb3ZlZFxyXG4gICAgICAgICAgICBjb25zdCBpbmNyZWFzaW5nTmV3SW5kZXhTZXF1ZW5jZSA9IG1vdmVkXHJcbiAgICAgICAgICAgICAgICA/IGdldFNlcXVlbmNlKG5ld0luZGV4VG9PbGRJbmRleE1hcClcclxuICAgICAgICAgICAgICAgIDogRU1QVFlfQVJSO1xyXG4gICAgICAgICAgICBqID0gaW5jcmVhc2luZ05ld0luZGV4U2VxdWVuY2UubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgLy8gbG9vcGluZyBiYWNrd2FyZHMgc28gdGhhdCB3ZSBjYW4gdXNlIGxhc3QgcGF0Y2hlZCBub2RlIGFzIGFuY2hvclxyXG4gICAgICAgICAgICBmb3IgKGkgPSB0b0JlUGF0Y2hlZCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0SW5kZXggPSBzMiArIGk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBuZXh0Q2hpbGQgPSBjMltuZXh0SW5kZXhdO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYW5jaG9yID0gbmV4dEluZGV4ICsgMSA8IGwyID8gYzJbbmV4dEluZGV4ICsgMV0uZWwgOiBwYXJlbnRBbmNob3I7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3SW5kZXhUb09sZEluZGV4TWFwW2ldID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbW91bnQgbmV3XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0Y2gobnVsbCwgbmV4dENoaWxkLCBjb250YWluZXIsIGFuY2hvciwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgaXNTVkcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAobW92ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBtb3ZlIGlmOlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIHN0YWJsZSBzdWJzZXF1ZW5jZSAoZS5nLiBhIHJldmVyc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT1IgY3VycmVudCBub2RlIGlzIG5vdCBhbW9uZyB0aGUgc3RhYmxlIHNlcXVlbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGogPCAwIHx8IGkgIT09IGluY3JlYXNpbmdOZXdJbmRleFNlcXVlbmNlW2pdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdmUobmV4dENoaWxkLCBjb250YWluZXIsIGFuY2hvciwgMiAvKiBSRU9SREVSICovKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGotLTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3QgbW92ZSA9ICh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlLCBwYXJlbnRTdXNwZW5zZSA9IG51bGwpID0+IHtcclxuICAgICAgICBjb25zdCB7IGVsLCB0eXBlLCB0cmFuc2l0aW9uLCBjaGlsZHJlbiwgc2hhcGVGbGFnIH0gPSB2bm9kZTtcclxuICAgICAgICBpZiAoc2hhcGVGbGFnICYgNiAvKiBDT01QT05FTlQgKi8pIHtcclxuICAgICAgICAgICAgbW92ZSh2bm9kZS5jb21wb25lbnQuc3ViVHJlZSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIHNoYXBlRmxhZyAmIDEyOCAvKiBTVVNQRU5TRSAqLykge1xyXG4gICAgICAgICAgICB2bm9kZS5zdXNwZW5zZS5tb3ZlKGNvbnRhaW5lciwgYW5jaG9yLCBtb3ZlVHlwZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHNoYXBlRmxhZyAmIDY0IC8qIFRFTEVQT1JUICovKSB7XHJcbiAgICAgICAgICAgIHR5cGUubW92ZSh2bm9kZSwgY29udGFpbmVyLCBhbmNob3IsIGludGVybmFscyk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHR5cGUgPT09IEZyYWdtZW50KSB7XHJcbiAgICAgICAgICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbW92ZShjaGlsZHJlbltpXSwgY29udGFpbmVyLCBhbmNob3IsIG1vdmVUeXBlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBob3N0SW5zZXJ0KHZub2RlLmFuY2hvciwgY29udGFpbmVyLCBhbmNob3IpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHN0YXRpYyBub2RlIG1vdmUgY2FuIG9ubHkgaGFwcGVuIHdoZW4gZm9yY2UgdXBkYXRpbmcgSE1SXHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB0eXBlID09PSBTdGF0aWMpIHtcclxuICAgICAgICAgICAgbW92ZVN0YXRpY05vZGUodm5vZGUsIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBzaW5nbGUgbm9kZXNcclxuICAgICAgICBjb25zdCBuZWVkVHJhbnNpdGlvbiA9IG1vdmVUeXBlICE9PSAyIC8qIFJFT1JERVIgKi8gJiZcclxuICAgICAgICAgICAgc2hhcGVGbGFnICYgMSAvKiBFTEVNRU5UICovICYmXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb247XHJcbiAgICAgICAgaWYgKG5lZWRUcmFuc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIGlmIChtb3ZlVHlwZSA9PT0gMCAvKiBFTlRFUiAqLykge1xyXG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbi5iZWZvcmVFbnRlcihlbCk7XHJcbiAgICAgICAgICAgICAgICBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgICAgICBxdWV1ZVBvc3RSZW5kZXJFZmZlY3QoKCkgPT4gdHJhbnNpdGlvbi5lbnRlcihlbCksIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHsgbGVhdmUsIGRlbGF5TGVhdmUsIGFmdGVyTGVhdmUgfSA9IHRyYW5zaXRpb247XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZW1vdmUgPSAoKSA9PiBob3N0SW5zZXJ0KGVsLCBjb250YWluZXIsIGFuY2hvcik7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwZXJmb3JtTGVhdmUgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVhdmUoZWwsICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFmdGVyTGVhdmUgJiYgYWZ0ZXJMZWF2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIGlmIChkZWxheUxlYXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsYXlMZWF2ZShlbCwgcmVtb3ZlLCBwZXJmb3JtTGVhdmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGVyZm9ybUxlYXZlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGhvc3RJbnNlcnQoZWwsIGNvbnRhaW5lciwgYW5jaG9yKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3QgdW5tb3VudCA9ICh2bm9kZSwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUgPSBmYWxzZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHsgdHlwZSwgcHJvcHMsIHJlZiwgY2hpbGRyZW4sIGR5bmFtaWNDaGlsZHJlbiwgc2hhcGVGbGFnLCBwYXRjaEZsYWcsIGRpcnMgfSA9IHZub2RlO1xyXG4gICAgICAgIC8vIHVuc2V0IHJlZlxyXG4gICAgICAgIGlmIChyZWYgIT0gbnVsbCAmJiBwYXJlbnRDb21wb25lbnQpIHtcclxuICAgICAgICAgICAgc2V0UmVmKHJlZiwgbnVsbCwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgbnVsbCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzaGFwZUZsYWcgJiAyNTYgLyogQ09NUE9ORU5UX1NIT1VMRF9LRUVQX0FMSVZFICovKSB7XHJcbiAgICAgICAgICAgIHBhcmVudENvbXBvbmVudC5jdHguZGVhY3RpdmF0ZSh2bm9kZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc2hvdWxkSW52b2tlRGlycyA9IHNoYXBlRmxhZyAmIDEgLyogRUxFTUVOVCAqLyAmJiBkaXJzO1xyXG4gICAgICAgIGxldCB2bm9kZUhvb2s7XHJcbiAgICAgICAgaWYgKCh2bm9kZUhvb2sgPSBwcm9wcyAmJiBwcm9wcy5vblZub2RlQmVmb3JlVW5tb3VudCkpIHtcclxuICAgICAgICAgICAgaW52b2tlVk5vZGVIb29rKHZub2RlSG9vaywgcGFyZW50Q29tcG9uZW50LCB2bm9kZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzaGFwZUZsYWcgJiA2IC8qIENPTVBPTkVOVCAqLykge1xyXG4gICAgICAgICAgICB1bm1vdW50Q29tcG9uZW50KHZub2RlLmNvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICggc2hhcGVGbGFnICYgMTI4IC8qIFNVU1BFTlNFICovKSB7XHJcbiAgICAgICAgICAgICAgICB2bm9kZS5zdXNwZW5zZS51bm1vdW50KHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHNob3VsZEludm9rZURpcnMpIHtcclxuICAgICAgICAgICAgICAgIGludm9rZURpcmVjdGl2ZUhvb2sodm5vZGUsIG51bGwsIHBhcmVudENvbXBvbmVudCwgJ2JlZm9yZVVubW91bnQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZHluYW1pY0NoaWxkcmVuICYmXHJcbiAgICAgICAgICAgICAgICAvLyAjMTE1MzogZmFzdCBwYXRoIHNob3VsZCBub3QgYmUgdGFrZW4gZm9yIG5vbi1zdGFibGUgKHYtZm9yKSBmcmFnbWVudHNcclxuICAgICAgICAgICAgICAgICh0eXBlICE9PSBGcmFnbWVudCB8fFxyXG4gICAgICAgICAgICAgICAgICAgIChwYXRjaEZsYWcgPiAwICYmIHBhdGNoRmxhZyAmIDY0IC8qIFNUQUJMRV9GUkFHTUVOVCAqLykpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBmYXN0IHBhdGggZm9yIGJsb2NrIG5vZGVzOiBvbmx5IG5lZWQgdG8gdW5tb3VudCBkeW5hbWljIGNoaWxkcmVuLlxyXG4gICAgICAgICAgICAgICAgdW5tb3VudENoaWxkcmVuKGR5bmFtaWNDaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoc2hhcGVGbGFnICYgMTYgLyogQVJSQVlfQ0hJTERSRU4gKi8pIHtcclxuICAgICAgICAgICAgICAgIHVubW91bnRDaGlsZHJlbihjaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gYW4gdW5tb3VudGVkIHRlbGVwb3J0IHNob3VsZCBhbHdheXMgcmVtb3ZlIGl0cyBjaGlsZHJlblxyXG4gICAgICAgICAgICBpZiAoc2hhcGVGbGFnICYgNjQgLyogVEVMRVBPUlQgKi8pIHtcclxuICAgICAgICAgICAgICAgIHZub2RlLnR5cGUucmVtb3ZlKHZub2RlLCBpbnRlcm5hbHMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChkb1JlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgcmVtb3ZlKHZub2RlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKHZub2RlSG9vayA9IHByb3BzICYmIHByb3BzLm9uVm5vZGVVbm1vdW50ZWQpIHx8IHNob3VsZEludm9rZURpcnMpIHtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHZub2RlSG9vayAmJiBpbnZva2VWTm9kZUhvb2sodm5vZGVIb29rLCBwYXJlbnRDb21wb25lbnQsIHZub2RlKTtcclxuICAgICAgICAgICAgICAgIHNob3VsZEludm9rZURpcnMgJiZcclxuICAgICAgICAgICAgICAgICAgICBpbnZva2VEaXJlY3RpdmVIb29rKHZub2RlLCBudWxsLCBwYXJlbnRDb21wb25lbnQsICd1bm1vdW50ZWQnKTtcclxuICAgICAgICAgICAgfSwgcGFyZW50U3VzcGVuc2UpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCByZW1vdmUgPSB2bm9kZSA9PiB7XHJcbiAgICAgICAgY29uc3QgeyB0eXBlLCBlbCwgYW5jaG9yLCB0cmFuc2l0aW9uIH0gPSB2bm9kZTtcclxuICAgICAgICBpZiAodHlwZSA9PT0gRnJhZ21lbnQpIHtcclxuICAgICAgICAgICAgcmVtb3ZlRnJhZ21lbnQoZWwsIGFuY2hvcik7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB0eXBlID09PSBTdGF0aWMpIHtcclxuICAgICAgICAgICAgcmVtb3ZlU3RhdGljTm9kZSh2bm9kZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcGVyZm9ybVJlbW92ZSA9ICgpID0+IHtcclxuICAgICAgICAgICAgaG9zdFJlbW92ZShlbCk7XHJcbiAgICAgICAgICAgIGlmICh0cmFuc2l0aW9uICYmICF0cmFuc2l0aW9uLnBlcnNpc3RlZCAmJiB0cmFuc2l0aW9uLmFmdGVyTGVhdmUpIHtcclxuICAgICAgICAgICAgICAgIHRyYW5zaXRpb24uYWZ0ZXJMZWF2ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgMSAvKiBFTEVNRU5UICovICYmXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24gJiZcclxuICAgICAgICAgICAgIXRyYW5zaXRpb24ucGVyc2lzdGVkKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHsgbGVhdmUsIGRlbGF5TGVhdmUgfSA9IHRyYW5zaXRpb247XHJcbiAgICAgICAgICAgIGNvbnN0IHBlcmZvcm1MZWF2ZSA9ICgpID0+IGxlYXZlKGVsLCBwZXJmb3JtUmVtb3ZlKTtcclxuICAgICAgICAgICAgaWYgKGRlbGF5TGVhdmUpIHtcclxuICAgICAgICAgICAgICAgIGRlbGF5TGVhdmUodm5vZGUuZWwsIHBlcmZvcm1SZW1vdmUsIHBlcmZvcm1MZWF2ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBwZXJmb3JtTGVhdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcGVyZm9ybVJlbW92ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBjb25zdCByZW1vdmVGcmFnbWVudCA9IChjdXIsIGVuZCkgPT4ge1xyXG4gICAgICAgIC8vIEZvciBmcmFnbWVudHMsIGRpcmVjdGx5IHJlbW92ZSBhbGwgY29udGFpbmVkIERPTSBub2Rlcy5cclxuICAgICAgICAvLyAoZnJhZ21lbnQgY2hpbGQgbm9kZXMgY2Fubm90IGhhdmUgdHJhbnNpdGlvbilcclxuICAgICAgICBsZXQgbmV4dDtcclxuICAgICAgICB3aGlsZSAoY3VyICE9PSBlbmQpIHtcclxuICAgICAgICAgICAgbmV4dCA9IGhvc3ROZXh0U2libGluZyhjdXIpO1xyXG4gICAgICAgICAgICBob3N0UmVtb3ZlKGN1cik7XHJcbiAgICAgICAgICAgIGN1ciA9IG5leHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGhvc3RSZW1vdmUoZW5kKTtcclxuICAgIH07XHJcbiAgICBjb25zdCB1bm1vdW50Q29tcG9uZW50ID0gKGluc3RhbmNlLCBwYXJlbnRTdXNwZW5zZSwgZG9SZW1vdmUpID0+IHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIGluc3RhbmNlLnR5cGUuX19obXJJZCkge1xyXG4gICAgICAgICAgICB1bnJlZ2lzdGVySE1SKGluc3RhbmNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgeyBidW0sIGVmZmVjdHMsIHVwZGF0ZSwgc3ViVHJlZSwgdW0gfSA9IGluc3RhbmNlO1xyXG4gICAgICAgIC8vIGJlZm9yZVVubW91bnQgaG9va1xyXG4gICAgICAgIGlmIChidW0pIHtcclxuICAgICAgICAgICAgaW52b2tlQXJyYXlGbnMoYnVtKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGVmZmVjdHMpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZmZlY3RzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBzdG9wKGVmZmVjdHNbaV0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHVwZGF0ZSBtYXkgYmUgbnVsbCBpZiBhIGNvbXBvbmVudCBpcyB1bm1vdW50ZWQgYmVmb3JlIGl0cyBhc3luY1xyXG4gICAgICAgIC8vIHNldHVwIGhhcyByZXNvbHZlZC5cclxuICAgICAgICBpZiAodXBkYXRlKSB7XHJcbiAgICAgICAgICAgIHN0b3AodXBkYXRlKTtcclxuICAgICAgICAgICAgdW5tb3VudChzdWJUcmVlLCBpbnN0YW5jZSwgcGFyZW50U3VzcGVuc2UsIGRvUmVtb3ZlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gdW5tb3VudGVkIGhvb2tcclxuICAgICAgICBpZiAodW0pIHtcclxuICAgICAgICAgICAgcXVldWVQb3N0UmVuZGVyRWZmZWN0KHVtLCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHF1ZXVlUG9zdFJlbmRlckVmZmVjdCgoKSA9PiB7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLmlzVW5tb3VudGVkID0gdHJ1ZTtcclxuICAgICAgICB9LCBwYXJlbnRTdXNwZW5zZSk7XHJcbiAgICAgICAgLy8gQSBjb21wb25lbnQgd2l0aCBhc3luYyBkZXAgaW5zaWRlIGEgcGVuZGluZyBzdXNwZW5zZSBpcyB1bm1vdW50ZWQgYmVmb3JlXHJcbiAgICAgICAgLy8gaXRzIGFzeW5jIGRlcCByZXNvbHZlcy4gVGhpcyBzaG91bGQgcmVtb3ZlIHRoZSBkZXAgZnJvbSB0aGUgc3VzcGVuc2UsIGFuZFxyXG4gICAgICAgIC8vIGNhdXNlIHRoZSBzdXNwZW5zZSB0byByZXNvbHZlIGltbWVkaWF0ZWx5IGlmIHRoYXQgd2FzIHRoZSBsYXN0IGRlcC5cclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgIHBhcmVudFN1c3BlbnNlICYmXHJcbiAgICAgICAgICAgICFwYXJlbnRTdXNwZW5zZS5pc1Jlc29sdmVkICYmXHJcbiAgICAgICAgICAgICFwYXJlbnRTdXNwZW5zZS5pc1VubW91bnRlZCAmJlxyXG4gICAgICAgICAgICBpbnN0YW5jZS5hc3luY0RlcCAmJlxyXG4gICAgICAgICAgICAhaW5zdGFuY2UuYXN5bmNSZXNvbHZlZCkge1xyXG4gICAgICAgICAgICBwYXJlbnRTdXNwZW5zZS5kZXBzLS07XHJcbiAgICAgICAgICAgIGlmIChwYXJlbnRTdXNwZW5zZS5kZXBzID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnRTdXNwZW5zZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB8fCBfX1ZVRV9QUk9EX0RFVlRPT0xTX18pIHtcclxuICAgICAgICAgICAgZGV2dG9vbHNDb21wb25lbnRSZW1vdmVkKGluc3RhbmNlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgY29uc3QgdW5tb3VudENoaWxkcmVuID0gKGNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSA9IGZhbHNlLCBzdGFydCA9IDApID0+IHtcclxuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB1bm1vdW50KGNoaWxkcmVuW2ldLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlLCBkb1JlbW92ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IGdldE5leHRIb3N0Tm9kZSA9IHZub2RlID0+IHtcclxuICAgICAgICBpZiAodm5vZGUuc2hhcGVGbGFnICYgNiAvKiBDT01QT05FTlQgKi8pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGdldE5leHRIb3N0Tm9kZSh2bm9kZS5jb21wb25lbnQuc3ViVHJlZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICggdm5vZGUuc2hhcGVGbGFnICYgMTI4IC8qIFNVU1BFTlNFICovKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB2bm9kZS5zdXNwZW5zZS5uZXh0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBob3N0TmV4dFNpYmxpbmcoKHZub2RlLmFuY2hvciB8fCB2bm9kZS5lbCkpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogIzExNTZcclxuICAgICAqIFdoZW4gYSBjb21wb25lbnQgaXMgSE1SLWVuYWJsZWQsIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIHN0YXRpYyBub2Rlc1xyXG4gICAgICogaW5zaWRlIGEgYmxvY2sgYWxzbyBpbmhlcml0IHRoZSBET00gZWxlbWVudCBmcm9tIHRoZSBwcmV2aW91cyB0cmVlIHNvIHRoYXRcclxuICAgICAqIEhNUiB1cGRhdGVzICh3aGljaCBhcmUgZnVsbCB1cGRhdGVzKSBjYW4gcmV0cmlldmUgdGhlIGVsZW1lbnQgZm9yIHBhdGNoaW5nLlxyXG4gICAgICpcclxuICAgICAqIERldiBvbmx5LlxyXG4gICAgICovXHJcbiAgICBjb25zdCB0cmF2ZXJzZVN0YXRpY0NoaWxkcmVuID0gKG4xLCBuMikgPT4ge1xyXG4gICAgICAgIGNvbnN0IGNoMSA9IG4xLmNoaWxkcmVuO1xyXG4gICAgICAgIGNvbnN0IGNoMiA9IG4yLmNoaWxkcmVuO1xyXG4gICAgICAgIGlmIChpc0FycmF5KGNoMSkgJiYgaXNBcnJheShjaDIpKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2gxLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIG9ubHkgY2FsbGVkIGluIHRoZSBvcHRpbWl6ZWQgcGF0aCBzbyBhcnJheSBjaGlsZHJlbiBhcmVcclxuICAgICAgICAgICAgICAgIC8vIGd1YXJhbnRlZWQgdG8gYmUgdm5vZGVzXHJcbiAgICAgICAgICAgICAgICBjb25zdCBjMSA9IGNoMVtpXTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGMyID0gKGNoMltpXSA9IGNsb25lSWZNb3VudGVkKGNoMltpXSkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGMyLnNoYXBlRmxhZyAmIDEgLyogRUxFTUVOVCAqLyAmJiAhYzIuZHluYW1pY0NoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGMyLnBhdGNoRmxhZyA8PSAwIHx8IGMyLnBhdGNoRmxhZyA9PT0gMzIgLyogSFlEUkFURV9FVkVOVFMgKi8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYzIuZWwgPSBjMS5lbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdHJhdmVyc2VTdGF0aWNDaGlsZHJlbihjMSwgYzIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIGNvbnN0IHJlbmRlciA9ICh2bm9kZSwgY29udGFpbmVyKSA9PiB7XHJcbiAgICAgICAgaWYgKHZub2RlID09IG51bGwpIHtcclxuICAgICAgICAgICAgaWYgKGNvbnRhaW5lci5fdm5vZGUpIHtcclxuICAgICAgICAgICAgICAgIHVubW91bnQoY29udGFpbmVyLl92bm9kZSwgbnVsbCwgbnVsbCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHBhdGNoKGNvbnRhaW5lci5fdm5vZGUgfHwgbnVsbCwgdm5vZGUsIGNvbnRhaW5lcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZsdXNoUG9zdEZsdXNoQ2JzKCk7XHJcbiAgICAgICAgY29udGFpbmVyLl92bm9kZSA9IHZub2RlO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IGludGVybmFscyA9IHtcclxuICAgICAgICBwOiBwYXRjaCxcclxuICAgICAgICB1bTogdW5tb3VudCxcclxuICAgICAgICBtOiBtb3ZlLFxyXG4gICAgICAgIHI6IHJlbW92ZSxcclxuICAgICAgICBtdDogbW91bnRDb21wb25lbnQsXHJcbiAgICAgICAgbWM6IG1vdW50Q2hpbGRyZW4sXHJcbiAgICAgICAgcGM6IHBhdGNoQ2hpbGRyZW4sXHJcbiAgICAgICAgcGJjOiBwYXRjaEJsb2NrQ2hpbGRyZW4sXHJcbiAgICAgICAgbjogZ2V0TmV4dEhvc3ROb2RlLFxyXG4gICAgICAgIG86IG9wdGlvbnNcclxuICAgIH07XHJcbiAgICBsZXQgaHlkcmF0ZTtcclxuICAgIGxldCBoeWRyYXRlTm9kZTtcclxuICAgIGlmIChjcmVhdGVIeWRyYXRpb25GbnMpIHtcclxuICAgICAgICBbaHlkcmF0ZSwgaHlkcmF0ZU5vZGVdID0gY3JlYXRlSHlkcmF0aW9uRm5zKGludGVybmFscyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIHJlbmRlcixcclxuICAgICAgICBoeWRyYXRlLFxyXG4gICAgICAgIGNyZWF0ZUFwcDogY3JlYXRlQXBwQVBJKHJlbmRlciwgaHlkcmF0ZSlcclxuICAgIH07XHJcbn1cclxuZnVuY3Rpb24gaW52b2tlVk5vZGVIb29rKGhvb2ssIGluc3RhbmNlLCB2bm9kZSwgcHJldlZOb2RlID0gbnVsbCkge1xyXG4gICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcoaG9vaywgaW5zdGFuY2UsIDcgLyogVk5PREVfSE9PSyAqLywgW1xyXG4gICAgICAgIHZub2RlLFxyXG4gICAgICAgIHByZXZWTm9kZVxyXG4gICAgXSk7XHJcbn1cclxuLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTG9uZ2VzdF9pbmNyZWFzaW5nX3N1YnNlcXVlbmNlXHJcbmZ1bmN0aW9uIGdldFNlcXVlbmNlKGFycikge1xyXG4gICAgY29uc3QgcCA9IGFyci5zbGljZSgpO1xyXG4gICAgY29uc3QgcmVzdWx0ID0gWzBdO1xyXG4gICAgbGV0IGksIGosIHUsIHYsIGM7XHJcbiAgICBjb25zdCBsZW4gPSBhcnIubGVuZ3RoO1xyXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgY29uc3QgYXJySSA9IGFycltpXTtcclxuICAgICAgICBpZiAoYXJySSAhPT0gMCkge1xyXG4gICAgICAgICAgICBqID0gcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXTtcclxuICAgICAgICAgICAgaWYgKGFycltqXSA8IGFyckkpIHtcclxuICAgICAgICAgICAgICAgIHBbaV0gPSBqO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goaSk7XHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB1ID0gMDtcclxuICAgICAgICAgICAgdiA9IHJlc3VsdC5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICB3aGlsZSAodSA8IHYpIHtcclxuICAgICAgICAgICAgICAgIGMgPSAoKHUgKyB2KSAvIDIpIHwgMDtcclxuICAgICAgICAgICAgICAgIGlmIChhcnJbcmVzdWx0W2NdXSA8IGFyckkpIHtcclxuICAgICAgICAgICAgICAgICAgICB1ID0gYyArIDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2ID0gYztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoYXJySSA8IGFycltyZXN1bHRbdV1dKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBwW2ldID0gcmVzdWx0W3UgLSAxXTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJlc3VsdFt1XSA9IGk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB1ID0gcmVzdWx0Lmxlbmd0aDtcclxuICAgIHYgPSByZXN1bHRbdSAtIDFdO1xyXG4gICAgd2hpbGUgKHUtLSA+IDApIHtcclxuICAgICAgICByZXN1bHRbdV0gPSB2O1xyXG4gICAgICAgIHYgPSBwW3ZdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxuXG4vLyBTaW1wbGUgZWZmZWN0LlxyXG5mdW5jdGlvbiB3YXRjaEVmZmVjdChlZmZlY3QsIG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBkb1dhdGNoKGVmZmVjdCwgbnVsbCwgb3B0aW9ucyk7XHJcbn1cclxuLy8gaW5pdGlhbCB2YWx1ZSBmb3Igd2F0Y2hlcnMgdG8gdHJpZ2dlciBvbiB1bmRlZmluZWQgaW5pdGlhbCB2YWx1ZXNcclxuY29uc3QgSU5JVElBTF9XQVRDSEVSX1ZBTFVFID0ge307XHJcbi8vIGltcGxlbWVudGF0aW9uXHJcbmZ1bmN0aW9uIHdhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpIHtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIWlzRnVuY3Rpb24oY2IpKSB7XHJcbiAgICAgICAgd2FybihgXFxgd2F0Y2goZm4sIG9wdGlvbnM/KVxcYCBzaWduYXR1cmUgaGFzIGJlZW4gbW92ZWQgdG8gYSBzZXBhcmF0ZSBBUEkuIGAgK1xyXG4gICAgICAgICAgICBgVXNlIFxcYHdhdGNoRWZmZWN0KGZuLCBvcHRpb25zPylcXGAgaW5zdGVhZC4gXFxgd2F0Y2hcXGAgbm93IG9ubHkgYCArXHJcbiAgICAgICAgICAgIGBzdXBwb3J0cyBcXGB3YXRjaChzb3VyY2UsIGNiLCBvcHRpb25zPykgc2lnbmF0dXJlLmApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGRvV2F0Y2goc291cmNlLCBjYiwgb3B0aW9ucyk7XHJcbn1cclxuZnVuY3Rpb24gZG9XYXRjaChzb3VyY2UsIGNiLCB7IGltbWVkaWF0ZSwgZGVlcCwgZmx1c2gsIG9uVHJhY2ssIG9uVHJpZ2dlciB9ID0gRU1QVFlfT0JKLCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZSkge1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhY2IpIHtcclxuICAgICAgICBpZiAoaW1tZWRpYXRlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgd2Fybihgd2F0Y2goKSBcImltbWVkaWF0ZVwiIG9wdGlvbiBpcyBvbmx5IHJlc3BlY3RlZCB3aGVuIHVzaW5nIHRoZSBgICtcclxuICAgICAgICAgICAgICAgIGB3YXRjaChzb3VyY2UsIGNhbGxiYWNrLCBvcHRpb25zPykgc2lnbmF0dXJlLmApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGVlcCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYHdhdGNoKCkgXCJkZWVwXCIgb3B0aW9uIGlzIG9ubHkgcmVzcGVjdGVkIHdoZW4gdXNpbmcgdGhlIGAgK1xyXG4gICAgICAgICAgICAgICAgYHdhdGNoKHNvdXJjZSwgY2FsbGJhY2ssIG9wdGlvbnM/KSBzaWduYXR1cmUuYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3Qgd2FybkludmFsaWRTb3VyY2UgPSAocykgPT4ge1xyXG4gICAgICAgIHdhcm4oYEludmFsaWQgd2F0Y2ggc291cmNlOiBgLCBzLCBgQSB3YXRjaCBzb3VyY2UgY2FuIG9ubHkgYmUgYSBnZXR0ZXIvZWZmZWN0IGZ1bmN0aW9uLCBhIHJlZiwgYCArXHJcbiAgICAgICAgICAgIGBhIHJlYWN0aXZlIG9iamVjdCwgb3IgYW4gYXJyYXkgb2YgdGhlc2UgdHlwZXMuYCk7XHJcbiAgICB9O1xyXG4gICAgbGV0IGdldHRlcjtcclxuICAgIGNvbnN0IGlzUmVmU291cmNlID0gaXNSZWYoc291cmNlKTtcclxuICAgIGlmIChpc1JlZlNvdXJjZSkge1xyXG4gICAgICAgIGdldHRlciA9ICgpID0+IHNvdXJjZS52YWx1ZTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzUmVhY3RpdmUoc291cmNlKSkge1xyXG4gICAgICAgIGdldHRlciA9ICgpID0+IHNvdXJjZTtcclxuICAgICAgICBkZWVwID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzQXJyYXkoc291cmNlKSkge1xyXG4gICAgICAgIGdldHRlciA9ICgpID0+IHNvdXJjZS5tYXAocyA9PiB7XHJcbiAgICAgICAgICAgIGlmIChpc1JlZihzKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHMudmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoaXNSZWFjdGl2ZShzKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRyYXZlcnNlKHMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzRnVuY3Rpb24ocykpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsV2l0aEVycm9ySGFuZGxpbmcocywgaW5zdGFuY2UsIDIgLyogV0FUQ0hfR0VUVEVSICovKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuSW52YWxpZFNvdXJjZShzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNGdW5jdGlvbihzb3VyY2UpKSB7XHJcbiAgICAgICAgaWYgKGNiKSB7XHJcbiAgICAgICAgICAgIC8vIGdldHRlciB3aXRoIGNiXHJcbiAgICAgICAgICAgIGdldHRlciA9ICgpID0+IGNhbGxXaXRoRXJyb3JIYW5kbGluZyhzb3VyY2UsIGluc3RhbmNlLCAyIC8qIFdBVENIX0dFVFRFUiAqLyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBubyBjYiAtPiBzaW1wbGUgZWZmZWN0XHJcbiAgICAgICAgICAgIGdldHRlciA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZSAmJiBpbnN0YW5jZS5pc1VubW91bnRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChjbGVhbnVwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2xlYW51cCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxXaXRoRXJyb3JIYW5kbGluZyhzb3VyY2UsIGluc3RhbmNlLCAzIC8qIFdBVENIX0NBTExCQUNLICovLCBbb25JbnZhbGlkYXRlXSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgZ2V0dGVyID0gTk9PUDtcclxuICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgd2FybkludmFsaWRTb3VyY2Uoc291cmNlKTtcclxuICAgIH1cclxuICAgIGlmIChjYiAmJiBkZWVwKSB7XHJcbiAgICAgICAgY29uc3QgYmFzZUdldHRlciA9IGdldHRlcjtcclxuICAgICAgICBnZXR0ZXIgPSAoKSA9PiB0cmF2ZXJzZShiYXNlR2V0dGVyKCkpO1xyXG4gICAgfVxyXG4gICAgbGV0IGNsZWFudXA7XHJcbiAgICBjb25zdCBvbkludmFsaWRhdGUgPSAoZm4pID0+IHtcclxuICAgICAgICBjbGVhbnVwID0gcnVubmVyLm9wdGlvbnMub25TdG9wID0gKCkgPT4ge1xyXG4gICAgICAgICAgICBjYWxsV2l0aEVycm9ySGFuZGxpbmcoZm4sIGluc3RhbmNlLCA0IC8qIFdBVENIX0NMRUFOVVAgKi8pO1xyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgbGV0IG9sZFZhbHVlID0gaXNBcnJheShzb3VyY2UpID8gW10gOiBJTklUSUFMX1dBVENIRVJfVkFMVUU7XHJcbiAgICBjb25zdCBqb2IgPSAoKSA9PiB7XHJcbiAgICAgICAgaWYgKCFydW5uZXIuYWN0aXZlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNiKSB7XHJcbiAgICAgICAgICAgIC8vIHdhdGNoKHNvdXJjZSwgY2IpXHJcbiAgICAgICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gcnVubmVyKCk7XHJcbiAgICAgICAgICAgIGlmIChkZWVwIHx8IGlzUmVmU291cmNlIHx8IGhhc0NoYW5nZWQobmV3VmFsdWUsIG9sZFZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gY2xlYW51cCBiZWZvcmUgcnVubmluZyBjYiBhZ2FpblxyXG4gICAgICAgICAgICAgICAgaWYgKGNsZWFudXApIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhbnVwKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZyhjYiwgaW5zdGFuY2UsIDMgLyogV0FUQ0hfQ0FMTEJBQ0sgKi8sIFtcclxuICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICAvLyBwYXNzIHVuZGVmaW5lZCBhcyB0aGUgb2xkIHZhbHVlIHdoZW4gaXQncyBjaGFuZ2VkIGZvciB0aGUgZmlyc3QgdGltZVxyXG4gICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID09PSBJTklUSUFMX1dBVENIRVJfVkFMVUUgPyB1bmRlZmluZWQgOiBvbGRWYWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICBvbkludmFsaWRhdGVcclxuICAgICAgICAgICAgICAgIF0pO1xyXG4gICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBuZXdWYWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gd2F0Y2hFZmZlY3RcclxuICAgICAgICAgICAgcnVubmVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8vIGltcG9ydGFudDogbWFyayB0aGUgam9iIGFzIGEgd2F0Y2hlciBjYWxsYmFjayBzbyB0aGF0IHNjaGVkdWxlciBrbm93cyBpdFxyXG4gICAgLy8gaXQgaXMgYWxsb3dlZCB0byBzZWxmLXRyaWdnZXIgKCMxNzI3KVxyXG4gICAgam9iLmFsbG93UmVjdXJzZSA9ICEhY2I7XHJcbiAgICBsZXQgc2NoZWR1bGVyO1xyXG4gICAgaWYgKGZsdXNoID09PSAnc3luYycpIHtcclxuICAgICAgICBzY2hlZHVsZXIgPSBqb2I7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChmbHVzaCA9PT0gJ3ByZScpIHtcclxuICAgICAgICAvLyBlbnN1cmUgaXQncyBxdWV1ZWQgYmVmb3JlIGNvbXBvbmVudCB1cGRhdGVzICh3aGljaCBoYXZlIHBvc2l0aXZlIGlkcylcclxuICAgICAgICBqb2IuaWQgPSAtMTtcclxuICAgICAgICBzY2hlZHVsZXIgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghaW5zdGFuY2UgfHwgaW5zdGFuY2UuaXNNb3VudGVkKSB7XHJcbiAgICAgICAgICAgICAgICBxdWV1ZVByZUZsdXNoQ2Ioam9iKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIHdpdGggJ3ByZScgb3B0aW9uLCB0aGUgZmlyc3QgY2FsbCBtdXN0IGhhcHBlbiBiZWZvcmVcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBjb21wb25lbnQgaXMgbW91bnRlZCBzbyBpdCBpcyBjYWxsZWQgc3luY2hyb25vdXNseS5cclxuICAgICAgICAgICAgICAgIGpvYigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHNjaGVkdWxlciA9ICgpID0+IHF1ZXVlUG9zdFJlbmRlckVmZmVjdChqb2IsIGluc3RhbmNlICYmIGluc3RhbmNlLnN1c3BlbnNlKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHJ1bm5lciA9IGVmZmVjdChnZXR0ZXIsIHtcclxuICAgICAgICBsYXp5OiB0cnVlLFxyXG4gICAgICAgIG9uVHJhY2ssXHJcbiAgICAgICAgb25UcmlnZ2VyLFxyXG4gICAgICAgIHNjaGVkdWxlclxyXG4gICAgfSk7XHJcbiAgICByZWNvcmRJbnN0YW5jZUJvdW5kRWZmZWN0KHJ1bm5lcik7XHJcbiAgICAvLyBpbml0aWFsIHJ1blxyXG4gICAgaWYgKGNiKSB7XHJcbiAgICAgICAgaWYgKGltbWVkaWF0ZSkge1xyXG4gICAgICAgICAgICBqb2IoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIG9sZFZhbHVlID0gcnVubmVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcnVubmVyKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICAgIHN0b3AocnVubmVyKTtcclxuICAgICAgICBpZiAoaW5zdGFuY2UpIHtcclxuICAgICAgICAgICAgcmVtb3ZlKGluc3RhbmNlLmVmZmVjdHMsIHJ1bm5lcik7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxyXG4vLyB0aGlzLiR3YXRjaFxyXG5mdW5jdGlvbiBpbnN0YW5jZVdhdGNoKHNvdXJjZSwgY2IsIG9wdGlvbnMpIHtcclxuICAgIGNvbnN0IHB1YmxpY1RoaXMgPSB0aGlzLnByb3h5O1xyXG4gICAgY29uc3QgZ2V0dGVyID0gaXNTdHJpbmcoc291cmNlKVxyXG4gICAgICAgID8gKCkgPT4gcHVibGljVGhpc1tzb3VyY2VdXHJcbiAgICAgICAgOiBzb3VyY2UuYmluZChwdWJsaWNUaGlzKTtcclxuICAgIHJldHVybiBkb1dhdGNoKGdldHRlciwgY2IuYmluZChwdWJsaWNUaGlzKSwgb3B0aW9ucywgdGhpcyk7XHJcbn1cclxuZnVuY3Rpb24gdHJhdmVyc2UodmFsdWUsIHNlZW4gPSBuZXcgU2V0KCkpIHtcclxuICAgIGlmICghaXNPYmplY3QodmFsdWUpIHx8IHNlZW4uaGFzKHZhbHVlKSkge1xyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuICAgIHNlZW4uYWRkKHZhbHVlKTtcclxuICAgIGlmIChpc1JlZih2YWx1ZSkpIHtcclxuICAgICAgICB0cmF2ZXJzZSh2YWx1ZS52YWx1ZSwgc2Vlbik7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSkge1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdHJhdmVyc2UodmFsdWVbaV0sIHNlZW4pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgTWFwKSB7XHJcbiAgICAgICAgdmFsdWUuZm9yRWFjaCgodiwga2V5KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIHRvIHJlZ2lzdGVyIG11dGF0aW9uIGRlcCBmb3IgZXhpc3Rpbmcga2V5c1xyXG4gICAgICAgICAgICB0cmF2ZXJzZSh2YWx1ZS5nZXQoa2V5KSwgc2Vlbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFNldCkge1xyXG4gICAgICAgIHZhbHVlLmZvckVhY2godiA9PiB7XHJcbiAgICAgICAgICAgIHRyYXZlcnNlKHYsIHNlZW4pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdmFsdWUpIHtcclxuICAgICAgICAgICAgdHJhdmVyc2UodmFsdWVba2V5XSwgc2Vlbik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG59XG5cbmZ1bmN0aW9uIHByb3ZpZGUoa2V5LCB2YWx1ZSkge1xyXG4gICAgaWYgKCFjdXJyZW50SW5zdGFuY2UpIHtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYHByb3ZpZGUoKSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSBzZXR1cCgpLmApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGxldCBwcm92aWRlcyA9IGN1cnJlbnRJbnN0YW5jZS5wcm92aWRlcztcclxuICAgICAgICAvLyBieSBkZWZhdWx0IGFuIGluc3RhbmNlIGluaGVyaXRzIGl0cyBwYXJlbnQncyBwcm92aWRlcyBvYmplY3RcclxuICAgICAgICAvLyBidXQgd2hlbiBpdCBuZWVkcyB0byBwcm92aWRlIHZhbHVlcyBvZiBpdHMgb3duLCBpdCBjcmVhdGVzIGl0c1xyXG4gICAgICAgIC8vIG93biBwcm92aWRlcyBvYmplY3QgdXNpbmcgcGFyZW50IHByb3ZpZGVzIG9iamVjdCBhcyBwcm90b3R5cGUuXHJcbiAgICAgICAgLy8gdGhpcyB3YXkgaW4gYGluamVjdGAgd2UgY2FuIHNpbXBseSBsb29rIHVwIGluamVjdGlvbnMgZnJvbSBkaXJlY3RcclxuICAgICAgICAvLyBwYXJlbnQgYW5kIGxldCB0aGUgcHJvdG90eXBlIGNoYWluIGRvIHRoZSB3b3JrLlxyXG4gICAgICAgIGNvbnN0IHBhcmVudFByb3ZpZGVzID0gY3VycmVudEluc3RhbmNlLnBhcmVudCAmJiBjdXJyZW50SW5zdGFuY2UucGFyZW50LnByb3ZpZGVzO1xyXG4gICAgICAgIGlmIChwYXJlbnRQcm92aWRlcyA9PT0gcHJvdmlkZXMpIHtcclxuICAgICAgICAgICAgcHJvdmlkZXMgPSBjdXJyZW50SW5zdGFuY2UucHJvdmlkZXMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFByb3ZpZGVzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVFMgZG9lc24ndCBhbGxvdyBzeW1ib2wgYXMgaW5kZXggdHlwZVxyXG4gICAgICAgIHByb3ZpZGVzW2tleV0gPSB2YWx1ZTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBpbmplY3Qoa2V5LCBkZWZhdWx0VmFsdWUpIHtcclxuICAgIC8vIGZhbGxiYWNrIHRvIGBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2VgIHNvIHRoYXQgdGhpcyBjYW4gYmUgY2FsbGVkIGluXHJcbiAgICAvLyBhIGZ1bmN0aW9uYWwgY29tcG9uZW50XHJcbiAgICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZSB8fCBjdXJyZW50UmVuZGVyaW5nSW5zdGFuY2U7XHJcbiAgICBpZiAoaW5zdGFuY2UpIHtcclxuICAgICAgICBjb25zdCBwcm92aWRlcyA9IGluc3RhbmNlLnByb3ZpZGVzO1xyXG4gICAgICAgIGlmIChrZXkgaW4gcHJvdmlkZXMpIHtcclxuICAgICAgICAgICAgLy8gVFMgZG9lc24ndCBhbGxvdyBzeW1ib2wgYXMgaW5kZXggdHlwZVxyXG4gICAgICAgICAgICByZXR1cm4gcHJvdmlkZXNba2V5XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYGluamVjdGlvbiBcIiR7U3RyaW5nKGtleSl9XCIgbm90IGZvdW5kLmApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIHdhcm4oYGluamVjdCgpIGNhbiBvbmx5IGJlIHVzZWQgaW5zaWRlIHNldHVwKCkgb3IgZnVuY3Rpb25hbCBjb21wb25lbnRzLmApO1xyXG4gICAgfVxyXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUR1cGxpY2F0ZUNoZWNrZXIoKSB7XHJcbiAgICBjb25zdCBjYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XHJcbiAgICByZXR1cm4gKHR5cGUsIGtleSkgPT4ge1xyXG4gICAgICAgIGlmIChjYWNoZVtrZXldKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYCR7dHlwZX0gcHJvcGVydHkgXCIke2tleX1cIiBpcyBhbHJlYWR5IGRlZmluZWQgaW4gJHtjYWNoZVtrZXldfS5gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNhY2hlW2tleV0gPSB0eXBlO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbn1cclxubGV0IGlzSW5CZWZvcmVDcmVhdGUgPSBmYWxzZTtcclxuZnVuY3Rpb24gYXBwbHlPcHRpb25zKGluc3RhbmNlLCBvcHRpb25zLCBkZWZlcnJlZERhdGEgPSBbXSwgZGVmZXJyZWRXYXRjaCA9IFtdLCBhc01peGluID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IHsgXHJcbiAgICAvLyBjb21wb3NpdGlvblxyXG4gICAgbWl4aW5zLCBleHRlbmRzOiBleHRlbmRzT3B0aW9ucywgXHJcbiAgICAvLyBzdGF0ZVxyXG4gICAgZGF0YTogZGF0YU9wdGlvbnMsIGNvbXB1dGVkOiBjb21wdXRlZE9wdGlvbnMsIG1ldGhvZHMsIHdhdGNoOiB3YXRjaE9wdGlvbnMsIHByb3ZpZGU6IHByb3ZpZGVPcHRpb25zLCBpbmplY3Q6IGluamVjdE9wdGlvbnMsIFxyXG4gICAgLy8gYXNzZXRzXHJcbiAgICBjb21wb25lbnRzLCBkaXJlY3RpdmVzLCBcclxuICAgIC8vIGxpZmVjeWNsZVxyXG4gICAgYmVmb3JlTW91bnQsIG1vdW50ZWQsIGJlZm9yZVVwZGF0ZSwgdXBkYXRlZCwgYWN0aXZhdGVkLCBkZWFjdGl2YXRlZCwgYmVmb3JlVW5tb3VudCwgdW5tb3VudGVkLCByZW5kZXIsIHJlbmRlclRyYWNrZWQsIHJlbmRlclRyaWdnZXJlZCwgZXJyb3JDYXB0dXJlZCB9ID0gb3B0aW9ucztcclxuICAgIGNvbnN0IHB1YmxpY1RoaXMgPSBpbnN0YW5jZS5wcm94eTtcclxuICAgIGNvbnN0IGN0eCA9IGluc3RhbmNlLmN0eDtcclxuICAgIGNvbnN0IGdsb2JhbE1peGlucyA9IGluc3RhbmNlLmFwcENvbnRleHQubWl4aW5zO1xyXG4gICAgaWYgKGFzTWl4aW4gJiYgcmVuZGVyICYmIGluc3RhbmNlLnJlbmRlciA9PT0gTk9PUCkge1xyXG4gICAgICAgIGluc3RhbmNlLnJlbmRlciA9IHJlbmRlcjtcclxuICAgIH1cclxuICAgIC8vIGFwcGx5T3B0aW9ucyBpcyBjYWxsZWQgbm9uLWFzLW1peGluIG9uY2UgcGVyIGluc3RhbmNlXHJcbiAgICBpZiAoIWFzTWl4aW4pIHtcclxuICAgICAgICBpc0luQmVmb3JlQ3JlYXRlID0gdHJ1ZTtcclxuICAgICAgICBjYWxsU3luY0hvb2soJ2JlZm9yZUNyZWF0ZScsIG9wdGlvbnMsIHB1YmxpY1RoaXMsIGdsb2JhbE1peGlucyk7XHJcbiAgICAgICAgaXNJbkJlZm9yZUNyZWF0ZSA9IGZhbHNlO1xyXG4gICAgICAgIC8vIGdsb2JhbCBtaXhpbnMgYXJlIGFwcGxpZWQgZmlyc3RcclxuICAgICAgICBhcHBseU1peGlucyhpbnN0YW5jZSwgZ2xvYmFsTWl4aW5zLCBkZWZlcnJlZERhdGEsIGRlZmVycmVkV2F0Y2gpO1xyXG4gICAgfVxyXG4gICAgLy8gZXh0ZW5kaW5nIGEgYmFzZSBjb21wb25lbnQuLi5cclxuICAgIGlmIChleHRlbmRzT3B0aW9ucykge1xyXG4gICAgICAgIGFwcGx5T3B0aW9ucyhpbnN0YW5jZSwgZXh0ZW5kc09wdGlvbnMsIGRlZmVycmVkRGF0YSwgZGVmZXJyZWRXYXRjaCwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgICAvLyBsb2NhbCBtaXhpbnNcclxuICAgIGlmIChtaXhpbnMpIHtcclxuICAgICAgICBhcHBseU1peGlucyhpbnN0YW5jZSwgbWl4aW5zLCBkZWZlcnJlZERhdGEsIGRlZmVycmVkV2F0Y2gpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzID0gKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gY3JlYXRlRHVwbGljYXRlQ2hlY2tlcigpIDogbnVsbDtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICBjb25zdCBbcHJvcHNPcHRpb25zXSA9IGluc3RhbmNlLnByb3BzT3B0aW9ucztcclxuICAgICAgICBpZiAocHJvcHNPcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3BzT3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEdXBsaWNhdGVQcm9wZXJ0aWVzKFwiUHJvcHNcIiAvKiBQUk9QUyAqLywga2V5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIG9wdGlvbnMgaW5pdGlhbGl6YXRpb24gb3JkZXIgKHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBWdWUgMik6XHJcbiAgICAvLyAtIHByb3BzIChhbHJlYWR5IGRvbmUgb3V0c2lkZSBvZiB0aGlzIGZ1bmN0aW9uKVxyXG4gICAgLy8gLSBpbmplY3RcclxuICAgIC8vIC0gbWV0aG9kc1xyXG4gICAgLy8gLSBkYXRhIChkZWZlcnJlZCBzaW5jZSBpdCByZWxpZXMgb24gYHRoaXNgIGFjY2VzcylcclxuICAgIC8vIC0gY29tcHV0ZWRcclxuICAgIC8vIC0gd2F0Y2ggKGRlZmVycmVkIHNpbmNlIGl0IHJlbGllcyBvbiBgdGhpc2AgYWNjZXNzKVxyXG4gICAgaWYgKGluamVjdE9wdGlvbnMpIHtcclxuICAgICAgICBpZiAoaXNBcnJheShpbmplY3RPcHRpb25zKSkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluamVjdE9wdGlvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGluamVjdE9wdGlvbnNbaV07XHJcbiAgICAgICAgICAgICAgICBjdHhba2V5XSA9IGluamVjdChrZXkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyhcIkluamVjdFwiIC8qIElOSkVDVCAqLywga2V5KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gaW5qZWN0T3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0ID0gaW5qZWN0T3B0aW9uc1trZXldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzT2JqZWN0KG9wdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBjdHhba2V5XSA9IGluamVjdChvcHQuZnJvbSwgb3B0LmRlZmF1bHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY3R4W2tleV0gPSBpbmplY3Qob3B0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoXCJJbmplY3RcIiAvKiBJTkpFQ1QgKi8sIGtleSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAobWV0aG9kcykge1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIG1ldGhvZHMpIHtcclxuICAgICAgICAgICAgY29uc3QgbWV0aG9kSGFuZGxlciA9IG1ldGhvZHNba2V5XTtcclxuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24obWV0aG9kSGFuZGxlcikpIHtcclxuICAgICAgICAgICAgICAgIGN0eFtrZXldID0gbWV0aG9kSGFuZGxlci5iaW5kKHB1YmxpY1RoaXMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyhcIk1ldGhvZHNcIiAvKiBNRVRIT0RTICovLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgTWV0aG9kIFwiJHtrZXl9XCIgaGFzIHR5cGUgXCIke3R5cGVvZiBtZXRob2RIYW5kbGVyfVwiIGluIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbi4gYCArXHJcbiAgICAgICAgICAgICAgICAgICAgYERpZCB5b3UgcmVmZXJlbmNlIHRoZSBmdW5jdGlvbiBjb3JyZWN0bHk/YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoIWFzTWl4aW4pIHtcclxuICAgICAgICBpZiAoZGVmZXJyZWREYXRhLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBkZWZlcnJlZERhdGEuZm9yRWFjaChkYXRhRm4gPT4gcmVzb2x2ZURhdGEoaW5zdGFuY2UsIGRhdGFGbiwgcHVibGljVGhpcykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGF0YU9wdGlvbnMpIHtcclxuICAgICAgICAgICAgcmVzb2x2ZURhdGEoaW5zdGFuY2UsIGRhdGFPcHRpb25zLCBwdWJsaWNUaGlzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICBjb25zdCByYXdEYXRhID0gdG9SYXcoaW5zdGFuY2UuZGF0YSk7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJhd0RhdGEpIHtcclxuICAgICAgICAgICAgICAgIGNoZWNrRHVwbGljYXRlUHJvcGVydGllcyhcIkRhdGFcIiAvKiBEQVRBICovLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgLy8gZXhwb3NlIGRhdGEgb24gY3R4IGR1cmluZyBkZXZcclxuICAgICAgICAgICAgICAgIGlmIChrZXlbMF0gIT09ICckJyAmJiBrZXlbMF0gIT09ICdfJykge1xyXG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gcmF3RGF0YVtrZXldLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6IE5PT1BcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGRhdGFPcHRpb25zKSB7XHJcbiAgICAgICAgZGVmZXJyZWREYXRhLnB1c2goZGF0YU9wdGlvbnMpO1xyXG4gICAgfVxyXG4gICAgaWYgKGNvbXB1dGVkT3B0aW9ucykge1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGNvbXB1dGVkT3B0aW9ucykge1xyXG4gICAgICAgICAgICBjb25zdCBvcHQgPSBjb21wdXRlZE9wdGlvbnNba2V5XTtcclxuICAgICAgICAgICAgY29uc3QgZ2V0ID0gaXNGdW5jdGlvbihvcHQpXHJcbiAgICAgICAgICAgICAgICA/IG9wdC5iaW5kKHB1YmxpY1RoaXMsIHB1YmxpY1RoaXMpXHJcbiAgICAgICAgICAgICAgICA6IGlzRnVuY3Rpb24ob3B0LmdldClcclxuICAgICAgICAgICAgICAgICAgICA/IG9wdC5nZXQuYmluZChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKVxyXG4gICAgICAgICAgICAgICAgICAgIDogTk9PUDtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBnZXQgPT09IE5PT1ApIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYENvbXB1dGVkIHByb3BlcnR5IFwiJHtrZXl9XCIgaGFzIG5vIGdldHRlci5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBzZXQgPSAhaXNGdW5jdGlvbihvcHQpICYmIGlzRnVuY3Rpb24ob3B0LnNldClcclxuICAgICAgICAgICAgICAgID8gb3B0LnNldC5iaW5kKHB1YmxpY1RoaXMpXHJcbiAgICAgICAgICAgICAgICA6IChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKVxyXG4gICAgICAgICAgICAgICAgICAgID8gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXJuKGBXcml0ZSBvcGVyYXRpb24gZmFpbGVkOiBjb21wdXRlZCBwcm9wZXJ0eSBcIiR7a2V5fVwiIGlzIHJlYWRvbmx5LmApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICA6IE5PT1A7XHJcbiAgICAgICAgICAgIGNvbnN0IGMgPSBjb21wdXRlZCh7XHJcbiAgICAgICAgICAgICAgICBnZXQsXHJcbiAgICAgICAgICAgICAgICBzZXRcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIGtleSwge1xyXG4gICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGdldDogKCkgPT4gYy52YWx1ZSxcclxuICAgICAgICAgICAgICAgIHNldDogdiA9PiAoYy52YWx1ZSA9IHYpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0R1cGxpY2F0ZVByb3BlcnRpZXMoXCJDb21wdXRlZFwiIC8qIENPTVBVVEVEICovLCBrZXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHdhdGNoT3B0aW9ucykge1xyXG4gICAgICAgIGRlZmVycmVkV2F0Y2gucHVzaCh3YXRjaE9wdGlvbnMpO1xyXG4gICAgfVxyXG4gICAgaWYgKCFhc01peGluICYmIGRlZmVycmVkV2F0Y2gubGVuZ3RoKSB7XHJcbiAgICAgICAgZGVmZXJyZWRXYXRjaC5mb3JFYWNoKHdhdGNoT3B0aW9ucyA9PiB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHdhdGNoT3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgY3JlYXRlV2F0Y2hlcih3YXRjaE9wdGlvbnNba2V5XSwgY3R4LCBwdWJsaWNUaGlzLCBrZXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBpZiAocHJvdmlkZU9wdGlvbnMpIHtcclxuICAgICAgICBjb25zdCBwcm92aWRlcyA9IGlzRnVuY3Rpb24ocHJvdmlkZU9wdGlvbnMpXHJcbiAgICAgICAgICAgID8gcHJvdmlkZU9wdGlvbnMuY2FsbChwdWJsaWNUaGlzKVxyXG4gICAgICAgICAgICA6IHByb3ZpZGVPcHRpb25zO1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByb3ZpZGVzKSB7XHJcbiAgICAgICAgICAgIHByb3ZpZGUoa2V5LCBwcm92aWRlc1trZXldKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBhc3NldCBvcHRpb25zLlxyXG4gICAgLy8gVG8gcmVkdWNlIG1lbW9yeSB1c2FnZSwgb25seSBjb21wb25lbnRzIHdpdGggbWl4aW5zIG9yIGV4dGVuZHMgd2lsbCBoYXZlXHJcbiAgICAvLyByZXNvbHZlZCBhc3NldCByZWdpc3RyeSBhdHRhY2hlZCB0byBpbnN0YW5jZS5cclxuICAgIGlmIChhc01peGluKSB7XHJcbiAgICAgICAgaWYgKGNvbXBvbmVudHMpIHtcclxuICAgICAgICAgICAgZXh0ZW5kKGluc3RhbmNlLmNvbXBvbmVudHMgfHxcclxuICAgICAgICAgICAgICAgIChpbnN0YW5jZS5jb21wb25lbnRzID0gZXh0ZW5kKHt9LCBpbnN0YW5jZS50eXBlLmNvbXBvbmVudHMpKSwgY29tcG9uZW50cyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXJlY3RpdmVzKSB7XHJcbiAgICAgICAgICAgIGV4dGVuZChpbnN0YW5jZS5kaXJlY3RpdmVzIHx8XHJcbiAgICAgICAgICAgICAgICAoaW5zdGFuY2UuZGlyZWN0aXZlcyA9IGV4dGVuZCh7fSwgaW5zdGFuY2UudHlwZS5kaXJlY3RpdmVzKSksIGRpcmVjdGl2ZXMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vIGxpZmVjeWNsZSBvcHRpb25zXHJcbiAgICBpZiAoIWFzTWl4aW4pIHtcclxuICAgICAgICBjYWxsU3luY0hvb2soJ2NyZWF0ZWQnLCBvcHRpb25zLCBwdWJsaWNUaGlzLCBnbG9iYWxNaXhpbnMpO1xyXG4gICAgfVxyXG4gICAgaWYgKGJlZm9yZU1vdW50KSB7XHJcbiAgICAgICAgb25CZWZvcmVNb3VudChiZWZvcmVNb3VudC5iaW5kKHB1YmxpY1RoaXMpKTtcclxuICAgIH1cclxuICAgIGlmIChtb3VudGVkKSB7XHJcbiAgICAgICAgb25Nb3VudGVkKG1vdW50ZWQuYmluZChwdWJsaWNUaGlzKSk7XHJcbiAgICB9XHJcbiAgICBpZiAoYmVmb3JlVXBkYXRlKSB7XHJcbiAgICAgICAgb25CZWZvcmVVcGRhdGUoYmVmb3JlVXBkYXRlLmJpbmQocHVibGljVGhpcykpO1xyXG4gICAgfVxyXG4gICAgaWYgKHVwZGF0ZWQpIHtcclxuICAgICAgICBvblVwZGF0ZWQodXBkYXRlZC5iaW5kKHB1YmxpY1RoaXMpKTtcclxuICAgIH1cclxuICAgIGlmIChhY3RpdmF0ZWQpIHtcclxuICAgICAgICBvbkFjdGl2YXRlZChhY3RpdmF0ZWQuYmluZChwdWJsaWNUaGlzKSk7XHJcbiAgICB9XHJcbiAgICBpZiAoZGVhY3RpdmF0ZWQpIHtcclxuICAgICAgICBvbkRlYWN0aXZhdGVkKGRlYWN0aXZhdGVkLmJpbmQocHVibGljVGhpcykpO1xyXG4gICAgfVxyXG4gICAgaWYgKGVycm9yQ2FwdHVyZWQpIHtcclxuICAgICAgICBvbkVycm9yQ2FwdHVyZWQoZXJyb3JDYXB0dXJlZC5iaW5kKHB1YmxpY1RoaXMpKTtcclxuICAgIH1cclxuICAgIGlmIChyZW5kZXJUcmFja2VkKSB7XHJcbiAgICAgICAgb25SZW5kZXJUcmFja2VkKHJlbmRlclRyYWNrZWQuYmluZChwdWJsaWNUaGlzKSk7XHJcbiAgICB9XHJcbiAgICBpZiAocmVuZGVyVHJpZ2dlcmVkKSB7XHJcbiAgICAgICAgb25SZW5kZXJUcmlnZ2VyZWQocmVuZGVyVHJpZ2dlcmVkLmJpbmQocHVibGljVGhpcykpO1xyXG4gICAgfVxyXG4gICAgaWYgKGJlZm9yZVVubW91bnQpIHtcclxuICAgICAgICBvbkJlZm9yZVVubW91bnQoYmVmb3JlVW5tb3VudC5iaW5kKHB1YmxpY1RoaXMpKTtcclxuICAgIH1cclxuICAgIGlmICh1bm1vdW50ZWQpIHtcclxuICAgICAgICBvblVubW91bnRlZCh1bm1vdW50ZWQuYmluZChwdWJsaWNUaGlzKSk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY2FsbFN5bmNIb29rKG5hbWUsIG9wdGlvbnMsIGN0eCwgZ2xvYmFsTWl4aW5zKSB7XHJcbiAgICBjYWxsSG9va0Zyb21NaXhpbnMobmFtZSwgZ2xvYmFsTWl4aW5zLCBjdHgpO1xyXG4gICAgY29uc3QgeyBleHRlbmRzOiBiYXNlLCBtaXhpbnMgfSA9IG9wdGlvbnM7XHJcbiAgICBpZiAoYmFzZSkge1xyXG4gICAgICAgIGNhbGxIb29rRnJvbUV4dGVuZHMobmFtZSwgYmFzZSwgY3R4KTtcclxuICAgIH1cclxuICAgIGlmIChtaXhpbnMpIHtcclxuICAgICAgICBjYWxsSG9va0Zyb21NaXhpbnMobmFtZSwgbWl4aW5zLCBjdHgpO1xyXG4gICAgfVxyXG4gICAgY29uc3Qgc2VsZkhvb2sgPSBvcHRpb25zW25hbWVdO1xyXG4gICAgaWYgKHNlbGZIb29rKSB7XHJcbiAgICAgICAgc2VsZkhvb2suY2FsbChjdHgpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGNhbGxIb29rRnJvbUV4dGVuZHMobmFtZSwgYmFzZSwgY3R4KSB7XHJcbiAgICBpZiAoYmFzZS5leHRlbmRzKSB7XHJcbiAgICAgICAgY2FsbEhvb2tGcm9tRXh0ZW5kcyhuYW1lLCBiYXNlLmV4dGVuZHMsIGN0eCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCBiYXNlSG9vayA9IGJhc2VbbmFtZV07XHJcbiAgICBpZiAoYmFzZUhvb2spIHtcclxuICAgICAgICBiYXNlSG9vay5jYWxsKGN0eCk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY2FsbEhvb2tGcm9tTWl4aW5zKG5hbWUsIG1peGlucywgY3R4KSB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1peGlucy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGNoYWluZWRNaXhpbnMgPSBtaXhpbnNbaV0ubWl4aW5zO1xyXG4gICAgICAgIGlmIChjaGFpbmVkTWl4aW5zKSB7XHJcbiAgICAgICAgICAgIGNhbGxIb29rRnJvbU1peGlucyhuYW1lLCBjaGFpbmVkTWl4aW5zLCBjdHgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBmbiA9IG1peGluc1tpXVtuYW1lXTtcclxuICAgICAgICBpZiAoZm4pIHtcclxuICAgICAgICAgICAgZm4uY2FsbChjdHgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBhcHBseU1peGlucyhpbnN0YW5jZSwgbWl4aW5zLCBkZWZlcnJlZERhdGEsIGRlZmVycmVkV2F0Y2gpIHtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWl4aW5zLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgYXBwbHlPcHRpb25zKGluc3RhbmNlLCBtaXhpbnNbaV0sIGRlZmVycmVkRGF0YSwgZGVmZXJyZWRXYXRjaCwgdHJ1ZSk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gcmVzb2x2ZURhdGEoaW5zdGFuY2UsIGRhdGFGbiwgcHVibGljVGhpcykge1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhaXNGdW5jdGlvbihkYXRhRm4pKSB7XHJcbiAgICAgICAgd2FybihgVGhlIGRhdGEgb3B0aW9uIG11c3QgYmUgYSBmdW5jdGlvbi4gYCArXHJcbiAgICAgICAgICAgIGBQbGFpbiBvYmplY3QgdXNhZ2UgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC5gKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGRhdGEgPSBkYXRhRm4uY2FsbChwdWJsaWNUaGlzLCBwdWJsaWNUaGlzKTtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgaXNQcm9taXNlKGRhdGEpKSB7XHJcbiAgICAgICAgd2FybihgZGF0YSgpIHJldHVybmVkIGEgUHJvbWlzZSAtIG5vdGUgZGF0YSgpIGNhbm5vdCBiZSBhc3luYzsgSWYgeW91IGAgK1xyXG4gICAgICAgICAgICBgaW50ZW5kIHRvIHBlcmZvcm0gZGF0YSBmZXRjaGluZyBiZWZvcmUgY29tcG9uZW50IHJlbmRlcnMsIHVzZSBgICtcclxuICAgICAgICAgICAgYGFzeW5jIHNldHVwKCkgKyA8U3VzcGVuc2U+LmApO1xyXG4gICAgfVxyXG4gICAgaWYgKCFpc09iamVjdChkYXRhKSkge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuKGBkYXRhKCkgc2hvdWxkIHJldHVybiBhbiBvYmplY3QuYCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChpbnN0YW5jZS5kYXRhID09PSBFTVBUWV9PQkopIHtcclxuICAgICAgICBpbnN0YW5jZS5kYXRhID0gcmVhY3RpdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICAvLyBleGlzdGluZyBkYXRhOiB0aGlzIGlzIGEgbWl4aW4gb3IgZXh0ZW5kcy5cclxuICAgICAgICBleHRlbmQoaW5zdGFuY2UuZGF0YSwgZGF0YSk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gY3JlYXRlV2F0Y2hlcihyYXcsIGN0eCwgcHVibGljVGhpcywga2V5KSB7XHJcbiAgICBjb25zdCBnZXR0ZXIgPSAoKSA9PiBwdWJsaWNUaGlzW2tleV07XHJcbiAgICBpZiAoaXNTdHJpbmcocmF3KSkge1xyXG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSBjdHhbcmF3XTtcclxuICAgICAgICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xyXG4gICAgICAgICAgICB3YXRjaChnZXR0ZXIsIGhhbmRsZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgd2FybihgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgXCIke3Jhd31cImAsIGhhbmRsZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzRnVuY3Rpb24ocmF3KSkge1xyXG4gICAgICAgIHdhdGNoKGdldHRlciwgcmF3LmJpbmQocHVibGljVGhpcykpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNPYmplY3QocmF3KSkge1xyXG4gICAgICAgIGlmIChpc0FycmF5KHJhdykpIHtcclxuICAgICAgICAgICAgcmF3LmZvckVhY2gociA9PiBjcmVhdGVXYXRjaGVyKHIsIGN0eCwgcHVibGljVGhpcywga2V5KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBoYW5kbGVyID0gaXNGdW5jdGlvbihyYXcuaGFuZGxlcilcclxuICAgICAgICAgICAgICAgID8gcmF3LmhhbmRsZXIuYmluZChwdWJsaWNUaGlzKVxyXG4gICAgICAgICAgICAgICAgOiBjdHhbcmF3LmhhbmRsZXJdO1xyXG4gICAgICAgICAgICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xyXG4gICAgICAgICAgICAgICAgd2F0Y2goZ2V0dGVyLCBoYW5kbGVyLCByYXcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgd2FybihgSW52YWxpZCB3YXRjaCBoYW5kbGVyIHNwZWNpZmllZCBieSBrZXkgXCIke3Jhdy5oYW5kbGVyfVwiYCwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICB3YXJuKGBJbnZhbGlkIHdhdGNoIG9wdGlvbjogXCIke2tleX1cImApO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIHJlc29sdmVNZXJnZWRPcHRpb25zKGluc3RhbmNlKSB7XHJcbiAgICBjb25zdCByYXcgPSBpbnN0YW5jZS50eXBlO1xyXG4gICAgY29uc3QgeyBfX21lcmdlZCwgbWl4aW5zLCBleHRlbmRzOiBleHRlbmRzT3B0aW9ucyB9ID0gcmF3O1xyXG4gICAgaWYgKF9fbWVyZ2VkKVxyXG4gICAgICAgIHJldHVybiBfX21lcmdlZDtcclxuICAgIGNvbnN0IGdsb2JhbE1peGlucyA9IGluc3RhbmNlLmFwcENvbnRleHQubWl4aW5zO1xyXG4gICAgaWYgKCFnbG9iYWxNaXhpbnMubGVuZ3RoICYmICFtaXhpbnMgJiYgIWV4dGVuZHNPcHRpb25zKVxyXG4gICAgICAgIHJldHVybiByYXc7XHJcbiAgICBjb25zdCBvcHRpb25zID0ge307XHJcbiAgICBtZXJnZU9wdGlvbnMob3B0aW9ucywgcmF3LCBpbnN0YW5jZSk7XHJcbiAgICBnbG9iYWxNaXhpbnMuZm9yRWFjaChtID0+IG1lcmdlT3B0aW9ucyhvcHRpb25zLCBtLCBpbnN0YW5jZSkpO1xyXG4gICAgcmV0dXJuIChyYXcuX19tZXJnZWQgPSBvcHRpb25zKTtcclxufVxyXG5mdW5jdGlvbiBtZXJnZU9wdGlvbnModG8sIGZyb20sIGluc3RhbmNlKSB7XHJcbiAgICBjb25zdCBzdHJhdHMgPSBpbnN0YW5jZS5hcHBDb250ZXh0LmNvbmZpZy5vcHRpb25NZXJnZVN0cmF0ZWdpZXM7XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBmcm9tKSB7XHJcbiAgICAgICAgaWYgKHN0cmF0cyAmJiBoYXNPd24oc3RyYXRzLCBrZXkpKSB7XHJcbiAgICAgICAgICAgIHRvW2tleV0gPSBzdHJhdHNba2V5XSh0b1trZXldLCBmcm9tW2tleV0sIGluc3RhbmNlLnByb3h5LCBrZXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICghaGFzT3duKHRvLCBrZXkpKSB7XHJcbiAgICAgICAgICAgIHRvW2tleV0gPSBmcm9tW2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgeyBtaXhpbnMsIGV4dGVuZHM6IGV4dGVuZHNPcHRpb25zIH0gPSBmcm9tO1xyXG4gICAgZXh0ZW5kc09wdGlvbnMgJiYgbWVyZ2VPcHRpb25zKHRvLCBleHRlbmRzT3B0aW9ucywgaW5zdGFuY2UpO1xyXG4gICAgbWl4aW5zICYmXHJcbiAgICAgICAgbWl4aW5zLmZvckVhY2goKG0pID0+IG1lcmdlT3B0aW9ucyh0bywgbSwgaW5zdGFuY2UpKTtcclxufVxuXG5jb25zdCBwdWJsaWNQcm9wZXJ0aWVzTWFwID0gZXh0ZW5kKE9iamVjdC5jcmVhdGUobnVsbCksIHtcclxuICAgICQ6IGkgPT4gaSxcclxuICAgICRlbDogaSA9PiBpLnZub2RlLmVsLFxyXG4gICAgJGRhdGE6IGkgPT4gaS5kYXRhLFxyXG4gICAgJHByb3BzOiBpID0+ICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgPyBzaGFsbG93UmVhZG9ubHkoaS5wcm9wcykgOiBpLnByb3BzKSxcclxuICAgICRhdHRyczogaSA9PiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gc2hhbGxvd1JlYWRvbmx5KGkuYXR0cnMpIDogaS5hdHRycyksXHJcbiAgICAkc2xvdHM6IGkgPT4gKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/IHNoYWxsb3dSZWFkb25seShpLnNsb3RzKSA6IGkuc2xvdHMpLFxyXG4gICAgJHJlZnM6IGkgPT4gKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/IHNoYWxsb3dSZWFkb25seShpLnJlZnMpIDogaS5yZWZzKSxcclxuICAgICRwYXJlbnQ6IGkgPT4gaS5wYXJlbnQgJiYgaS5wYXJlbnQucHJveHksXHJcbiAgICAkcm9vdDogaSA9PiBpLnJvb3QgJiYgaS5yb290LnByb3h5LFxyXG4gICAgJGVtaXQ6IGkgPT4gaS5lbWl0LFxyXG4gICAgJG9wdGlvbnM6IGkgPT4gKF9fVlVFX09QVElPTlNfQVBJX18gPyByZXNvbHZlTWVyZ2VkT3B0aW9ucyhpKSA6IGkudHlwZSksXHJcbiAgICAkZm9yY2VVcGRhdGU6IGkgPT4gKCkgPT4gcXVldWVKb2IoaS51cGRhdGUpLFxyXG4gICAgJG5leHRUaWNrOiAoKSA9PiBuZXh0VGljayxcclxuICAgICR3YXRjaDogaSA9PiAoX19WVUVfT1BUSU9OU19BUElfXyA/IGluc3RhbmNlV2F0Y2guYmluZChpKSA6IE5PT1ApXHJcbn0pO1xyXG5jb25zdCBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMgPSB7XHJcbiAgICBnZXQoeyBfOiBpbnN0YW5jZSB9LCBrZXkpIHtcclxuICAgICAgICBjb25zdCB7IGN0eCwgc2V0dXBTdGF0ZSwgZGF0YSwgcHJvcHMsIGFjY2Vzc0NhY2hlLCB0eXBlLCBhcHBDb250ZXh0IH0gPSBpbnN0YW5jZTtcclxuICAgICAgICAvLyBsZXQgQHZ1ZS9yZWFjdGl2aXR5IGtub3cgaXQgc2hvdWxkIG5ldmVyIG9ic2VydmUgVnVlIHB1YmxpYyBpbnN0YW5jZXMuXHJcbiAgICAgICAgaWYgKGtleSA9PT0gXCJfX3Zfc2tpcFwiIC8qIFNLSVAgKi8pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGRhdGEgLyBwcm9wcyAvIGN0eFxyXG4gICAgICAgIC8vIFRoaXMgZ2V0dGVyIGdldHMgY2FsbGVkIGZvciBldmVyeSBwcm9wZXJ0eSBhY2Nlc3Mgb24gdGhlIHJlbmRlciBjb250ZXh0XHJcbiAgICAgICAgLy8gZHVyaW5nIHJlbmRlciBhbmQgaXMgYSBtYWpvciBob3RzcG90LiBUaGUgbW9zdCBleHBlbnNpdmUgcGFydCBvZiB0aGlzXHJcbiAgICAgICAgLy8gaXMgdGhlIG11bHRpcGxlIGhhc093bigpIGNhbGxzLiBJdCdzIG11Y2ggZmFzdGVyIHRvIGRvIGEgc2ltcGxlIHByb3BlcnR5XHJcbiAgICAgICAgLy8gYWNjZXNzIG9uIGEgcGxhaW4gb2JqZWN0LCBzbyB3ZSB1c2UgYW4gYWNjZXNzQ2FjaGUgb2JqZWN0ICh3aXRoIG51bGxcclxuICAgICAgICAvLyBwcm90b3R5cGUpIHRvIG1lbW9pemUgd2hhdCBhY2Nlc3MgdHlwZSBhIGtleSBjb3JyZXNwb25kcyB0by5cclxuICAgICAgICBsZXQgbm9ybWFsaXplZFByb3BzO1xyXG4gICAgICAgIGlmIChrZXlbMF0gIT09ICckJykge1xyXG4gICAgICAgICAgICBjb25zdCBuID0gYWNjZXNzQ2FjaGVba2V5XTtcclxuICAgICAgICAgICAgaWYgKG4gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgc3dpdGNoIChuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwIC8qIFNFVFVQICovOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2V0dXBTdGF0ZVtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMSAvKiBEQVRBICovOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0YVtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMyAvKiBDT05URVhUICovOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3R4W2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyIC8qIFBST1BTICovOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvcHNba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBkZWZhdWx0OiBqdXN0IGZhbGx0aHJvdWdoXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoc2V0dXBTdGF0ZSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihzZXR1cFN0YXRlLCBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMCAvKiBTRVRVUCAqLztcclxuICAgICAgICAgICAgICAgIHJldHVybiBzZXR1cFN0YXRlW2tleV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZGF0YSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihkYXRhLCBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMSAvKiBEQVRBICovO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFba2V5XTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChcclxuICAgICAgICAgICAgLy8gb25seSBjYWNoZSBvdGhlciBwcm9wZXJ0aWVzIHdoZW4gaW5zdGFuY2UgaGFzIGRlY2xhcmVkICh0aHVzIHN0YWJsZSlcclxuICAgICAgICAgICAgLy8gcHJvcHNcclxuICAgICAgICAgICAgKG5vcm1hbGl6ZWRQcm9wcyA9IGluc3RhbmNlLnByb3BzT3B0aW9uc1swXSkgJiZcclxuICAgICAgICAgICAgICAgIGhhc093bihub3JtYWxpemVkUHJvcHMsIGtleSkpIHtcclxuICAgICAgICAgICAgICAgIGFjY2Vzc0NhY2hlW2tleV0gPSAyIC8qIFBST1BTICovO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb3BzW2tleV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoY3R4ICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGN0eCwga2V5KSkge1xyXG4gICAgICAgICAgICAgICAgYWNjZXNzQ2FjaGVba2V5XSA9IDMgLyogQ09OVEVYVCAqLztcclxuICAgICAgICAgICAgICAgIHJldHVybiBjdHhba2V5XTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICghX19WVUVfT1BUSU9OU19BUElfXyB8fCAhaXNJbkJlZm9yZUNyZWF0ZSkge1xyXG4gICAgICAgICAgICAgICAgYWNjZXNzQ2FjaGVba2V5XSA9IDQgLyogT1RIRVIgKi87XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcHVibGljR2V0dGVyID0gcHVibGljUHJvcGVydGllc01hcFtrZXldO1xyXG4gICAgICAgIGxldCBjc3NNb2R1bGUsIGdsb2JhbFByb3BlcnRpZXM7XHJcbiAgICAgICAgLy8gcHVibGljICR4eHggcHJvcGVydGllc1xyXG4gICAgICAgIGlmIChwdWJsaWNHZXR0ZXIpIHtcclxuICAgICAgICAgICAgaWYgKGtleSA9PT0gJyRhdHRycycpIHtcclxuICAgICAgICAgICAgICAgIHRyYWNrKGluc3RhbmNlLCBcImdldFwiIC8qIEdFVCAqLywga2V5KTtcclxuICAgICAgICAgICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBtYXJrQXR0cnNBY2Nlc3NlZCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBwdWJsaWNHZXR0ZXIoaW5zdGFuY2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChcclxuICAgICAgICAvLyBjc3MgbW9kdWxlIChpbmplY3RlZCBieSB2dWUtbG9hZGVyKVxyXG4gICAgICAgIChjc3NNb2R1bGUgPSB0eXBlLl9fY3NzTW9kdWxlcykgJiZcclxuICAgICAgICAgICAgKGNzc01vZHVsZSA9IGNzc01vZHVsZVtrZXldKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gY3NzTW9kdWxlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChjdHggIT09IEVNUFRZX09CSiAmJiBoYXNPd24oY3R4LCBrZXkpKSB7XHJcbiAgICAgICAgICAgIC8vIHVzZXIgbWF5IHNldCBjdXN0b20gcHJvcGVydGllcyB0byBgdGhpc2AgdGhhdCBzdGFydCB3aXRoIGAkYFxyXG4gICAgICAgICAgICBhY2Nlc3NDYWNoZVtrZXldID0gMyAvKiBDT05URVhUICovO1xyXG4gICAgICAgICAgICByZXR1cm4gY3R4W2tleV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKFxyXG4gICAgICAgIC8vIGdsb2JhbCBwcm9wZXJ0aWVzXHJcbiAgICAgICAgKChnbG9iYWxQcm9wZXJ0aWVzID0gYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcyksXHJcbiAgICAgICAgICAgIGhhc093bihnbG9iYWxQcm9wZXJ0aWVzLCBrZXkpKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gZ2xvYmFsUHJvcGVydGllc1trZXldO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcclxuICAgICAgICAgICAgY3VycmVudFJlbmRlcmluZ0luc3RhbmNlICYmXHJcbiAgICAgICAgICAgICghaXNTdHJpbmcoa2V5KSB8fFxyXG4gICAgICAgICAgICAgICAgLy8gIzEwOTEgYXZvaWQgaW50ZXJuYWwgaXNSZWYvaXNWTm9kZSBjaGVja3Mgb24gY29tcG9uZW50IGluc3RhbmNlIGxlYWRpbmdcclxuICAgICAgICAgICAgICAgIC8vIHRvIGluZmluaXRlIHdhcm5pbmcgbG9vcFxyXG4gICAgICAgICAgICAgICAga2V5LmluZGV4T2YoJ19fdicpICE9PSAwKSkge1xyXG4gICAgICAgICAgICBpZiAoZGF0YSAhPT0gRU1QVFlfT0JKICYmIGtleVswXSA9PT0gJyQnICYmIGhhc093bihkYXRhLCBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICB3YXJuKGBQcm9wZXJ0eSAke0pTT04uc3RyaW5naWZ5KGtleSl9IG11c3QgYmUgYWNjZXNzZWQgdmlhICRkYXRhIGJlY2F1c2UgaXQgc3RhcnRzIHdpdGggYSByZXNlcnZlZCBgICtcclxuICAgICAgICAgICAgICAgICAgICBgY2hhcmFjdGVyIGFuZCBpcyBub3QgcHJveGllZCBvbiB0aGUgcmVuZGVyIGNvbnRleHQuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB3YXJuKGBQcm9wZXJ0eSAke0pTT04uc3RyaW5naWZ5KGtleSl9IHdhcyBhY2Nlc3NlZCBkdXJpbmcgcmVuZGVyIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgIGBidXQgaXMgbm90IGRlZmluZWQgb24gaW5zdGFuY2UuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgc2V0KHsgXzogaW5zdGFuY2UgfSwga2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIGNvbnN0IHsgZGF0YSwgc2V0dXBTdGF0ZSwgY3R4IH0gPSBpbnN0YW5jZTtcclxuICAgICAgICBpZiAoc2V0dXBTdGF0ZSAhPT0gRU1QVFlfT0JKICYmIGhhc093bihzZXR1cFN0YXRlLCBrZXkpKSB7XHJcbiAgICAgICAgICAgIHNldHVwU3RhdGVba2V5XSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChkYXRhICE9PSBFTVBUWV9PQkogJiYgaGFzT3duKGRhdGEsIGtleSkpIHtcclxuICAgICAgICAgICAgZGF0YVtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGtleSBpbiBpbnN0YW5jZS5wcm9wcykge1xyXG4gICAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiZcclxuICAgICAgICAgICAgICAgIHdhcm4oYEF0dGVtcHRpbmcgdG8gbXV0YXRlIHByb3AgXCIke2tleX1cIi4gUHJvcHMgYXJlIHJlYWRvbmx5LmAsIGluc3RhbmNlKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoa2V5WzBdID09PSAnJCcgJiYga2V5LnNsaWNlKDEpIGluIGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICAgICAgd2FybihgQXR0ZW1wdGluZyB0byBtdXRhdGUgcHVibGljIHByb3BlcnR5IFwiJHtrZXl9XCIuIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgIGBQcm9wZXJ0aWVzIHN0YXJ0aW5nIHdpdGggJCBhcmUgcmVzZXJ2ZWQgYW5kIHJlYWRvbmx5LmAsIGluc3RhbmNlKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBrZXkgaW4gaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcuZ2xvYmFsUHJvcGVydGllcykge1xyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN0eCwga2V5LCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY3R4W2tleV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcbiAgICBoYXMoeyBfOiB7IGRhdGEsIHNldHVwU3RhdGUsIGFjY2Vzc0NhY2hlLCBjdHgsIGFwcENvbnRleHQsIHByb3BzT3B0aW9ucyB9IH0sIGtleSkge1xyXG4gICAgICAgIGxldCBub3JtYWxpemVkUHJvcHM7XHJcbiAgICAgICAgcmV0dXJuIChhY2Nlc3NDYWNoZVtrZXldICE9PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgKGRhdGEgIT09IEVNUFRZX09CSiAmJiBoYXNPd24oZGF0YSwga2V5KSkgfHxcclxuICAgICAgICAgICAgKHNldHVwU3RhdGUgIT09IEVNUFRZX09CSiAmJiBoYXNPd24oc2V0dXBTdGF0ZSwga2V5KSkgfHxcclxuICAgICAgICAgICAgKChub3JtYWxpemVkUHJvcHMgPSBwcm9wc09wdGlvbnNbMF0pICYmIGhhc093bihub3JtYWxpemVkUHJvcHMsIGtleSkpIHx8XHJcbiAgICAgICAgICAgIGhhc093bihjdHgsIGtleSkgfHxcclxuICAgICAgICAgICAgaGFzT3duKHB1YmxpY1Byb3BlcnRpZXNNYXAsIGtleSkgfHxcclxuICAgICAgICAgICAgaGFzT3duKGFwcENvbnRleHQuY29uZmlnLmdsb2JhbFByb3BlcnRpZXMsIGtleSkpO1xyXG4gICAgfVxyXG59O1xyXG5pZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFmYWxzZSkge1xyXG4gICAgUHVibGljSW5zdGFuY2VQcm94eUhhbmRsZXJzLm93bktleXMgPSAodGFyZ2V0KSA9PiB7XHJcbiAgICAgICAgd2FybihgQXZvaWQgYXBwIGxvZ2ljIHRoYXQgcmVsaWVzIG9uIGVudW1lcmF0aW5nIGtleXMgb24gYSBjb21wb25lbnQgaW5zdGFuY2UuIGAgK1xyXG4gICAgICAgICAgICBgVGhlIGtleXMgd2lsbCBiZSBlbXB0eSBpbiBwcm9kdWN0aW9uIG1vZGUgdG8gYXZvaWQgcGVyZm9ybWFuY2Ugb3ZlcmhlYWQuYCk7XHJcbiAgICAgICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyh0YXJnZXQpO1xyXG4gICAgfTtcclxufVxyXG5jb25zdCBSdW50aW1lQ29tcGlsZWRQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMgPSBleHRlbmQoe30sIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycywge1xyXG4gICAgZ2V0KHRhcmdldCwga2V5KSB7XHJcbiAgICAgICAgLy8gZmFzdCBwYXRoIGZvciB1bnNjb3BhYmxlcyB3aGVuIHVzaW5nIGB3aXRoYCBibG9ja1xyXG4gICAgICAgIGlmIChrZXkgPT09IFN5bWJvbC51bnNjb3BhYmxlcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMuZ2V0KHRhcmdldCwga2V5LCB0YXJnZXQpO1xyXG4gICAgfSxcclxuICAgIGhhcyhfLCBrZXkpIHtcclxuICAgICAgICBjb25zdCBoYXMgPSBrZXlbMF0gIT09ICdfJyAmJiAhaXNHbG9iYWxseVdoaXRlbGlzdGVkKGtleSk7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhaGFzICYmIFB1YmxpY0luc3RhbmNlUHJveHlIYW5kbGVycy5oYXMoXywga2V5KSkge1xyXG4gICAgICAgICAgICB3YXJuKGBQcm9wZXJ0eSAke0pTT04uc3RyaW5naWZ5KGtleSl9IHNob3VsZCBub3Qgc3RhcnQgd2l0aCBfIHdoaWNoIGlzIGEgcmVzZXJ2ZWQgcHJlZml4IGZvciBWdWUgaW50ZXJuYWxzLmApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaGFzO1xyXG4gICAgfVxyXG59KTtcclxuLy8gSW4gZGV2IG1vZGUsIHRoZSBwcm94eSB0YXJnZXQgZXhwb3NlcyB0aGUgc2FtZSBwcm9wZXJ0aWVzIGFzIHNlZW4gb24gYHRoaXNgXHJcbi8vIGZvciBlYXNpZXIgY29uc29sZSBpbnNwZWN0aW9uLiBJbiBwcm9kIG1vZGUgaXQgd2lsbCBiZSBhbiBlbXB0eSBvYmplY3Qgc29cclxuLy8gdGhlc2UgcHJvcGVydGllcyBkZWZpbml0aW9ucyBjYW4gYmUgc2tpcHBlZC5cclxuZnVuY3Rpb24gY3JlYXRlUmVuZGVyQ29udGV4dChpbnN0YW5jZSkge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0ge307XHJcbiAgICAvLyBleHBvc2UgaW50ZXJuYWwgaW5zdGFuY2UgZm9yIHByb3h5IGhhbmRsZXJzXHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBgX2AsIHtcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXHJcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXHJcbiAgICAgICAgZ2V0OiAoKSA9PiBpbnN0YW5jZVxyXG4gICAgfSk7XHJcbiAgICAvLyBleHBvc2UgcHVibGljIHByb3BlcnRpZXNcclxuICAgIE9iamVjdC5rZXlzKHB1YmxpY1Byb3BlcnRpZXNNYXApLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHtcclxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgZ2V0OiAoKSA9PiBwdWJsaWNQcm9wZXJ0aWVzTWFwW2tleV0oaW5zdGFuY2UpLFxyXG4gICAgICAgICAgICAvLyBpbnRlcmNlcHRlZCBieSB0aGUgcHJveHkgc28gbm8gbmVlZCBmb3IgaW1wbGVtZW50YXRpb24sXHJcbiAgICAgICAgICAgIC8vIGJ1dCBuZWVkZWQgdG8gcHJldmVudCBzZXQgZXJyb3JzXHJcbiAgICAgICAgICAgIHNldDogTk9PUFxyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICAvLyBleHBvc2UgZ2xvYmFsIHByb3BlcnRpZXNcclxuICAgIGNvbnN0IHsgZ2xvYmFsUHJvcGVydGllcyB9ID0gaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWc7XHJcbiAgICBPYmplY3Qua2V5cyhnbG9iYWxQcm9wZXJ0aWVzKS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XHJcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgIGdldDogKCkgPT4gZ2xvYmFsUHJvcGVydGllc1trZXldLFxyXG4gICAgICAgICAgICBzZXQ6IE5PT1BcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHRhcmdldDtcclxufVxyXG4vLyBkZXYgb25seVxyXG5mdW5jdGlvbiBleHBvc2VQcm9wc09uUmVuZGVyQ29udGV4dChpbnN0YW5jZSkge1xyXG4gICAgY29uc3QgeyBjdHgsIHByb3BzT3B0aW9uczogW3Byb3BzT3B0aW9uc10gfSA9IGluc3RhbmNlO1xyXG4gICAgaWYgKHByb3BzT3B0aW9ucykge1xyXG4gICAgICAgIE9iamVjdC5rZXlzKHByb3BzT3B0aW9ucykuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHtcclxuICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IGluc3RhbmNlLnByb3BzW2tleV0sXHJcbiAgICAgICAgICAgICAgICBzZXQ6IE5PT1BcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuLy8gZGV2IG9ubHlcclxuZnVuY3Rpb24gZXhwb3NlU2V0dXBTdGF0ZU9uUmVuZGVyQ29udGV4dChpbnN0YW5jZSkge1xyXG4gICAgY29uc3QgeyBjdHgsIHNldHVwU3RhdGUgfSA9IGluc3RhbmNlO1xyXG4gICAgT2JqZWN0LmtleXModG9SYXcoc2V0dXBTdGF0ZSkpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBrZXksIHtcclxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBnZXQ6ICgpID0+IHNldHVwU3RhdGVba2V5XSxcclxuICAgICAgICAgICAgc2V0OiBOT09QXHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxufVxuXG5jb25zdCBlbXB0eUFwcENvbnRleHQgPSBjcmVhdGVBcHBDb250ZXh0KCk7XHJcbmxldCB1aWQkMSA9IDA7XHJcbmZ1bmN0aW9uIGNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKHZub2RlLCBwYXJlbnQsIHN1c3BlbnNlKSB7XHJcbiAgICBjb25zdCB0eXBlID0gdm5vZGUudHlwZTtcclxuICAgIC8vIGluaGVyaXQgcGFyZW50IGFwcCBjb250ZXh0IC0gb3IgLSBpZiByb290LCBhZG9wdCBmcm9tIHJvb3Qgdm5vZGVcclxuICAgIGNvbnN0IGFwcENvbnRleHQgPSAocGFyZW50ID8gcGFyZW50LmFwcENvbnRleHQgOiB2bm9kZS5hcHBDb250ZXh0KSB8fCBlbXB0eUFwcENvbnRleHQ7XHJcbiAgICBjb25zdCBpbnN0YW5jZSA9IHtcclxuICAgICAgICB1aWQ6IHVpZCQxKyssXHJcbiAgICAgICAgdm5vZGUsXHJcbiAgICAgICAgdHlwZSxcclxuICAgICAgICBwYXJlbnQsXHJcbiAgICAgICAgYXBwQ29udGV4dCxcclxuICAgICAgICByb290OiBudWxsLFxyXG4gICAgICAgIG5leHQ6IG51bGwsXHJcbiAgICAgICAgc3ViVHJlZTogbnVsbCxcclxuICAgICAgICB1cGRhdGU6IG51bGwsXHJcbiAgICAgICAgcmVuZGVyOiBudWxsLFxyXG4gICAgICAgIHByb3h5OiBudWxsLFxyXG4gICAgICAgIHdpdGhQcm94eTogbnVsbCxcclxuICAgICAgICBlZmZlY3RzOiBudWxsLFxyXG4gICAgICAgIHByb3ZpZGVzOiBwYXJlbnQgPyBwYXJlbnQucHJvdmlkZXMgOiBPYmplY3QuY3JlYXRlKGFwcENvbnRleHQucHJvdmlkZXMpLFxyXG4gICAgICAgIGFjY2Vzc0NhY2hlOiBudWxsLFxyXG4gICAgICAgIHJlbmRlckNhY2hlOiBbXSxcclxuICAgICAgICAvLyBsb2NhbCByZXNvdmxlZCBhc3NldHNcclxuICAgICAgICBjb21wb25lbnRzOiBudWxsLFxyXG4gICAgICAgIGRpcmVjdGl2ZXM6IG51bGwsXHJcbiAgICAgICAgLy8gcmVzb2x2ZWQgcHJvcHMgYW5kIGVtaXRzIG9wdGlvbnNcclxuICAgICAgICBwcm9wc09wdGlvbnM6IG5vcm1hbGl6ZVByb3BzT3B0aW9ucyh0eXBlLCBhcHBDb250ZXh0KSxcclxuICAgICAgICBlbWl0c09wdGlvbnM6IG5vcm1hbGl6ZUVtaXRzT3B0aW9ucyh0eXBlLCBhcHBDb250ZXh0KSxcclxuICAgICAgICAvLyBlbWl0XHJcbiAgICAgICAgZW1pdDogbnVsbCxcclxuICAgICAgICBlbWl0dGVkOiBudWxsLFxyXG4gICAgICAgIC8vIHN0YXRlXHJcbiAgICAgICAgY3R4OiBFTVBUWV9PQkosXHJcbiAgICAgICAgZGF0YTogRU1QVFlfT0JKLFxyXG4gICAgICAgIHByb3BzOiBFTVBUWV9PQkosXHJcbiAgICAgICAgYXR0cnM6IEVNUFRZX09CSixcclxuICAgICAgICBzbG90czogRU1QVFlfT0JKLFxyXG4gICAgICAgIHJlZnM6IEVNUFRZX09CSixcclxuICAgICAgICBzZXR1cFN0YXRlOiBFTVBUWV9PQkosXHJcbiAgICAgICAgc2V0dXBDb250ZXh0OiBudWxsLFxyXG4gICAgICAgIC8vIHN1c3BlbnNlIHJlbGF0ZWRcclxuICAgICAgICBzdXNwZW5zZSxcclxuICAgICAgICBhc3luY0RlcDogbnVsbCxcclxuICAgICAgICBhc3luY1Jlc29sdmVkOiBmYWxzZSxcclxuICAgICAgICAvLyBsaWZlY3ljbGUgaG9va3NcclxuICAgICAgICAvLyBub3QgdXNpbmcgZW51bXMgaGVyZSBiZWNhdXNlIGl0IHJlc3VsdHMgaW4gY29tcHV0ZWQgcHJvcGVydGllc1xyXG4gICAgICAgIGlzTW91bnRlZDogZmFsc2UsXHJcbiAgICAgICAgaXNVbm1vdW50ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGlzRGVhY3RpdmF0ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGJjOiBudWxsLFxyXG4gICAgICAgIGM6IG51bGwsXHJcbiAgICAgICAgYm06IG51bGwsXHJcbiAgICAgICAgbTogbnVsbCxcclxuICAgICAgICBidTogbnVsbCxcclxuICAgICAgICB1OiBudWxsLFxyXG4gICAgICAgIHVtOiBudWxsLFxyXG4gICAgICAgIGJ1bTogbnVsbCxcclxuICAgICAgICBkYTogbnVsbCxcclxuICAgICAgICBhOiBudWxsLFxyXG4gICAgICAgIHJ0ZzogbnVsbCxcclxuICAgICAgICBydGM6IG51bGwsXHJcbiAgICAgICAgZWM6IG51bGxcclxuICAgIH07XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgaW5zdGFuY2UuY3R4ID0gY3JlYXRlUmVuZGVyQ29udGV4dChpbnN0YW5jZSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpbnN0YW5jZS5jdHggPSB7IF86IGluc3RhbmNlIH07XHJcbiAgICB9XHJcbiAgICBpbnN0YW5jZS5yb290ID0gcGFyZW50ID8gcGFyZW50LnJvb3QgOiBpbnN0YW5jZTtcclxuICAgIGluc3RhbmNlLmVtaXQgPSBlbWl0LmJpbmQobnVsbCwgaW5zdGFuY2UpO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB8fCBfX1ZVRV9QUk9EX0RFVlRPT0xTX18pIHtcclxuICAgICAgICBkZXZ0b29sc0NvbXBvbmVudEFkZGVkKGluc3RhbmNlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBpbnN0YW5jZTtcclxufVxyXG5sZXQgY3VycmVudEluc3RhbmNlID0gbnVsbDtcclxuY29uc3QgZ2V0Q3VycmVudEluc3RhbmNlID0gKCkgPT4gY3VycmVudEluc3RhbmNlIHx8IGN1cnJlbnRSZW5kZXJpbmdJbnN0YW5jZTtcclxuY29uc3Qgc2V0Q3VycmVudEluc3RhbmNlID0gKGluc3RhbmNlKSA9PiB7XHJcbiAgICBjdXJyZW50SW5zdGFuY2UgPSBpbnN0YW5jZTtcclxufTtcclxuY29uc3QgaXNCdWlsdEluVGFnID0gLyojX19QVVJFX18qLyBtYWtlTWFwKCdzbG90LGNvbXBvbmVudCcpO1xyXG5mdW5jdGlvbiB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZSwgY29uZmlnKSB7XHJcbiAgICBjb25zdCBhcHBJc05hdGl2ZVRhZyA9IGNvbmZpZy5pc05hdGl2ZVRhZyB8fCBOTztcclxuICAgIGlmIChpc0J1aWx0SW5UYWcobmFtZSkgfHwgYXBwSXNOYXRpdmVUYWcobmFtZSkpIHtcclxuICAgICAgICB3YXJuKCdEbyBub3QgdXNlIGJ1aWx0LWluIG9yIHJlc2VydmVkIEhUTUwgZWxlbWVudHMgYXMgY29tcG9uZW50IGlkOiAnICsgbmFtZSk7XHJcbiAgICB9XHJcbn1cclxubGV0IGlzSW5TU1JDb21wb25lbnRTZXR1cCA9IGZhbHNlO1xyXG5mdW5jdGlvbiBzZXR1cENvbXBvbmVudChpbnN0YW5jZSwgaXNTU1IgPSBmYWxzZSkge1xyXG4gICAgaXNJblNTUkNvbXBvbmVudFNldHVwID0gaXNTU1I7XHJcbiAgICBjb25zdCB7IHByb3BzLCBjaGlsZHJlbiwgc2hhcGVGbGFnIH0gPSBpbnN0YW5jZS52bm9kZTtcclxuICAgIGNvbnN0IGlzU3RhdGVmdWwgPSBzaGFwZUZsYWcgJiA0IC8qIFNUQVRFRlVMX0NPTVBPTkVOVCAqLztcclxuICAgIGluaXRQcm9wcyhpbnN0YW5jZSwgcHJvcHMsIGlzU3RhdGVmdWwsIGlzU1NSKTtcclxuICAgIGluaXRTbG90cyhpbnN0YW5jZSwgY2hpbGRyZW4pO1xyXG4gICAgY29uc3Qgc2V0dXBSZXN1bHQgPSBpc1N0YXRlZnVsXHJcbiAgICAgICAgPyBzZXR1cFN0YXRlZnVsQ29tcG9uZW50KGluc3RhbmNlLCBpc1NTUilcclxuICAgICAgICA6IHVuZGVmaW5lZDtcclxuICAgIGlzSW5TU1JDb21wb25lbnRTZXR1cCA9IGZhbHNlO1xyXG4gICAgcmV0dXJuIHNldHVwUmVzdWx0O1xyXG59XHJcbmZ1bmN0aW9uIHNldHVwU3RhdGVmdWxDb21wb25lbnQoaW5zdGFuY2UsIGlzU1NSKSB7XHJcbiAgICBjb25zdCBDb21wb25lbnQgPSBpbnN0YW5jZS50eXBlO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIGlmIChDb21wb25lbnQubmFtZSkge1xyXG4gICAgICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUoQ29tcG9uZW50Lm5hbWUsIGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKENvbXBvbmVudC5jb21wb25lbnRzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoQ29tcG9uZW50LmNvbXBvbmVudHMpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YWxpZGF0ZUNvbXBvbmVudE5hbWUobmFtZXNbaV0sIGluc3RhbmNlLmFwcENvbnRleHQuY29uZmlnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoQ29tcG9uZW50LmRpcmVjdGl2ZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgbmFtZXMgPSBPYmplY3Qua2V5cyhDb21wb25lbnQuZGlyZWN0aXZlcyk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHZhbGlkYXRlRGlyZWN0aXZlTmFtZShuYW1lc1tpXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyAwLiBjcmVhdGUgcmVuZGVyIHByb3h5IHByb3BlcnR5IGFjY2VzcyBjYWNoZVxyXG4gICAgaW5zdGFuY2UuYWNjZXNzQ2FjaGUgPSB7fTtcclxuICAgIC8vIDEuIGNyZWF0ZSBwdWJsaWMgaW5zdGFuY2UgLyByZW5kZXIgcHJveHlcclxuICAgIC8vIGFsc28gbWFyayBpdCByYXcgc28gaXQncyBuZXZlciBvYnNlcnZlZFxyXG4gICAgaW5zdGFuY2UucHJveHkgPSBuZXcgUHJveHkoaW5zdGFuY2UuY3R4LCBQdWJsaWNJbnN0YW5jZVByb3h5SGFuZGxlcnMpO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIGV4cG9zZVByb3BzT25SZW5kZXJDb250ZXh0KGluc3RhbmNlKTtcclxuICAgIH1cclxuICAgIC8vIDIuIGNhbGwgc2V0dXAoKVxyXG4gICAgY29uc3QgeyBzZXR1cCB9ID0gQ29tcG9uZW50O1xyXG4gICAgaWYgKHNldHVwKSB7XHJcbiAgICAgICAgY29uc3Qgc2V0dXBDb250ZXh0ID0gKGluc3RhbmNlLnNldHVwQ29udGV4dCA9XHJcbiAgICAgICAgICAgIHNldHVwLmxlbmd0aCA+IDEgPyBjcmVhdGVTZXR1cENvbnRleHQoaW5zdGFuY2UpIDogbnVsbCk7XHJcbiAgICAgICAgY3VycmVudEluc3RhbmNlID0gaW5zdGFuY2U7XHJcbiAgICAgICAgcGF1c2VUcmFja2luZygpO1xyXG4gICAgICAgIGNvbnN0IHNldHVwUmVzdWx0ID0gY2FsbFdpdGhFcnJvckhhbmRsaW5nKHNldHVwLCBpbnN0YW5jZSwgMCAvKiBTRVRVUF9GVU5DVElPTiAqLywgWyhwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSA/IHNoYWxsb3dSZWFkb25seShpbnN0YW5jZS5wcm9wcykgOiBpbnN0YW5jZS5wcm9wcywgc2V0dXBDb250ZXh0XSk7XHJcbiAgICAgICAgcmVzZXRUcmFja2luZygpO1xyXG4gICAgICAgIGN1cnJlbnRJbnN0YW5jZSA9IG51bGw7XHJcbiAgICAgICAgaWYgKGlzUHJvbWlzZShzZXR1cFJlc3VsdCkpIHtcclxuICAgICAgICAgICAgaWYgKGlzU1NSKSB7XHJcbiAgICAgICAgICAgICAgICAvLyByZXR1cm4gdGhlIHByb21pc2Ugc28gc2VydmVyLXJlbmRlcmVyIGNhbiB3YWl0IG9uIGl0XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2V0dXBSZXN1bHQudGhlbigocmVzb2x2ZWRSZXN1bHQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVTZXR1cFJlc3VsdChpbnN0YW5jZSwgcmVzb2x2ZWRSZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhc3luYyBzZXR1cCByZXR1cm5lZCBQcm9taXNlLlxyXG4gICAgICAgICAgICAgICAgLy8gYmFpbCBoZXJlIGFuZCB3YWl0IGZvciByZS1lbnRyeS5cclxuICAgICAgICAgICAgICAgIGluc3RhbmNlLmFzeW5jRGVwID0gc2V0dXBSZXN1bHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBzZXR1cFJlc3VsdCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgZmluaXNoQ29tcG9uZW50U2V0dXAoaW5zdGFuY2UpO1xyXG4gICAgfVxyXG59XHJcbmZ1bmN0aW9uIGhhbmRsZVNldHVwUmVzdWx0KGluc3RhbmNlLCBzZXR1cFJlc3VsdCwgaXNTU1IpIHtcclxuICAgIGlmIChpc0Z1bmN0aW9uKHNldHVwUmVzdWx0KSkge1xyXG4gICAgICAgIC8vIHNldHVwIHJldHVybmVkIGFuIGlubGluZSByZW5kZXIgZnVuY3Rpb25cclxuICAgICAgICBpbnN0YW5jZS5yZW5kZXIgPSBzZXR1cFJlc3VsdDtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzT2JqZWN0KHNldHVwUmVzdWx0KSkge1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgaXNWTm9kZShzZXR1cFJlc3VsdCkpIHtcclxuICAgICAgICAgICAgd2Fybihgc2V0dXAoKSBzaG91bGQgbm90IHJldHVybiBWTm9kZXMgZGlyZWN0bHkgLSBgICtcclxuICAgICAgICAgICAgICAgIGByZXR1cm4gYSByZW5kZXIgZnVuY3Rpb24gaW5zdGVhZC5gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gc2V0dXAgcmV0dXJuZWQgYmluZGluZ3MuXHJcbiAgICAgICAgLy8gYXNzdW1pbmcgYSByZW5kZXIgZnVuY3Rpb24gY29tcGlsZWQgZnJvbSB0ZW1wbGF0ZSBpcyBwcmVzZW50LlxyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgfHwgX19WVUVfUFJPRF9ERVZUT09MU19fKSB7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLmRldnRvb2xzUmF3U2V0dXBTdGF0ZSA9IHNldHVwUmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpbnN0YW5jZS5zZXR1cFN0YXRlID0gcHJveHlSZWZzKHNldHVwUmVzdWx0KTtcclxuICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgICAgIGV4cG9zZVNldHVwU3RhdGVPblJlbmRlckNvbnRleHQoaW5zdGFuY2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBzZXR1cFJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgd2Fybihgc2V0dXAoKSBzaG91bGQgcmV0dXJuIGFuIG9iamVjdC4gUmVjZWl2ZWQ6ICR7c2V0dXBSZXN1bHQgPT09IG51bGwgPyAnbnVsbCcgOiB0eXBlb2Ygc2V0dXBSZXN1bHR9YCk7XHJcbiAgICB9XHJcbiAgICBmaW5pc2hDb21wb25lbnRTZXR1cChpbnN0YW5jZSk7XHJcbn1cclxubGV0IGNvbXBpbGU7XHJcbi8qKlxyXG4gKiBGb3IgcnVudGltZS1kb20gdG8gcmVnaXN0ZXIgdGhlIGNvbXBpbGVyLlxyXG4gKiBOb3RlIHRoZSBleHBvcnRlZCBtZXRob2QgdXNlcyBhbnkgdG8gYXZvaWQgZC50cyByZWx5aW5nIG9uIHRoZSBjb21waWxlciB0eXBlcy5cclxuICovXHJcbmZ1bmN0aW9uIHJlZ2lzdGVyUnVudGltZUNvbXBpbGVyKF9jb21waWxlKSB7XHJcbiAgICBjb21waWxlID0gX2NvbXBpbGU7XHJcbn1cclxuZnVuY3Rpb24gZmluaXNoQ29tcG9uZW50U2V0dXAoaW5zdGFuY2UsIGlzU1NSKSB7XHJcbiAgICBjb25zdCBDb21wb25lbnQgPSBpbnN0YW5jZS50eXBlO1xyXG4gICAgLy8gdGVtcGxhdGUgLyByZW5kZXIgZnVuY3Rpb24gbm9ybWFsaXphdGlvblxyXG4gICAgaWYgKCFpbnN0YW5jZS5yZW5kZXIpIHtcclxuICAgICAgICAvLyBjb3VsZCBiZSBzZXQgZnJvbSBzZXR1cCgpXHJcbiAgICAgICAgaWYgKGNvbXBpbGUgJiYgQ29tcG9uZW50LnRlbXBsYXRlICYmICFDb21wb25lbnQucmVuZGVyKSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIHN0YXJ0TWVhc3VyZShpbnN0YW5jZSwgYGNvbXBpbGVgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBDb21wb25lbnQucmVuZGVyID0gY29tcGlsZShDb21wb25lbnQudGVtcGxhdGUsIHtcclxuICAgICAgICAgICAgICAgIGlzQ3VzdG9tRWxlbWVudDogaW5zdGFuY2UuYXBwQ29udGV4dC5jb25maWcuaXNDdXN0b21FbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgZGVsaW1pdGVyczogQ29tcG9uZW50LmRlbGltaXRlcnNcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIGVuZE1lYXN1cmUoaW5zdGFuY2UsIGBjb21waWxlYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaW5zdGFuY2UucmVuZGVyID0gKENvbXBvbmVudC5yZW5kZXIgfHwgTk9PUCk7XHJcbiAgICAgICAgLy8gZm9yIHJ1bnRpbWUtY29tcGlsZWQgcmVuZGVyIGZ1bmN0aW9ucyB1c2luZyBgd2l0aGAgYmxvY2tzLCB0aGUgcmVuZGVyXHJcbiAgICAgICAgLy8gcHJveHkgdXNlZCBuZWVkcyBhIGRpZmZlcmVudCBgaGFzYCBoYW5kbGVyIHdoaWNoIGlzIG1vcmUgcGVyZm9ybWFudCBhbmRcclxuICAgICAgICAvLyBhbHNvIG9ubHkgYWxsb3dzIGEgd2hpdGVsaXN0IG9mIGdsb2JhbHMgdG8gZmFsbHRocm91Z2guXHJcbiAgICAgICAgaWYgKGluc3RhbmNlLnJlbmRlci5fcmMpIHtcclxuICAgICAgICAgICAgaW5zdGFuY2Uud2l0aFByb3h5ID0gbmV3IFByb3h5KGluc3RhbmNlLmN0eCwgUnVudGltZUNvbXBpbGVkUHVibGljSW5zdGFuY2VQcm94eUhhbmRsZXJzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBzdXBwb3J0IGZvciAyLnggb3B0aW9uc1xyXG4gICAgaWYgKF9fVlVFX09QVElPTlNfQVBJX18pIHtcclxuICAgICAgICBjdXJyZW50SW5zdGFuY2UgPSBpbnN0YW5jZTtcclxuICAgICAgICBhcHBseU9wdGlvbnMoaW5zdGFuY2UsIENvbXBvbmVudCk7XHJcbiAgICAgICAgY3VycmVudEluc3RhbmNlID0gbnVsbDtcclxuICAgIH1cclxuICAgIC8vIHdhcm4gbWlzc2luZyB0ZW1wbGF0ZS9yZW5kZXJcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykgJiYgIUNvbXBvbmVudC5yZW5kZXIgJiYgaW5zdGFuY2UucmVuZGVyID09PSBOT09QKSB7XHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXHJcbiAgICAgICAgaWYgKCFjb21waWxlICYmIENvbXBvbmVudC50ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICB3YXJuKGBDb21wb25lbnQgcHJvdmlkZWQgdGVtcGxhdGUgb3B0aW9uIGJ1dCBgICtcclxuICAgICAgICAgICAgICAgIGBydW50aW1lIGNvbXBpbGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBidWlsZCBvZiBWdWUuYCArXHJcbiAgICAgICAgICAgICAgICAoIGAgQ29uZmlndXJlIHlvdXIgYnVuZGxlciB0byBhbGlhcyBcInZ1ZVwiIHRvIFwidnVlL2Rpc3QvdnVlLmVzbS1idW5kbGVyLmpzXCIuYFxyXG4gICAgICAgICAgICAgICAgICAgICkgLyogc2hvdWxkIG5vdCBoYXBwZW4gKi8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgd2FybihgQ29tcG9uZW50IGlzIG1pc3NpbmcgdGVtcGxhdGUgb3IgcmVuZGVyIGZ1bmN0aW9uLmApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5jb25zdCBhdHRySGFuZGxlcnMgPSB7XHJcbiAgICBnZXQ6ICh0YXJnZXQsIGtleSkgPT4ge1xyXG4gICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgbWFya0F0dHJzQWNjZXNzZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldFtrZXldO1xyXG4gICAgfSxcclxuICAgIHNldDogKCkgPT4ge1xyXG4gICAgICAgIHdhcm4oYHNldHVwQ29udGV4dC5hdHRycyBpcyByZWFkb25seS5gKTtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9LFxyXG4gICAgZGVsZXRlUHJvcGVydHk6ICgpID0+IHtcclxuICAgICAgICB3YXJuKGBzZXR1cENvbnRleHQuYXR0cnMgaXMgcmVhZG9ubHkuYCk7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG59O1xyXG5mdW5jdGlvbiBjcmVhdGVTZXR1cENvbnRleHQoaW5zdGFuY2UpIHtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAvLyBXZSB1c2UgZ2V0dGVycyBpbiBkZXYgaW4gY2FzZSBsaWJzIGxpa2UgdGVzdC11dGlscyBvdmVyd3JpdGUgaW5zdGFuY2VcclxuICAgICAgICAvLyBwcm9wZXJ0aWVzIChvdmVyd3JpdGVzIHNob3VsZCBub3QgYmUgZG9uZSBpbiBwcm9kKVxyXG4gICAgICAgIHJldHVybiBPYmplY3QuZnJlZXplKHtcclxuICAgICAgICAgICAgZ2V0IGF0dHJzKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm94eShpbnN0YW5jZS5hdHRycywgYXR0ckhhbmRsZXJzKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZ2V0IHNsb3RzKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNoYWxsb3dSZWFkb25seShpbnN0YW5jZS5zbG90cyk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGdldCBlbWl0KCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIChldmVudCwgLi4uYXJncykgPT4gaW5zdGFuY2UuZW1pdChldmVudCwgLi4uYXJncyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGF0dHJzOiBpbnN0YW5jZS5hdHRycyxcclxuICAgICAgICAgICAgc2xvdHM6IGluc3RhbmNlLnNsb3RzLFxyXG4gICAgICAgICAgICBlbWl0OiBpbnN0YW5jZS5lbWl0XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG4vLyByZWNvcmQgZWZmZWN0cyBjcmVhdGVkIGR1cmluZyBhIGNvbXBvbmVudCdzIHNldHVwKCkgc28gdGhhdCB0aGV5IGNhbiBiZVxyXG4vLyBzdG9wcGVkIHdoZW4gdGhlIGNvbXBvbmVudCB1bm1vdW50c1xyXG5mdW5jdGlvbiByZWNvcmRJbnN0YW5jZUJvdW5kRWZmZWN0KGVmZmVjdCkge1xyXG4gICAgaWYgKGN1cnJlbnRJbnN0YW5jZSkge1xyXG4gICAgICAgIChjdXJyZW50SW5zdGFuY2UuZWZmZWN0cyB8fCAoY3VycmVudEluc3RhbmNlLmVmZmVjdHMgPSBbXSkpLnB1c2goZWZmZWN0KTtcclxuICAgIH1cclxufVxyXG5jb25zdCBjbGFzc2lmeVJFID0gLyg/Ol58Wy1fXSkoXFx3KS9nO1xyXG5jb25zdCBjbGFzc2lmeSA9IChzdHIpID0+IHN0ci5yZXBsYWNlKGNsYXNzaWZ5UkUsIGMgPT4gYy50b1VwcGVyQ2FzZSgpKS5yZXBsYWNlKC9bLV9dL2csICcnKTtcclxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuZnVuY3Rpb24gZm9ybWF0Q29tcG9uZW50TmFtZShpbnN0YW5jZSwgQ29tcG9uZW50LCBpc1Jvb3QgPSBmYWxzZSkge1xyXG4gICAgbGV0IG5hbWUgPSBpc0Z1bmN0aW9uKENvbXBvbmVudClcclxuICAgICAgICA/IENvbXBvbmVudC5kaXNwbGF5TmFtZSB8fCBDb21wb25lbnQubmFtZVxyXG4gICAgICAgIDogQ29tcG9uZW50Lm5hbWU7XHJcbiAgICBpZiAoIW5hbWUgJiYgQ29tcG9uZW50Ll9fZmlsZSkge1xyXG4gICAgICAgIGNvbnN0IG1hdGNoID0gQ29tcG9uZW50Ll9fZmlsZS5tYXRjaCgvKFteL1xcXFxdKylcXC52dWUkLyk7XHJcbiAgICAgICAgaWYgKG1hdGNoKSB7XHJcbiAgICAgICAgICAgIG5hbWUgPSBtYXRjaFsxXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoIW5hbWUgJiYgaW5zdGFuY2UgJiYgaW5zdGFuY2UucGFyZW50KSB7XHJcbiAgICAgICAgLy8gdHJ5IHRvIGluZmVyIHRoZSBuYW1lIGJhc2VkIG9uIHJldmVyc2UgcmVzb2x1dGlvblxyXG4gICAgICAgIGNvbnN0IGluZmVyRnJvbVJlZ2lzdHJ5ID0gKHJlZ2lzdHJ5KSA9PiB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHJlZ2lzdHJ5KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVnaXN0cnlba2V5XSA9PT0gQ29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgbmFtZSA9XHJcbiAgICAgICAgICAgIGluZmVyRnJvbVJlZ2lzdHJ5KGluc3RhbmNlLmNvbXBvbmVudHMgfHxcclxuICAgICAgICAgICAgICAgIGluc3RhbmNlLnBhcmVudC50eXBlLmNvbXBvbmVudHMpIHx8IGluZmVyRnJvbVJlZ2lzdHJ5KGluc3RhbmNlLmFwcENvbnRleHQuY29tcG9uZW50cyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmFtZSA/IGNsYXNzaWZ5KG5hbWUpIDogaXNSb290ID8gYEFwcGAgOiBgQW5vbnltb3VzYDtcclxufVxuXG5mdW5jdGlvbiBjb21wdXRlZChnZXR0ZXJPck9wdGlvbnMpIHtcclxuICAgIGNvbnN0IGMgPSBjb21wdXRlZCQxKGdldHRlck9yT3B0aW9ucyk7XHJcbiAgICByZWNvcmRJbnN0YW5jZUJvdW5kRWZmZWN0KGMuZWZmZWN0KTtcclxuICAgIHJldHVybiBjO1xyXG59XG5cbi8vIGltcGxlbWVudGF0aW9uLCBjbG9zZSB0byBuby1vcFxyXG5mdW5jdGlvbiBkZWZpbmVDb21wb25lbnQob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGlzRnVuY3Rpb24ob3B0aW9ucykgPyB7IHNldHVwOiBvcHRpb25zLCBuYW1lOiBvcHRpb25zLm5hbWUgfSA6IG9wdGlvbnM7XHJcbn1cblxuZnVuY3Rpb24gZGVmaW5lQXN5bmNDb21wb25lbnQoc291cmNlKSB7XHJcbiAgICBpZiAoaXNGdW5jdGlvbihzb3VyY2UpKSB7XHJcbiAgICAgICAgc291cmNlID0geyBsb2FkZXI6IHNvdXJjZSB9O1xyXG4gICAgfVxyXG4gICAgY29uc3QgeyBsb2FkZXIsIGxvYWRpbmdDb21wb25lbnQ6IGxvYWRpbmdDb21wb25lbnQsIGVycm9yQ29tcG9uZW50OiBlcnJvckNvbXBvbmVudCwgZGVsYXkgPSAyMDAsIHRpbWVvdXQsIC8vIHVuZGVmaW5lZCA9IG5ldmVyIHRpbWVzIG91dFxyXG4gICAgc3VzcGVuc2libGUgPSB0cnVlLCBvbkVycm9yOiB1c2VyT25FcnJvciB9ID0gc291cmNlO1xyXG4gICAgbGV0IHBlbmRpbmdSZXF1ZXN0ID0gbnVsbDtcclxuICAgIGxldCByZXNvbHZlZENvbXA7XHJcbiAgICBsZXQgcmV0cmllcyA9IDA7XHJcbiAgICBjb25zdCByZXRyeSA9ICgpID0+IHtcclxuICAgICAgICByZXRyaWVzKys7XHJcbiAgICAgICAgcGVuZGluZ1JlcXVlc3QgPSBudWxsO1xyXG4gICAgICAgIHJldHVybiBsb2FkKCk7XHJcbiAgICB9O1xyXG4gICAgY29uc3QgbG9hZCA9ICgpID0+IHtcclxuICAgICAgICBsZXQgdGhpc1JlcXVlc3Q7XHJcbiAgICAgICAgcmV0dXJuIChwZW5kaW5nUmVxdWVzdCB8fFxyXG4gICAgICAgICAgICAodGhpc1JlcXVlc3QgPSBwZW5kaW5nUmVxdWVzdCA9IGxvYWRlcigpXHJcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcclxuICAgICAgICAgICAgICAgIGVyciA9IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyIDogbmV3IEVycm9yKFN0cmluZyhlcnIpKTtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyT25FcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJSZXRyeSA9ICgpID0+IHJlc29sdmUocmV0cnkoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJGYWlsID0gKCkgPT4gcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJPbkVycm9yKGVyciwgdXNlclJldHJ5LCB1c2VyRmFpbCwgcmV0cmllcyArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oKGNvbXApID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzUmVxdWVzdCAhPT0gcGVuZGluZ1JlcXVlc3QgJiYgcGVuZGluZ1JlcXVlc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGVuZGluZ1JlcXVlc3Q7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFjb21wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgd2FybihgQXN5bmMgY29tcG9uZW50IGxvYWRlciByZXNvbHZlZCB0byB1bmRlZmluZWQuIGAgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgSWYgeW91IGFyZSB1c2luZyByZXRyeSgpLCBtYWtlIHN1cmUgdG8gcmV0dXJuIGl0cyByZXR1cm4gdmFsdWUuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBpbnRlcm9wIG1vZHVsZSBkZWZhdWx0XHJcbiAgICAgICAgICAgICAgICBpZiAoY29tcCAmJlxyXG4gICAgICAgICAgICAgICAgICAgIChjb21wLl9fZXNNb2R1bGUgfHwgY29tcFtTeW1ib2wudG9TdHJpbmdUYWddID09PSAnTW9kdWxlJykpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb21wID0gY29tcC5kZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBjb21wICYmICFpc09iamVjdChjb21wKSAmJiAhaXNGdW5jdGlvbihjb21wKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhc3luYyBjb21wb25lbnQgbG9hZCByZXN1bHQ6ICR7Y29tcH1gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJlc29sdmVkQ29tcCA9IGNvbXA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY29tcDtcclxuICAgICAgICAgICAgfSkpKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gZGVmaW5lQ29tcG9uZW50KHtcclxuICAgICAgICBfX2FzeW5jTG9hZGVyOiBsb2FkLFxyXG4gICAgICAgIG5hbWU6ICdBc3luY0NvbXBvbmVudFdyYXBwZXInLFxyXG4gICAgICAgIHNldHVwKCkge1xyXG4gICAgICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGN1cnJlbnRJbnN0YW5jZTtcclxuICAgICAgICAgICAgLy8gYWxyZWFkeSByZXNvbHZlZFxyXG4gICAgICAgICAgICBpZiAocmVzb2x2ZWRDb21wKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4gY3JlYXRlSW5uZXJDb21wKHJlc29sdmVkQ29tcCwgaW5zdGFuY2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBwZW5kaW5nUmVxdWVzdCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICBoYW5kbGVFcnJvcihlcnIsIGluc3RhbmNlLCAxMyAvKiBBU1lOQ19DT01QT05FTlRfTE9BREVSICovKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gc3VzcGVuc2UtY29udHJvbGxlZCBvciBTU1IuXHJcbiAgICAgICAgICAgIGlmICgoIHN1c3BlbnNpYmxlICYmIGluc3RhbmNlLnN1c3BlbnNlKSB8fFxyXG4gICAgICAgICAgICAgICAgKGZhbHNlICkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkKClcclxuICAgICAgICAgICAgICAgICAgICAudGhlbihjb21wID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4gY3JlYXRlSW5uZXJDb21wKGNvbXAsIGluc3RhbmNlKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgb25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiBlcnJvckNvbXBvbmVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGNyZWF0ZVZOb2RlKGVycm9yQ29tcG9uZW50LCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGxvYWRlZCA9IHJlZihmYWxzZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gcmVmKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGRlbGF5ZWQgPSByZWYoISFkZWxheSk7XHJcbiAgICAgICAgICAgIGlmIChkZWxheSkge1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsYXllZC52YWx1ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSwgZGVsYXkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aW1lb3V0ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbG9hZGVkLnZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBFcnJvcihgQXN5bmMgY29tcG9uZW50IHRpbWVkIG91dCBhZnRlciAke3RpbWVvdXR9bXMuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRXJyb3IoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IudmFsdWUgPSBlcnI7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSwgdGltZW91dCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbG9hZCgpXHJcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBsb2FkZWQudmFsdWUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBvbkVycm9yKGVycik7XHJcbiAgICAgICAgICAgICAgICBlcnJvci52YWx1ZSA9IGVycjtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAobG9hZGVkLnZhbHVlICYmIHJlc29sdmVkQ29tcCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVJbm5lckNvbXAocmVzb2x2ZWRDb21wLCBpbnN0YW5jZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChlcnJvci52YWx1ZSAmJiBlcnJvckNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVWTm9kZShlcnJvckNvbXBvbmVudCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IudmFsdWVcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxvYWRpbmdDb21wb25lbnQgJiYgIWRlbGF5ZWQudmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUobG9hZGluZ0NvbXBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gY3JlYXRlSW5uZXJDb21wKGNvbXAsIHsgdm5vZGU6IHsgcHJvcHMsIGNoaWxkcmVuIH0gfSkge1xyXG4gICAgcmV0dXJuIGNyZWF0ZVZOb2RlKGNvbXAsIHByb3BzLCBjaGlsZHJlbik7XHJcbn1cblxuLy8gQWN0dWFsIGltcGxlbWVudGF0aW9uXHJcbmZ1bmN0aW9uIGgodHlwZSwgcHJvcHNPckNoaWxkcmVuLCBjaGlsZHJlbikge1xyXG4gICAgY29uc3QgbCA9IGFyZ3VtZW50cy5sZW5ndGg7XHJcbiAgICBpZiAobCA9PT0gMikge1xyXG4gICAgICAgIGlmIChpc09iamVjdChwcm9wc09yQ2hpbGRyZW4pICYmICFpc0FycmF5KHByb3BzT3JDaGlsZHJlbikpIHtcclxuICAgICAgICAgICAgLy8gc2luZ2xlIHZub2RlIHdpdGhvdXQgcHJvcHNcclxuICAgICAgICAgICAgaWYgKGlzVk5vZGUocHJvcHNPckNoaWxkcmVuKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHR5cGUsIG51bGwsIFtwcm9wc09yQ2hpbGRyZW5dKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBwcm9wcyB3aXRob3V0IGNoaWxkcmVuXHJcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVWTm9kZSh0eXBlLCBwcm9wc09yQ2hpbGRyZW4pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gb21pdCBwcm9wc1xyXG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlVk5vZGUodHlwZSwgbnVsbCwgcHJvcHNPckNoaWxkcmVuKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBpZiAobCA+IDMpIHtcclxuICAgICAgICAgICAgY2hpbGRyZW4gPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChsID09PSAzICYmIGlzVk5vZGUoY2hpbGRyZW4pKSB7XHJcbiAgICAgICAgICAgIGNoaWxkcmVuID0gW2NoaWxkcmVuXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHR5cGUsIHByb3BzT3JDaGlsZHJlbiwgY2hpbGRyZW4pO1xyXG4gICAgfVxyXG59XG5cbmNvbnN0IHNzckNvbnRleHRLZXkgPSBTeW1ib2woKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpID8gYHNzckNvbnRleHRgIDogYGApO1xyXG5jb25zdCB1c2VTU1JDb250ZXh0ID0gKCkgPT4ge1xyXG4gICAge1xyXG4gICAgICAgIGNvbnN0IGN0eCA9IGluamVjdChzc3JDb250ZXh0S2V5KTtcclxuICAgICAgICBpZiAoIWN0eCkge1xyXG4gICAgICAgICAgICB3YXJuKGBTZXJ2ZXIgcmVuZGVyaW5nIGNvbnRleHQgbm90IHByb3ZpZGVkLiBNYWtlIHN1cmUgdG8gb25seSBjYWxsIGAgK1xyXG4gICAgICAgICAgICAgICAgYHVzZVNzckNvbnRleHQoKSBjb25kaXRpb25hbGx5IGluIHRoZSBzZXJ2ZXIgYnVpbGQuYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjdHg7XHJcbiAgICB9XHJcbn07XG5cbi8qKlxyXG4gKiBBY3R1YWwgaW1wbGVtZW50YXRpb25cclxuICovXHJcbmZ1bmN0aW9uIHJlbmRlckxpc3Qoc291cmNlLCByZW5kZXJJdGVtKSB7XHJcbiAgICBsZXQgcmV0O1xyXG4gICAgaWYgKGlzQXJyYXkoc291cmNlKSB8fCBpc1N0cmluZyhzb3VyY2UpKSB7XHJcbiAgICAgICAgcmV0ID0gbmV3IEFycmF5KHNvdXJjZS5sZW5ndGgpO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0gc291cmNlLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICByZXRbaV0gPSByZW5kZXJJdGVtKHNvdXJjZVtpXSwgaSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodHlwZW9mIHNvdXJjZSA9PT0gJ251bWJlcicpIHtcclxuICAgICAgICByZXQgPSBuZXcgQXJyYXkoc291cmNlKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNvdXJjZTsgaSsrKSB7XHJcbiAgICAgICAgICAgIHJldFtpXSA9IHJlbmRlckl0ZW0oaSArIDEsIGkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzT2JqZWN0KHNvdXJjZSkpIHtcclxuICAgICAgICBpZiAoc291cmNlW1N5bWJvbC5pdGVyYXRvcl0pIHtcclxuICAgICAgICAgICAgcmV0ID0gQXJyYXkuZnJvbShzb3VyY2UsIHJlbmRlckl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XHJcbiAgICAgICAgICAgIHJldCA9IG5ldyBBcnJheShrZXlzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsID0ga2V5cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XHJcbiAgICAgICAgICAgICAgICByZXRbaV0gPSByZW5kZXJJdGVtKHNvdXJjZVtrZXldLCBrZXksIGkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgcmV0ID0gW107XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmV0O1xyXG59XG5cbi8qKlxyXG4gKiBGb3IgcHJlZml4aW5nIGtleXMgaW4gdi1vbj1cIm9ialwiIHdpdGggXCJvblwiXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5mdW5jdGlvbiB0b0hhbmRsZXJzKG9iaikge1xyXG4gICAgY29uc3QgcmV0ID0ge307XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmICFpc09iamVjdChvYmopKSB7XHJcbiAgICAgICAgd2Fybihgdi1vbiB3aXRoIG5vIGFyZ3VtZW50IGV4cGVjdHMgYW4gb2JqZWN0IHZhbHVlLmApO1xyXG4gICAgICAgIHJldHVybiByZXQ7XHJcbiAgICB9XHJcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcclxuICAgICAgICByZXRbYG9uJHtjYXBpdGFsaXplKGtleSl9YF0gPSBvYmpba2V5XTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXQ7XHJcbn1cblxuLyoqXHJcbiAqIENvbXBpbGVyIHJ1bnRpbWUgaGVscGVyIGZvciBjcmVhdGluZyBkeW5hbWljIHNsb3RzIG9iamVjdFxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlU2xvdHMoc2xvdHMsIGR5bmFtaWNTbG90cykge1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkeW5hbWljU2xvdHMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBzbG90ID0gZHluYW1pY1Nsb3RzW2ldO1xyXG4gICAgICAgIC8vIGFycmF5IG9mIGR5bmFtaWMgc2xvdCBnZW5lcmF0ZWQgYnkgPHRlbXBsYXRlIHYtZm9yPVwiLi4uXCIgI1suLi5dPlxyXG4gICAgICAgIGlmIChpc0FycmF5KHNsb3QpKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgc2xvdC5sZW5ndGg7IGorKykge1xyXG4gICAgICAgICAgICAgICAgc2xvdHNbc2xvdFtqXS5uYW1lXSA9IHNsb3Rbal0uZm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoc2xvdCkge1xyXG4gICAgICAgICAgICAvLyBjb25kaXRpb25hbCBzaW5nbGUgc2xvdCBnZW5lcmF0ZWQgYnkgPHRlbXBsYXRlIHYtaWY9XCIuLi5cIiAjZm9vPlxyXG4gICAgICAgICAgICBzbG90c1tzbG90Lm5hbWVdID0gc2xvdC5mbjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc2xvdHM7XHJcbn1cblxuLy8gQ29yZSBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbmNvbnN0IHZlcnNpb24gPSBcIjMuMC4wLXJjLjEwXCI7XHJcbi8qKlxyXG4gKiBTU1IgdXRpbHMgZm9yIFxcQHZ1ZS9zZXJ2ZXItcmVuZGVyZXIuIE9ubHkgZXhwb3NlZCBpbiBjanMgYnVpbGRzLlxyXG4gKiBAaW50ZXJuYWxcclxuICovXHJcbmNvbnN0IHNzclV0aWxzID0gKCBudWxsKTtcblxuZXhwb3J0IHsgQmFzZVRyYW5zaXRpb24sIENvbW1lbnQsIEZyYWdtZW50LCBLZWVwQWxpdmUsIFN0YXRpYywgU3VzcGVuc2UsIFRlbGVwb3J0LCBUZXh0LCBjYWxsV2l0aEFzeW5jRXJyb3JIYW5kbGluZywgY2FsbFdpdGhFcnJvckhhbmRsaW5nLCBjbG9uZVZOb2RlLCBjb21wdXRlZCwgY3JlYXRlQmxvY2ssIGNyZWF0ZUNvbW1lbnRWTm9kZSwgY3JlYXRlSHlkcmF0aW9uUmVuZGVyZXIsIGNyZWF0ZVJlbmRlcmVyLCBjcmVhdGVTbG90cywgY3JlYXRlU3RhdGljVk5vZGUsIGNyZWF0ZVRleHRWTm9kZSwgY3JlYXRlVk5vZGUsIGRlZmluZUFzeW5jQ29tcG9uZW50LCBkZWZpbmVDb21wb25lbnQsIGRldnRvb2xzLCBnZXRDdXJyZW50SW5zdGFuY2UsIGdldFRyYW5zaXRpb25SYXdDaGlsZHJlbiwgaCwgaGFuZGxlRXJyb3IsIGluamVjdCwgaXNWTm9kZSwgbWVyZ2VQcm9wcywgbmV4dFRpY2ssIG9uQWN0aXZhdGVkLCBvbkJlZm9yZU1vdW50LCBvbkJlZm9yZVVubW91bnQsIG9uQmVmb3JlVXBkYXRlLCBvbkRlYWN0aXZhdGVkLCBvbkVycm9yQ2FwdHVyZWQsIG9uTW91bnRlZCwgb25SZW5kZXJUcmFja2VkLCBvblJlbmRlclRyaWdnZXJlZCwgb25Vbm1vdW50ZWQsIG9uVXBkYXRlZCwgb3BlbkJsb2NrLCBwb3BTY29wZUlkLCBwcm92aWRlLCBwdXNoU2NvcGVJZCwgcXVldWVQb3N0Rmx1c2hDYiwgcmVnaXN0ZXJSdW50aW1lQ29tcGlsZXIsIHJlbmRlckxpc3QsIHJlbmRlclNsb3QsIHJlc29sdmVDb21wb25lbnQsIHJlc29sdmVEaXJlY3RpdmUsIHJlc29sdmVEeW5hbWljQ29tcG9uZW50LCByZXNvbHZlVHJhbnNpdGlvbkhvb2tzLCBzZXRCbG9ja1RyYWNraW5nLCBzZXREZXZ0b29sc0hvb2ssIHNldFRyYW5zaXRpb25Ib29rcywgc3NyQ29udGV4dEtleSwgc3NyVXRpbHMsIHRvSGFuZGxlcnMsIHRyYW5zZm9ybVZOb2RlQXJncywgdXNlU1NSQ29udGV4dCwgdXNlVHJhbnNpdGlvblN0YXRlLCB2ZXJzaW9uLCB3YXJuLCB3YXRjaCwgd2F0Y2hFZmZlY3QsIHdpdGhDdHgsIHdpdGhEaXJlY3RpdmVzLCB3aXRoU2NvcGVJZCB9O1xuIiwiaW1wb3J0IHsgY2FtZWxpemUsIHdhcm4sIGNhbGxXaXRoQXN5bmNFcnJvckhhbmRsaW5nLCBnZXRDdXJyZW50SW5zdGFuY2UsIG9uTW91bnRlZCwgd2F0Y2hFZmZlY3QsIHVucmVmLCBGcmFnbWVudCwgaCwgQmFzZVRyYW5zaXRpb24sIHVzZVRyYW5zaXRpb25TdGF0ZSwgb25VcGRhdGVkLCBnZXRUcmFuc2l0aW9uUmF3Q2hpbGRyZW4sIHNldFRyYW5zaXRpb25Ib29rcywgcmVzb2x2ZVRyYW5zaXRpb25Ib29rcywgY3JlYXRlVk5vZGUsIGNyZWF0ZVJlbmRlcmVyLCBjcmVhdGVIeWRyYXRpb25SZW5kZXJlciB9IGZyb20gJ0B2dWUvcnVudGltZS1jb3JlJztcbmV4cG9ydCAqIGZyb20gJ0B2dWUvcnVudGltZS1jb3JlJztcbmltcG9ydCB7IGlzU3RyaW5nLCBpc0FycmF5LCBoeXBoZW5hdGUsIGNhcGl0YWxpemUsIGlzU3BlY2lhbEJvb2xlYW5BdHRyLCBpc09uLCBpc01vZGVsTGlzdGVuZXIsIGlzRnVuY3Rpb24sIEVNUFRZX09CSiwgZXh0ZW5kLCBpc09iamVjdCwgdG9OdW1iZXIsIGludm9rZUFycmF5Rm5zLCBsb29zZUluZGV4T2YsIGxvb3NlRXF1YWwsIGlzSFRNTFRhZywgaXNTVkdUYWcgfSBmcm9tICdAdnVlL3NoYXJlZCc7XG5cbmNvbnN0IHN2Z05TID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJztcclxuY29uc3QgZG9jID0gKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBkb2N1bWVudCA6IG51bGwpO1xyXG5sZXQgdGVtcENvbnRhaW5lcjtcclxubGV0IHRlbXBTVkdDb250YWluZXI7XHJcbmNvbnN0IG5vZGVPcHMgPSB7XHJcbiAgICBpbnNlcnQ6IChjaGlsZCwgcGFyZW50LCBhbmNob3IpID0+IHtcclxuICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBhbmNob3IgfHwgbnVsbCk7XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlOiBjaGlsZCA9PiB7XHJcbiAgICAgICAgY29uc3QgcGFyZW50ID0gY2hpbGQucGFyZW50Tm9kZTtcclxuICAgICAgICBpZiAocGFyZW50KSB7XHJcbiAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChjaGlsZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIGNyZWF0ZUVsZW1lbnQ6ICh0YWcsIGlzU1ZHLCBpcykgPT4gaXNTVkdcclxuICAgICAgICA/IGRvYy5jcmVhdGVFbGVtZW50TlMoc3ZnTlMsIHRhZylcclxuICAgICAgICA6IGRvYy5jcmVhdGVFbGVtZW50KHRhZywgaXMgPyB7IGlzIH0gOiB1bmRlZmluZWQpLFxyXG4gICAgY3JlYXRlVGV4dDogdGV4dCA9PiBkb2MuY3JlYXRlVGV4dE5vZGUodGV4dCksXHJcbiAgICBjcmVhdGVDb21tZW50OiB0ZXh0ID0+IGRvYy5jcmVhdGVDb21tZW50KHRleHQpLFxyXG4gICAgc2V0VGV4dDogKG5vZGUsIHRleHQpID0+IHtcclxuICAgICAgICBub2RlLm5vZGVWYWx1ZSA9IHRleHQ7XHJcbiAgICB9LFxyXG4gICAgc2V0RWxlbWVudFRleHQ6IChlbCwgdGV4dCkgPT4ge1xyXG4gICAgICAgIGVsLnRleHRDb250ZW50ID0gdGV4dDtcclxuICAgIH0sXHJcbiAgICBwYXJlbnROb2RlOiBub2RlID0+IG5vZGUucGFyZW50Tm9kZSxcclxuICAgIG5leHRTaWJsaW5nOiBub2RlID0+IG5vZGUubmV4dFNpYmxpbmcsXHJcbiAgICBxdWVyeVNlbGVjdG9yOiBzZWxlY3RvciA9PiBkb2MucXVlcnlTZWxlY3RvcihzZWxlY3RvciksXHJcbiAgICBzZXRTY29wZUlkKGVsLCBpZCkge1xyXG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShpZCwgJycpO1xyXG4gICAgfSxcclxuICAgIGNsb25lTm9kZShlbCkge1xyXG4gICAgICAgIHJldHVybiBlbC5jbG9uZU5vZGUodHJ1ZSk7XHJcbiAgICB9LFxyXG4gICAgLy8gX19VTlNBRkVfX1xyXG4gICAgLy8gUmVhc29uOiBpbm5lckhUTUwuXHJcbiAgICAvLyBTdGF0aWMgY29udGVudCBoZXJlIGNhbiBvbmx5IGNvbWUgZnJvbSBjb21waWxlZCB0ZW1wbGF0ZXMuXHJcbiAgICAvLyBBcyBsb25nIGFzIHRoZSB1c2VyIG9ubHkgdXNlcyB0cnVzdGVkIHRlbXBsYXRlcywgdGhpcyBpcyBzYWZlLlxyXG4gICAgaW5zZXJ0U3RhdGljQ29udGVudChjb250ZW50LCBwYXJlbnQsIGFuY2hvciwgaXNTVkcpIHtcclxuICAgICAgICBjb25zdCB0ZW1wID0gaXNTVkdcclxuICAgICAgICAgICAgPyB0ZW1wU1ZHQ29udGFpbmVyIHx8XHJcbiAgICAgICAgICAgICAgICAodGVtcFNWR0NvbnRhaW5lciA9IGRvYy5jcmVhdGVFbGVtZW50TlMoc3ZnTlMsICdzdmcnKSlcclxuICAgICAgICAgICAgOiB0ZW1wQ29udGFpbmVyIHx8ICh0ZW1wQ29udGFpbmVyID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ2RpdicpKTtcclxuICAgICAgICB0ZW1wLmlubmVySFRNTCA9IGNvbnRlbnQ7XHJcbiAgICAgICAgY29uc3QgZmlyc3QgPSB0ZW1wLmZpcnN0Q2hpbGQ7XHJcbiAgICAgICAgbGV0IG5vZGUgPSBmaXJzdDtcclxuICAgICAgICBsZXQgbGFzdCA9IG5vZGU7XHJcbiAgICAgICAgd2hpbGUgKG5vZGUpIHtcclxuICAgICAgICAgICAgbGFzdCA9IG5vZGU7XHJcbiAgICAgICAgICAgIG5vZGVPcHMuaW5zZXJ0KG5vZGUsIHBhcmVudCwgYW5jaG9yKTtcclxuICAgICAgICAgICAgbm9kZSA9IHRlbXAuZmlyc3RDaGlsZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFtmaXJzdCwgbGFzdF07XHJcbiAgICB9XHJcbn07XG5cbi8vIGNvbXBpbGVyIHNob3VsZCBub3JtYWxpemUgY2xhc3MgKyA6Y2xhc3MgYmluZGluZ3Mgb24gdGhlIHNhbWUgZWxlbWVudFxyXG4vLyBpbnRvIGEgc2luZ2xlIGJpbmRpbmcgWydzdGF0aWNDbGFzcycsIGR5bmFtaWNdXHJcbmZ1bmN0aW9uIHBhdGNoQ2xhc3MoZWwsIHZhbHVlLCBpc1NWRykge1xyXG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcclxuICAgICAgICB2YWx1ZSA9ICcnO1xyXG4gICAgfVxyXG4gICAgaWYgKGlzU1ZHKSB7XHJcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKCdjbGFzcycsIHZhbHVlKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIGRpcmVjdGx5IHNldHRpbmcgY2xhc3NOYW1lIHNob3VsZCBiZSBmYXN0ZXIgdGhhbiBzZXRBdHRyaWJ1dGUgaW4gdGhlb3J5XHJcbiAgICAgICAgLy8gaWYgdGhpcyBpcyBhbiBlbGVtZW50IGR1cmluZyBhIHRyYW5zaXRpb24sIHRha2UgdGhlIHRlbXBvcmFyeSB0cmFuc2l0aW9uXHJcbiAgICAgICAgLy8gY2xhc3NlcyBpbnRvIGFjY291bnQuXHJcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbkNsYXNzZXMgPSBlbC5fdnRjO1xyXG4gICAgICAgIGlmICh0cmFuc2l0aW9uQ2xhc3Nlcykge1xyXG4gICAgICAgICAgICB2YWx1ZSA9ICh2YWx1ZVxyXG4gICAgICAgICAgICAgICAgPyBbdmFsdWUsIC4uLnRyYW5zaXRpb25DbGFzc2VzXVxyXG4gICAgICAgICAgICAgICAgOiBbLi4udHJhbnNpdGlvbkNsYXNzZXNdKS5qb2luKCcgJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsLmNsYXNzTmFtZSA9IHZhbHVlO1xyXG4gICAgfVxyXG59XG5cbmZ1bmN0aW9uIHBhdGNoU3R5bGUoZWwsIHByZXYsIG5leHQpIHtcclxuICAgIGNvbnN0IHN0eWxlID0gZWwuc3R5bGU7XHJcbiAgICBpZiAoIW5leHQpIHtcclxuICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChpc1N0cmluZyhuZXh0KSkge1xyXG4gICAgICAgIGlmIChwcmV2ICE9PSBuZXh0KSB7XHJcbiAgICAgICAgICAgIHN0eWxlLmNzc1RleHQgPSBuZXh0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIG5leHQpIHtcclxuICAgICAgICAgICAgc2V0U3R5bGUoc3R5bGUsIGtleSwgbmV4dFtrZXldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHByZXYgJiYgIWlzU3RyaW5nKHByZXYpKSB7XHJcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIHByZXYpIHtcclxuICAgICAgICAgICAgICAgIGlmIChuZXh0W2tleV0gPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNldFN0eWxlKHN0eWxlLCBrZXksICcnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5jb25zdCBpbXBvcnRhbnRSRSA9IC9cXHMqIWltcG9ydGFudCQvO1xyXG5mdW5jdGlvbiBzZXRTdHlsZShzdHlsZSwgbmFtZSwgdmFsKSB7XHJcbiAgICBpZiAoaXNBcnJheSh2YWwpKSB7XHJcbiAgICAgICAgdmFsLmZvckVhY2godiA9PiBzZXRTdHlsZShzdHlsZSwgbmFtZSwgdikpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aCgnLS0nKSkge1xyXG4gICAgICAgICAgICAvLyBjdXN0b20gcHJvcGVydHkgZGVmaW5pdGlvblxyXG4gICAgICAgICAgICBzdHlsZS5zZXRQcm9wZXJ0eShuYW1lLCB2YWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgcHJlZml4ZWQgPSBhdXRvUHJlZml4KHN0eWxlLCBuYW1lKTtcclxuICAgICAgICAgICAgaWYgKGltcG9ydGFudFJFLnRlc3QodmFsKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gIWltcG9ydGFudFxyXG4gICAgICAgICAgICAgICAgc3R5bGUuc2V0UHJvcGVydHkoaHlwaGVuYXRlKHByZWZpeGVkKSwgdmFsLnJlcGxhY2UoaW1wb3J0YW50UkUsICcnKSwgJ2ltcG9ydGFudCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgc3R5bGVbcHJlZml4ZWRdID0gdmFsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmNvbnN0IHByZWZpeGVzID0gWydXZWJraXQnLCAnTW96JywgJ21zJ107XHJcbmNvbnN0IHByZWZpeENhY2hlID0ge307XHJcbmZ1bmN0aW9uIGF1dG9QcmVmaXgoc3R5bGUsIHJhd05hbWUpIHtcclxuICAgIGNvbnN0IGNhY2hlZCA9IHByZWZpeENhY2hlW3Jhd05hbWVdO1xyXG4gICAgaWYgKGNhY2hlZCkge1xyXG4gICAgICAgIHJldHVybiBjYWNoZWQ7XHJcbiAgICB9XHJcbiAgICBsZXQgbmFtZSA9IGNhbWVsaXplKHJhd05hbWUpO1xyXG4gICAgaWYgKG5hbWUgIT09ICdmaWx0ZXInICYmIG5hbWUgaW4gc3R5bGUpIHtcclxuICAgICAgICByZXR1cm4gKHByZWZpeENhY2hlW3Jhd05hbWVdID0gbmFtZSk7XHJcbiAgICB9XHJcbiAgICBuYW1lID0gY2FwaXRhbGl6ZShuYW1lKTtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJlZml4ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICBjb25zdCBwcmVmaXhlZCA9IHByZWZpeGVzW2ldICsgbmFtZTtcclxuICAgICAgICBpZiAocHJlZml4ZWQgaW4gc3R5bGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIChwcmVmaXhDYWNoZVtyYXdOYW1lXSA9IHByZWZpeGVkKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmF3TmFtZTtcclxufVxuXG5jb25zdCB4bGlua05TID0gJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnO1xyXG5mdW5jdGlvbiBwYXRjaEF0dHIoZWwsIGtleSwgdmFsdWUsIGlzU1ZHKSB7XHJcbiAgICBpZiAoaXNTVkcgJiYga2V5LnN0YXJ0c1dpdGgoJ3hsaW5rOicpKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcclxuICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlTlMoeGxpbmtOUywga2V5LnNsaWNlKDYsIGtleS5sZW5ndGgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZU5TKHhsaW5rTlMsIGtleSwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vIG5vdGUgd2UgYXJlIG9ubHkgY2hlY2tpbmcgYm9vbGVhbiBhdHRyaWJ1dGVzIHRoYXQgZG9uJ3QgaGF2ZSBhXHJcbiAgICAgICAgLy8gY29ycmVzcG9uZGluZyBkb20gcHJvcCBvZiB0aGUgc2FtZSBuYW1lIGhlcmUuXHJcbiAgICAgICAgY29uc3QgaXNCb29sZWFuID0gaXNTcGVjaWFsQm9vbGVhbkF0dHIoa2V5KTtcclxuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCAoaXNCb29sZWFuICYmIHZhbHVlID09PSBmYWxzZSkpIHtcclxuICAgICAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKGtleSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCBpc0Jvb2xlYW4gPyAnJyA6IHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxuLy8gX19VTlNBRkVfX1xyXG4vLyBmdW5jdGlvbnMuIFRoZSB1c2VyIGlzIHJlc3BvbnNpYmxlIGZvciB1c2luZyB0aGVtIHdpdGggb25seSB0cnVzdGVkIGNvbnRlbnQuXHJcbmZ1bmN0aW9uIHBhdGNoRE9NUHJvcChlbCwga2V5LCB2YWx1ZSwgXHJcbi8vIHRoZSBmb2xsb3dpbmcgYXJncyBhcmUgcGFzc2VkIG9ubHkgZHVlIHRvIHBvdGVudGlhbCBpbm5lckhUTUwvdGV4dENvbnRlbnRcclxuLy8gb3ZlcnJpZGluZyBleGlzdGluZyBWTm9kZXMsIGluIHdoaWNoIGNhc2UgdGhlIG9sZCB0cmVlIG11c3QgYmUgcHJvcGVybHlcclxuLy8gdW5tb3VudGVkLlxyXG5wcmV2Q2hpbGRyZW4sIHBhcmVudENvbXBvbmVudCwgcGFyZW50U3VzcGVuc2UsIHVubW91bnRDaGlsZHJlbikge1xyXG4gICAgaWYgKGtleSA9PT0gJ2lubmVySFRNTCcgfHwga2V5ID09PSAndGV4dENvbnRlbnQnKSB7XHJcbiAgICAgICAgaWYgKHByZXZDaGlsZHJlbikge1xyXG4gICAgICAgICAgICB1bm1vdW50Q2hpbGRyZW4ocHJldkNoaWxkcmVuLCBwYXJlbnRDb21wb25lbnQsIHBhcmVudFN1c3BlbnNlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxba2V5XSA9IHZhbHVlID09IG51bGwgPyAnJyA6IHZhbHVlO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChrZXkgPT09ICd2YWx1ZScgJiYgZWwudGFnTmFtZSAhPT0gJ1BST0dSRVNTJykge1xyXG4gICAgICAgIC8vIHN0b3JlIHZhbHVlIGFzIF92YWx1ZSBhcyB3ZWxsIHNpbmNlXHJcbiAgICAgICAgLy8gbm9uLXN0cmluZyB2YWx1ZXMgd2lsbCBiZSBzdHJpbmdpZmllZC5cclxuICAgICAgICBlbC5fdmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHZhbHVlID09IG51bGwgPyAnJyA6IHZhbHVlO1xyXG4gICAgICAgIGlmIChlbC52YWx1ZSAhPT0gbmV3VmFsdWUpIHtcclxuICAgICAgICAgICAgZWwudmFsdWUgPSBuZXdWYWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKHZhbHVlID09PSAnJyAmJiB0eXBlb2YgZWxba2V5XSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgLy8gZS5nLiA8c2VsZWN0IG11bHRpcGxlPiBjb21waWxlcyB0byB7IG11bHRpcGxlOiAnJyB9XHJcbiAgICAgICAgZWxba2V5XSA9IHRydWU7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh2YWx1ZSA9PSBudWxsICYmIHR5cGVvZiBlbFtrZXldID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIC8vIGUuZy4gPGRpdiA6aWQ9XCJudWxsXCI+XHJcbiAgICAgICAgZWxba2V5XSA9ICcnO1xyXG4gICAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShrZXkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgLy8gc29tZSBwcm9wZXJ0aWVzIHBlcmZvcm0gdmFsdWUgdmFsaWRhdGlvbiBhbmQgdGhyb3dcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBlbFtrZXldID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICAgICAgICAgIHdhcm4oYEZhaWxlZCBzZXR0aW5nIHByb3AgXCIke2tleX1cIiBvbiA8JHtlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCl9PjogYCArXHJcbiAgICAgICAgICAgICAgICAgICAgYHZhbHVlICR7dmFsdWV9IGlzIGludmFsaWQuYCwgZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cblxuLy8gQXN5bmMgZWRnZSBjYXNlIGZpeCByZXF1aXJlcyBzdG9yaW5nIGFuIGV2ZW50IGxpc3RlbmVyJ3MgYXR0YWNoIHRpbWVzdGFtcC5cclxubGV0IF9nZXROb3cgPSBEYXRlLm5vdztcclxuLy8gRGV0ZXJtaW5lIHdoYXQgZXZlbnQgdGltZXN0YW1wIHRoZSBicm93c2VyIGlzIHVzaW5nLiBBbm5veWluZ2x5LCB0aGVcclxuLy8gdGltZXN0YW1wIGNhbiBlaXRoZXIgYmUgaGktcmVzIChyZWxhdGl2ZSB0byBwYWdlIGxvYWQpIG9yIGxvdy1yZXNcclxuLy8gKHJlbGF0aXZlIHRvIFVOSVggZXBvY2gpLCBzbyBpbiBvcmRlciB0byBjb21wYXJlIHRpbWUgd2UgaGF2ZSB0byB1c2UgdGhlXHJcbi8vIHNhbWUgdGltZXN0YW1wIHR5cGUgd2hlbiBzYXZpbmcgdGhlIGZsdXNoIHRpbWVzdGFtcC5cclxuaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiZcclxuICAgIF9nZXROb3coKSA+IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpLnRpbWVTdGFtcCkge1xyXG4gICAgLy8gaWYgdGhlIGxvdy1yZXMgdGltZXN0YW1wIHdoaWNoIGlzIGJpZ2dlciB0aGFuIHRoZSBldmVudCB0aW1lc3RhbXBcclxuICAgIC8vICh3aGljaCBpcyBldmFsdWF0ZWQgQUZURVIpIGl0IG1lYW5zIHRoZSBldmVudCBpcyB1c2luZyBhIGhpLXJlcyB0aW1lc3RhbXAsXHJcbiAgICAvLyBhbmQgd2UgbmVlZCB0byB1c2UgdGhlIGhpLXJlcyB2ZXJzaW9uIGZvciBldmVudCBsaXN0ZW5lcnMgYXMgd2VsbC5cclxuICAgIF9nZXROb3cgPSAoKSA9PiBwZXJmb3JtYW5jZS5ub3coKTtcclxufVxyXG4vLyBUbyBhdm9pZCB0aGUgb3ZlcmhlYWQgb2YgcmVwZWF0ZWRseSBjYWxsaW5nIHBlcmZvcm1hbmNlLm5vdygpLCB3ZSBjYWNoZVxyXG4vLyBhbmQgdXNlIHRoZSBzYW1lIHRpbWVzdGFtcCBmb3IgYWxsIGV2ZW50IGxpc3RlbmVycyBhdHRhY2hlZCBpbiB0aGUgc2FtZSB0aWNrLlxyXG5sZXQgY2FjaGVkTm93ID0gMDtcclxuY29uc3QgcCA9IFByb21pc2UucmVzb2x2ZSgpO1xyXG5jb25zdCByZXNldCA9ICgpID0+IHtcclxuICAgIGNhY2hlZE5vdyA9IDA7XHJcbn07XHJcbmNvbnN0IGdldE5vdyA9ICgpID0+IGNhY2hlZE5vdyB8fCAocC50aGVuKHJlc2V0KSwgKGNhY2hlZE5vdyA9IF9nZXROb3coKSkpO1xyXG5mdW5jdGlvbiBhZGRFdmVudExpc3RlbmVyKGVsLCBldmVudCwgaGFuZGxlciwgb3B0aW9ucykge1xyXG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgaGFuZGxlciwgb3B0aW9ucyk7XHJcbn1cclxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpIHtcclxuICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIsIG9wdGlvbnMpO1xyXG59XHJcbmZ1bmN0aW9uIHBhdGNoRXZlbnQoZWwsIHJhd05hbWUsIHByZXZWYWx1ZSwgbmV4dFZhbHVlLCBpbnN0YW5jZSA9IG51bGwpIHtcclxuICAgIC8vIHZlaSA9IHZ1ZSBldmVudCBpbnZva2Vyc1xyXG4gICAgY29uc3QgaW52b2tlcnMgPSBlbC5fdmVpIHx8IChlbC5fdmVpID0ge30pO1xyXG4gICAgY29uc3QgZXhpc3RpbmdJbnZva2VyID0gaW52b2tlcnNbcmF3TmFtZV07XHJcbiAgICBpZiAobmV4dFZhbHVlICYmIGV4aXN0aW5nSW52b2tlcikge1xyXG4gICAgICAgIC8vIHBhdGNoXHJcbiAgICAgICAgZXhpc3RpbmdJbnZva2VyLnZhbHVlID0gbmV4dFZhbHVlO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgY29uc3QgW25hbWUsIG9wdGlvbnNdID0gcGFyc2VOYW1lKHJhd05hbWUpO1xyXG4gICAgICAgIGlmIChuZXh0VmFsdWUpIHtcclxuICAgICAgICAgICAgLy8gYWRkXHJcbiAgICAgICAgICAgIGNvbnN0IGludm9rZXIgPSAoaW52b2tlcnNbcmF3TmFtZV0gPSBjcmVhdGVJbnZva2VyKG5leHRWYWx1ZSwgaW5zdGFuY2UpKTtcclxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgbmFtZSwgaW52b2tlciwgb3B0aW9ucyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGV4aXN0aW5nSW52b2tlcikge1xyXG4gICAgICAgICAgICAvLyByZW1vdmVcclxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihlbCwgbmFtZSwgZXhpc3RpbmdJbnZva2VyLCBvcHRpb25zKTtcclxuICAgICAgICAgICAgaW52b2tlcnNbcmF3TmFtZV0gPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbmNvbnN0IG9wdGlvbnNNb2RpZmllclJFID0gLyg/Ok9uY2V8UGFzc2l2ZXxDYXB0dXJlKSQvO1xyXG5mdW5jdGlvbiBwYXJzZU5hbWUobmFtZSkge1xyXG4gICAgbGV0IG9wdGlvbnM7XHJcbiAgICBpZiAob3B0aW9uc01vZGlmaWVyUkUudGVzdChuYW1lKSkge1xyXG4gICAgICAgIG9wdGlvbnMgPSB7fTtcclxuICAgICAgICBsZXQgbTtcclxuICAgICAgICB3aGlsZSAoKG0gPSBuYW1lLm1hdGNoKG9wdGlvbnNNb2RpZmllclJFKSkpIHtcclxuICAgICAgICAgICAgbmFtZSA9IG5hbWUuc2xpY2UoMCwgbmFtZS5sZW5ndGggLSBtWzBdLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIG9wdGlvbnNbbVswXS50b0xvd2VyQ2FzZSgpXSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIFtuYW1lLnNsaWNlKDIpLnRvTG93ZXJDYXNlKCksIG9wdGlvbnNdO1xyXG59XHJcbmZ1bmN0aW9uIGNyZWF0ZUludm9rZXIoaW5pdGlhbFZhbHVlLCBpbnN0YW5jZSkge1xyXG4gICAgY29uc3QgaW52b2tlciA9IChlKSA9PiB7XHJcbiAgICAgICAgLy8gYXN5bmMgZWRnZSBjYXNlICM2NTY2OiBpbm5lciBjbGljayBldmVudCB0cmlnZ2VycyBwYXRjaCwgZXZlbnQgaGFuZGxlclxyXG4gICAgICAgIC8vIGF0dGFjaGVkIHRvIG91dGVyIGVsZW1lbnQgZHVyaW5nIHBhdGNoLCBhbmQgdHJpZ2dlcmVkIGFnYWluLiBUaGlzXHJcbiAgICAgICAgLy8gaGFwcGVucyBiZWNhdXNlIGJyb3dzZXJzIGZpcmUgbWljcm90YXNrIHRpY2tzIGJldHdlZW4gZXZlbnQgcHJvcGFnYXRpb24uXHJcbiAgICAgICAgLy8gdGhlIHNvbHV0aW9uIGlzIHNpbXBsZTogd2Ugc2F2ZSB0aGUgdGltZXN0YW1wIHdoZW4gYSBoYW5kbGVyIGlzIGF0dGFjaGVkLFxyXG4gICAgICAgIC8vIGFuZCB0aGUgaGFuZGxlciB3b3VsZCBvbmx5IGZpcmUgaWYgdGhlIGV2ZW50IHBhc3NlZCB0byBpdCB3YXMgZmlyZWRcclxuICAgICAgICAvLyBBRlRFUiBpdCB3YXMgYXR0YWNoZWQuXHJcbiAgICAgICAgY29uc3QgdGltZVN0YW1wID0gZS50aW1lU3RhbXAgfHwgX2dldE5vdygpO1xyXG4gICAgICAgIGlmICh0aW1lU3RhbXAgPj0gaW52b2tlci5hdHRhY2hlZCAtIDEpIHtcclxuICAgICAgICAgICAgY2FsbFdpdGhBc3luY0Vycm9ySGFuZGxpbmcocGF0Y2hTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oZSwgaW52b2tlci52YWx1ZSksIGluc3RhbmNlLCA1IC8qIE5BVElWRV9FVkVOVF9IQU5ETEVSICovLCBbZV0pO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBpbnZva2VyLnZhbHVlID0gaW5pdGlhbFZhbHVlO1xyXG4gICAgaW52b2tlci5hdHRhY2hlZCA9IGdldE5vdygpO1xyXG4gICAgcmV0dXJuIGludm9rZXI7XHJcbn1cclxuZnVuY3Rpb24gcGF0Y2hTdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oZSwgdmFsdWUpIHtcclxuICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xyXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsU3RvcCA9IGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uO1xyXG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uID0gKCkgPT4ge1xyXG4gICAgICAgICAgICBvcmlnaW5hbFN0b3AuY2FsbChlKTtcclxuICAgICAgICAgICAgZS5fc3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gdmFsdWUubWFwKGZuID0+IChlKSA9PiAhZS5fc3RvcHBlZCAmJiBmbihlKSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcbn1cblxuY29uc3QgbmF0aXZlT25SRSA9IC9eb25bYS16XS87XHJcbmNvbnN0IGZvcmNlUGF0Y2hQcm9wID0gKF8sIGtleSkgPT4ga2V5ID09PSAndmFsdWUnO1xyXG5jb25zdCBwYXRjaFByb3AgPSAoZWwsIGtleSwgcHJldlZhbHVlLCBuZXh0VmFsdWUsIGlzU1ZHID0gZmFsc2UsIHByZXZDaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdW5tb3VudENoaWxkcmVuKSA9PiB7XHJcbiAgICBzd2l0Y2ggKGtleSkge1xyXG4gICAgICAgIC8vIHNwZWNpYWxcclxuICAgICAgICBjYXNlICdjbGFzcyc6XHJcbiAgICAgICAgICAgIHBhdGNoQ2xhc3MoZWwsIG5leHRWYWx1ZSwgaXNTVkcpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlICdzdHlsZSc6XHJcbiAgICAgICAgICAgIHBhdGNoU3R5bGUoZWwsIHByZXZWYWx1ZSwgbmV4dFZhbHVlKTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgaWYgKGlzT24oa2V5KSkge1xyXG4gICAgICAgICAgICAgICAgLy8gaWdub3JlIHYtbW9kZWwgbGlzdGVuZXJzXHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzTW9kZWxMaXN0ZW5lcihrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGF0Y2hFdmVudChlbCwga2V5LCBwcmV2VmFsdWUsIG5leHRWYWx1ZSwgcGFyZW50Q29tcG9uZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChzaG91bGRTZXRBc1Byb3AoZWwsIGtleSwgbmV4dFZhbHVlLCBpc1NWRykpIHtcclxuICAgICAgICAgICAgICAgIHBhdGNoRE9NUHJvcChlbCwga2V5LCBuZXh0VmFsdWUsIHByZXZDaGlsZHJlbiwgcGFyZW50Q29tcG9uZW50LCBwYXJlbnRTdXNwZW5zZSwgdW5tb3VudENoaWxkcmVuKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgPGlucHV0IHYtbW9kZWwgdHlwZT1cImNoZWNrYm94XCI+IHdpdGhcclxuICAgICAgICAgICAgICAgIC8vIDp0cnVlLXZhbHVlICYgOmZhbHNlLXZhbHVlXHJcbiAgICAgICAgICAgICAgICAvLyBzdG9yZSB2YWx1ZSBhcyBkb20gcHJvcGVydGllcyBzaW5jZSBub24tc3RyaW5nIHZhbHVlcyB3aWxsIGJlXHJcbiAgICAgICAgICAgICAgICAvLyBzdHJpbmdpZmllZC5cclxuICAgICAgICAgICAgICAgIGlmIChrZXkgPT09ICd0cnVlLXZhbHVlJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsLl90cnVlVmFsdWUgPSBuZXh0VmFsdWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChrZXkgPT09ICdmYWxzZS12YWx1ZScpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbC5fZmFsc2VWYWx1ZSA9IG5leHRWYWx1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHBhdGNoQXR0cihlbCwga2V5LCBuZXh0VmFsdWUsIGlzU1ZHKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgIH1cclxufTtcclxuZnVuY3Rpb24gc2hvdWxkU2V0QXNQcm9wKGVsLCBrZXksIHZhbHVlLCBpc1NWRykge1xyXG4gICAgaWYgKGlzU1ZHKSB7XHJcbiAgICAgICAgLy8gbW9zdCBrZXlzIG11c3QgYmUgc2V0IGFzIGF0dHJpYnV0ZSBvbiBzdmcgZWxlbWVudHMgdG8gd29ya1xyXG4gICAgICAgIC8vIC4uLmV4Y2VwdCBpbm5lckhUTUxcclxuICAgICAgICBpZiAoa2V5ID09PSAnaW5uZXJIVE1MJykge1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gb3IgbmF0aXZlIG9uY2xpY2sgd2l0aCBmdW5jdGlvbiB2YWx1ZXNcclxuICAgICAgICBpZiAoa2V5IGluIGVsICYmIG5hdGl2ZU9uUkUudGVzdChrZXkpICYmIGlzRnVuY3Rpb24odmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICAvLyBzcGVsbGNoZWNrIGFuZCBkcmFnZ2FibGUgYXJlIG51bWVyYXRlZCBhdHRycywgaG93ZXZlciB0aGVpclxyXG4gICAgLy8gY29ycmVzcG9uZGluZyBET00gcHJvcGVydGllcyBhcmUgYWN0dWFsbHkgYm9vbGVhbnMgLSB0aGlzIGxlYWRzIHRvXHJcbiAgICAvLyBzZXR0aW5nIGl0IHdpdGggYSBzdHJpbmcgXCJmYWxzZVwiIHZhbHVlIGxlYWRpbmcgaXQgdG8gYmUgY29lcmNlZCB0b1xyXG4gICAgLy8gYHRydWVgLCBzbyB3ZSBuZWVkIHRvIGFsd2F5cyB0cmVhdCB0aGVtIGFzIGF0dHJpYnV0ZXMuXHJcbiAgICAvLyBOb3RlIHRoYXQgYGNvbnRlbnRFZGl0YWJsZWAgZG9lc24ndCBoYXZlIHRoaXMgcHJvYmxlbTogaXRzIERPTVxyXG4gICAgLy8gcHJvcGVydHkgaXMgYWxzbyBlbnVtZXJhdGVkIHN0cmluZyB2YWx1ZXMuXHJcbiAgICBpZiAoa2V5ID09PSAnc3BlbGxjaGVjaycgfHwga2V5ID09PSAnZHJhZ2dhYmxlJykge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vICMxNzg3IGZvcm0gYXMgYW4gYXR0cmlidXRlIG11c3QgYmUgYSBzdHJpbmcsIHdoaWxlIGl0IGFjY2VwdHMgYW4gRWxlbWVudCBhc1xyXG4gICAgLy8gYSBwcm9wXHJcbiAgICBpZiAoa2V5ID09PSAnZm9ybScgJiYgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIC8vICMxNTI2IDxpbnB1dCBsaXN0PiBtdXN0IGJlIHNldCBhcyBhdHRyaWJ1dGVcclxuICAgIGlmIChrZXkgPT09ICdsaXN0JyAmJiBlbC50YWdOYW1lID09PSAnSU5QVVQnKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgLy8gbmF0aXZlIG9uY2xpY2sgd2l0aCBzdHJpbmcgdmFsdWUsIG11c3QgYmUgc2V0IGFzIGF0dHJpYnV0ZVxyXG4gICAgaWYgKG5hdGl2ZU9uUkUudGVzdChrZXkpICYmIGlzU3RyaW5nKHZhbHVlKSkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIHJldHVybiBrZXkgaW4gZWw7XHJcbn1cblxuZnVuY3Rpb24gdXNlQ3NzTW9kdWxlKG5hbWUgPSAnJHN0eWxlJykge1xyXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cclxuICAgIHtcclxuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IGdldEN1cnJlbnRJbnN0YW5jZSgpO1xyXG4gICAgICAgIGlmICghaW5zdGFuY2UpIHtcclxuICAgICAgICAgICAgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmIHdhcm4oYHVzZUNzc01vZHVsZSBtdXN0IGJlIGNhbGxlZCBpbnNpZGUgc2V0dXAoKWApO1xyXG4gICAgICAgICAgICByZXR1cm4gRU1QVFlfT0JKO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtb2R1bGVzID0gaW5zdGFuY2UudHlwZS5fX2Nzc01vZHVsZXM7XHJcbiAgICAgICAgaWYgKCFtb2R1bGVzKSB7XHJcbiAgICAgICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiB3YXJuKGBDdXJyZW50IGluc3RhbmNlIGRvZXMgbm90IGhhdmUgQ1NTIG1vZHVsZXMgaW5qZWN0ZWQuYCk7XHJcbiAgICAgICAgICAgIHJldHVybiBFTVBUWV9PQko7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG1vZCA9IG1vZHVsZXNbbmFtZV07XHJcbiAgICAgICAgaWYgKCFtb2QpIHtcclxuICAgICAgICAgICAgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgICAgICB3YXJuKGBDdXJyZW50IGluc3RhbmNlIGRvZXMgbm90IGhhdmUgQ1NTIG1vZHVsZSBuYW1lZCBcIiR7bmFtZX1cIi5gKTtcclxuICAgICAgICAgICAgcmV0dXJuIEVNUFRZX09CSjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG1vZDtcclxuICAgIH1cclxufVxuXG5mdW5jdGlvbiB1c2VDc3NWYXJzKGdldHRlciwgc2NvcGVkID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7XHJcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgaWYgKCFpbnN0YW5jZSkge1xyXG4gICAgICAgIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJlxyXG4gICAgICAgICAgICB3YXJuKGB1c2VDc3NWYXJzIGlzIGNhbGxlZCB3aXRob3V0IGN1cnJlbnQgYWN0aXZlIGNvbXBvbmVudCBpbnN0YW5jZS5gKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBjb25zdCBwcmVmaXggPSBzY29wZWQgJiYgaW5zdGFuY2UudHlwZS5fX3Njb3BlSWRcclxuICAgICAgICA/IGAke2luc3RhbmNlLnR5cGUuX19zY29wZUlkLnJlcGxhY2UoL15kYXRhLXYtLywgJycpfS1gXHJcbiAgICAgICAgOiBgYDtcclxuICAgIG9uTW91bnRlZCgoKSA9PiB7XHJcbiAgICAgICAgd2F0Y2hFZmZlY3QoKCkgPT4ge1xyXG4gICAgICAgICAgICBzZXRWYXJzT25WTm9kZShpbnN0YW5jZS5zdWJUcmVlLCBnZXR0ZXIoaW5zdGFuY2UucHJveHkpLCBwcmVmaXgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gc2V0VmFyc09uVk5vZGUodm5vZGUsIHZhcnMsIHByZWZpeCkge1xyXG4gICAgaWYgKCB2bm9kZS5zaGFwZUZsYWcgJiAxMjggLyogU1VTUEVOU0UgKi8pIHtcclxuICAgICAgICBjb25zdCB7IGlzUmVzb2x2ZWQsIGlzSHlkcmF0aW5nLCBmYWxsYmFja1RyZWUsIHN1YlRyZWUgfSA9IHZub2RlLnN1c3BlbnNlO1xyXG4gICAgICAgIGlmIChpc1Jlc29sdmVkIHx8IGlzSHlkcmF0aW5nKSB7XHJcbiAgICAgICAgICAgIHZub2RlID0gc3ViVHJlZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZub2RlLnN1c3BlbnNlLmVmZmVjdHMucHVzaCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBzZXRWYXJzT25WTm9kZShzdWJUcmVlLCB2YXJzLCBwcmVmaXgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdm5vZGUgPSBmYWxsYmFja1RyZWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gZHJpbGwgZG93biBIT0NzIHVudGlsIGl0J3MgYSBub24tY29tcG9uZW50IHZub2RlXHJcbiAgICB3aGlsZSAodm5vZGUuY29tcG9uZW50KSB7XHJcbiAgICAgICAgdm5vZGUgPSB2bm9kZS5jb21wb25lbnQuc3ViVHJlZTtcclxuICAgIH1cclxuICAgIGlmICh2bm9kZS5zaGFwZUZsYWcgJiAxIC8qIEVMRU1FTlQgKi8gJiYgdm5vZGUuZWwpIHtcclxuICAgICAgICBjb25zdCBzdHlsZSA9IHZub2RlLmVsLnN0eWxlO1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHZhcnMpIHtcclxuICAgICAgICAgICAgc3R5bGUuc2V0UHJvcGVydHkoYC0tJHtwcmVmaXh9JHtrZXl9YCwgdW5yZWYodmFyc1trZXldKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodm5vZGUudHlwZSA9PT0gRnJhZ21lbnQpIHtcclxuICAgICAgICB2bm9kZS5jaGlsZHJlbi5mb3JFYWNoKGMgPT4gc2V0VmFyc09uVk5vZGUoYywgdmFycywgcHJlZml4KSk7XHJcbiAgICB9XHJcbn1cblxuY29uc3QgVFJBTlNJVElPTiA9ICd0cmFuc2l0aW9uJztcclxuY29uc3QgQU5JTUFUSU9OID0gJ2FuaW1hdGlvbic7XHJcbi8vIERPTSBUcmFuc2l0aW9uIGlzIGEgaGlnaGVyLW9yZGVyLWNvbXBvbmVudCBiYXNlZCBvbiB0aGUgcGxhdGZvcm0tYWdub3N0aWNcclxuLy8gYmFzZSBUcmFuc2l0aW9uIGNvbXBvbmVudCwgd2l0aCBET00tc3BlY2lmaWMgbG9naWMuXHJcbmNvbnN0IFRyYW5zaXRpb24gPSAocHJvcHMsIHsgc2xvdHMgfSkgPT4gaChCYXNlVHJhbnNpdGlvbiwgcmVzb2x2ZVRyYW5zaXRpb25Qcm9wcyhwcm9wcyksIHNsb3RzKTtcclxuVHJhbnNpdGlvbi5kaXNwbGF5TmFtZSA9ICdUcmFuc2l0aW9uJztcclxuY29uc3QgRE9NVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycyA9IHtcclxuICAgIG5hbWU6IFN0cmluZyxcclxuICAgIHR5cGU6IFN0cmluZyxcclxuICAgIGNzczoge1xyXG4gICAgICAgIHR5cGU6IEJvb2xlYW4sXHJcbiAgICAgICAgZGVmYXVsdDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIGR1cmF0aW9uOiBbU3RyaW5nLCBOdW1iZXIsIE9iamVjdF0sXHJcbiAgICBlbnRlckZyb21DbGFzczogU3RyaW5nLFxyXG4gICAgZW50ZXJBY3RpdmVDbGFzczogU3RyaW5nLFxyXG4gICAgZW50ZXJUb0NsYXNzOiBTdHJpbmcsXHJcbiAgICBhcHBlYXJGcm9tQ2xhc3M6IFN0cmluZyxcclxuICAgIGFwcGVhckFjdGl2ZUNsYXNzOiBTdHJpbmcsXHJcbiAgICBhcHBlYXJUb0NsYXNzOiBTdHJpbmcsXHJcbiAgICBsZWF2ZUZyb21DbGFzczogU3RyaW5nLFxyXG4gICAgbGVhdmVBY3RpdmVDbGFzczogU3RyaW5nLFxyXG4gICAgbGVhdmVUb0NsYXNzOiBTdHJpbmdcclxufTtcclxuY29uc3QgVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycyA9IChUcmFuc2l0aW9uLnByb3BzID0gLyojX19QVVJFX18qLyBleHRlbmQoe30sIEJhc2VUcmFuc2l0aW9uLnByb3BzLCBET01UcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzKSk7XHJcbmZ1bmN0aW9uIHJlc29sdmVUcmFuc2l0aW9uUHJvcHMocmF3UHJvcHMpIHtcclxuICAgIGxldCB7IG5hbWUgPSAndicsIHR5cGUsIGNzcyA9IHRydWUsIGR1cmF0aW9uLCBlbnRlckZyb21DbGFzcyA9IGAke25hbWV9LWVudGVyLWZyb21gLCBlbnRlckFjdGl2ZUNsYXNzID0gYCR7bmFtZX0tZW50ZXItYWN0aXZlYCwgZW50ZXJUb0NsYXNzID0gYCR7bmFtZX0tZW50ZXItdG9gLCBhcHBlYXJGcm9tQ2xhc3MgPSBlbnRlckZyb21DbGFzcywgYXBwZWFyQWN0aXZlQ2xhc3MgPSBlbnRlckFjdGl2ZUNsYXNzLCBhcHBlYXJUb0NsYXNzID0gZW50ZXJUb0NsYXNzLCBsZWF2ZUZyb21DbGFzcyA9IGAke25hbWV9LWxlYXZlLWZyb21gLCBsZWF2ZUFjdGl2ZUNsYXNzID0gYCR7bmFtZX0tbGVhdmUtYWN0aXZlYCwgbGVhdmVUb0NsYXNzID0gYCR7bmFtZX0tbGVhdmUtdG9gIH0gPSByYXdQcm9wcztcclxuICAgIGNvbnN0IGJhc2VQcm9wcyA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcmF3UHJvcHMpIHtcclxuICAgICAgICBpZiAoIShrZXkgaW4gRE9NVHJhbnNpdGlvblByb3BzVmFsaWRhdG9ycykpIHtcclxuICAgICAgICAgICAgYmFzZVByb3BzW2tleV0gPSByYXdQcm9wc1trZXldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICghY3NzKSB7XHJcbiAgICAgICAgcmV0dXJuIGJhc2VQcm9wcztcclxuICAgIH1cclxuICAgIGNvbnN0IGR1cmF0aW9ucyA9IG5vcm1hbGl6ZUR1cmF0aW9uKGR1cmF0aW9uKTtcclxuICAgIGNvbnN0IGVudGVyRHVyYXRpb24gPSBkdXJhdGlvbnMgJiYgZHVyYXRpb25zWzBdO1xyXG4gICAgY29uc3QgbGVhdmVEdXJhdGlvbiA9IGR1cmF0aW9ucyAmJiBkdXJhdGlvbnNbMV07XHJcbiAgICBjb25zdCB7IG9uQmVmb3JlRW50ZXIsIG9uRW50ZXIsIG9uRW50ZXJDYW5jZWxsZWQsIG9uTGVhdmUsIG9uTGVhdmVDYW5jZWxsZWQsIG9uQmVmb3JlQXBwZWFyID0gb25CZWZvcmVFbnRlciwgb25BcHBlYXIgPSBvbkVudGVyLCBvbkFwcGVhckNhbmNlbGxlZCA9IG9uRW50ZXJDYW5jZWxsZWQgfSA9IGJhc2VQcm9wcztcclxuICAgIGNvbnN0IGZpbmlzaEVudGVyID0gKGVsLCBpc0FwcGVhciwgZG9uZSkgPT4ge1xyXG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgaXNBcHBlYXIgPyBhcHBlYXJUb0NsYXNzIDogZW50ZXJUb0NsYXNzKTtcclxuICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGlzQXBwZWFyID8gYXBwZWFyQWN0aXZlQ2xhc3MgOiBlbnRlckFjdGl2ZUNsYXNzKTtcclxuICAgICAgICBkb25lICYmIGRvbmUoKTtcclxuICAgIH07XHJcbiAgICBjb25zdCBmaW5pc2hMZWF2ZSA9IChlbCwgZG9uZSkgPT4ge1xyXG4gICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTtcclxuICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlQWN0aXZlQ2xhc3MpO1xyXG4gICAgICAgIGRvbmUgJiYgZG9uZSgpO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IG1ha2VFbnRlckhvb2sgPSAoaXNBcHBlYXIpID0+IHtcclxuICAgICAgICByZXR1cm4gKGVsLCBkb25lKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGhvb2sgPSBpc0FwcGVhciA/IG9uQXBwZWFyIDogb25FbnRlcjtcclxuICAgICAgICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IGZpbmlzaEVudGVyKGVsLCBpc0FwcGVhciwgZG9uZSk7XHJcbiAgICAgICAgICAgIGhvb2sgJiYgaG9vayhlbCwgcmVzb2x2ZSk7XHJcbiAgICAgICAgICAgIG5leHRGcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGlzQXBwZWFyID8gYXBwZWFyRnJvbUNsYXNzIDogZW50ZXJGcm9tQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBpc0FwcGVhciA/IGFwcGVhclRvQ2xhc3MgOiBlbnRlclRvQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCEoaG9vayAmJiBob29rLmxlbmd0aCA+IDEpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVudGVyRHVyYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChyZXNvbHZlLCBlbnRlckR1cmF0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoZW5UcmFuc2l0aW9uRW5kcyhlbCwgdHlwZSwgcmVzb2x2ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBleHRlbmQoYmFzZVByb3BzLCB7XHJcbiAgICAgICAgb25CZWZvcmVFbnRlcihlbCkge1xyXG4gICAgICAgICAgICBvbkJlZm9yZUVudGVyICYmIG9uQmVmb3JlRW50ZXIoZWwpO1xyXG4gICAgICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGVudGVyQWN0aXZlQ2xhc3MpO1xyXG4gICAgICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIGVudGVyRnJvbUNsYXNzKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIG9uQmVmb3JlQXBwZWFyKGVsKSB7XHJcbiAgICAgICAgICAgIG9uQmVmb3JlQXBwZWFyICYmIG9uQmVmb3JlQXBwZWFyKGVsKTtcclxuICAgICAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBhcHBlYXJBY3RpdmVDbGFzcyk7XHJcbiAgICAgICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgYXBwZWFyRnJvbUNsYXNzKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIG9uRW50ZXI6IG1ha2VFbnRlckhvb2soZmFsc2UpLFxyXG4gICAgICAgIG9uQXBwZWFyOiBtYWtlRW50ZXJIb29rKHRydWUpLFxyXG4gICAgICAgIG9uTGVhdmUoZWwsIGRvbmUpIHtcclxuICAgICAgICAgICAgY29uc3QgcmVzb2x2ZSA9ICgpID0+IGZpbmlzaExlYXZlKGVsLCBkb25lKTtcclxuICAgICAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUFjdGl2ZUNsYXNzKTtcclxuICAgICAgICAgICAgYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBsZWF2ZUZyb21DbGFzcyk7XHJcbiAgICAgICAgICAgIG5leHRGcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZW1vdmVUcmFuc2l0aW9uQ2xhc3MoZWwsIGxlYXZlRnJvbUNsYXNzKTtcclxuICAgICAgICAgICAgICAgIGFkZFRyYW5zaXRpb25DbGFzcyhlbCwgbGVhdmVUb0NsYXNzKTtcclxuICAgICAgICAgICAgICAgIGlmICghKG9uTGVhdmUgJiYgb25MZWF2ZS5sZW5ndGggPiAxKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsZWF2ZUR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbGVhdmVEdXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGVuVHJhbnNpdGlvbkVuZHMoZWwsIHR5cGUsIHJlc29sdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIG9uTGVhdmUgJiYgb25MZWF2ZShlbCwgcmVzb2x2ZSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBvbkVudGVyQ2FuY2VsbGVkKGVsKSB7XHJcbiAgICAgICAgICAgIGZpbmlzaEVudGVyKGVsLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIG9uRW50ZXJDYW5jZWxsZWQgJiYgb25FbnRlckNhbmNlbGxlZChlbCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBvbkFwcGVhckNhbmNlbGxlZChlbCkge1xyXG4gICAgICAgICAgICBmaW5pc2hFbnRlcihlbCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIG9uQXBwZWFyQ2FuY2VsbGVkICYmIG9uQXBwZWFyQ2FuY2VsbGVkKGVsKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIG9uTGVhdmVDYW5jZWxsZWQoZWwpIHtcclxuICAgICAgICAgICAgZmluaXNoTGVhdmUoZWwpO1xyXG4gICAgICAgICAgICBvbkxlYXZlQ2FuY2VsbGVkICYmIG9uTGVhdmVDYW5jZWxsZWQoZWwpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG59XHJcbmZ1bmN0aW9uIG5vcm1hbGl6ZUR1cmF0aW9uKGR1cmF0aW9uKSB7XHJcbiAgICBpZiAoZHVyYXRpb24gPT0gbnVsbCkge1xyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoaXNPYmplY3QoZHVyYXRpb24pKSB7XHJcbiAgICAgICAgcmV0dXJuIFtOdW1iZXJPZihkdXJhdGlvbi5lbnRlciksIE51bWJlck9mKGR1cmF0aW9uLmxlYXZlKV07XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBjb25zdCBuID0gTnVtYmVyT2YoZHVyYXRpb24pO1xyXG4gICAgICAgIHJldHVybiBbbiwgbl07XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gTnVtYmVyT2YodmFsKSB7XHJcbiAgICBjb25zdCByZXMgPSB0b051bWJlcih2YWwpO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSlcclxuICAgICAgICB2YWxpZGF0ZUR1cmF0aW9uKHJlcyk7XHJcbiAgICByZXR1cm4gcmVzO1xyXG59XHJcbmZ1bmN0aW9uIHZhbGlkYXRlRHVyYXRpb24odmFsKSB7XHJcbiAgICBpZiAodHlwZW9mIHZhbCAhPT0gJ251bWJlcicpIHtcclxuICAgICAgICB3YXJuKGA8dHJhbnNpdGlvbj4gZXhwbGljaXQgZHVyYXRpb24gaXMgbm90IGEgdmFsaWQgbnVtYmVyIC0gYCArXHJcbiAgICAgICAgICAgIGBnb3QgJHtKU09OLnN0cmluZ2lmeSh2YWwpfS5gKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGlzTmFOKHZhbCkpIHtcclxuICAgICAgICB3YXJuKGA8dHJhbnNpdGlvbj4gZXhwbGljaXQgZHVyYXRpb24gaXMgTmFOIC0gYCArXHJcbiAgICAgICAgICAgICd0aGUgZHVyYXRpb24gZXhwcmVzc2lvbiBtaWdodCBiZSBpbmNvcnJlY3QuJyk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gYWRkVHJhbnNpdGlvbkNsYXNzKGVsLCBjbHMpIHtcclxuICAgIGNscy5zcGxpdCgvXFxzKy8pLmZvckVhY2goYyA9PiBjICYmIGVsLmNsYXNzTGlzdC5hZGQoYykpO1xyXG4gICAgKGVsLl92dGMgfHxcclxuICAgICAgICAoZWwuX3Z0YyA9IG5ldyBTZXQoKSkpLmFkZChjbHMpO1xyXG59XHJcbmZ1bmN0aW9uIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgY2xzKSB7XHJcbiAgICBjbHMuc3BsaXQoL1xccysvKS5mb3JFYWNoKGMgPT4gYyAmJiBlbC5jbGFzc0xpc3QucmVtb3ZlKGMpKTtcclxuICAgIGNvbnN0IHsgX3Z0YyB9ID0gZWw7XHJcbiAgICBpZiAoX3Z0Yykge1xyXG4gICAgICAgIF92dGMuZGVsZXRlKGNscyk7XHJcbiAgICAgICAgaWYgKCFfdnRjLnNpemUpIHtcclxuICAgICAgICAgICAgZWwuX3Z0YyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gbmV4dEZyYW1lKGNiKSB7XHJcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShjYik7XHJcbiAgICB9KTtcclxufVxyXG5mdW5jdGlvbiB3aGVuVHJhbnNpdGlvbkVuZHMoZWwsIGV4cGVjdGVkVHlwZSwgY2IpIHtcclxuICAgIGNvbnN0IHsgdHlwZSwgdGltZW91dCwgcHJvcENvdW50IH0gPSBnZXRUcmFuc2l0aW9uSW5mbyhlbCwgZXhwZWN0ZWRUeXBlKTtcclxuICAgIGlmICghdHlwZSkge1xyXG4gICAgICAgIHJldHVybiBjYigpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgZW5kRXZlbnQgPSB0eXBlICsgJ2VuZCc7XHJcbiAgICBsZXQgZW5kZWQgPSAwO1xyXG4gICAgY29uc3QgZW5kID0gKCkgPT4ge1xyXG4gICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZW5kRXZlbnQsIG9uRW5kKTtcclxuICAgICAgICBjYigpO1xyXG4gICAgfTtcclxuICAgIGNvbnN0IG9uRW5kID0gKGUpID0+IHtcclxuICAgICAgICBpZiAoZS50YXJnZXQgPT09IGVsKSB7XHJcbiAgICAgICAgICAgIGlmICgrK2VuZGVkID49IHByb3BDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgZW5kKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgaWYgKGVuZGVkIDwgcHJvcENvdW50KSB7XHJcbiAgICAgICAgICAgIGVuZCgpO1xyXG4gICAgICAgIH1cclxuICAgIH0sIHRpbWVvdXQgKyAxKTtcclxuICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZW5kRXZlbnQsIG9uRW5kKTtcclxufVxyXG5mdW5jdGlvbiBnZXRUcmFuc2l0aW9uSW5mbyhlbCwgZXhwZWN0ZWRUeXBlKSB7XHJcbiAgICBjb25zdCBzdHlsZXMgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCk7XHJcbiAgICAvLyBKU0RPTSBtYXkgcmV0dXJuIHVuZGVmaW5lZCBmb3IgdHJhbnNpdGlvbiBwcm9wZXJ0aWVzXHJcbiAgICBjb25zdCBnZXRTdHlsZVByb3BlcnRpZXMgPSAoa2V5KSA9PiAoc3R5bGVzW2tleV0gfHwgJycpLnNwbGl0KCcsICcpO1xyXG4gICAgY29uc3QgdHJhbnNpdGlvbkRlbGF5cyA9IGdldFN0eWxlUHJvcGVydGllcyhUUkFOU0lUSU9OICsgJ0RlbGF5Jyk7XHJcbiAgICBjb25zdCB0cmFuc2l0aW9uRHVyYXRpb25zID0gZ2V0U3R5bGVQcm9wZXJ0aWVzKFRSQU5TSVRJT04gKyAnRHVyYXRpb24nKTtcclxuICAgIGNvbnN0IHRyYW5zaXRpb25UaW1lb3V0ID0gZ2V0VGltZW91dCh0cmFuc2l0aW9uRGVsYXlzLCB0cmFuc2l0aW9uRHVyYXRpb25zKTtcclxuICAgIGNvbnN0IGFuaW1hdGlvbkRlbGF5cyA9IGdldFN0eWxlUHJvcGVydGllcyhBTklNQVRJT04gKyAnRGVsYXknKTtcclxuICAgIGNvbnN0IGFuaW1hdGlvbkR1cmF0aW9ucyA9IGdldFN0eWxlUHJvcGVydGllcyhBTklNQVRJT04gKyAnRHVyYXRpb24nKTtcclxuICAgIGNvbnN0IGFuaW1hdGlvblRpbWVvdXQgPSBnZXRUaW1lb3V0KGFuaW1hdGlvbkRlbGF5cywgYW5pbWF0aW9uRHVyYXRpb25zKTtcclxuICAgIGxldCB0eXBlID0gbnVsbDtcclxuICAgIGxldCB0aW1lb3V0ID0gMDtcclxuICAgIGxldCBwcm9wQ291bnQgPSAwO1xyXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXHJcbiAgICBpZiAoZXhwZWN0ZWRUeXBlID09PSBUUkFOU0lUSU9OKSB7XHJcbiAgICAgICAgaWYgKHRyYW5zaXRpb25UaW1lb3V0ID4gMCkge1xyXG4gICAgICAgICAgICB0eXBlID0gVFJBTlNJVElPTjtcclxuICAgICAgICAgICAgdGltZW91dCA9IHRyYW5zaXRpb25UaW1lb3V0O1xyXG4gICAgICAgICAgICBwcm9wQ291bnQgPSB0cmFuc2l0aW9uRHVyYXRpb25zLmxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChleHBlY3RlZFR5cGUgPT09IEFOSU1BVElPTikge1xyXG4gICAgICAgIGlmIChhbmltYXRpb25UaW1lb3V0ID4gMCkge1xyXG4gICAgICAgICAgICB0eXBlID0gQU5JTUFUSU9OO1xyXG4gICAgICAgICAgICB0aW1lb3V0ID0gYW5pbWF0aW9uVGltZW91dDtcclxuICAgICAgICAgICAgcHJvcENvdW50ID0gYW5pbWF0aW9uRHVyYXRpb25zLmxlbmd0aDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICB0aW1lb3V0ID0gTWF0aC5tYXgodHJhbnNpdGlvblRpbWVvdXQsIGFuaW1hdGlvblRpbWVvdXQpO1xyXG4gICAgICAgIHR5cGUgPVxyXG4gICAgICAgICAgICB0aW1lb3V0ID4gMFxyXG4gICAgICAgICAgICAgICAgPyB0cmFuc2l0aW9uVGltZW91dCA+IGFuaW1hdGlvblRpbWVvdXRcclxuICAgICAgICAgICAgICAgICAgICA/IFRSQU5TSVRJT05cclxuICAgICAgICAgICAgICAgICAgICA6IEFOSU1BVElPTlxyXG4gICAgICAgICAgICAgICAgOiBudWxsO1xyXG4gICAgICAgIHByb3BDb3VudCA9IHR5cGVcclxuICAgICAgICAgICAgPyB0eXBlID09PSBUUkFOU0lUSU9OXHJcbiAgICAgICAgICAgICAgICA/IHRyYW5zaXRpb25EdXJhdGlvbnMubGVuZ3RoXHJcbiAgICAgICAgICAgICAgICA6IGFuaW1hdGlvbkR1cmF0aW9ucy5sZW5ndGhcclxuICAgICAgICAgICAgOiAwO1xyXG4gICAgfVxyXG4gICAgY29uc3QgaGFzVHJhbnNmb3JtID0gdHlwZSA9PT0gVFJBTlNJVElPTiAmJlxyXG4gICAgICAgIC9cXGIodHJhbnNmb3JtfGFsbCkoLHwkKS8udGVzdChzdHlsZXNbVFJBTlNJVElPTiArICdQcm9wZXJ0eSddKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgdHlwZSxcclxuICAgICAgICB0aW1lb3V0LFxyXG4gICAgICAgIHByb3BDb3VudCxcclxuICAgICAgICBoYXNUcmFuc2Zvcm1cclxuICAgIH07XHJcbn1cclxuZnVuY3Rpb24gZ2V0VGltZW91dChkZWxheXMsIGR1cmF0aW9ucykge1xyXG4gICAgd2hpbGUgKGRlbGF5cy5sZW5ndGggPCBkdXJhdGlvbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgZGVsYXlzID0gZGVsYXlzLmNvbmNhdChkZWxheXMpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIE1hdGgubWF4KC4uLmR1cmF0aW9ucy5tYXAoKGQsIGkpID0+IHRvTXMoZCkgKyB0b01zKGRlbGF5c1tpXSkpKTtcclxufVxyXG4vLyBPbGQgdmVyc2lvbnMgb2YgQ2hyb21pdW0gKGJlbG93IDYxLjAuMzE2My4xMDApIGZvcm1hdHMgZmxvYXRpbmcgcG9pbnRlclxyXG4vLyBudW1iZXJzIGluIGEgbG9jYWxlLWRlcGVuZGVudCB3YXksIHVzaW5nIGEgY29tbWEgaW5zdGVhZCBvZiBhIGRvdC5cclxuLy8gSWYgY29tbWEgaXMgbm90IHJlcGxhY2VkIHdpdGggYSBkb3QsIHRoZSBpbnB1dCB3aWxsIGJlIHJvdW5kZWQgZG93blxyXG4vLyAoaS5lLiBhY3RpbmcgYXMgYSBmbG9vciBmdW5jdGlvbikgY2F1c2luZyB1bmV4cGVjdGVkIGJlaGF2aW9yc1xyXG5mdW5jdGlvbiB0b01zKHMpIHtcclxuICAgIHJldHVybiBOdW1iZXIocy5zbGljZSgwLCAtMSkucmVwbGFjZSgnLCcsICcuJykpICogMTAwMDtcclxufVxuXG5mdW5jdGlvbiB0b1JhdyhvYnNlcnZlZCkge1xyXG4gICAgcmV0dXJuICgob2JzZXJ2ZWQgJiYgdG9SYXcob2JzZXJ2ZWRbXCJfX3ZfcmF3XCIgLyogUkFXICovXSkpIHx8IG9ic2VydmVkKTtcclxufVxuXG5jb25zdCBwb3NpdGlvbk1hcCA9IG5ldyBXZWFrTWFwKCk7XHJcbmNvbnN0IG5ld1Bvc2l0aW9uTWFwID0gbmV3IFdlYWtNYXAoKTtcclxuY29uc3QgVHJhbnNpdGlvbkdyb3VwSW1wbCA9IHtcclxuICAgIG5hbWU6ICdUcmFuc2l0aW9uR3JvdXAnLFxyXG4gICAgcHJvcHM6IC8qI19fUFVSRV9fKi8gZXh0ZW5kKHt9LCBUcmFuc2l0aW9uUHJvcHNWYWxpZGF0b3JzLCB7XHJcbiAgICAgICAgdGFnOiBTdHJpbmcsXHJcbiAgICAgICAgbW92ZUNsYXNzOiBTdHJpbmdcclxuICAgIH0pLFxyXG4gICAgc2V0dXAocHJvcHMsIHsgc2xvdHMgfSkge1xyXG4gICAgICAgIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKCk7XHJcbiAgICAgICAgY29uc3Qgc3RhdGUgPSB1c2VUcmFuc2l0aW9uU3RhdGUoKTtcclxuICAgICAgICBsZXQgcHJldkNoaWxkcmVuO1xyXG4gICAgICAgIGxldCBjaGlsZHJlbjtcclxuICAgICAgICBvblVwZGF0ZWQoKCkgPT4ge1xyXG4gICAgICAgICAgICAvLyBjaGlsZHJlbiBpcyBndWFyYW50ZWVkIHRvIGV4aXN0IGFmdGVyIGluaXRpYWwgcmVuZGVyXHJcbiAgICAgICAgICAgIGlmICghcHJldkNoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IG1vdmVDbGFzcyA9IHByb3BzLm1vdmVDbGFzcyB8fCBgJHtwcm9wcy5uYW1lIHx8ICd2J30tbW92ZWA7XHJcbiAgICAgICAgICAgIGlmICghaGFzQ1NTVHJhbnNmb3JtKHByZXZDaGlsZHJlblswXS5lbCwgaW5zdGFuY2Uudm5vZGUuZWwsIG1vdmVDbGFzcykpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyB3ZSBkaXZpZGUgdGhlIHdvcmsgaW50byB0aHJlZSBsb29wcyB0byBhdm9pZCBtaXhpbmcgRE9NIHJlYWRzIGFuZCB3cml0ZXNcclxuICAgICAgICAgICAgLy8gaW4gZWFjaCBpdGVyYXRpb24gLSB3aGljaCBoZWxwcyBwcmV2ZW50IGxheW91dCB0aHJhc2hpbmcuXHJcbiAgICAgICAgICAgIHByZXZDaGlsZHJlbi5mb3JFYWNoKGNhbGxQZW5kaW5nQ2JzKTtcclxuICAgICAgICAgICAgcHJldkNoaWxkcmVuLmZvckVhY2gocmVjb3JkUG9zaXRpb24pO1xyXG4gICAgICAgICAgICBjb25zdCBtb3ZlZENoaWxkcmVuID0gcHJldkNoaWxkcmVuLmZpbHRlcihhcHBseVRyYW5zbGF0aW9uKTtcclxuICAgICAgICAgICAgLy8gZm9yY2UgcmVmbG93IHRvIHB1dCBldmVyeXRoaW5nIGluIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIGZvcmNlUmVmbG93KCk7XHJcbiAgICAgICAgICAgIG1vdmVkQ2hpbGRyZW4uZm9yRWFjaChjID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVsID0gYy5lbDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0eWxlID0gZWwuc3R5bGU7XHJcbiAgICAgICAgICAgICAgICBhZGRUcmFuc2l0aW9uQ2xhc3MoZWwsIG1vdmVDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICBzdHlsZS50cmFuc2Zvcm0gPSBzdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSBzdHlsZS50cmFuc2l0aW9uRHVyYXRpb24gPSAnJztcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNiID0gKGVsLl9tb3ZlQ2IgPSAoZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlICYmIGUudGFyZ2V0ICE9PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZSB8fCAvdHJhbnNmb3JtJC8udGVzdChlLnByb3BlcnR5TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGNiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwuX21vdmVDYiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVRyYW5zaXRpb25DbGFzcyhlbCwgbW92ZUNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBjYik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhd1Byb3BzID0gdG9SYXcocHJvcHMpO1xyXG4gICAgICAgICAgICBjb25zdCBjc3NUcmFuc2l0aW9uUHJvcHMgPSByZXNvbHZlVHJhbnNpdGlvblByb3BzKHJhd1Byb3BzKTtcclxuICAgICAgICAgICAgY29uc3QgdGFnID0gcmF3UHJvcHMudGFnIHx8IEZyYWdtZW50O1xyXG4gICAgICAgICAgICBwcmV2Q2hpbGRyZW4gPSBjaGlsZHJlbjtcclxuICAgICAgICAgICAgY2hpbGRyZW4gPSBzbG90cy5kZWZhdWx0ID8gZ2V0VHJhbnNpdGlvblJhd0NoaWxkcmVuKHNsb3RzLmRlZmF1bHQoKSkgOiBbXTtcclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2hpbGQgPSBjaGlsZHJlbltpXTtcclxuICAgICAgICAgICAgICAgIGlmIChjaGlsZC5rZXkgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNldFRyYW5zaXRpb25Ib29rcyhjaGlsZCwgcmVzb2x2ZVRyYW5zaXRpb25Ib29rcyhjaGlsZCwgY3NzVHJhbnNpdGlvblByb3BzLCBzdGF0ZSwgaW5zdGFuY2UpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdhcm4oYDxUcmFuc2l0aW9uR3JvdXA+IGNoaWxkcmVuIG11c3QgYmUga2V5ZWQuYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHByZXZDaGlsZHJlbikge1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmV2Q2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGlsZCA9IHByZXZDaGlsZHJlbltpXTtcclxuICAgICAgICAgICAgICAgICAgICBzZXRUcmFuc2l0aW9uSG9va3MoY2hpbGQsIHJlc29sdmVUcmFuc2l0aW9uSG9va3MoY2hpbGQsIGNzc1RyYW5zaXRpb25Qcm9wcywgc3RhdGUsIGluc3RhbmNlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25NYXAuc2V0KGNoaWxkLCBjaGlsZC5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVZOb2RlKHRhZywgbnVsbCwgY2hpbGRyZW4pO1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn07XHJcbmNvbnN0IFRyYW5zaXRpb25Hcm91cCA9IFRyYW5zaXRpb25Hcm91cEltcGw7XHJcbmZ1bmN0aW9uIGNhbGxQZW5kaW5nQ2JzKGMpIHtcclxuICAgIGNvbnN0IGVsID0gYy5lbDtcclxuICAgIGlmIChlbC5fbW92ZUNiKSB7XHJcbiAgICAgICAgZWwuX21vdmVDYigpO1xyXG4gICAgfVxyXG4gICAgaWYgKGVsLl9lbnRlckNiKSB7XHJcbiAgICAgICAgZWwuX2VudGVyQ2IoKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiByZWNvcmRQb3NpdGlvbihjKSB7XHJcbiAgICBuZXdQb3NpdGlvbk1hcC5zZXQoYywgYy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSk7XHJcbn1cclxuZnVuY3Rpb24gYXBwbHlUcmFuc2xhdGlvbihjKSB7XHJcbiAgICBjb25zdCBvbGRQb3MgPSBwb3NpdGlvbk1hcC5nZXQoYyk7XHJcbiAgICBjb25zdCBuZXdQb3MgPSBuZXdQb3NpdGlvbk1hcC5nZXQoYyk7XHJcbiAgICBjb25zdCBkeCA9IG9sZFBvcy5sZWZ0IC0gbmV3UG9zLmxlZnQ7XHJcbiAgICBjb25zdCBkeSA9IG9sZFBvcy50b3AgLSBuZXdQb3MudG9wO1xyXG4gICAgaWYgKGR4IHx8IGR5KSB7XHJcbiAgICAgICAgY29uc3QgcyA9IGMuZWwuc3R5bGU7XHJcbiAgICAgICAgcy50cmFuc2Zvcm0gPSBzLndlYmtpdFRyYW5zZm9ybSA9IGB0cmFuc2xhdGUoJHtkeH1weCwke2R5fXB4KWA7XHJcbiAgICAgICAgcy50cmFuc2l0aW9uRHVyYXRpb24gPSAnMHMnO1xyXG4gICAgICAgIHJldHVybiBjO1xyXG4gICAgfVxyXG59XHJcbi8vIHRoaXMgaXMgcHV0IGluIGEgZGVkaWNhdGVkIGZ1bmN0aW9uIHRvIGF2b2lkIHRoZSBsaW5lIGZyb20gYmVpbmcgdHJlZXNoYWtlblxyXG5mdW5jdGlvbiBmb3JjZVJlZmxvdygpIHtcclxuICAgIHJldHVybiBkb2N1bWVudC5ib2R5Lm9mZnNldEhlaWdodDtcclxufVxyXG5mdW5jdGlvbiBoYXNDU1NUcmFuc2Zvcm0oZWwsIHJvb3QsIG1vdmVDbGFzcykge1xyXG4gICAgLy8gRGV0ZWN0IHdoZXRoZXIgYW4gZWxlbWVudCB3aXRoIHRoZSBtb3ZlIGNsYXNzIGFwcGxpZWQgaGFzXHJcbiAgICAvLyBDU1MgdHJhbnNpdGlvbnMuIFNpbmNlIHRoZSBlbGVtZW50IG1heSBiZSBpbnNpZGUgYW4gZW50ZXJpbmdcclxuICAgIC8vIHRyYW5zaXRpb24gYXQgdGhpcyB2ZXJ5IG1vbWVudCwgd2UgbWFrZSBhIGNsb25lIG9mIGl0IGFuZCByZW1vdmVcclxuICAgIC8vIGFsbCBvdGhlciB0cmFuc2l0aW9uIGNsYXNzZXMgYXBwbGllZCB0byBlbnN1cmUgb25seSB0aGUgbW92ZSBjbGFzc1xyXG4gICAgLy8gaXMgYXBwbGllZC5cclxuICAgIGNvbnN0IGNsb25lID0gZWwuY2xvbmVOb2RlKCk7XHJcbiAgICBpZiAoZWwuX3Z0Yykge1xyXG4gICAgICAgIGVsLl92dGMuZm9yRWFjaChjbHMgPT4ge1xyXG4gICAgICAgICAgICBjbHMuc3BsaXQoL1xccysvKS5mb3JFYWNoKGMgPT4gYyAmJiBjbG9uZS5jbGFzc0xpc3QucmVtb3ZlKGMpKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIG1vdmVDbGFzcy5zcGxpdCgvXFxzKy8pLmZvckVhY2goYyA9PiBjICYmIGNsb25lLmNsYXNzTGlzdC5hZGQoYykpO1xyXG4gICAgY2xvbmUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgIGNvbnN0IGNvbnRhaW5lciA9IChyb290Lm5vZGVUeXBlID09PSAxXHJcbiAgICAgICAgPyByb290XHJcbiAgICAgICAgOiByb290LnBhcmVudE5vZGUpO1xyXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNsb25lKTtcclxuICAgIGNvbnN0IHsgaGFzVHJhbnNmb3JtIH0gPSBnZXRUcmFuc2l0aW9uSW5mbyhjbG9uZSk7XHJcbiAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoY2xvbmUpO1xyXG4gICAgcmV0dXJuIGhhc1RyYW5zZm9ybTtcclxufVxuXG5jb25zdCBnZXRNb2RlbEFzc2lnbmVyID0gKHZub2RlKSA9PiB7XHJcbiAgICBjb25zdCBmbiA9IHZub2RlLnByb3BzWydvblVwZGF0ZTptb2RlbFZhbHVlJ107XHJcbiAgICByZXR1cm4gaXNBcnJheShmbikgPyB2YWx1ZSA9PiBpbnZva2VBcnJheUZucyhmbiwgdmFsdWUpIDogZm47XHJcbn07XHJcbmZ1bmN0aW9uIG9uQ29tcG9zaXRpb25TdGFydChlKSB7XHJcbiAgICBlLnRhcmdldC5jb21wb3NpbmcgPSB0cnVlO1xyXG59XHJcbmZ1bmN0aW9uIG9uQ29tcG9zaXRpb25FbmQoZSkge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQ7XHJcbiAgICBpZiAodGFyZ2V0LmNvbXBvc2luZykge1xyXG4gICAgICAgIHRhcmdldC5jb21wb3NpbmcgPSBmYWxzZTtcclxuICAgICAgICB0cmlnZ2VyKHRhcmdldCwgJ2lucHV0Jyk7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gdHJpZ2dlcihlbCwgdHlwZSkge1xyXG4gICAgY29uc3QgZSA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7XHJcbiAgICBlLmluaXRFdmVudCh0eXBlLCB0cnVlLCB0cnVlKTtcclxuICAgIGVsLmRpc3BhdGNoRXZlbnQoZSk7XHJcbn1cclxuLy8gV2UgYXJlIGV4cG9ydGluZyB0aGUgdi1tb2RlbCBydW50aW1lIGRpcmVjdGx5IGFzIHZub2RlIGhvb2tzIHNvIHRoYXQgaXQgY2FuXHJcbi8vIGJlIHRyZWUtc2hha2VuIGluIGNhc2Ugdi1tb2RlbCBpcyBuZXZlciB1c2VkLlxyXG5jb25zdCB2TW9kZWxUZXh0ID0ge1xyXG4gICAgY3JlYXRlZChlbCwgeyB2YWx1ZSwgbW9kaWZpZXJzOiB7IGxhenksIHRyaW0sIG51bWJlciB9IH0sIHZub2RlKSB7XHJcbiAgICAgICAgZWwudmFsdWUgPSB2YWx1ZSA9PSBudWxsID8gJycgOiB2YWx1ZTtcclxuICAgICAgICBlbC5fYXNzaWduID0gZ2V0TW9kZWxBc3NpZ25lcih2bm9kZSk7XHJcbiAgICAgICAgY29uc3QgY2FzdFRvTnVtYmVyID0gbnVtYmVyIHx8IGVsLnR5cGUgPT09ICdudW1iZXInO1xyXG4gICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsIGxhenkgPyAnY2hhbmdlJyA6ICdpbnB1dCcsIGUgPT4ge1xyXG4gICAgICAgICAgICBpZiAoZS50YXJnZXQuY29tcG9zaW5nKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICBsZXQgZG9tVmFsdWUgPSBlbC52YWx1ZTtcclxuICAgICAgICAgICAgaWYgKHRyaW0pIHtcclxuICAgICAgICAgICAgICAgIGRvbVZhbHVlID0gZG9tVmFsdWUudHJpbSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGNhc3RUb051bWJlcikge1xyXG4gICAgICAgICAgICAgICAgZG9tVmFsdWUgPSB0b051bWJlcihkb21WYWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWwuX2Fzc2lnbihkb21WYWx1ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHRyaW0pIHtcclxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgJ2NoYW5nZScsICgpID0+IHtcclxuICAgICAgICAgICAgICAgIGVsLnZhbHVlID0gZWwudmFsdWUudHJpbSgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFsYXp5KSB7XHJcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICdjb21wb3NpdGlvbnN0YXJ0Jywgb25Db21wb3NpdGlvblN0YXJ0KTtcclxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcihlbCwgJ2NvbXBvc2l0aW9uZW5kJywgb25Db21wb3NpdGlvbkVuZCk7XHJcbiAgICAgICAgICAgIC8vIFNhZmFyaSA8IDEwLjIgJiBVSVdlYlZpZXcgZG9lc24ndCBmaXJlIGNvbXBvc2l0aW9uZW5kIHdoZW5cclxuICAgICAgICAgICAgLy8gc3dpdGNoaW5nIGZvY3VzIGJlZm9yZSBjb25maXJtaW5nIGNvbXBvc2l0aW9uIGNob2ljZVxyXG4gICAgICAgICAgICAvLyB0aGlzIGFsc28gZml4ZXMgdGhlIGlzc3VlIHdoZXJlIHNvbWUgYnJvd3NlcnMgZS5nLiBpT1MgQ2hyb21lXHJcbiAgICAgICAgICAgIC8vIGZpcmVzIFwiY2hhbmdlXCIgaW5zdGVhZCBvZiBcImlucHV0XCIgb24gYXV0b2NvbXBsZXRlLlxyXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAnY2hhbmdlJywgb25Db21wb3NpdGlvbkVuZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIGJlZm9yZVVwZGF0ZShlbCwgeyB2YWx1ZSwgbW9kaWZpZXJzOiB7IHRyaW0sIG51bWJlciB9IH0sIHZub2RlKSB7XHJcbiAgICAgICAgZWwuX2Fzc2lnbiA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpO1xyXG4gICAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBlbCkge1xyXG4gICAgICAgICAgICBpZiAodHJpbSAmJiBlbC52YWx1ZS50cmltKCkgPT09IHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKChudW1iZXIgfHwgZWwudHlwZSA9PT0gJ251bWJlcicpICYmIHRvTnVtYmVyKGVsLnZhbHVlKSA9PT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHZhbHVlID09IG51bGwgPyAnJyA6IHZhbHVlO1xyXG4gICAgICAgIGlmIChlbC52YWx1ZSAhPT0gbmV3VmFsdWUpIHtcclxuICAgICAgICAgICAgZWwudmFsdWUgPSBuZXdWYWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn07XHJcbmNvbnN0IHZNb2RlbENoZWNrYm94ID0ge1xyXG4gICAgY3JlYXRlZChlbCwgYmluZGluZywgdm5vZGUpIHtcclxuICAgICAgICBzZXRDaGVja2VkKGVsLCBiaW5kaW5nLCB2bm9kZSk7XHJcbiAgICAgICAgZWwuX2Fzc2lnbiA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpO1xyXG4gICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICdjaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1vZGVsVmFsdWUgPSBlbC5fbW9kZWxWYWx1ZTtcclxuICAgICAgICAgICAgY29uc3QgZWxlbWVudFZhbHVlID0gZ2V0VmFsdWUoZWwpO1xyXG4gICAgICAgICAgICBjb25zdCBjaGVja2VkID0gZWwuY2hlY2tlZDtcclxuICAgICAgICAgICAgY29uc3QgYXNzaWduID0gZWwuX2Fzc2lnbjtcclxuICAgICAgICAgICAgaWYgKGlzQXJyYXkobW9kZWxWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbG9vc2VJbmRleE9mKG1vZGVsVmFsdWUsIGVsZW1lbnRWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBmb3VuZCA9IGluZGV4ICE9PSAtMTtcclxuICAgICAgICAgICAgICAgIGlmIChjaGVja2VkICYmICFmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFzc2lnbihtb2RlbFZhbHVlLmNvbmNhdChlbGVtZW50VmFsdWUpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFjaGVja2VkICYmIGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBbLi4ubW9kZWxWYWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWQuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICBhc3NpZ24oZmlsdGVyZWQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYXNzaWduKGdldENoZWNrYm94VmFsdWUoZWwsIGNoZWNrZWQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfSxcclxuICAgIGJlZm9yZVVwZGF0ZShlbCwgYmluZGluZywgdm5vZGUpIHtcclxuICAgICAgICBlbC5fYXNzaWduID0gZ2V0TW9kZWxBc3NpZ25lcih2bm9kZSk7XHJcbiAgICAgICAgc2V0Q2hlY2tlZChlbCwgYmluZGluZywgdm5vZGUpO1xyXG4gICAgfVxyXG59O1xyXG5mdW5jdGlvbiBzZXRDaGVja2VkKGVsLCB7IHZhbHVlLCBvbGRWYWx1ZSB9LCB2bm9kZSkge1xyXG4gICAgZWwuX21vZGVsVmFsdWUgPSB2YWx1ZTtcclxuICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xyXG4gICAgICAgIGVsLmNoZWNrZWQgPSBsb29zZUluZGV4T2YodmFsdWUsIHZub2RlLnByb3BzLnZhbHVlKSA+IC0xO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodmFsdWUgIT09IG9sZFZhbHVlKSB7XHJcbiAgICAgICAgZWwuY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIGdldENoZWNrYm94VmFsdWUoZWwsIHRydWUpKTtcclxuICAgIH1cclxufVxyXG5jb25zdCB2TW9kZWxSYWRpbyA9IHtcclxuICAgIGNyZWF0ZWQoZWwsIHsgdmFsdWUgfSwgdm5vZGUpIHtcclxuICAgICAgICBlbC5jaGVja2VkID0gbG9vc2VFcXVhbCh2YWx1ZSwgdm5vZGUucHJvcHMudmFsdWUpO1xyXG4gICAgICAgIGVsLl9hc3NpZ24gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTtcclxuICAgICAgICBhZGRFdmVudExpc3RlbmVyKGVsLCAnY2hhbmdlJywgKCkgPT4ge1xyXG4gICAgICAgICAgICBlbC5fYXNzaWduKGdldFZhbHVlKGVsKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9LFxyXG4gICAgYmVmb3JlVXBkYXRlKGVsLCB7IHZhbHVlLCBvbGRWYWx1ZSB9LCB2bm9kZSkge1xyXG4gICAgICAgIGVsLl9hc3NpZ24gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTtcclxuICAgICAgICBpZiAodmFsdWUgIT09IG9sZFZhbHVlKSB7XHJcbiAgICAgICAgICAgIGVsLmNoZWNrZWQgPSBsb29zZUVxdWFsKHZhbHVlLCB2bm9kZS5wcm9wcy52YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59O1xyXG5jb25zdCB2TW9kZWxTZWxlY3QgPSB7XHJcbiAgICBjcmVhdGVkKGVsLCBiaW5kaW5nLCB2bm9kZSkge1xyXG4gICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoZWwsICdjaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkVmFsID0gQXJyYXkucHJvdG90eXBlLmZpbHRlclxyXG4gICAgICAgICAgICAgICAgLmNhbGwoZWwub3B0aW9ucywgKG8pID0+IG8uc2VsZWN0ZWQpXHJcbiAgICAgICAgICAgICAgICAubWFwKGdldFZhbHVlKTtcclxuICAgICAgICAgICAgZWwuX2Fzc2lnbihlbC5tdWx0aXBsZSA/IHNlbGVjdGVkVmFsIDogc2VsZWN0ZWRWYWxbMF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGVsLl9hc3NpZ24gPSBnZXRNb2RlbEFzc2lnbmVyKHZub2RlKTtcclxuICAgIH0sXHJcbiAgICAvLyBzZXQgdmFsdWUgaW4gbW91bnRlZCAmIHVwZGF0ZWQgYmVjYXVzZSA8c2VsZWN0PiByZWxpZXMgb24gaXRzIGNoaWxkcmVuXHJcbiAgICAvLyA8b3B0aW9uPnMuXHJcbiAgICBtb3VudGVkKGVsLCB7IHZhbHVlIH0pIHtcclxuICAgICAgICBzZXRTZWxlY3RlZChlbCwgdmFsdWUpO1xyXG4gICAgfSxcclxuICAgIGJlZm9yZVVwZGF0ZShlbCwgX2JpbmRpbmcsIHZub2RlKSB7XHJcbiAgICAgICAgZWwuX2Fzc2lnbiA9IGdldE1vZGVsQXNzaWduZXIodm5vZGUpO1xyXG4gICAgfSxcclxuICAgIHVwZGF0ZWQoZWwsIHsgdmFsdWUgfSkge1xyXG4gICAgICAgIHNldFNlbGVjdGVkKGVsLCB2YWx1ZSk7XHJcbiAgICB9XHJcbn07XHJcbmZ1bmN0aW9uIHNldFNlbGVjdGVkKGVsLCB2YWx1ZSkge1xyXG4gICAgY29uc3QgaXNNdWx0aXBsZSA9IGVsLm11bHRpcGxlO1xyXG4gICAgaWYgKGlzTXVsdGlwbGUgJiYgIWlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgICAgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpICYmXHJcbiAgICAgICAgICAgIHdhcm4oYDxzZWxlY3QgbXVsdGlwbGUgdi1tb2RlbD4gZXhwZWN0cyBhbiBBcnJheSB2YWx1ZSBmb3IgaXRzIGJpbmRpbmcsIGAgK1xyXG4gICAgICAgICAgICAgICAgYGJ1dCBnb3QgJHtPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLnNsaWNlKDgsIC0xKX0uYCk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBlbC5vcHRpb25zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IGVsLm9wdGlvbnNbaV07XHJcbiAgICAgICAgY29uc3Qgb3B0aW9uVmFsdWUgPSBnZXRWYWx1ZShvcHRpb24pO1xyXG4gICAgICAgIGlmIChpc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IGxvb3NlSW5kZXhPZih2YWx1ZSwgb3B0aW9uVmFsdWUpID4gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAobG9vc2VFcXVhbChnZXRWYWx1ZShvcHRpb24pLCB2YWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGVsLnNlbGVjdGVkSW5kZXggPSBpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKCFpc011bHRpcGxlKSB7XHJcbiAgICAgICAgZWwuc2VsZWN0ZWRJbmRleCA9IC0xO1xyXG4gICAgfVxyXG59XHJcbi8vIHJldHJpZXZlIHJhdyB2YWx1ZSBzZXQgdmlhIDp2YWx1ZSBiaW5kaW5nc1xyXG5mdW5jdGlvbiBnZXRWYWx1ZShlbCkge1xyXG4gICAgcmV0dXJuICdfdmFsdWUnIGluIGVsID8gZWwuX3ZhbHVlIDogZWwudmFsdWU7XHJcbn1cclxuLy8gcmV0cmlldmUgcmF3IHZhbHVlIGZvciB0cnVlLXZhbHVlIGFuZCBmYWxzZS12YWx1ZSBzZXQgdmlhIDp0cnVlLXZhbHVlIG9yIDpmYWxzZS12YWx1ZSBiaW5kaW5nc1xyXG5mdW5jdGlvbiBnZXRDaGVja2JveFZhbHVlKGVsLCBjaGVja2VkKSB7XHJcbiAgICBjb25zdCBrZXkgPSBjaGVja2VkID8gJ190cnVlVmFsdWUnIDogJ19mYWxzZVZhbHVlJztcclxuICAgIHJldHVybiBrZXkgaW4gZWwgPyBlbFtrZXldIDogY2hlY2tlZDtcclxufVxyXG5jb25zdCB2TW9kZWxEeW5hbWljID0ge1xyXG4gICAgY3JlYXRlZChlbCwgYmluZGluZywgdm5vZGUpIHtcclxuICAgICAgICBjYWxsTW9kZWxIb29rKGVsLCBiaW5kaW5nLCB2bm9kZSwgbnVsbCwgJ2NyZWF0ZWQnKTtcclxuICAgIH0sXHJcbiAgICBtb3VudGVkKGVsLCBiaW5kaW5nLCB2bm9kZSkge1xyXG4gICAgICAgIGNhbGxNb2RlbEhvb2soZWwsIGJpbmRpbmcsIHZub2RlLCBudWxsLCAnbW91bnRlZCcpO1xyXG4gICAgfSxcclxuICAgIGJlZm9yZVVwZGF0ZShlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSkge1xyXG4gICAgICAgIGNhbGxNb2RlbEhvb2soZWwsIGJpbmRpbmcsIHZub2RlLCBwcmV2Vk5vZGUsICdiZWZvcmVVcGRhdGUnKTtcclxuICAgIH0sXHJcbiAgICB1cGRhdGVkKGVsLCBiaW5kaW5nLCB2bm9kZSwgcHJldlZOb2RlKSB7XHJcbiAgICAgICAgY2FsbE1vZGVsSG9vayhlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSwgJ3VwZGF0ZWQnKTtcclxuICAgIH1cclxufTtcclxuZnVuY3Rpb24gY2FsbE1vZGVsSG9vayhlbCwgYmluZGluZywgdm5vZGUsIHByZXZWTm9kZSwgaG9vaykge1xyXG4gICAgbGV0IG1vZGVsVG9Vc2U7XHJcbiAgICBzd2l0Y2ggKGVsLnRhZ05hbWUpIHtcclxuICAgICAgICBjYXNlICdTRUxFQ1QnOlxyXG4gICAgICAgICAgICBtb2RlbFRvVXNlID0gdk1vZGVsU2VsZWN0O1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlICdURVhUQVJFQSc6XHJcbiAgICAgICAgICAgIG1vZGVsVG9Vc2UgPSB2TW9kZWxUZXh0O1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICBzd2l0Y2ggKHZub2RlLnByb3BzICYmIHZub2RlLnByb3BzLnR5cGUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2NoZWNrYm94JzpcclxuICAgICAgICAgICAgICAgICAgICBtb2RlbFRvVXNlID0gdk1vZGVsQ2hlY2tib3g7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdyYWRpbyc6XHJcbiAgICAgICAgICAgICAgICAgICAgbW9kZWxUb1VzZSA9IHZNb2RlbFJhZGlvO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBtb2RlbFRvVXNlID0gdk1vZGVsVGV4dDtcclxuICAgICAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgY29uc3QgZm4gPSBtb2RlbFRvVXNlW2hvb2tdO1xyXG4gICAgZm4gJiYgZm4oZWwsIGJpbmRpbmcsIHZub2RlLCBwcmV2Vk5vZGUpO1xyXG59XG5cbmNvbnN0IHN5c3RlbU1vZGlmaWVycyA9IFsnY3RybCcsICdzaGlmdCcsICdhbHQnLCAnbWV0YSddO1xyXG5jb25zdCBtb2RpZmllckd1YXJkcyA9IHtcclxuICAgIHN0b3A6IGUgPT4gZS5zdG9wUHJvcGFnYXRpb24oKSxcclxuICAgIHByZXZlbnQ6IGUgPT4gZS5wcmV2ZW50RGVmYXVsdCgpLFxyXG4gICAgc2VsZjogZSA9PiBlLnRhcmdldCAhPT0gZS5jdXJyZW50VGFyZ2V0LFxyXG4gICAgY3RybDogZSA9PiAhZS5jdHJsS2V5LFxyXG4gICAgc2hpZnQ6IGUgPT4gIWUuc2hpZnRLZXksXHJcbiAgICBhbHQ6IGUgPT4gIWUuYWx0S2V5LFxyXG4gICAgbWV0YTogZSA9PiAhZS5tZXRhS2V5LFxyXG4gICAgbGVmdDogZSA9PiAnYnV0dG9uJyBpbiBlICYmIGUuYnV0dG9uICE9PSAwLFxyXG4gICAgbWlkZGxlOiBlID0+ICdidXR0b24nIGluIGUgJiYgZS5idXR0b24gIT09IDEsXHJcbiAgICByaWdodDogZSA9PiAnYnV0dG9uJyBpbiBlICYmIGUuYnV0dG9uICE9PSAyLFxyXG4gICAgZXhhY3Q6IChlLCBtb2RpZmllcnMpID0+IHN5c3RlbU1vZGlmaWVycy5zb21lKG0gPT4gZVtgJHttfUtleWBdICYmICFtb2RpZmllcnMuaW5jbHVkZXMobSkpXHJcbn07XHJcbi8qKlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY29uc3Qgd2l0aE1vZGlmaWVycyA9IChmbiwgbW9kaWZpZXJzKSA9PiB7XHJcbiAgICByZXR1cm4gKGV2ZW50LCAuLi5hcmdzKSA9PiB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtb2RpZmllcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgY29uc3QgZ3VhcmQgPSBtb2RpZmllckd1YXJkc1ttb2RpZmllcnNbaV1dO1xyXG4gICAgICAgICAgICBpZiAoZ3VhcmQgJiYgZ3VhcmQoZXZlbnQsIG1vZGlmaWVycykpXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmbihldmVudCwgLi4uYXJncyk7XHJcbiAgICB9O1xyXG59O1xyXG4vLyBLZXB0IGZvciAyLnggY29tcGF0LlxyXG4vLyBOb3RlOiBJRTExIGNvbXBhdCBmb3IgYHNwYWNlYmFyYCBhbmQgYGRlbGAgaXMgcmVtb3ZlZCBmb3Igbm93LlxyXG5jb25zdCBrZXlOYW1lcyA9IHtcclxuICAgIGVzYzogJ2VzY2FwZScsXHJcbiAgICBzcGFjZTogJyAnLFxyXG4gICAgdXA6ICdhcnJvdy11cCcsXHJcbiAgICBsZWZ0OiAnYXJyb3ctbGVmdCcsXHJcbiAgICByaWdodDogJ2Fycm93LXJpZ2h0JyxcclxuICAgIGRvd246ICdhcnJvdy1kb3duJyxcclxuICAgIGRlbGV0ZTogJ2JhY2tzcGFjZSdcclxufTtcclxuLyoqXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb25zdCB3aXRoS2V5cyA9IChmbiwgbW9kaWZpZXJzKSA9PiB7XHJcbiAgICByZXR1cm4gKGV2ZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKCEoJ2tleScgaW4gZXZlbnQpKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgY29uc3QgZXZlbnRLZXkgPSBoeXBoZW5hdGUoZXZlbnQua2V5KTtcclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgLy8gTm9uZSBvZiB0aGUgcHJvdmlkZWQga2V5IG1vZGlmaWVycyBtYXRjaCB0aGUgY3VycmVudCBldmVudCBrZXlcclxuICAgICAgICAhbW9kaWZpZXJzLnNvbWUoayA9PiBrID09PSBldmVudEtleSB8fCBrZXlOYW1lc1trXSA9PT0gZXZlbnRLZXkpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZuKGV2ZW50KTtcclxuICAgIH07XHJcbn07XG5cbmNvbnN0IHZTaG93ID0ge1xyXG4gICAgYmVmb3JlTW91bnQoZWwsIHsgdmFsdWUgfSwgeyB0cmFuc2l0aW9uIH0pIHtcclxuICAgICAgICBlbC5fdm9kID0gZWwuc3R5bGUuZGlzcGxheSA9PT0gJ25vbmUnID8gJycgOiBlbC5zdHlsZS5kaXNwbGF5O1xyXG4gICAgICAgIGlmICh0cmFuc2l0aW9uICYmIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24uYmVmb3JlRW50ZXIoZWwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgc2V0RGlzcGxheShlbCwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH0sXHJcbiAgICBtb3VudGVkKGVsLCB7IHZhbHVlIH0sIHsgdHJhbnNpdGlvbiB9KSB7XHJcbiAgICAgICAgaWYgKHRyYW5zaXRpb24gJiYgdmFsdWUpIHtcclxuICAgICAgICAgICAgdHJhbnNpdGlvbi5lbnRlcihlbCk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHVwZGF0ZWQoZWwsIHsgdmFsdWUsIG9sZFZhbHVlIH0sIHsgdHJhbnNpdGlvbiB9KSB7XHJcbiAgICAgICAgaWYgKCF2YWx1ZSA9PT0gIW9sZFZhbHVlKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgaWYgKHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uLmJlZm9yZUVudGVyKGVsKTtcclxuICAgICAgICAgICAgICAgIHNldERpc3BsYXkoZWwsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgdHJhbnNpdGlvbi5lbnRlcihlbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uLmxlYXZlKGVsLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0RGlzcGxheShlbCwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHNldERpc3BsYXkoZWwsIHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9LFxyXG4gICAgYmVmb3JlVW5tb3VudChlbCwgeyB2YWx1ZSB9KSB7XHJcbiAgICAgICAgc2V0RGlzcGxheShlbCwgdmFsdWUpO1xyXG4gICAgfVxyXG59O1xyXG5mdW5jdGlvbiBzZXREaXNwbGF5KGVsLCB2YWx1ZSkge1xyXG4gICAgZWwuc3R5bGUuZGlzcGxheSA9IHZhbHVlID8gZWwuX3ZvZCA6ICdub25lJztcclxufVxuXG5jb25zdCByZW5kZXJlck9wdGlvbnMgPSBleHRlbmQoeyBwYXRjaFByb3AsIGZvcmNlUGF0Y2hQcm9wIH0sIG5vZGVPcHMpO1xyXG4vLyBsYXp5IGNyZWF0ZSB0aGUgcmVuZGVyZXIgLSB0aGlzIG1ha2VzIGNvcmUgcmVuZGVyZXIgbG9naWMgdHJlZS1zaGFrYWJsZVxyXG4vLyBpbiBjYXNlIHRoZSB1c2VyIG9ubHkgaW1wb3J0cyByZWFjdGl2aXR5IHV0aWxpdGllcyBmcm9tIFZ1ZS5cclxubGV0IHJlbmRlcmVyO1xyXG5sZXQgZW5hYmxlZEh5ZHJhdGlvbiA9IGZhbHNlO1xyXG5mdW5jdGlvbiBlbnN1cmVSZW5kZXJlcigpIHtcclxuICAgIHJldHVybiByZW5kZXJlciB8fCAocmVuZGVyZXIgPSBjcmVhdGVSZW5kZXJlcihyZW5kZXJlck9wdGlvbnMpKTtcclxufVxyXG5mdW5jdGlvbiBlbnN1cmVIeWRyYXRpb25SZW5kZXJlcigpIHtcclxuICAgIHJlbmRlcmVyID0gZW5hYmxlZEh5ZHJhdGlvblxyXG4gICAgICAgID8gcmVuZGVyZXJcclxuICAgICAgICA6IGNyZWF0ZUh5ZHJhdGlvblJlbmRlcmVyKHJlbmRlcmVyT3B0aW9ucyk7XHJcbiAgICBlbmFibGVkSHlkcmF0aW9uID0gdHJ1ZTtcclxuICAgIHJldHVybiByZW5kZXJlcjtcclxufVxyXG4vLyB1c2UgZXhwbGljaXQgdHlwZSBjYXN0cyBoZXJlIHRvIGF2b2lkIGltcG9ydCgpIGNhbGxzIGluIHJvbGxlZC11cCBkLnRzXHJcbmNvbnN0IHJlbmRlciA9ICgoLi4uYXJncykgPT4ge1xyXG4gICAgZW5zdXJlUmVuZGVyZXIoKS5yZW5kZXIoLi4uYXJncyk7XHJcbn0pO1xyXG5jb25zdCBoeWRyYXRlID0gKCguLi5hcmdzKSA9PiB7XHJcbiAgICBlbnN1cmVIeWRyYXRpb25SZW5kZXJlcigpLmh5ZHJhdGUoLi4uYXJncyk7XHJcbn0pO1xyXG5jb25zdCBjcmVhdGVBcHAgPSAoKC4uLmFyZ3MpID0+IHtcclxuICAgIGNvbnN0IGFwcCA9IGVuc3VyZVJlbmRlcmVyKCkuY3JlYXRlQXBwKC4uLmFyZ3MpO1xyXG4gICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSkge1xyXG4gICAgICAgIGluamVjdE5hdGl2ZVRhZ0NoZWNrKGFwcCk7XHJcbiAgICB9XHJcbiAgICBjb25zdCB7IG1vdW50IH0gPSBhcHA7XHJcbiAgICBhcHAubW91bnQgPSAoY29udGFpbmVyT3JTZWxlY3RvcikgPT4ge1xyXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lciA9IG5vcm1hbGl6ZUNvbnRhaW5lcihjb250YWluZXJPclNlbGVjdG9yKTtcclxuICAgICAgICBpZiAoIWNvbnRhaW5lcilcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IGFwcC5fY29tcG9uZW50O1xyXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihjb21wb25lbnQpICYmICFjb21wb25lbnQucmVuZGVyICYmICFjb21wb25lbnQudGVtcGxhdGUpIHtcclxuICAgICAgICAgICAgY29tcG9uZW50LnRlbXBsYXRlID0gY29udGFpbmVyLmlubmVySFRNTDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY2xlYXIgY29udGVudCBiZWZvcmUgbW91bnRpbmdcclxuICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJyc7XHJcbiAgICAgICAgY29uc3QgcHJveHkgPSBtb3VudChjb250YWluZXIpO1xyXG4gICAgICAgIGNvbnRhaW5lci5yZW1vdmVBdHRyaWJ1dGUoJ3YtY2xvYWsnKTtcclxuICAgICAgICBjb250YWluZXIuc2V0QXR0cmlidXRlKCdkYXRhLXYtYXBwJywgJycpO1xyXG4gICAgICAgIHJldHVybiBwcm94eTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gYXBwO1xyXG59KTtcclxuY29uc3QgY3JlYXRlU1NSQXBwID0gKCguLi5hcmdzKSA9PiB7XHJcbiAgICBjb25zdCBhcHAgPSBlbnN1cmVIeWRyYXRpb25SZW5kZXJlcigpLmNyZWF0ZUFwcCguLi5hcmdzKTtcclxuICAgIGlmICgocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykpIHtcclxuICAgICAgICBpbmplY3ROYXRpdmVUYWdDaGVjayhhcHApO1xyXG4gICAgfVxyXG4gICAgY29uc3QgeyBtb3VudCB9ID0gYXBwO1xyXG4gICAgYXBwLm1vdW50ID0gKGNvbnRhaW5lck9yU2VsZWN0b3IpID0+IHtcclxuICAgICAgICBjb25zdCBjb250YWluZXIgPSBub3JtYWxpemVDb250YWluZXIoY29udGFpbmVyT3JTZWxlY3Rvcik7XHJcbiAgICAgICAgaWYgKGNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICByZXR1cm4gbW91bnQoY29udGFpbmVyLCB0cnVlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIGFwcDtcclxufSk7XHJcbmZ1bmN0aW9uIGluamVjdE5hdGl2ZVRhZ0NoZWNrKGFwcCkge1xyXG4gICAgLy8gSW5qZWN0IGBpc05hdGl2ZVRhZ2BcclxuICAgIC8vIHRoaXMgaXMgdXNlZCBmb3IgY29tcG9uZW50IG5hbWUgdmFsaWRhdGlvbiAoZGV2IG9ubHkpXHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXBwLmNvbmZpZywgJ2lzTmF0aXZlVGFnJywge1xyXG4gICAgICAgIHZhbHVlOiAodGFnKSA9PiBpc0hUTUxUYWcodGFnKSB8fCBpc1NWR1RhZyh0YWcpLFxyXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZVxyXG4gICAgfSk7XHJcbn1cclxuZnVuY3Rpb24gbm9ybWFsaXplQ29udGFpbmVyKGNvbnRhaW5lcikge1xyXG4gICAgaWYgKGlzU3RyaW5nKGNvbnRhaW5lcikpIHtcclxuICAgICAgICBjb25zdCByZXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGNvbnRhaW5lcik7XHJcbiAgICAgICAgaWYgKChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiAhcmVzKSB7XHJcbiAgICAgICAgICAgIHdhcm4oYEZhaWxlZCB0byBtb3VudCBhcHA6IG1vdW50IHRhcmdldCBzZWxlY3RvciByZXR1cm5lZCBudWxsLmApO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNvbnRhaW5lcjtcclxufVxuXG5leHBvcnQgeyBUcmFuc2l0aW9uLCBUcmFuc2l0aW9uR3JvdXAsIGNyZWF0ZUFwcCwgY3JlYXRlU1NSQXBwLCBoeWRyYXRlLCByZW5kZXIsIHVzZUNzc01vZHVsZSwgdXNlQ3NzVmFycywgdk1vZGVsQ2hlY2tib3gsIHZNb2RlbER5bmFtaWMsIHZNb2RlbFJhZGlvLCB2TW9kZWxTZWxlY3QsIHZNb2RlbFRleHQsIHZTaG93LCB3aXRoS2V5cywgd2l0aE1vZGlmaWVycyB9O1xuIiwiaW1wb3J0IHsgc2V0RGV2dG9vbHNIb29rLCB3YXJuIH0gZnJvbSAnQHZ1ZS9ydW50aW1lLWRvbSc7XG5leHBvcnQgKiBmcm9tICdAdnVlL3J1bnRpbWUtZG9tJztcbmltcG9ydCB7IGdldEdsb2JhbFRoaXMgfSBmcm9tICdAdnVlL3NoYXJlZCc7XG5cbmZ1bmN0aW9uIGluaXREZXYoKSB7XHJcbiAgICBjb25zdCB0YXJnZXQgPSBnZXRHbG9iYWxUaGlzKCk7XHJcbiAgICB0YXJnZXQuX19WVUVfXyA9IHRydWU7XHJcbiAgICBzZXREZXZ0b29sc0hvb2sodGFyZ2V0Ll9fVlVFX0RFVlRPT0xTX0dMT0JBTF9IT09LX18pO1xyXG4gICAge1xyXG4gICAgICAgIGNvbnNvbGUuaW5mbyhgWW91IGFyZSBydW5uaW5nIGEgZGV2ZWxvcG1lbnQgYnVpbGQgb2YgVnVlLlxcbmAgK1xyXG4gICAgICAgICAgICBgTWFrZSBzdXJlIHRvIHVzZSB0aGUgcHJvZHVjdGlvbiBidWlsZCAoKi5wcm9kLmpzKSB3aGVuIGRlcGxveWluZyBmb3IgcHJvZHVjdGlvbi5gKTtcclxuICAgIH1cclxufVxuXG4vLyBUaGlzIGVudHJ5IGV4cG9ydHMgdGhlIHJ1bnRpbWUgb25seSwgYW5kIGlzIGJ1aWx0IGFzXHJcbihwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSAmJiBpbml0RGV2KCk7XHJcbmNvbnN0IGNvbXBpbGUgPSAoKSA9PiB7XHJcbiAgICBpZiAoKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpKSB7XHJcbiAgICAgICAgd2FybihgUnVudGltZSBjb21waWxhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnVpbGQgb2YgVnVlLmAgK1xyXG4gICAgICAgICAgICAoIGAgQ29uZmlndXJlIHlvdXIgYnVuZGxlciB0byBhbGlhcyBcInZ1ZVwiIHRvIFwidnVlL2Rpc3QvdnVlLmVzbS1idW5kbGVyLmpzXCIuYFxyXG4gICAgICAgICAgICAgICAgKSAvKiBzaG91bGQgbm90IGhhcHBlbiAqLyk7XHJcbiAgICB9XHJcbn07XG5cbmV4cG9ydCB7IGNvbXBpbGUgfTtcbiIsImltcG9ydCB7IHdyaXRhYmxlIH0gZnJvbSBcInN2ZWx0ZS9zdG9yZVwiO1xyXG5pbXBvcnQgeyBnZXRMb2NhbEl0ZW0sIHNldExvY2FsSXRlbSB9IGZyb20gXCIuLi9saWIvc3RvcmVcIjtcclxuXHJcbi8qKiDnlKjmnaXmmL7npLrnrJTorrDnmoTlnLDmlrkgKi9cclxuZXhwb3J0IGNvbnN0IG5vdGVfbGlzdF9zdG9yZSA9IHdyaXRhYmxlKFtdIGFzIE5vdGVbXSk7XHJcblxyXG4vKiog56yU6K6w55qE57G75Z6LICovXHJcbnR5cGUgTm90ZSA9IHtcclxuICAvKiog5oyC6L2954K5ICovXHJcbiAgcG9pbnQ6IEVsZW1lbnQ7XHJcbiAgLyoqIOWGheWuuSAqL1xyXG4gIGNvbnRlbnQ6IHN0cmluZztcclxufTtcclxuXHJcbmNvbnN0IGRlZmF1bHRTZXR0aW5nID0ge1xyXG4gIGE6IDMsXHJcbiAgc3dhdGNoZXM6IHtcclxuICAgIHRleHRDb2xvcjoge1xyXG4gICAgICBkZWZhdWx0OiBcIiMzMzNcIixcclxuICAgICAgbGlzdDogW1xyXG4gICAgICAgIFwiI0VCNTc1N1wiLFxyXG4gICAgICAgIFwiI0YyQzk0Q1wiLFxyXG4gICAgICAgIFwiIzlCNTFFMFwiLFxyXG4gICAgICAgIFwiI0UwRTBFMFwiLFxyXG4gICAgICAgIFwiIzJGODBFRFwiLFxyXG4gICAgICAgIFwiIzJGODBFRFwiLFxyXG4gICAgICAgIFwiIzgyODI4MlwiLFxyXG4gICAgICAgIFwiIzI3QUU2MFwiLFxyXG4gICAgICAgIFwiIzI3QUU2MFwiLFxyXG4gICAgICAgIFwiI0VCNTc1N1wiLFxyXG4gICAgICAgIFwiIzU2Q0NGMlwiLFxyXG4gICAgICAgIFwiI0YyOTk0QVwiLFxyXG4gICAgICAgIFwiIzRGNEY0RlwiLFxyXG4gICAgICAgIFwiIzIxOTY1M1wiLFxyXG4gICAgICAgIFwiI0JCNkJEOVwiLFxyXG4gICAgICAgIFwiI0YyRjJGMlwiLFxyXG4gICAgICAgIFwiIzJEOUNEQlwiLFxyXG4gICAgICAgIFwiIzJEOUNEQlwiLFxyXG4gICAgICAgIFwiI0JEQkRCRFwiLFxyXG4gICAgICAgIFwiIzZGQ0Y5N1wiLFxyXG4gICAgICAgIFwiIzZGQ0Y5N1wiLFxyXG4gICAgICBdLFxyXG4gICAgfSxcclxuICAgIGJnQ29sb3I6IHtcclxuICAgICAgZGVmYXVsdDogXCIjRUI1NzU3XCIsXHJcbiAgICAgIGxpc3Q6IFtcclxuICAgICAgICBcIiNFQjU3NTdcIixcclxuICAgICAgICBcIiNGMkM5NENcIixcclxuICAgICAgICBcIiM5QjUxRTBcIixcclxuICAgICAgICBcIiNFMEUwRTBcIixcclxuICAgICAgICBcIiMyRjgwRURcIixcclxuICAgICAgICBcIiMyRjgwRURcIixcclxuICAgICAgICBcIiM4MjgyODJcIixcclxuICAgICAgICBcIiMyN0FFNjBcIixcclxuICAgICAgICBcIiMyN0FFNjBcIixcclxuICAgICAgICBcIiNFQjU3NTdcIixcclxuICAgICAgICBcIiM1NkNDRjJcIixcclxuICAgICAgICBcIiNGMjk5NEFcIixcclxuICAgICAgICBcIiM0RjRGNEZcIixcclxuICAgICAgICBcIiMyMTk2NTNcIixcclxuICAgICAgICBcIiNCQjZCRDlcIixcclxuICAgICAgICBcIiNGMkYyRjJcIixcclxuICAgICAgICBcIiMyRDlDREJcIixcclxuICAgICAgICBcIiMyRDlDREJcIixcclxuICAgICAgICBcIiNCREJEQkRcIixcclxuICAgICAgICBcIiM2RkNGOTdcIixcclxuICAgICAgICBcIiM2RkNGOTdcIixcclxuICAgICAgXSxcclxuICAgIH0sXHJcbiAgICB1bmRlcmxpbmVDb2xvcjoge1xyXG4gICAgICBkZWZhdWx0OiBcIiNFQjU3NTdcIixcclxuICAgICAgbGlzdDogW1xyXG4gICAgICAgIFwiI0VCNTc1N1wiLFxyXG4gICAgICAgIFwiI0YyQzk0Q1wiLFxyXG4gICAgICAgIFwiIzlCNTFFMFwiLFxyXG4gICAgICAgIFwiI0UwRTBFMFwiLFxyXG4gICAgICAgIFwiIzJGODBFRFwiLFxyXG4gICAgICAgIFwiIzJGODBFRFwiLFxyXG4gICAgICAgIFwiIzgyODI4MlwiLFxyXG4gICAgICAgIFwiIzI3QUU2MFwiLFxyXG4gICAgICAgIFwiIzI3QUU2MFwiLFxyXG4gICAgICAgIFwiI0VCNTc1N1wiLFxyXG4gICAgICAgIFwiIzU2Q0NGMlwiLFxyXG4gICAgICAgIFwiI0YyOTk0QVwiLFxyXG4gICAgICAgIFwiIzRGNEY0RlwiLFxyXG4gICAgICAgIFwiIzIxOTY1M1wiLFxyXG4gICAgICAgIFwiI0JCNkJEOVwiLFxyXG4gICAgICAgIFwiI0YyRjJGMlwiLFxyXG4gICAgICAgIFwiIzJEOUNEQlwiLFxyXG4gICAgICAgIFwiIzJEOUNEQlwiLFxyXG4gICAgICAgIFwiI0JEQkRCRFwiLFxyXG4gICAgICAgIFwiIzZGQ0Y5N1wiLFxyXG4gICAgICAgIFwiIzZGQ0Y5N1wiLFxyXG4gICAgICBdLFxyXG4gICAgfSxcclxuICB9LFxyXG59O1xyXG5cclxuY2xhc3MgUGFnZU5vdGVzU3RvcmU8VCBleHRlbmRzIHsgW2s6IHN0cmluZ106IGFueSB9LCBLIGV4dGVuZHMga2V5b2YgVD4ge1xyXG4gIHByaXZhdGUgc3RvcmUgPSB7fSBhcyBUO1xyXG4gIC8qKiDmsqHmnInliqDovb3njqnphY3nva7ov5nkuKogcHJvbWlzZSDkuI3kvJrnu5PmnZ8gKi9cclxuICBwcml2YXRlIGluaXRpYWxpemluZzogUHJvbWlzZTxhbnk+O1xyXG4gIHByaXZhdGUgX3dyaXRhYmxlID0gd3JpdGFibGUoe30gYXMgVCk7XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzdG9yZVBhdGg6IHN0cmluZykge1xyXG4gICAgdGhpcy5pbml0aWFsaXppbmcgPSBnZXRMb2NhbEl0ZW0oc3RvcmVQYXRoLCBKU09OLnN0cmluZ2lmeShkZWZhdWx0U2V0dGluZykpLnRoZW4oKHIpID0+IHtcclxuICAgICAgdGhpcy5zdG9yZSA9IEpTT04ucGFyc2Uocik7XHJcbiAgICAgIHRoaXMuX3dyaXRhYmxlLnNldCh0aGlzLnN0b3JlKTtcclxuXHJcbiAgICAgIHRoaXMuX3dyaXRhYmxlLnN1YnNjcmliZSgocikgPT4ge1xyXG4gICAgICAgIHRoaXMuc3RvcmUgPSByO1xyXG4gICAgICAgIHRoaXMuc2F2ZShyKVxyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfSk7XHJcbiAgfVxyXG4gIHByb3RlY3RlZCBhc3luYyBnZXRTdG9yZSgpOiBQcm9taXNlPFQ+IHtcclxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6aW5nO1xyXG4gICAgcmV0dXJuIHRoaXMuc3RvcmU7XHJcbiAgfVxyXG4gIHByb3RlY3RlZCBzYXZlKHI6IFQpIHtcclxuICAgIHNldExvY2FsSXRlbSh0aGlzLnN0b3JlUGF0aCwgSlNPTi5zdHJpbmdpZnkocikpO1xyXG4gIH1cclxuICBnZXRXcml0YWJsZSgpIHtcclxuICAgIHJldHVybiB0aGlzLl93cml0YWJsZTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGdldChrOiBLKTogUHJvbWlzZTxUW0tdPiB7XHJcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0U3RvcmUoKSlba107XHJcbiAgfVxyXG4gIGFzeW5jIHNldChrOiBLLCB2YWx1ZTogVFtLXSkge1xyXG4gICAgY29uc3QgcyA9IGF3YWl0IHRoaXMuZ2V0U3RvcmUoKTtcclxuICAgIHNba10gPSB2YWx1ZTtcclxuICAgIHRoaXMuX3dyaXRhYmxlLnNldChzKTtcclxuICAgIHRoaXMuc2F2ZShzKVxyXG4gIH1cclxufVxyXG5cclxudHlwZSBkZWZhdWx0U2V0dGluZyA9IHR5cGVvZiBkZWZhdWx0U2V0dGluZztcclxuXHJcbi8qKiDorr7nva7nm7jlhbPnmoTlrZjlgqggKi9cclxuZXhwb3J0IGNvbnN0IHNldHRpbmdTdG9yZSA9IG5ldyBQYWdlTm90ZXNTdG9yZTxkZWZhdWx0U2V0dGluZywga2V5b2YgZGVmYXVsdFNldHRpbmc+KFwiX19zZXR0aW5nX19cIik7XHJcbiIsImltcG9ydCB7IGRlcml2ZWQsIGdldCwgd3JpdGFibGUgfSBmcm9tICdzdmVsdGUvc3RvcmUnO1xyXG5cclxuZXhwb3J0IGNvbnN0IHN0eWxlTGlzdCA9IHdyaXRhYmxlKDxzdHJpbmdbXT5bXSk7XHJcblxyXG4vKiog5qC55o2uIHN0eWxlTGlzdCDorqHnrpflh7rmnaXnmoQgY3NzIOeJh+autSAqL1xyXG5leHBvcnQgY29uc3Qgc3R5bGVUZXh0ID0gZGVyaXZlZChzdHlsZUxpc3QsICgkc3R5bGVMaXN0KSA9PiB7XHJcbiAgcmV0dXJuIGA8c3R5bGU+XHJcbiAgJHtnZXQoc3R5bGVMaXN0KS5qb2luKFwiXFxuXCIpfVxyXG4gIDwvc3R5bGU+YDtcclxufSk7IiwidmFyIGc7XG5cbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXG5nID0gKGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcztcbn0pKCk7XG5cbnRyeSB7XG5cdC8vIFRoaXMgd29ya3MgaWYgZXZhbCBpcyBhbGxvd2VkIChzZWUgQ1NQKVxuXHRnID0gZyB8fCBuZXcgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpO1xufSBjYXRjaCAoZSkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxuXHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIikgZyA9IHdpbmRvdztcbn1cblxuLy8gZyBjYW4gc3RpbGwgYmUgdW5kZWZpbmVkLCBidXQgbm90aGluZyB0byBkbyBhYm91dCBpdC4uLlxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3Ncbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cblxubW9kdWxlLmV4cG9ydHMgPSBnO1xuIiwiLypcbiAqIGF1dGhvcjogd2VuZHV4XG4gKiBlbWFpbDogODI0NzgzMTQ2QHFxLmNvbVxuICogc291cmNlIGNvZGU6IGh0dHBzOi8vZ2l0aHViLmNvbS93ZW5kdXgvQWpheC1ob29rXG4gKi9cblxuLy8gU2F2ZSBvcmlnaW5hbCBYTUxIdHRwUmVxdWVzdCBhcyBfcnhoclxudmFyIHJlYWxYaHIgPSBcIl9yeGhyXCJcblxuZXhwb3J0IGZ1bmN0aW9uIGNvbmZpZ0V2ZW50KGV2ZW50LCB4aHJQcm94eSkge1xuICAgIHZhciBlID0ge307XG4gICAgZm9yICh2YXIgYXR0ciBpbiBldmVudCkgZVthdHRyXSA9IGV2ZW50W2F0dHJdO1xuICAgIC8vIHhoclByb3h5IGluc3RlYWRcbiAgICBlLnRhcmdldCA9IGUuY3VycmVudFRhcmdldCA9IHhoclByb3h5XG4gICAgcmV0dXJuIGU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBob29rKHByb3h5KSB7XG4gICAgLy8gQXZvaWQgZG91YmxlIGhvb2tBamF4XG4gICAgd2luZG93W3JlYWxYaHJdID0gd2luZG93W3JlYWxYaHJdIHx8IFhNTEh0dHBSZXF1ZXN0XG5cbiAgICBYTUxIdHRwUmVxdWVzdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHhociA9IG5ldyB3aW5kb3dbcmVhbFhocl07XG4gICAgICAgIC8vIFdlIHNob3VsZG4ndCBob29rQWpheCBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUgYmVjYXVzZSB3ZSBjYW4ndFxuICAgICAgICAvLyBndWFyYW50ZWUgdGhhdCBhbGwgYXR0cmlidXRlcyBhcmUgb24gdGhlIHByb3RvdHlwZeOAglxuICAgICAgICAvLyBJbnN0ZWFkLCBob29raW5nIFhNTEh0dHBSZXF1ZXN0IGluc3RhbmNlIGNhbiBhdm9pZCB0aGlzIHByb2JsZW0uXG4gICAgICAgIGZvciAodmFyIGF0dHIgaW4geGhyKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IFwiXCI7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHR5cGUgPSB0eXBlb2YgeGhyW2F0dHJdIC8vIE1heSBjYXVzZSBleGNlcHRpb24gb24gc29tZSBicm93c2VyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgLy8gaG9va0FqYXggbWV0aG9kcyBvZiB4aHIsIHN1Y2ggYXMgYG9wZW5g44CBYHNlbmRgIC4uLlxuICAgICAgICAgICAgICAgIHRoaXNbYXR0cl0gPSBob29rRnVuY3Rpb24oYXR0cik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBhdHRyLCB7XG4gICAgICAgICAgICAgICAgICAgIGdldDogZ2V0dGVyRmFjdG9yeShhdHRyKSxcbiAgICAgICAgICAgICAgICAgICAgc2V0OiBzZXR0ZXJGYWN0b3J5KGF0dHIpLFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgIHhoci5nZXRQcm94eSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGF0XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy54aHIgPSB4aHI7XG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGUgZ2V0dGVyIGZvciBhdHRyaWJ1dGVzIG9mIHhoclxuICAgIGZ1bmN0aW9uIGdldHRlckZhY3RvcnkoYXR0cikge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHYgPSB0aGlzLmhhc093blByb3BlcnR5KGF0dHIgKyBcIl9cIikgPyB0aGlzW2F0dHIgKyBcIl9cIl0gOiB0aGlzLnhoclthdHRyXTtcbiAgICAgICAgICAgIHZhciBhdHRyR2V0dGVySG9vayA9IChwcm94eVthdHRyXSB8fCB7fSlbXCJnZXR0ZXJcIl1cbiAgICAgICAgICAgIHJldHVybiBhdHRyR2V0dGVySG9vayAmJiBhdHRyR2V0dGVySG9vayh2LCB0aGlzKSB8fCB2XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBzZXR0ZXIgZm9yIGF0dHJpYnV0ZXMgb2YgeGhyOyBieSB0aGlzIHdlIGhhdmUgYW4gb3Bwb3J0dW5pdHlcbiAgICAvLyB0byBob29rQWpheCBldmVudCBjYWxsYmFja3Mg77yIZWc6IGBvbmxvYWRg77yJIG9mIHhocjtcbiAgICBmdW5jdGlvbiBzZXR0ZXJGYWN0b3J5KGF0dHIpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICB2YXIgeGhyID0gdGhpcy54aHI7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgaG9vayA9IHByb3h5W2F0dHJdO1xuICAgICAgICAgICAgLy8gaG9va0FqYXggIGV2ZW50IGNhbGxiYWNrcyBzdWNoIGFzIGBvbmxvYWRg44CBYG9ucmVhZHlzdGF0ZWNoYW5nZWAuLi5cbiAgICAgICAgICAgIGlmIChhdHRyLnN1YnN0cmluZygwLCAyKSA9PT0gJ29uJykge1xuICAgICAgICAgICAgICAgIHRoYXRbYXR0ciArIFwiX1wiXSA9IHY7XG4gICAgICAgICAgICAgICAgeGhyW2F0dHJdID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IGNvbmZpZ0V2ZW50KGUsIHRoYXQpXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXQgPSBwcm94eVthdHRyXSAmJiBwcm94eVthdHRyXS5jYWxsKHRoYXQsIHhociwgZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0IHx8IHYuY2FsbCh0aGF0LCBlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vSWYgdGhlIGF0dHJpYnV0ZSBpc24ndCB3cml0YWJsZSwgZ2VuZXJhdGUgcHJveHkgYXR0cmlidXRlXG4gICAgICAgICAgICAgICAgdmFyIGF0dHJTZXR0ZXJIb29rID0gKGhvb2sgfHwge30pW1wic2V0dGVyXCJdO1xuICAgICAgICAgICAgICAgIHYgPSBhdHRyU2V0dGVySG9vayAmJiBhdHRyU2V0dGVySG9vayh2LCB0aGF0KSB8fCB2XG4gICAgICAgICAgICAgICAgdGhpc1thdHRyICsgXCJfXCJdID0gdjtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyBOb3QgYWxsIGF0dHJpYnV0ZXMgb2YgeGhyIGFyZSB3cml0YWJsZShzZXR0ZXIgbWF5IHVuZGVmaW5lZCkuXG4gICAgICAgICAgICAgICAgICAgIHhoclthdHRyXSA9IHY7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhvb2sgbWV0aG9kcyBvZiB4aHIuXG4gICAgZnVuY3Rpb24gaG9va0Z1bmN0aW9uKGZ1bikge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cylcbiAgICAgICAgICAgIGlmIChwcm94eVtmdW5dKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJldCA9IHByb3h5W2Z1bl0uY2FsbCh0aGlzLCBhcmdzLCB0aGlzLnhocilcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgcHJveHkgcmV0dXJuIHZhbHVlIGV4aXN0cywgcmV0dXJuIGl0IGRpcmVjdGx5LFxuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBjYWxsIHRoZSBmdW5jdGlvbiBvZiB4aHIuXG4gICAgICAgICAgICAgICAgaWYgKHJldCkgcmV0dXJuIHJldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnhocltmdW5dLmFwcGx5KHRoaXMueGhyLCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiB0aGUgcmVhbCBYTUxIdHRwUmVxdWVzdFxuICAgIHJldHVybiB3aW5kb3dbcmVhbFhocl07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bkhvb2soKSB7XG4gICAgaWYgKHdpbmRvd1tyZWFsWGhyXSkgWE1MSHR0cFJlcXVlc3QgPSB3aW5kb3dbcmVhbFhocl07XG4gICAgd2luZG93W3JlYWxYaHJdID0gdW5kZWZpbmVkO1xufVxuXG5cbiIsIi8qXG4gKiBhdXRob3I6IHdlbmR1eFxuICogZW1haWw6IDgyNDc4MzE0NkBxcS5jb21cbiAqIHNvdXJjZSBjb2RlOiBodHRwczovL2dpdGh1Yi5jb20vd2VuZHV4L0FqYXgtaG9va1xuICovXG5cbmltcG9ydCB7aG9vaywgdW5Ib29rLCBjb25maWdFdmVudH0gZnJvbSBcIi4veGhyLWhvb2tcIjtcblxudmFyIGV2ZW50cyA9IFsnbG9hZCcsICdsb2FkZW5kJywgJ3RpbWVvdXQnLCAnZXJyb3InLCAncmVhZHlzdGF0ZWNoYW5nZScsICdhYm9ydCddO1xudmFyIGV2ZW50TG9hZCA9IGV2ZW50c1swXSxcbiAgICBldmVudExvYWRFbmQgPSBldmVudHNbMV0sXG4gICAgZXZlbnRUaW1lb3V0ID0gZXZlbnRzWzJdLFxuICAgIGV2ZW50RXJyb3IgPSBldmVudHNbM10sXG4gICAgZXZlbnRSZWFkeVN0YXRlQ2hhbmdlID0gZXZlbnRzWzRdLFxuICAgIGV2ZW50QWJvcnQgPSBldmVudHNbNV07XG5cblxudmFyIHNpbmdsZXRvbixcbiAgICBwcm90b3R5cGUgPSAncHJvdG90eXBlJztcblxuXG5leHBvcnQgZnVuY3Rpb24gcHJveHkocHJveHkpIHtcbiAgICBpZiAoc2luZ2xldG9uKSB0aHJvdyBcIlByb3h5IGFscmVhZHkgZXhpc3RzXCI7XG4gICAgcmV0dXJuIHNpbmdsZXRvbiA9IG5ldyBQcm94eShwcm94eSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1blByb3h5KCkge1xuICAgIHNpbmdsZXRvbiA9IG51bGxcbiAgICB1bkhvb2soKVxufVxuXG5mdW5jdGlvbiB0cmltKHN0cikge1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xufVxuXG5mdW5jdGlvbiBnZXRFdmVudFRhcmdldCh4aHIpIHtcbiAgICByZXR1cm4geGhyLndhdGNoZXIgfHwgKHhoci53YXRjaGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpKTtcbn1cblxuZnVuY3Rpb24gdHJpZ2dlckxpc3RlbmVyKHhociwgbmFtZSkge1xuICAgIHZhciB4aHJQcm94eSA9IHhoci5nZXRQcm94eSgpO1xuICAgIHZhciBjYWxsYmFjayA9ICdvbicgKyBuYW1lICsgJ18nO1xuICAgIHZhciBldmVudCA9IGNvbmZpZ0V2ZW50KHt0eXBlOiBuYW1lfSwgeGhyUHJveHkpO1xuICAgIHhoclByb3h5W2NhbGxiYWNrXSAmJiB4aHJQcm94eVtjYWxsYmFja10oZXZlbnQpO1xuICAgIHZhciBldnQ7XG4gICAgaWYodHlwZW9mKEV2ZW50KSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBldnQgPSBuZXcgRXZlbnQobmFtZSx7YnViYmxlczogZmFsc2V9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yNzE3Njk4My9kaXNwYXRjaGV2ZW50LW5vdC13b3JraW5nLWluLWllMTFcbiAgICAgICAgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0V2ZW50Jyk7XG4gICAgICAgIGV2dC5pbml0RXZlbnQobmFtZSwgZmFsc2UsIHRydWUpO1xuICAgIH1cbiAgICBnZXRFdmVudFRhcmdldCh4aHIpLmRpc3BhdGNoRXZlbnQoZXZ0KTtcbn1cblxuXG5mdW5jdGlvbiBIYW5kbGVyKHhocikge1xuICAgIHRoaXMueGhyID0geGhyO1xuICAgIHRoaXMueGhyUHJveHkgPSB4aHIuZ2V0UHJveHkoKTtcbn1cblxuSGFuZGxlcltwcm90b3R5cGVdID0gT2JqZWN0LmNyZWF0ZSh7XG4gICAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZShyZXNwb25zZSkge1xuICAgICAgICB2YXIgeGhyUHJveHkgPSB0aGlzLnhoclByb3h5O1xuICAgICAgICB2YXIgeGhyID0gdGhpcy54aHI7XG4gICAgICAgIHhoclByb3h5LnJlYWR5U3RhdGUgPSA0O1xuICAgICAgICB4aHIucmVzSGVhZGVyID0gcmVzcG9uc2UuaGVhZGVycztcbiAgICAgICAgeGhyUHJveHkucmVzcG9uc2UgPSB4aHJQcm94eS5yZXNwb25zZVRleHQgPSByZXNwb25zZS5yZXNwb25zZTtcbiAgICAgICAgeGhyUHJveHkuc3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXR1c1RleHQ7XG4gICAgICAgIHhoclByb3h5LnN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICAgICAgdHJpZ2dlckxpc3RlbmVyKHhociwgZXZlbnRSZWFkeVN0YXRlQ2hhbmdlKTtcbiAgICAgICAgdHJpZ2dlckxpc3RlbmVyKHhociwgZXZlbnRMb2FkKTtcbiAgICAgICAgdHJpZ2dlckxpc3RlbmVyKHhociwgZXZlbnRMb2FkRW5kKTtcbiAgICB9LFxuICAgIHJlamVjdDogZnVuY3Rpb24gcmVqZWN0KGVycm9yKSB7XG4gICAgICAgIHRoaXMueGhyUHJveHkuc3RhdHVzID0gMDtcbiAgICAgICAgdHJpZ2dlckxpc3RlbmVyKHRoaXMueGhyLCBlcnJvci50eXBlKTtcbiAgICAgICAgdHJpZ2dlckxpc3RlbmVyKHRoaXMueGhyLCBldmVudExvYWRFbmQpO1xuICAgIH1cbn0pO1xuXG5mdW5jdGlvbiBtYWtlSGFuZGxlcihuZXh0KSB7XG4gICAgZnVuY3Rpb24gc3ViKHhocikge1xuICAgICAgICBIYW5kbGVyLmNhbGwodGhpcywgeGhyKTtcbiAgICB9XG5cbiAgICBzdWJbcHJvdG90eXBlXSA9IE9iamVjdC5jcmVhdGUoSGFuZGxlcltwcm90b3R5cGVdKTtcbiAgICBzdWJbcHJvdG90eXBlXS5uZXh0ID0gbmV4dDtcbiAgICByZXR1cm4gc3ViO1xufVxuXG52YXIgUmVxdWVzdEhhbmRsZXIgPSBtYWtlSGFuZGxlcihmdW5jdGlvbiAocnEpIHtcbiAgICB2YXIgeGhyID0gdGhpcy54aHI7XG4gICAgcnEgPSBycSB8fCB4aHIuY29uZmlnO1xuICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSBycS53aXRoQ3JlZGVudGlhbHM7XG4gICAgeGhyLm9wZW4ocnEubWV0aG9kLCBycS51cmwsIHJxLmFzeW5jICE9PSBmYWxzZSwgcnEudXNlciwgcnEucGFzc3dvcmQpO1xuICAgIGZvciAodmFyIGtleSBpbiBycS5oZWFkZXJzKSB7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgcnEuaGVhZGVyc1trZXldKTtcbiAgICB9XG4gICAgeGhyLnNlbmQocnEuYm9keSk7XG59KTtcblxudmFyIFJlc3BvbnNlSGFuZGxlciA9IG1ha2VIYW5kbGVyKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgIHRoaXMucmVzb2x2ZShyZXNwb25zZSk7XG59KTtcblxudmFyIEVycm9ySGFuZGxlciA9IG1ha2VIYW5kbGVyKGZ1bmN0aW9uIChlcnJvcikge1xuICAgIHRoaXMucmVqZWN0KGVycm9yKTtcbn0pO1xuXG5mdW5jdGlvbiBQcm94eShwcm94eSkge1xuICAgIHZhciBvblJlcXVlc3QgPSBwcm94eS5vblJlcXVlc3QsXG4gICAgICAgIG9uUmVzcG9uc2UgPSBwcm94eS5vblJlc3BvbnNlLFxuICAgICAgICBvbkVycm9yID0gcHJveHkub25FcnJvcjtcblxuICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlKHhociwgeGhyUHJveHkpIHtcbiAgICAgICAgdmFyIGhhbmRsZXIgPSBuZXcgUmVzcG9uc2VIYW5kbGVyKHhocik7XG4gICAgICAgIGlmICghb25SZXNwb25zZSkgcmV0dXJuIGhhbmRsZXIucmVzb2x2ZSgpO1xuICAgICAgICB2YXIgcmV0ID0ge1xuICAgICAgICAgICAgcmVzcG9uc2U6IHhoclByb3h5LnJlc3BvbnNlLFxuICAgICAgICAgICAgc3RhdHVzOiB4aHJQcm94eS5zdGF0dXMsXG4gICAgICAgICAgICBzdGF0dXNUZXh0OiB4aHJQcm94eS5zdGF0dXNUZXh0LFxuICAgICAgICAgICAgY29uZmlnOiB4aHIuY29uZmlnLFxuICAgICAgICAgICAgaGVhZGVyczogeGhyLnJlc0hlYWRlciB8fCB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkuc3BsaXQoJ1xcclxcbicpLnJlZHVjZShmdW5jdGlvbiAob2IsIHN0cikge1xuICAgICAgICAgICAgICAgIGlmIChzdHIgPT09IFwiXCIpIHJldHVybiBvYjtcbiAgICAgICAgICAgICAgICB2YXIgbSA9IHN0ci5zcGxpdChcIjpcIik7XG4gICAgICAgICAgICAgICAgb2JbbS5zaGlmdCgpXSA9IHRyaW0obS5qb2luKCc6JykpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYjtcbiAgICAgICAgICAgIH0sIHt9KVxuICAgICAgICB9O1xuICAgICAgICBvblJlc3BvbnNlKHJldCwgaGFuZGxlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25lcnJvcih4aHIsIHhoclByb3h5LCBlKSB7XG4gICAgICAgIHZhciBoYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlcih4aHIpO1xuICAgICAgICB2YXIgZXJyb3IgPSB7Y29uZmlnOiB4aHIuY29uZmlnLCBlcnJvcjogZX07XG4gICAgICAgIGlmIChvbkVycm9yKSB7XG4gICAgICAgICAgICBvbkVycm9yKGVycm9yLCBoYW5kbGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGhhbmRsZXIubmV4dChlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmV2ZW50WGhyUHJveHlDYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JDYWxsYmFjayh4aHIsIGUpIHtcbiAgICAgICAgb25lcnJvcih4aHIsIHRoaXMsIGUpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdGF0ZUNoYW5nZUNhbGxiYWNrKHhociwgeGhyUHJveHkpIHtcbiAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0ICYmIHhoci5zdGF0dXMgIT09IDApIHtcbiAgICAgICAgICAgIGhhbmRsZVJlc3BvbnNlKHhociwgeGhyUHJveHkpO1xuICAgICAgICB9IGVsc2UgaWYgKHhoci5yZWFkeVN0YXRlICE9PSA0KSB7XG4gICAgICAgICAgICB0cmlnZ2VyTGlzdGVuZXIoeGhyLCBldmVudFJlYWR5U3RhdGVDaGFuZ2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBob29rKHtcbiAgICAgICAgb25sb2FkOiBwcmV2ZW50WGhyUHJveHlDYWxsYmFjayxcbiAgICAgICAgb25sb2FkZW5kOiBwcmV2ZW50WGhyUHJveHlDYWxsYmFjayxcbiAgICAgICAgb25lcnJvcjogZXJyb3JDYWxsYmFjayxcbiAgICAgICAgb250aW1lb3V0OiBlcnJvckNhbGxiYWNrLFxuICAgICAgICBvbmFib3J0OiBlcnJvckNhbGxiYWNrLFxuICAgICAgICBvbnJlYWR5c3RhdGVjaGFuZ2U6IGZ1bmN0aW9uICh4aHIpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZUNoYW5nZUNhbGxiYWNrKHhociwgdGhpcyk7XG4gICAgICAgIH0sXG4gICAgICAgIG9wZW46IGZ1bmN0aW9uIG9wZW4oYXJncywgeGhyKSB7XG4gICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHhoci5jb25maWcgPSB7aGVhZGVyczoge319O1xuICAgICAgICAgICAgY29uZmlnLm1ldGhvZCA9IGFyZ3NbMF07XG4gICAgICAgICAgICBjb25maWcudXJsID0gYXJnc1sxXTtcbiAgICAgICAgICAgIGNvbmZpZy5hc3luYyA9IGFyZ3NbMl07XG4gICAgICAgICAgICBjb25maWcudXNlciA9IGFyZ3NbM107XG4gICAgICAgICAgICBjb25maWcucGFzc3dvcmQgPSBhcmdzWzRdO1xuICAgICAgICAgICAgY29uZmlnLnhociA9IHhocjtcbiAgICAgICAgICAgIHZhciBldk5hbWUgPSAnb24nICsgZXZlbnRSZWFkeVN0YXRlQ2hhbmdlO1xuICAgICAgICAgICAgaWYgKCF4aHJbZXZOYW1lXSkge1xuICAgICAgICAgICAgICAgIHhocltldk5hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RhdGVDaGFuZ2VDYWxsYmFjayh4aHIsIF90aGlzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZGVmYXVsdEVycm9ySGFuZGxlciA9IGZ1bmN0aW9uIGRlZmF1bHRFcnJvckhhbmRsZXIoZSkge1xuICAgICAgICAgICAgICAgIG9uZXJyb3IoeGhyLCBfdGhpcywgY29uZmlnRXZlbnQoZSwgX3RoaXMpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBbZXZlbnRFcnJvciwgZXZlbnRUaW1lb3V0LCBldmVudEFib3J0XS5mb3JFYWNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGV2ZW50ID0gJ29uJyArIGU7XG4gICAgICAgICAgICAgICAgaWYgKCF4aHJbZXZlbnRdKSB4aHJbZXZlbnRdID0gZGVmYXVsdEVycm9ySGFuZGxlcjtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyDlpoLmnpzmnInor7fmsYLmi6bmiKrlmajvvIzliJnlnKjosIPnlKhvblJlcXVlc3TlkI7lho3miZPlvIDpk77mjqXjgILlm6DkuLpvblJlcXVlc3TmnIDkvbPosIPnlKjml7bmnLrmmK/lnKhzZW5k5YmN77yMXG4gICAgICAgICAgICAvLyDmiYDku6XmiJHku6zlnKhzZW5k5oum5oiq5Ye95pWw5Lit5YaN5omL5Yqo6LCD55Sob3Blbu+8jOWboOatpOi/lOWbnnRydWXpmLvmraJ4aHIub3Blbuiwg+eUqOOAglxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIOWmguaenOayoeacieivt+axguaLpuaIquWZqO+8jOWImeS4jeeUqOmYu+aWrXhoci5vcGVu6LCD55SoXG4gICAgICAgICAgICBpZiAob25SZXF1ZXN0KSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgc2VuZDogZnVuY3Rpb24gKGFyZ3MsIHhocikge1xuICAgICAgICAgICAgdmFyIGNvbmZpZyA9IHhoci5jb25maWdcbiAgICAgICAgICAgIGNvbmZpZy53aXRoQ3JlZGVudGlhbHM9eGhyLndpdGhDcmVkZW50aWFsc1xuICAgICAgICAgICAgY29uZmlnLmJvZHkgPSBhcmdzWzBdO1xuICAgICAgICAgICAgaWYgKG9uUmVxdWVzdCkge1xuICAgICAgICAgICAgICAgIC8vIEluICdvblJlcXVlc3QnLCB3ZSBtYXkgY2FsbCBYSFIncyBldmVudCBoYW5kbGVyLCBzdWNoIGFzIGB4aHIub25sb2FkYC5cbiAgICAgICAgICAgICAgICAvLyBIb3dldmVyLCBYSFIncyBldmVudCBoYW5kbGVyIG1heSBub3QgYmUgc2V0IHVudGlsIHhoci5zZW5kIGlzIGNhbGxlZCBpblxuICAgICAgICAgICAgICAgIC8vIHRoZSB1c2VyJ3MgY29kZSwgc28gd2UgdXNlIGBzZXRUaW1lb3V0YCB0byBhdm9pZCB0aGlzIHNpdHVhdGlvblxuICAgICAgICAgICAgICAgIHZhciByZXEgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdChjb25maWcsIG5ldyBSZXF1ZXN0SGFuZGxlcih4aHIpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uZmlnLmFzeW5jID09PSBmYWxzZSA/IHJlcSgpIDogc2V0VGltZW91dChyZXEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHNldFJlcXVlc3RIZWFkZXI6IGZ1bmN0aW9uIChhcmdzLCB4aHIpIHtcbiAgICAgICAgICAgIC8vIENvbGxlY3QgcmVxdWVzdCBoZWFkZXJzXG4gICAgICAgICAgICB4aHIuY29uZmlnLmhlYWRlcnNbYXJnc1swXS50b0xvd2VyQ2FzZSgpXSA9IGFyZ3NbMV07XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcjogZnVuY3Rpb24gKGFyZ3MsIHhocikge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgICAgIGlmIChldmVudHMuaW5kZXhPZihhcmdzWzBdKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB2YXIgaGFuZGxlciA9IGFyZ3NbMV07XG4gICAgICAgICAgICAgICAgZ2V0RXZlbnRUYXJnZXQoeGhyKS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudCA9IGNvbmZpZ0V2ZW50KGUsIF90aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudHlwZSA9IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlzVHJ1c3RlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY2FsbChfdGhpcywgZXZlbnQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uIChfLCB4aHIpIHtcbiAgICAgICAgICAgIHZhciBoZWFkZXJzID0geGhyLnJlc0hlYWRlclxuICAgICAgICAgICAgaWYgKGhlYWRlcnMpIHtcbiAgICAgICAgICAgICAgICB2YXIgaGVhZGVyID0gXCJcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gaGVhZGVycykge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXIgKz0ga2V5ICsgJzogJyArIGhlYWRlcnNba2V5XSArICdcXHJcXG4nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaGVhZGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBnZXRSZXNwb25zZUhlYWRlcjogZnVuY3Rpb24gKGFyZ3MsIHhocikge1xuICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSB4aHIucmVzSGVhZGVyXG4gICAgICAgICAgICBpZiAoaGVhZGVycykge1xuICAgICAgICAgICAgICAgIHJldHVybiBoZWFkZXJzWyhhcmdzWzBdIHx8ICcnKS50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5cblxuXG4iLCIvKlxuICogYXV0aG9yOiB3ZW5kdXhcbiAqIGVtYWlsOiA4MjQ3ODMxNDZAcXEuY29tXG4gKiBzb3VyY2UgY29kZTogaHR0cHM6Ly9naXRodWIuY29tL3dlbmR1eC9BamF4LWhvb2tcbiAqKi9cbmV4cG9ydCB7aG9vaywgdW5Ib29rfWZyb20gXCIuL3NyYy94aHItaG9va1wiXG5leHBvcnQge3Byb3h5LCB1blByb3h5fSBmcm9tIFwiLi9zcmMveGhyLXByb3h5XCJcblxuIiwiZXhwb3J0IGZ1bmN0aW9uIOajgOa1i+WFg+e0oOeKtuaAgShcclxuICBzZWxlY3Rvcjogc3RyaW5nLFxyXG4gIOWHuueOsDogKGVsOiBIVE1MRWxlbWVudCkgPT4gdm9pZD0oKT0+e30sXHJcbiAg5Y+Y5YyWOiAoZWw6IEhUTUxFbGVtZW50KSA9PiB2b2lkPSgpPT57fSxcclxuICDmtojlpLE6ICgpID0+IHZvaWQ9KCk9Pnt9LFxyXG4pIHtcclxuICBsZXQgc3RhdHVzID0gZmFsc2U7XHJcbiAgbGV0IGh0bWwgPSBcIlwiO1xyXG4gIHNldEludGVydmFsKCgpID0+IHtcclxuICAgIGNvbnN0IGVsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBpZiAoc3RhdHVzICYmIGVsICYmIGVsLmlubmVySFRNTCAhPT0gaHRtbCkge1xyXG4gICAgICBodG1sID0gZWwuaW5uZXJIVE1MO1xyXG4gICAgICDlj5jljJYoZWwpO1xyXG4gICAgfVxyXG4gICAgaWYgKGVsICYmICFzdGF0dXMpIHtcclxuICAgICAgc3RhdHVzID0gdHJ1ZTtcclxuICAgICAg5Ye6546wKGVsKTtcclxuICAgIH0gZWxzZSBpZiAoIWVsICYmIHN0YXR1cykge1xyXG4gICAgICBzdGF0dXMgPSBmYWxzZTtcclxuICAgICAg5raI5aSxKCk7XHJcbiAgICB9XHJcbiAgfSwgMTAwKTtcclxufVxyXG5cclxuZXhwb3J0IHsgZ2V0U2VsZWN0b3JzIH0gZnJvbSBcIi4uLy4uL+e9kemhteeslOiusC91dGlsXCI7XHJcbiIsImV4cG9ydCBjb25zdCBjb3B5ID0gKHN0cjogc3RyaW5nKSA9PiB7XHJcbiAgLy8g56ys5LiA56eNXHJcbiAgcmV0dXJuIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHN0cik7XHJcbn07XHJcbiIsIi8vID09VXNlclNjcmlwdD09XHJcbi8vIEBuYW1lICAgICAgICAg5pu05aW955qE5oiR5p2l5a+85Ye6XHJcbi8vIEBuYW1lc3BhY2UgICAgaHR0cHM6Ly9zaGVuemlsb25nLmNuL1xyXG4vLyBAdmVyc2lvbiAgICAgIDEuMC4wXHJcbi8vIEBkZXNjcmlwdGlvbiAg5LuO5oiR5p2l5a+85Ye6bWFya2Rvd24g5paH5qGjXHJcbi8vIEBhdXRob3IgICAgICAg5bSu55SfIGFkbWluQHNoZW56aWxvbmcuY25cclxuLy8gQGluY2x1ZGUgICAgICBodHRwczovL3d3dy53b2xhaS5jb20vKlxyXG4vLyBAZ3JhbnQgICAgICAgIHVuc2FmZVdpbmRvd1xyXG4vLyBAZ3JhbnQgICAgICAgIEdNLnNldFZhbHVlXHJcbi8vIEBncmFudCAgICAgICAgR00uZ2V0VmFsdWVcclxuLy8gQGdyYW50ICAgICAgICBHTS54bWxIdHRwUmVxdWVzdFxyXG4vLyA9PS9Vc2VyU2NyaXB0PT1cclxuaW1wb3J0IHsgcHJveHkgfSBmcm9tIFwiYWpheC1ob29rXCI7XHJcbmltcG9ydCB7IOajgOa1i+WFg+e0oOeKtuaAgSB9IGZyb20gXCIuLi91dGlsL2RvbS9lbGVtZW50XCI7XHJcbmltcG9ydCB7IGNvcHkgfSBmcm9tIFwiLi4vdXRpbC9kb20v5Ymq6LS05p2/XCI7XHJcbmltcG9ydCB0eXBlIHtcclxuICBibG9ja0VxdWF0aW9uTm9kZSxcclxuICBib29rbWFya05vZGUsXHJcbiAgYnVsbExpc3ROb2RlLFxyXG4gIGNhbGxvdXROb2RlLFxyXG4gIGNvZGVOb2RlLFxyXG4gIGNvbHVtbk5vZGUsXHJcbiAgZW1iZWROb2RlLFxyXG4gIGVudW1MaXN0Tm9kZSxcclxuICBmaWxlTm9kZSxcclxuICBpbWFnZU5vZGUsXHJcbiAgbWlkSGVhZGVyTm9kZSxcclxuICBOb2RlLFxyXG4gIE5vZGVUaXRsZSxcclxuICBwYWdlQ2h1bmtSZXMsXHJcbiAgcGFnZU5vZGUsXHJcbiAgcXVvdGVOb2RlLFxyXG4gIHJvd05vZGUsXHJcbiAgc2ltcGxlVGFibGVOb2RlLFxyXG4gIHRleHROb2RlLFxyXG4gIHRvZG9MaXN0Tm9kZSxcclxufSBmcm9tIFwiLi93b2xhaS5pbnRlcmZhY2VcIjtcclxuXHJcbmNvbnN0IF9uID0gXCJcXG5cXG5cIjtcclxuLy8gY29uc3QgX24gPSBcIlxcblwiO1xyXG5cclxuZXhwb3J0IG5hbWVzcGFjZSDmiJHmnaVtZOWvvOWHuiB7XHJcbiAgZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRvTWFya2Rvd24ocDogcGFnZUNodW5rUmVzKSB7XHJcbiAgICBsZXQgbWRUZXh0ID0gXCJcIjtcclxuICAgIGNvbnN0IGJsb2NrcyA9IE9iamVjdC5rZXlzKHAuZGF0YS5ibG9jaylcclxuICAgICAgLm1hcCgoaykgPT4gcC5kYXRhLmJsb2NrW2tdKVxyXG4gICAgICAubWFwKChlbCkgPT4gZWwudmFsdWUpO1xyXG5cclxuICAgIGNvbnNvbGUubG9nKFwiW2Jsb2Nrc11cIiwgYmxvY2tzKTtcclxuXHJcbiAgICBjb25zdCBwYWdlID0gZmluZFBhZ2UoYmxvY2tzKTtcclxuICAgIGlmICghcGFnZSkge1xyXG4gICAgICB0aHJvdyBcIuayoeacieWvu+aJvuWIsHBhZ2XlnZdcIjtcclxuICAgIH1cclxuXHJcbiAgICBtZFRleHQgKz0gYXdhaXQgbm9kZVRvTWFya2Rvd24ocGFnZSwgcCk7XHJcbiAgICByZXR1cm4gbWRUZXh0O1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZmluZFBhZ2UocDogTm9kZVtdKTogcGFnZU5vZGUgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHAuZmluZCgoZWwpID0+IGVsLnR5cGUgPT09IFwicGFnZVwiKSBhcyBwYWdlTm9kZTtcclxuICB9XHJcbiAgaW50ZXJmYWNlIHBhcmVyIHtcclxuICAgIHBhcmVyOiAoTm9kZTogYW55LCBwYWdlQ2h1bmtSZXM6IHBhZ2VDaHVua1JlcykgPT4gUHJvbWlzZTxzdHJpbmc+O1xyXG4gICAgY2hlY2s6IChOb2RlOiBOb2RlLCBwYWdlQ2h1bmtSZXM6IHBhZ2VDaHVua1JlcykgPT4gYm9vbGVhbjtcclxuICAgIC8qKiDlhbbku5boh6rlrprkuYnmianlsZXpobkgKi9cclxuICAgIFtrOiBzdHJpbmddOiBhbnk7XHJcbiAgfVxyXG4gIGludGVyZmFjZSBzdWJfbm9kZV9wYXJlciB7XHJcbiAgICBwYXJlcjogKFxyXG4gICAgICAvKiog54i26IqC54K56Ieq6Lqr5Y+v6IO96Kej5p6Q5Ye65p2l55qE5Luj56CBICovIG1kX3N0cjogc3RyaW5nLFxyXG4gICAgICBOb2RlOiBhbnksXHJcbiAgICAgIHBhZ2VDaHVua1JlczogcGFnZUNodW5rUmVzLFxyXG4gICAgKSA9PiBQcm9taXNlPHN0cmluZz47XHJcbiAgICBjaGVjazogKHBhcmVudDogTm9kZSwgcGFnZUNodW5rUmVzOiBwYWdlQ2h1bmtSZXMpID0+IGJvb2xlYW47XHJcbiAgICAvKiog5YW25LuW6Ieq5a6a5LmJ5omp5bGV6aG5ICovXHJcbiAgICBbazogc3RyaW5nXTogYW55O1xyXG4gIH1cclxuICAvKiog5a2Y5YKo5omA5pyJ6IqC54K56Kej5p6Q5ZmoICovXHJcbiAgY29uc3Qgbm9kZVBhcmVycyA9IFtdIGFzIHBhcmVyW107XHJcbiAgLyoqIOWvuSDlrZDoioLngrnlkozniLboioLngrnnmoTlhbPns7sg6L+b6KGM5aSE55CG77yM5Zug5Li65LiN5ZCM54i25a2Q6IqC54K555qE57uE57uH5pa55byP5Y+v6IO95LiN5LiA5qC3ICovXHJcbiAgY29uc3Qgc3ViX25vZGVQYXJlcnMgPSBbXSBhcyBzdWJfbm9kZV9wYXJlcltdO1xyXG4gIGV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck5vZGVQYXJlciguLi5wYXJlcnM6IHBhcmVyW10pIHtcclxuICAgIG5vZGVQYXJlcnMucHVzaCguLi5wYXJlcnMpO1xyXG4gIH1cclxuICBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJTdWJOb2RlUGFyZXIoLi4ucGFyZXJzOiBzdWJfbm9kZV9wYXJlcltdKSB7XHJcbiAgICBzdWJfbm9kZVBhcmVycy5wdXNoKC4uLnBhcmVycyk7XHJcbiAgfVxyXG4gIGV4cG9ydCBhc3luYyBmdW5jdGlvbiBub2RlVG9NYXJrZG93bihwOiBOb2RlLCBwYWdlQ2h1bmtSZXM6IHBhZ2VDaHVua1Jlcyk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBjb25zdCBwYXJlciA9IG5vZGVQYXJlcnMuZmluZCgoZWwpID0+IGVsLmNoZWNrKHAsIHBhZ2VDaHVua1JlcykpO1xyXG4gICAgaWYgKHBhcmVyKSB7XHJcbiAgICAgIGNvbnN0IG1kX3N0ciA9IGF3YWl0IHBhcmVyLnBhcmVyKHAsIHBhZ2VDaHVua1Jlcyk7XHJcbiAgICAgIGlmIChwLnN1Yl9ub2Rlcy5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBzdWJfbm9kZV9wYXJlciA9IHN1Yl9ub2RlUGFyZXJzLmZpbmQoKGVsKSA9PiBlbC5jaGVjayhwLCBwYWdlQ2h1bmtSZXMpKTtcclxuICAgICAgICBpZiAoc3ViX25vZGVfcGFyZXIpIHtcclxuICAgICAgICAgIHJldHVybiBhd2FpdCBzdWJfbm9kZV9wYXJlci5wYXJlcihtZF9zdHIsIHAsIHBhZ2VDaHVua1Jlcyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKGBb5rKh5pyJ5a+55bqU55qE57uT5p6E6Kej5p6Q5ZmoICR7cC50eXBlfV1gLCBwKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG1kX3N0cjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbnNvbGUubG9nKGBb5rKh5pyJ5a+55bqU55qE6Kej5p6Q5ZmoICR7cC50eXBlfV1gLCBwKTtcclxuICAgICAgcmV0dXJuIGAtLS0g5rKh5pyJ5a+55bqU55qE6Kej5p6Q5ZmoIC0+ICR7cC50eXBlfSAtLS1gO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIOWvueWdl+eahHRpdGxl5bGe5oCn6L+b6KGM6Kej5p6QICovXHJcbiAgZXhwb3J0IGZ1bmN0aW9uIE5vZGVUaXRsZVRvTWFya2Rvd24ocDogTm9kZVRpdGxlKSB7XHJcbiAgICBpZiAoIXApIHtcclxuICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcFxyXG4gICAgICAubWFwKChlbCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHRleHQgPSBlbFswXTtcclxuICAgICAgICBpZiAoZWwubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICByZXR1cm4gdGV4dDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc3Qg5L+u6aWwID0gZWxbMV07XHJcblxyXG4gICAgICAgICAgaWYgKOS/rumlsC5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgLyoqIOaXoOS/rumlsOWVpeS5n+S4jeWBmiAqL1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGxldCBfdGV4dCA9IHRleHQ7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IG1vZGUgb2Yg5L+u6aWwKSB7XHJcbiAgICAgICAgICAgIGlmIChtb2RlWzBdID09PSBcIkxpbmtcIikge1xyXG4gICAgICAgICAgICAgIF90ZXh0ID0gYFske190ZXh0fV0oJHttb2RlWzFdfSlgO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGVbMF0gPT09IFwiQmlMaW5rXCIgLyoqIOaIkeadpeWGhemDqOmTvuaOpSAqLykge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHdvcmtzcGFjZV91cmwgPSBnZXRXb3JrVXJsKCk7XHJcbiAgICAgICAgICAgICAgX3RleHQgPSBgWyR7X3RleHR9XSgke3dvcmtzcGFjZV91cmx9JHttb2RlWzJdfSlgO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGVbMF0gPT09IFwiPD5cIiAvKiog6KGM5YaF5Luj56CB5Z2XICovKSB7XHJcbiAgICAgICAgICAgICAgX3RleHQgPSBgXFxgJHtfdGV4dH1cXGBgO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGVbMF0gPT09IFwiQlwiIC8qKiDnspfkvZMgKi8pIHtcclxuICAgICAgICAgICAgICBfdGV4dCA9IGAqKiR7X3RleHR9KipgO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKG1vZGVbMF0gPT09IFwiaFwiIC8qKiDlrZfkvZPku6Xlj4rog4zmma/popzoibIgKi8pIHtcclxuICAgICAgICAgICAgICAvKiog6L+Z6YeM5Zyo5p+Q5Lqb6YCJ6aG55LiL5Y+v5Lul6YCJ5oup5byA5ZCv6L2s5o2iICovXHJcbiAgICAgICAgICAgICAgX3RleHQgPSBfdGV4dDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChtb2RlWzBdID09PSBcImlcIiAvKiog5pac5L2TICovKSB7XHJcbiAgICAgICAgICAgICAgX3RleHQgPSBgKiR7X3RleHR9KmA7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobW9kZVswXSA9PT0gXCJVXCIgLyoqIOS4i+WIkue6vyAqLykge1xyXG4gICAgICAgICAgICAgIC8qKiDov5nph4zlnKjmn5DkupvpgInpobnkuIvlj6/ku6XpgInmi6nlvIDlkK/ovazmjaIgKi9cclxuICAgICAgICAgICAgICBfdGV4dCA9IGAke190ZXh0fWA7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobW9kZVswXSA9PT0gXCJTXCIgLyoqIOWIoOmZpOe6vyAqLykge1xyXG4gICAgICAgICAgICAgIF90ZXh0ID0gYH5+JHtfdGV4dH1+fmA7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobW9kZVswXSA9PT0gXCJFcXVhdGlvblwiIC8qKiDlhazlvI8gKi8pIHtcclxuICAgICAgICAgICAgICBfdGV4dCA9IGAkJHtfdGV4dH0kYDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAvKiog6L+Z6YeMbW9kZeeahOexu+Wei+W6lOW9k+Wni+e7iOS4uiBuZXZlciAqL1xyXG4gICAgICAgICAgICAgIG1vZGU7XHJcbiAgICAgICAgICAgICAgX3RleHQgPSBgPOacquefpeexu+WeiyAke21vZGVbMF19PmA7XHJcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coYDzmnKrnn6XnsbvlnosgJHttb2RlWzBdfT5gLCBtb2RlLCDkv67ppbAsIGVsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIF90ZXh0O1xyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLmpvaW4oXCJcIik7XHJcbiAgfVxyXG5cclxuICAvKiog5b2T5YmN5omT5byA6aG16Z2i55qE5bel5L2c56m66Ze06ZO+5o6lICovXHJcbiAgZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtVcmwoKSB7XHJcbiAgICByZXR1cm4gbG9jYXRpb24uaHJlZi5tYXRjaCgvLio/d29sYWlcXC5jb21cXC8uKj9cXC8vKVswXTtcclxuICB9XHJcbn1cclxuY29uc3QgTm9kZVRpdGxlVG9NYXJrZG93biA9IOaIkeadpW1k5a+85Ye6Lk5vZGVUaXRsZVRvTWFya2Rvd247XHJcbuaIkeadpW1k5a+85Ye6LnJlZ2lzdGVyTm9kZVBhcmVyKFxyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gcC50eXBlID09PSBcInF1b3RlXCIsXHJcbiAgICBhc3luYyBwYXJlcihwOiBxdW90ZU5vZGUpIHtcclxuICAgICAgcmV0dXJuIGA+ICR7Tm9kZVRpdGxlVG9NYXJrZG93bihwLmF0dHJpYnV0ZXMudGl0bGUpfWA7XHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgLyoqIOWvueWQhOe6p+agh+mimOi/m+ihjOWkhOeQhlxyXG4gICAqICDlr7lidWxsTGlzdOiKgueCuei/m+ihjOWkhOeQhiAqL1xyXG4gICgoKSA9PiB7XHJcbiAgICBjb25zdCBoZWFkZXIgPSB7IGJ1bGxMaXN0OiBcIi1cIiwgaGVhZGVyOiBcIiNcIiwgbWlkSGVhZGVyOiBcIiMjXCIsIHN1YkhlYWRlcjogXCIjIyNcIiwgdGlueUhlYWRlcjogXCIjIyMjXCIgfTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBjaGVjazogKHA6IGFueSkgPT4gaGVhZGVyLmhhc093blByb3BlcnR5KHAudHlwZSksXHJcbiAgICAgIGFzeW5jIHBhcmVyKHA6IG1pZEhlYWRlck5vZGUpIHtcclxuICAgICAgICBjb25zdCB0ID0gaGVhZGVyW3AudHlwZV07XHJcbiAgICAgICAgcmV0dXJuIGAke3R9ICR7Tm9kZVRpdGxlVG9NYXJrZG93bihwLmF0dHJpYnV0ZXMudGl0bGUpfWA7XHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG4gIH0pKCksXHJcbiAgLyoqIOaVsOWtl+WIl+ihqOeahOino+aekCAqL1xyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gcC50eXBlID09PSBcImVudW1MaXN0XCIsXHJcbiAgICBhc3luYyBwYXJlcihwOiBlbnVtTGlzdE5vZGUsIHBhZ2VDaHVua1Jlcykge1xyXG4gICAgICBsZXQgbCA9IDA7XHJcbiAgICAgIGNvbnN0IGJyb3RoZXJzID0gc3ViX25vZGVUb05vZGUocGFnZUNodW5rUmVzLmRhdGEuYmxvY2tbcC5wYXJlbnRfaWRdLnZhbHVlLCBwYWdlQ2h1bmtSZXMpO1xyXG4gICAgICBsZXQgaSA9IGJyb3RoZXJzLmZpbmRJbmRleCgoZWwpID0+IGVsLmlkID09PSBwLmlkKTtcclxuICAgICAgd2hpbGUgKGkgPj0gMCAmJiBicm90aGVyc1tpXS50eXBlID09PSBcImVudW1MaXN0XCIpIHtcclxuICAgICAgICBpIC09IDE7XHJcbiAgICAgICAgbCArPSAxO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIGNvbnN0IGwgPSBwYWdlQ2h1bmtSZXMuZGF0YS5ibG9ja1twLnBhcmVudF9pZF0udmFsdWUuc3ViX25vZGVzLmZpbmRJbmRleCgoaWQpID0+IGlkID09PSBwLmlkKSArIDE7XHJcbiAgICAgIHJldHVybiBgJHtsfS4gJHtOb2RlVGl0bGVUb01hcmtkb3duKHAuYXR0cmlidXRlcy50aXRsZSl9YDtcclxuICAgIH0sXHJcbiAgfSxcclxuICAvKiog5oqY5Y+g5YiX6KGo55qE6Kej5p6QICovXHJcbiAge1xyXG4gICAgY2hlY2s6IChwKSA9PiBwLnR5cGUgPT09IFwidG9nZ2xlTGlzdFwiLFxyXG4gICAgYXN5bmMgcGFyZXIocDogZW51bUxpc3ROb2RlLCBwYWdlQ2h1bmtSZXMpIHtcclxuICAgICAgcmV0dXJuIE5vZGVUaXRsZVRvTWFya2Rvd24ocC5hdHRyaWJ1dGVzLnRpdGxlKTtcclxuICAgIH0sXHJcbiAgfSxcclxuICAvKiog5a+55Lmm562+55qE6Kej5p6Q77yMICoq6L+Z6YeM5Yiw5pe25YCZ5bqU6K+l6KaB6LCD5oiQ5Y+v5o6n55qEKiogKi9cclxuICB7XHJcbiAgICBjaGVjazogKHApID0+IHAudHlwZSA9PT0gXCJib29rbWFya1wiLFxyXG4gICAgYXN5bmMgcGFyZXIocDogYm9va21hcmtOb2RlKSB7XHJcbiAgICAgIGNvbnN0IHJpY2ggPSBwLmF0dHJpYnV0ZXMucmljaF9tZWRpYVswXTtcclxuICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSByaWNoLmRlc2NyaXB0aW9uIHx8IFwiXCI7XHJcbiAgICAgIGNvbnN0IHRodW1ibmFpbCA9XHJcbiAgICAgICAgLyoqIOWSjOaIkeadpeS4gOagt+acieaPj+i/sOS/oeaBr+aJjeaYvuekuue8qeeVpeWbviAqLyBkZXNjcmlwdGlvbiAmJiByaWNoPy50aHVtYm5haWw/Lmxlbmd0aFxyXG4gICAgICAgICAgPyBgIVtdKCR7cmljaC50aHVtYm5haWxbMF0uaHJlZn0pezpoZWlnaHQ9XCI2MHB4XCIgd2lkdGg9XCI2MHB4XCJ9YFxyXG4gICAgICAgICAgOiBcIlwiO1xyXG4gICAgICByZXR1cm4gYD4gWyFbXSgke3JpY2guaWNvbnNbMF0uaHJlZn0pezpoZWlnaHQ9XCIzMHB4XCIgd2lkdGg9XCIzMHB4XCJ9IOW0rueUnyDkuIDkupvpmo/nrJRdKCR7cC5hdHRyaWJ1dGVzLnNvdXJjZX0gXCIke2Rlc2NyaXB0aW9ufVwiKSAke2Rlc2NyaXB0aW9ufSAke3RodW1ibmFpbH1gO1xyXG4gICAgfSxcclxuICB9LFxyXG4gIC8qKiDlr7nltYzlhaXlhoXlrrnnmoTop6PmnpDvvIwgKirov5nph4zliLDml7blgJnlupTor6XopoHosIPmiJDlj6/mjqfnmoQqKiAqL1xyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gW1wiZW1iZWRcIiwgXCJiaWxpYmlsaVZpZGVvXCIsIFwidGVuY2VudFZpZGVvXCIsIFwieW91a3VWaWRlb1wiLCBcInlvdXR1YmVWaWRlb1wiXS5pbmNsdWRlcyhwLnR5cGUpLFxyXG4gICAgYXN5bmMgcGFyZXIocDogZW1iZWROb2RlKSB7XHJcbiAgICAgIHJldHVybiBgPGlmcmFtZSBzcmM9XCIke3AuYXR0cmlidXRlcy5lbWJlZExpbmt9XCI+PC9pZnJhbWU+YDtcclxuICAgIH0sXHJcbiAgfSxcclxuICAvKiog5a+5552A6YeN5paH5a2X55qE6Kej5p6QICovXHJcbiAge1xyXG4gICAgY2hlY2s6IChwKSA9PiBbXCJjYWxsb3V0XCJdLmluY2x1ZGVzKHAudHlwZSksXHJcbiAgICBhc3luYyBwYXJlcihwOiBjYWxsb3V0Tm9kZSkge1xyXG4gICAgICByZXR1cm4gYDxlbT4ke+aIkeadpW1k5a+85Ye6Lk5vZGVUaXRsZVRvTWFya2Rvd24ocC5hdHRyaWJ1dGVzLnRpdGxlKX08L2VtPmA7XHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgLyoqIOWIhuWJsue6vyAqL1xyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gW1wiZGl2aWRlclwiXS5pbmNsdWRlcyhwLnR5cGUpLFxyXG4gICAgYXN5bmMgcGFyZXIocDogTm9kZSkge1xyXG4gICAgICByZXR1cm4gYC0tLWA7XHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgLyoqIOaWh+S7tiAqL1xyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gW1wiZmlsZVwiXS5pbmNsdWRlcyhwLnR5cGUpLFxyXG4gICAgYXN5bmMgcGFyZXIocDogZmlsZU5vZGUpIHtcclxuICAgICAgLyoqIFRPRE8g6L+Z6YeM6ZyA6KaB6I635Y+W562+5ZCN5omN6IO96K6/6ZeuICovXHJcbiAgICAgIGNvbnN0IHNyYyA9IGBodHRwczovL3NlY3VyZS1zdGF0aWMud29sYWkuY29tLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHAuYXR0cmlidXRlcy5maWxlWzBdKX1gO1xyXG4gICAgICByZXR1cm4gYFtmaWxlOiR7cC5hdHRyaWJ1dGVzLmFsaWFzWzBdfV0oJHtzcmN9fSlgO1xyXG4gICAgfSxcclxuICB9LFxyXG4gIC8qKiDlhazlvI8gKi9cclxuICB7XHJcbiAgICBjaGVjazogKHApID0+IFtcImJsb2NrRXF1YXRpb25cIl0uaW5jbHVkZXMocC50eXBlKSxcclxuICAgIGFzeW5jIHBhcmVyKHA6IGJsb2NrRXF1YXRpb25Ob2RlKSB7XHJcbiAgICAgIHJldHVybiBgJCRcXG4ke3AuYXR0cmlidXRlcy50aXRsZS5qb2luKFwiXFxuXCIpfVxcbiQkYDtcclxuICAgIH0sXHJcbiAgfSxcclxuICAvKiog5qih5p2/5oyJ6ZKuICovXHJcbiAge1xyXG4gICAgY2hlY2s6IChwKSA9PiBbXCJ0ZW1wbGF0ZUJ1dHRvblwiXS5pbmNsdWRlcyhwLnR5cGUpLFxyXG4gICAgYXN5bmMgcGFyZXIocDogTm9kZSkge1xyXG4gICAgICAvKiogVE9ETyDmmoLkuI3op6PmnpDmqKHmnb/mjInpkq4gKi9cclxuICAgICAgcmV0dXJuIGBgO1xyXG4gICAgfSxcclxuICB9LFxyXG4gIC8qKiDooajmoLzop6PmnpDlmaggKi9cclxuICB7XHJcbiAgICBjaGVjazogKHApID0+IFtcInNpbXBsZVRhYmxlXCJdLmluY2x1ZGVzKHAudHlwZSksXHJcbiAgICBhc3luYyBwYXJlcihwOiBzaW1wbGVUYWJsZU5vZGUpIHtcclxuICAgICAgLyoqIFRPRE8g5pqC5LiN6Kej5p6Q5qih5p2/5oyJ6ZKuICovXHJcbiAgICAgIGNvbnN0IGNlbGxzID0gSlNPTi5wYXJzZShwLmF0dHJpYnV0ZXMuY2VsbHMpIGFzIHNpbXBsZVRhYmxlTm9kZVtcImF0dHJpYnV0ZXNcIl1bXCJjZWxsc0pzb25cIl07XHJcbiAgICAgIGxldCBtZF9zdHIgPSBcIlwiO1xyXG4gICAgICAvKiog6YGN5Y6G6KGMICovXHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2VsbHNbMF0uY29sdW1uLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGkgPT09IDEpIHtcclxuICAgICAgICAgIC8qKiDmoIfpopjmoI/nmoTliIbpmpQgKi9cclxuICAgICAgICAgIG1kX3N0ciArPSBcInxcIiArIGNlbGxzLm1hcCgoZWwpID0+IFwiLVwiKS5qb2luKFwifFwiKSArIFwifFxcblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBtZF9zdHIgKz0gXCJ8XCI7XHJcbiAgICAgICAgLyoqIOmBjeWOhuWIlyAqL1xyXG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY2VsbHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgIC8qKiDlvZPliY3pgY3ljobliLDnmoTlhYPntKAgKi9cclxuICAgICAgICAgIGNvbnN0IGN1ciA9IGNlbGxzW2pdLmNvbHVtbltpXTtcclxuICAgICAgICAgIG1kX3N0ciArPSDmiJHmnaVtZOWvvOWHui5Ob2RlVGl0bGVUb01hcmtkb3duKGN1ci5hdHRyaWJ1dGVzLnRpdGxlKSArIFwifFwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBtZF9zdHIgKz0gXCJcXG5cIjtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbWRfc3RyO1xyXG4gICAgfSxcclxuICB9LFxyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gcC50eXBlID09PSBcInRleHRcIixcclxuICAgIGFzeW5jIHBhcmVyKHA6IHRleHROb2RlKSB7XHJcbiAgICAgIHJldHVybiBgJHtOb2RlVGl0bGVUb01hcmtkb3duKHAuYXR0cmlidXRlcy50aXRsZSl9YDtcclxuICAgIH0sXHJcbiAgfSxcclxuICB7XHJcbiAgICBjaGVjazogKHApID0+IHAudHlwZSA9PT0gXCJyb3dcIiB8fCBwLnR5cGUgPT09IFwiY29sdW1uXCIsXHJcbiAgICBhc3luYyBwYXJlcihwOiByb3dOb2RlLCBwYWdlQ2h1bmtSZXM6IHBhZ2VDaHVua1Jlcykge1xyXG4gICAgICBjb25zdCBzdWJfbm9kZXMgPSBwLnN1Yl9ub2Rlcy5tYXAoKGlkKSA9PiBwYWdlQ2h1bmtSZXMuZGF0YS5ibG9ja1tpZF0pO1xyXG4gICAgICBsZXQgbWRUZXh0ID0gYGA7XHJcbiAgICAgIGZvciAoY29uc3QgZWwgb2Ygc3ViX25vZGVzKSB7XHJcbiAgICAgICAgbWRUZXh0ICs9IChhd2FpdCDmiJHmnaVtZOWvvOWHui5ub2RlVG9NYXJrZG93bihlbC52YWx1ZSwgcGFnZUNodW5rUmVzKSkgKyBfbjtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbWRUZXh0O1xyXG4gICAgfSxcclxuICB9LFxyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gcC50eXBlID09PSBcImNvZGVcIixcclxuICAgIGFzeW5jIHBhcmVyKHA6IGNvZGVOb2RlLCBwYWdlQ2h1bmtSZXM6IHBhZ2VDaHVua1Jlcykge1xyXG4gICAgICByZXR1cm4gYFxcYFxcYFxcYCR7cC5hdHRyaWJ1dGVzLmxhbmd1YWdlfVxcbiR7Tm9kZVRpdGxlVG9NYXJrZG93bihwLmF0dHJpYnV0ZXMudGl0bGUpfVxcblxcYFxcYFxcYGA7XHJcbiAgICB9LFxyXG4gIH0sXHJcbiAge1xyXG4gICAgY2hlY2s6IChwKSA9PiBwLnR5cGUgPT09IFwiaW1hZ2VcIixcclxuICAgIGFzeW5jIHBhcmVyKHA6IGltYWdlTm9kZSwgcGFnZUNodW5rUmVzOiBwYWdlQ2h1bmtSZXMpIHtcclxuICAgICAgLyoqIOatpOWkhOmcgOimgeWcqOa1j+iniOWZqOWGheaJjeiDveato+W4uOi/kOihjCAqL1xyXG4gICAgICBjb25zdCBzcmMgPSAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgI2lkLSR7cC5pZH0gaW1nYCkgYXMgSFRNTEltYWdlRWxlbWVudCkuZ2V0QXR0cmlidXRlKFwic3JjXCIpO1xyXG4gICAgICByZXR1cm4gYCFbJHtOb2RlVGl0bGVUb01hcmtkb3duKHAuYXR0cmlidXRlcy50aXRsZSl9XSgke3NyY30pYDsgLy8gVE9ETyDmj4/ov7DlupTor6XopoHljrvojrflj5bliLBcclxuICAgIH0sXHJcbiAgfSxcclxuICB7XHJcbiAgICBjaGVjazogKHApID0+IHAudHlwZSA9PT0gXCJwYWdlXCIsXHJcbiAgICBhc3luYyBwYXJlcihwOiBwYWdlTm9kZSwgcGFnZUNodW5rUmVzOiBwYWdlQ2h1bmtSZXMpIHtcclxuICAgICAgY29uc3Qgd29ya3NwYWNlX3VybCA9IOaIkeadpW1k5a+85Ye6LmdldFdvcmtVcmwoKTtcclxuICAgICAgaWYgKHAuaWQgPT09IE9iamVjdC5rZXlzKHBhZ2VDaHVua1Jlcy5kYXRhLmJsb2NrKVswXSkge1xyXG4gICAgICAgIC8qKiDpobblsYLlnZcg5Lmf5bCx5piv5b2T5YmN6aG16Z2i5Z2XICovXHJcbiAgICAgICAgcmV0dXJuIGAjIFske05vZGVUaXRsZVRvTWFya2Rvd24ocC5hdHRyaWJ1dGVzLnRpdGxlKX1dKCR7d29ya3NwYWNlX3VybH0ke3AuaWR9KWA7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLyoqIOmhtemdouWGheW8leeUqOWFtuS7lumhtemdoueahOWdlyAqL1xyXG4gICAgICAgIHJldHVybiBgWyR7Tm9kZVRpdGxlVG9NYXJrZG93bihwLmF0dHJpYnV0ZXMudGl0bGUpfV0oJHt3b3Jrc3BhY2VfdXJsfSR7cC5pZH0pYDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuICB9LFxyXG4gIHtcclxuICAgIGNoZWNrOiAocCkgPT4gcC50eXBlID09PSBcInRvZG9MaXN0XCIsXHJcbiAgICBhc3luYyBwYXJlcihwOiB0b2RvTGlzdE5vZGUsIHBhZ2VDaHVua1JlczogcGFnZUNodW5rUmVzKSB7XHJcbiAgICAgIHJldHVybiBgWyR7cC5hdHRyaWJ1dGVzLmNoZWNrZWQgPT09IFwieWVzXCIgPyBcInhcIiA6IFwiIFwifV0gJHtOb2RlVGl0bGVUb01hcmtkb3duKHAuYXR0cmlidXRlcy50aXRsZSl9YDtcclxuICAgIH0sXHJcbiAgfSxcclxuKTtcclxuXHJcbmZ1bmN0aW9uIHN1Yl9ub2RlVG9Ob2RlKHA6IE5vZGUsIHBhZ2VDaHVua1JlczogcGFnZUNodW5rUmVzKSB7XHJcbiAgcmV0dXJuIHAuc3ViX25vZGVzLm1hcCgoaWQpID0+IHBhZ2VDaHVua1Jlcy5kYXRhLmJsb2NrW2lkXS52YWx1ZSk7XHJcbn1cclxu5oiR5p2lbWTlr7zlh7oucmVnaXN0ZXJTdWJOb2RlUGFyZXIoXHJcbiAgLyoqIOWvuemhtemdouS4i+mdoueahOS4gOe6p+iKgueCuei/m+ihjOWkhOeQhiAqLyB7XHJcbiAgICBjaGVjazogKHApID0+IHAudHlwZSA9PT0gXCJwYWdlXCIsXHJcbiAgICBhc3luYyBwYXJlcihtZF9zdHIsIHA6IE5vZGUsIHBhZ2VDaHVua1Jlcykge1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIG1kX3N0ciArXHJcbiAgICAgICAgXCJcXG5cXG5cIiArXHJcbiAgICAgICAgKFxyXG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoc3ViX25vZGVUb05vZGUocCwgcGFnZUNodW5rUmVzKS5tYXAoKHApID0+IOaIkeadpW1k5a+85Ye6Lm5vZGVUb01hcmtkb3duKHAsIHBhZ2VDaHVua1JlcykpKVxyXG4gICAgICAgICkuam9pbihcIlxcblxcblwiKVxyXG4gICAgICApO1xyXG4gICAgfSxcclxuICB9LFxyXG4gIC8qKiDlr7nliJfooajnsbvnmoTlsYLnuqfov5vooYzlpITnkIYgKi8ge1xyXG4gICAgY2hlY2s6IChwKSA9PiBbXCJidWxsTGlzdFwiLCBcImVudW1MaXN0XCIsIFwidG9kb0xpc3RcIl0uaW5jbHVkZXMocC50eXBlKSxcclxuICAgIGFzeW5jIHBhcmVyKG1kX3N0ciwgcDogTm9kZSwgcGFnZUNodW5rUmVzKSB7XHJcbiAgICAgIC8qKiDojrflj5bkuIDkuKroioLngrnmnInlpJrlsJHniLbnuqcgKi9cclxuICAgICAgZnVuY3Rpb24gZ2V0Tm9kZU51bWJlck9mTGF5ZXJzKHA6IE5vZGUsIHBhZ2VDaHVua1JlczogcGFnZUNodW5rUmVzKSB7XHJcbiAgICAgICAgbGV0IGwgPSAwO1xyXG4gICAgICAgIGxldCBjdXIgPSBwO1xyXG4gICAgICAgIHdoaWxlIChjdXI/LnBhcmVudF9pZCkge1xyXG4gICAgICAgICAgbCsrO1xyXG4gICAgICAgICAgY3VyID0gcGFnZUNodW5rUmVzLmRhdGEuYmxvY2tbY3VyLnBhcmVudF9pZF0/LnZhbHVlO1xyXG4gICAgICAgICAgaWYgKGN1cj8udHlwZSA9PT0gXCJ0b2dnbGVMaXN0XCIpIHtcclxuICAgICAgICAgICAgLyoqIOS4jeaYr+ebuOWQjOeahOe7k+aehOS6hu+8jOWxgue6p+WFs+ezu+eul+WIsOi/memHjOS9jee9ru+8jOabtOWkluWxgueahOWxgue6p+WFs+ezu+S6pOe7meivpee7k+aehOiHquihjOWkhOeQhiAqL1xyXG4gICAgICAgICAgICBsKys7IC8qKiDlm6DkuLrkuIrpnaLnrpfkuobpobXpnaLvvIzov5nph4zlsIYgdG9nZ2xlTGlzdCDlvZPlgZrlkozpobXpnaLkuIDmoLfnnIvlvoUgKi9cclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8qKiDkuI3nrpfpobXpnaLov5nkuIDnuqcgKi9cclxuICAgICAgICByZXR1cm4gbCAtIDE7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgbCA9IGdldE5vZGVOdW1iZXJPZkxheWVycyhwLCBwYWdlQ2h1bmtSZXMpIC0gMTtcclxuICAgICAgLy8gY29uc29sZS5sb2cobCxwLG1kX3N0cik7XHJcblxyXG4gICAgICBjb25zdCBtZF9zdHJfTGlzdCA9IChcclxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChzdWJfbm9kZVRvTm9kZShwLCBwYWdlQ2h1bmtSZXMpLm1hcCgocCkgPT4g5oiR5p2lbWTlr7zlh7oubm9kZVRvTWFya2Rvd24ocCwgcGFnZUNodW5rUmVzKSkpXHJcbiAgICAgICkubWFwKFxyXG4gICAgICAgIChtZF9zdHIpID0+XHJcbiAgICAgICAgICBgJHtcIlwiLnBhZEVuZCgvKiog5YiX6KGo5YaF55qE5piv5b2T5YmN6IqC54K555qE5a2Q6IqC54K56ICMbOaYr+W9k+WJjeiKgueCueeahOWxgue6p++8jOaJgOS7pei/memHjOimgSsxICovIGwgKyAxLCBcIlxcdFwiKX0ke21kX3N0cn1gLFxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4gYCR7bWRfc3RyfSR7bWRfc3RyX0xpc3QubGVuZ3RoID8gXCJcXG5cIiArIG1kX3N0cl9MaXN0LmpvaW4oXCJcXG5cIikgOiBcIlwifWA7XHJcbiAgICB9LFxyXG4gIH0sXHJcbiAgLyoqIOWvueaKmOWPoOWIl+ihqOexu+eahOWxgue6p+i/m+ihjOWkhOeQhiAqLyB7XHJcbiAgICBjaGVjazogKHApID0+IFtcInRvZ2dsZUxpc3RcIl0uaW5jbHVkZXMocC50eXBlKSxcclxuICAgIGFzeW5jIHBhcmVyKG1kX3N0ciwgcDogTm9kZSwgcGFnZUNodW5rUmVzKSB7XHJcbiAgICAgIGNvbnN0IG1kX3N0cl9MaXN0ID0gYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgICAgc3ViX25vZGVUb05vZGUocCwgcGFnZUNodW5rUmVzKS5tYXAoKHApID0+IOaIkeadpW1k5a+85Ye6Lm5vZGVUb01hcmtkb3duKHAsIHBhZ2VDaHVua1JlcykpLFxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4gYDxkZXRhaWxzPlxyXG4gICAgICA8c3VtbWFyeT4ke21kX3N0cn08L3N1bW1hcnk+XHJcbiR7bWRfc3RyX0xpc3Quam9pbihfbil9XHJcbiAgPC9kZXRhaWxzPmA7XHJcbiAgICB9LFxyXG4gIH0sXHJcbik7XHJcblxyXG5sZXQgY3VyRGF0YSA9IG51bGwgYXMgbnVsbCB8IHN0cmluZztcclxucHJveHkoe1xyXG4gIC8v6K+35rGC5Y+R6LW35YmN6L+b5YWlXHJcbiAgb25SZXF1ZXN0OiAoY29uZmlnLCBoYW5kbGVyKSA9PiB7XHJcbiAgICAvLyBjb25zb2xlLmxvZyhcIlvwn5Ka5byA5aeL6K+35rGCXVwiLCBjb25maWcudXJsKTtcclxuICAgIC8vIGNvbmZpZy51cmwgPSB1cmxIYW5kbGVyKGNvbmZpZy51cmwpO1xyXG4gICAgLyoqIOWFs+mXrSB3aXRoQ3JlZGVudGlhbHMg6YG/5YWN6Kem5Y+R6Leo5Z+fICovXHJcbiAgICAvLyBjb25maWcud2l0aENyZWRlbnRpYWxzID0gZmFsc2U7XHJcbiAgICBoYW5kbGVyLm5leHQoY29uZmlnKTtcclxuICB9LFxyXG4gIC8v6K+35rGC5Y+R55Sf6ZSZ6K+v5pe26L+b5YWl77yM5q+U5aaC6LaF5pe277yb5rOo5oSP77yM5LiN5YyF5ousaHR0cOeKtuaAgeeggemUmeivr++8jOWmgjQwNOS7jeeEtuS8muiupOS4uuivt+axguaIkOWKn1xyXG4gIG9uRXJyb3I6IChlcnIsIGhhbmRsZXIpID0+IHtcclxuICAgIGhhbmRsZXIubmV4dChlcnIpO1xyXG4gIH0sXHJcbiAgLy/or7fmsYLmiJDlip/lkI7ov5vlhaVcclxuICBvblJlc3BvbnNlOiAocmVzcG9uc2UsIGhhbmRsZXIpID0+IHtcclxuICAgIGhhbmRsZXIubmV4dChyZXNwb25zZSk7XHJcbiAgICBpZiAocmVzcG9uc2UuY29uZmlnLnVybC5lbmRzV2l0aChcInRyYW5zYWN0aW9uL2dldFBhZ2VDaHVua3NcIikpIHtcclxuICAgICAgY3VyRGF0YSA9IHJlc3BvbnNlLnJlc3BvbnNlO1xyXG4gICAgfVxyXG4gIH0sXHJcbn0pO1xyXG5cclxu5qOA5rWL5YWD57Sg54q25oCBKCdbZGF0YS1ncm93aW5nLXRpdGxlPVwi5aSN5Yi26aG16Z2i5byV55So6ZO+5o6lLeWktOmDqOagj1wiXScsIChlbCkgPT4ge1xyXG4gIGNvbnNvbGUubG9nKFwiWyAgZWxdXCIsIGVsKTtcclxuICBjb25zdCBidG4gPSBlbC5uZXh0RWxlbWVudFNpYmxpbmc7XHJcbiAgY29uc3QgbmV3QnRuID0gYnRuLmNsb25lTm9kZSh0cnVlKSBhcyBIVE1MRWxlbWVudDtcclxuICBidG4ucGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZChuZXdCdG4pO1xyXG5cclxuICBuZXdCdG4ucXVlcnlTZWxlY3RvckFsbChcInNwYW5cIilbMV0udGV4dENvbnRlbnQgPSBgW+KcqF0g5a+85Ye6TWFya2Rvd25gO1xyXG4gIG5ld0J0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYXN5bmMgKCkgPT4ge1xyXG4gICAgaWYgKGN1ckRhdGEgPT09IG51bGwpIHtcclxuICAgICAgcmV0dXJuIGFsZXJ0KFwi5rKh5pyJ6I635Y+W5Yiw5b2T5YmN6aG16Z2i5pWw5o2u77yM5oKo5Y+v5Lul5bCd6K+V5Yi35paw6YeN6K+V44CCXCIpO1xyXG4gICAgfVxyXG4gICAgY29uc3QgcmVzID0gSlNPTi5wYXJzZShjdXJEYXRhKTtcclxuICAgIGNvbnN0IG1kID0gYXdhaXQg5oiR5p2lbWTlr7zlh7oudG9NYXJrZG93bihyZXMpO1xyXG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFttZF0sIHsgdHlwZTogXCJ0ZXh0L3BsYWluO2NoYXJzZXQ9dXRmLThcIiB9KTtcclxuICAgIGNvbnN0IGRvd25sb2FkVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcclxuICAgIGNvbnNvbGUubG9nKGBbbWFya2Rvd246JHtkb3dubG9hZFVybH1dXFxuLS0tLVxcbmAsIG1kKTtcclxuICAgIGNvbnNvbGUubG9nKFwiW2NvcHkobWQpXVwiLCBjb3B5KG1kKSk7XHJcbiAgICBhbGVydChcIuWkjeWItuaIkOWKn1wiKTtcclxuICB9KTtcclxufSk7XHJcblxyXG5uYW1lc3BhY2Ug6ZmE5Yqg5oyJ6ZKuIHtcclxuICBleHBvcnQgbGV0IOW3sumZhOWKoCA9IGZhbHNlO1xyXG59XHJcbi8qKiDmm7/mjaIgd2luZG93cyDkuIrnmoQgeG1sIOWvueixoSAqL1xyXG4vL0B0cy1pZ25vcmVcclxudW5zYWZlV2luZG93LlhNTEh0dHBSZXF1ZXN0ID0gWE1MSHR0cFJlcXVlc3Q7XHJcbiJdLCJzb3VyY2VSb290IjoiIn0=