/* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./node_modules/axios/dist/browser/axios.cjs": /*!***************************************************!*\ !*** ./node_modules/axios/dist/browser/axios.cjs ***! \***************************************************/ /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; eval("/* provided dependency */ var process = __webpack_require__(/*! process/browser.js */ \"./node_modules/process/browser.js\");\n/* provided dependency */ var Buffer = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.js\")[\"Buffer\"];\n/*! Axios v1.8.4 Copyright (c) 2025 Matt Zabriskie and contributors */\n\n\nfunction bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n};\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val);\n};\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n};\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : __webpack_require__.g)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else {\n result[targetKey] = val;\n }\n };\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n};\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n};\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n};\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n};\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n};\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n};\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[Symbol.iterator];\n\n const iterator = generator.call(obj);\n\n let result;\n\n while ((result = iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n};\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n};\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n};\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n};\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n };\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n};\n\nconst noop = () => {};\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n};\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === 'FormData' && thing[Symbol.iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n };\n\n return visit(obj, 0);\n};\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\nvar utils$1 = {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap\n};\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils$1.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils$1.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype$1 = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype$1, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype$1);\n\n utils$1.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n AxiosError.call(axiosError, error.message, code, config, request, response);\n\n axiosError.cause = error;\n\n axiosError.name = error.name;\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\n// eslint-disable-next-line strict\nvar httpAdapter = null;\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils$1.isPlainObject(thing) || utils$1.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils$1.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils$1.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils$1.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils$1.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils$1.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils$1.isSpecCompliantForm(formData);\n\n if (!utils$1.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils$1.isDate(value)) {\n return value.toISOString();\n }\n\n if (!useBlob && utils$1.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils$1.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils$1.isArray(value) && isFlatArray(value)) ||\n ((utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils$1.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils$1.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils$1.forEach(value, function each(el, key) {\n const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils$1.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode$1(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode$1);\n } : encode$1;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nfunction buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils$1.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils$1.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils$1.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nvar InterceptorManager$1 = InterceptorManager;\n\nvar transitionalDefaults = {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n\nvar URLSearchParams$1 = typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n\nvar FormData$1 = typeof FormData !== 'undefined' ? FormData : null;\n\nvar Blob$1 = typeof Blob !== 'undefined' ? Blob : null;\n\nvar platform$1 = {\n isBrowser: true,\n classes: {\n URLSearchParams: URLSearchParams$1,\n FormData: FormData$1,\n Blob: Blob$1\n },\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n\nconst hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nvar utils = /*#__PURE__*/Object.freeze({\n __proto__: null,\n hasBrowserEnv: hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv: hasStandardBrowserEnv,\n navigator: _navigator,\n origin: origin\n});\n\nvar platform = {\n ...utils,\n ...platform$1\n};\n\nfunction toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils$1.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n }\n }, options));\n}\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils$1.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils$1.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils$1.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils$1.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils$1.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) {\n const obj = {};\n\n utils$1.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils$1.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils$1.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils$1.isObject(data);\n\n if (isObjectPayload && utils$1.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils$1.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils$1.isArrayBuffer(data) ||\n utils$1.isBuffer(data) ||\n utils$1.isStream(data) ||\n utils$1.isFile(data) ||\n utils$1.isBlob(data) ||\n utils$1.isReadableStream(data)\n ) {\n return data;\n }\n if (utils$1.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils$1.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils$1.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nvar defaults$1 = defaults;\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils$1.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nvar parseHeaders = rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils$1.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils$1.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils$1.isString(value)) return;\n\n if (utils$1.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils$1.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils$1.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils$1.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils$1.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite);\n } else if(utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils$1.isHeaders(header)) {\n for (const [key, value] of header.entries()) {\n setHeader(value, key, rewrite);\n }\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils$1.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils$1.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils$1.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils$1.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils$1.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils$1.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils$1.forEach(this, (value, header) => {\n const key = utils$1.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils$1.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils$1.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils$1.freezeMethods(AxiosHeaders);\n\nvar AxiosHeaders$1 = AxiosHeaders;\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nfunction transformData(fns, response) {\n const config = this || defaults$1;\n const context = response || config;\n const headers = AxiosHeaders$1.from(context.headers);\n let data = context.data;\n\n utils$1.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n\nfunction isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils$1.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nfunction settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n\nfunction parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\n/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn.apply(null, args);\n };\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs);\n }, threshold - passed);\n }\n }\n };\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nconst progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n};\n\nconst progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n};\n\nconst asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args));\n\nvar isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n\nvar cookies = platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils$1.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils$1.isString(path) && cookie.push('path=' + path);\n\n utils$1.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nfunction isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nfunction combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nfunction buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders$1 ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nfunction mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) {\n return utils$1.merge.call({caseless}, target, source);\n } else if (utils$1.isPlainObject(source)) {\n return utils$1.merge({}, source);\n } else if (utils$1.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils$1.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils$1.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils$1.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils$1.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils$1.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils$1.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n\nvar resolveConfig = (config) => {\n const newConfig = mergeConfig({}, config);\n\n let {data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth} = newConfig;\n\n newConfig.headers = headers = AxiosHeaders$1.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n let contentType;\n\n if (utils$1.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // Let the browser set it\n } else if ((contentType = headers.getContentType()) !== false) {\n // fix semicolon duplication issue for ReactNative FormData implementation\n const [type, ...tokens] = contentType ? contentType.split(';').map(token => token.trim()).filter(Boolean) : [];\n headers.setContentType([type || 'multipart/form-data', ...tokens].join('; '));\n }\n }\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n};\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nvar xhrAdapter = isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders$1.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders$1.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils$1.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n};\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n };\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT));\n }, timeout);\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n };\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils$1.asap(unsubscribe);\n\n return signal;\n }\n};\n\nvar composeSignals$1 = composeSignals;\n\nconst streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n};\n\nconst readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n};\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n};\n\nconst trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n };\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n};\n\nconst isFetchSupported = typeof fetch === 'function' && typeof Request === 'function' && typeof Response === 'function';\nconst isReadableStreamSupported = isFetchSupported && typeof ReadableStream === 'function';\n\n// used only inside the fetch adapter\nconst encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Response(str).arrayBuffer())\n);\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n};\n\nconst supportsRequestStream = isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n});\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst supportsResponseStream = isReadableStreamSupported &&\n test(() => utils$1.isReadableStream(new Response('').body));\n\n\nconst resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n};\n\nisFetchSupported && (((res) => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = utils$1.isFunction(res[type]) ? (res) => res[type]() :\n (_, config) => {\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n });\n });\n})(new Response));\n\nconst getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if(utils$1.isBlob(body)) {\n return body.size;\n }\n\n if(utils$1.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if(utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if(utils$1.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if(utils$1.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n};\n\nconst resolveBodyLength = async (headers, body) => {\n const length = utils$1.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n};\n\nvar fetchAdapter = isFetchSupported && (async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader);\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils$1.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = \"credentials\" in Request.prototype;\n request = new Request(url, {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n });\n\n let response = await fetch(request);\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders$1.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n });\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n});\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: fetchAdapter\n};\n\nutils$1.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false;\n\nvar adapters = {\n getAdapter: (adapters) => {\n adapters = utils$1.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n};\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nfunction dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders$1.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults$1.adapter);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders$1.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders$1.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n\nconst VERSION = \"1.8.4\";\n\nconst validators$1 = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators$1[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators$1.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators$1.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nvar validator = {\n assertOptions,\n validators: validators$1\n};\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig;\n this.interceptors = {\n request: new InterceptorManager$1(),\n response: new InterceptorManager$1()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack;\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils$1.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n };\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils$1.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils$1.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders$1.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift.apply(chain, requestInterceptorChain);\n chain.push.apply(chain, responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n i = 0;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nvar Axios$1 = Axios;\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nvar CancelToken$1 = CancelToken;\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nfunction spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nfunction isAxiosError(payload) {\n return utils$1.isObject(payload) && (payload.isAxiosError === true);\n}\n\nconst HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nvar HttpStatusCode$1 = HttpStatusCode;\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios$1(defaultConfig);\n const instance = bind(Axios$1.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils$1.extend(instance, Axios$1.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils$1.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults$1);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios$1;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken$1;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders$1;\n\naxios.formToJSON = thing => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode$1;\n\naxios.default = axios;\n\nmodule.exports = axios;\n//# sourceMappingURL=axios.cjs.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvZGlzdC9icm93c2VyL2F4aW9zLmNqcyIsIm1hcHBpbmdzIjoiOztBQUFBO0FBQ2E7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSxPQUFPLFVBQVU7QUFDakIsT0FBTyxnQkFBZ0I7O0FBRXZCO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0EsT0FBTyxTQUFTOztBQUVoQjtBQUNBO0FBQ0E7QUFDQSxXQUFXLEdBQUc7QUFDZDtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsR0FBRztBQUNkO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxHQUFHO0FBQ2Q7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxHQUFHO0FBQ2Q7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEdBQUc7QUFDZDtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsR0FBRztBQUNkLGFBQWEsU0FBUztBQUN0QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsR0FBRztBQUNkO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxHQUFHO0FBQ2Q7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEdBQUc7QUFDZCxhQUFhLFNBQVM7QUFDdEI7QUFDQTs7QUFFQTtB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QUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQjtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMENBQTBDLGFBQWE7QUFDdkQ7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUcsV0FBVyxjQUFjO0FBQzVCLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBMEMsT0FBTyxvQkFBb0IsT0FBTzs7QUFFNUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCLG1CQUFtQjtBQUM5Qzs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0Esb0RBQW9ELE1BQU07QUFDMUQsb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxnQkFBZ0I7QUFDM0IsV0FBVyxTQUFTO0FBQ3BCO0FBQ0EsYUFBYSxHQUFHO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFD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QTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxTQUFTLFFBQVE7O0FBRWpCO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0NBQXdDLFNBQVM7QUFDakQsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBOztBQUVBLFdBQVcsUUFBUTs7QUFFbkI7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsYUFB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QVU7QUFDckI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsR0FBRztBQUNkO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0RBQXdELGlCQUFpQjs7QUFFekU7QUFDQSwyQ0FBMkMsaUJBQWlCOztBQUU1RDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2Rpc3QvYnJvd3Nlci9heGlvcy5janM/M2M1MiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiEgQXhpb3MgdjEuOC40IENvcHlyaWdodCAoYykgMjAyNSBNYXR0IFphYnJpc2tpZSBhbmQgY29udHJpYnV0b3JzICovXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIGJpbmQoZm4sIHRoaXNBcmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHdyYXAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbi8vIHV0aWxzIGlzIGEgbGlicmFyeSBvZiBnZW5lcmljIGhlbHBlciBmdW5jdGlvbnMgbm9uLXNwZWNpZmljIHRvIGF4aW9zXG5cbmNvbnN0IHt0b1N0cmluZ30gPSBPYmplY3QucHJvdG90eXBlO1xuY29uc3Qge2dldFByb3RvdHlwZU9mfSA9IE9iamVjdDtcblxuY29uc3Qga2luZE9mID0gKGNhY2hlID0+IHRoaW5nID0+IHtcbiAgICBjb25zdCBzdHIgPSB0b1N0cmluZy5jYWxsKHRoaW5nKTtcbiAgICByZXR1cm4gY2FjaGVbc3RyXSB8fCAoY2FjaGVbc3RyXSA9IHN0ci5zbGljZSg4LCAtMSkudG9Mb3dlckNhc2UoKSk7XG59KShPYmplY3QuY3JlYXRlKG51bGwpKTtcblxuY29uc3Qga2luZE9mVGVzdCA9ICh0eXBlKSA9PiB7XG4gIHR5cGUgPSB0eXBlLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAodGhpbmcpID0+IGtpbmRPZih0aGluZykgPT09IHR5cGVcbn07XG5cbmNvbnN0IHR5cGVPZlRlc3QgPSB0eXBlID0+IHRoaW5nID0+IHR5cGVvZiB0aGluZyA9PT0gdHlwZTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhbiBBcnJheVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBBcnJheSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IHtpc0FycmF5fSA9IEFycmF5O1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIHVuZGVmaW5lZFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIHVuZGVmaW5lZCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzVW5kZWZpbmVkID0gdHlwZU9mVGVzdCgndW5kZWZpbmVkJyk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBCdWZmZXJcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQnVmZmVyLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNCdWZmZXIodmFsKSB7XG4gIHJldHVybiB2YWwgIT09IG51bGwgJiYgIWlzVW5kZWZpbmVkKHZhbCkgJiYgdmFsLmNvbnN0cnVjdG9yICE9PSBudWxsICYmICFpc1VuZGVmaW5lZCh2YWwuY29uc3RydWN0b3IpXG4gICAgJiYgaXNGdW5jdGlvbih2YWwuY29uc3RydWN0b3IuaXNCdWZmZXIpICYmIHZhbC5jb25zdHJ1Y3Rvci5pc0J1ZmZlcih2YWwpO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5QnVmZmVyXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBBcnJheUJ1ZmZlciwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzQXJyYXlCdWZmZXIgPSBraW5kT2ZUZXN0KCdBcnJheUJ1ZmZlcicpO1xuXG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSB2aWV3IG9uIGFuIEFycmF5QnVmZmVyXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIHZpZXcgb24gYW4gQXJyYXlCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5QnVmZmVyVmlldyh2YWwpIHtcbiAgbGV0IHJlc3VsdDtcbiAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnKSAmJiAoQXJyYXlCdWZmZXIuaXNWaWV3KSkge1xuICAgIHJlc3VsdCA9IEFycmF5QnVmZmVyLmlzVmlldyh2YWwpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCA9ICh2YWwpICYmICh2YWwuYnVmZmVyKSAmJiAoaXNBcnJheUJ1ZmZlcih2YWwuYnVmZmVyKSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIFN0cmluZ1xuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJpbmcsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1N0cmluZyA9IHR5cGVPZlRlc3QoJ3N0cmluZycpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBGdW5jdGlvbiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRnVuY3Rpb24gPSB0eXBlT2ZUZXN0KCdmdW5jdGlvbicpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgTnVtYmVyXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIE51bWJlciwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzTnVtYmVyID0gdHlwZU9mVGVzdCgnbnVtYmVyJyk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYW4gT2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSB0aGluZyBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIE9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzT2JqZWN0ID0gKHRoaW5nKSA9PiB0aGluZyAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpbmcgPT09ICdvYmplY3QnO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQm9vbGVhblxuICpcbiAqIEBwYXJhbSB7Kn0gdGhpbmcgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgQm9vbGVhbiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzQm9vbGVhbiA9IHRoaW5nID0+IHRoaW5nID09PSB0cnVlIHx8IHRoaW5nID09PSBmYWxzZTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIHBsYWluIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBwbGFpbiBPYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1BsYWluT2JqZWN0ID0gKHZhbCkgPT4ge1xuICBpZiAoa2luZE9mKHZhbCkgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgcHJvdG90eXBlID0gZ2V0UHJvdG90eXBlT2YodmFsKTtcbiAgcmV0dXJuIChwcm90b3R5cGUgPT09IG51bGwgfHwgcHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpID09PSBudWxsKSAmJiAhKFN5bWJvbC50b1N0cmluZ1RhZyBpbiB2YWwpICYmICEoU3ltYm9sLml0ZXJhdG9yIGluIHZhbCk7XG59O1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRGF0ZVxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBEYXRlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNEYXRlID0ga2luZE9mVGVzdCgnRGF0ZScpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRmlsZVxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBGaWxlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNGaWxlID0ga2luZE9mVGVzdCgnRmlsZScpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQmxvYlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBCbG9iLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNCbG9iID0ga2luZE9mVGVzdCgnQmxvYicpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRmlsZUxpc3RcbiAqXG4gKiBAcGFyYW0geyp9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzRmlsZUxpc3QgPSBraW5kT2ZUZXN0KCdGaWxlTGlzdCcpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgU3RyZWFtXG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIFN0cmVhbSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmNvbnN0IGlzU3RyZWFtID0gKHZhbCkgPT4gaXNPYmplY3QodmFsKSAmJiBpc0Z1bmN0aW9uKHZhbC5waXBlKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZvcm1EYXRhXG4gKlxuICogQHBhcmFtIHsqfSB0aGluZyBUaGUgdmFsdWUgdG8gdGVzdFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIEZvcm1EYXRhLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNGb3JtRGF0YSA9ICh0aGluZykgPT4ge1xuICBsZXQga2luZDtcbiAgcmV0dXJuIHRoaW5nICYmIChcbiAgICAodHlwZW9mIEZvcm1EYXRhID09PSAnZnVuY3Rpb24nICYmIHRoaW5nIGluc3RhbmNlb2YgRm9ybURhdGEpIHx8IChcbiAgICAgIGlzRnVuY3Rpb24odGhpbmcuYXBwZW5kKSAmJiAoXG4gICAgICAgIChraW5kID0ga2luZE9mKHRoaW5nKSkgPT09ICdmb3JtZGF0YScgfHxcbiAgICAgICAgLy8gZGV0ZWN0IGZvcm0tZGF0YSBpbnN0YW5jZVxuICAgICAgICAoa2luZCA9PT0gJ29iamVjdCcgJiYgaXNGdW5jdGlvbih0aGluZy50b1N0cmluZykgJiYgdGhpbmcudG9TdHJpbmcoKSA9PT0gJ1tvYmplY3QgRm9ybURhdGFdJylcbiAgICAgIClcbiAgICApXG4gIClcbn07XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBVUkxTZWFyY2hQYXJhbXMgb2JqZWN0XG4gKlxuICogQHBhcmFtIHsqfSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIFVSTFNlYXJjaFBhcmFtcyBvYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG5jb25zdCBpc1VSTFNlYXJjaFBhcmFtcyA9IGtpbmRPZlRlc3QoJ1VSTFNlYXJjaFBhcmFtcycpO1xuXG5jb25zdCBbaXNSZWFkYWJsZVN0cmVhbSwgaXNSZXF1ZXN0LCBpc1Jlc3BvbnNlLCBpc0hlYWRlcnNdID0gWydSZWFkYWJsZVN0cmVhbScsICdSZXF1ZXN0JywgJ1Jlc3BvbnNlJywgJ0hlYWRlcnMnXS5tYXAoa2luZE9mVGVzdCk7XG5cbi8qKlxuICogVHJpbSBleGNlc3Mgd2hpdGVzcGFjZSBvZmYgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIGEgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0ciBUaGUgU3RyaW5nIHRvIHRyaW1cbiAqXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgU3RyaW5nIGZyZWVkIG9mIGV4Y2VzcyB3aGl0ZXNwYWNlXG4gKi9cbmNvbnN0IHRyaW0gPSAoc3RyKSA9PiBzdHIudHJpbSA/XG4gIHN0ci50cmltKCkgOiBzdHIucmVwbGFjZSgvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csICcnKTtcblxuLyoqXG4gKiBJdGVyYXRlIG92ZXIgYW4gQXJyYXkgb3IgYW4gT2JqZWN0IGludm9raW5nIGEgZnVuY3Rpb24gZm9yIGVhY2ggaXRlbS5cbiAqXG4gKiBJZiBgb2JqYCBpcyBhbiBBcnJheSBjYWxsYmFjayB3aWxsIGJlIGNhbGxlZCBwYXNzaW5nXG4gKiB0aGUgdmFsdWUsIGluZGV4LCBhbmQgY29tcGxldGUgYXJyYXkgZm9yIGVhY2ggaXRlbS5cbiAqXG4gKiBJZiAnb2JqJyBpcyBhbiBPYmplY3QgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgcGFzc2luZ1xuICogdGhlIHZhbHVlLCBrZXksIGFuZCBjb21wbGV0ZSBvYmplY3QgZm9yIGVhY2ggcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IG9iaiBUaGUgb2JqZWN0IHRvIGl0ZXJhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBjYWxsYmFjayB0byBpbnZva2UgZm9yIGVhY2ggaXRlbVxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2FsbE93bktleXMgPSBmYWxzZV1cbiAqIEByZXR1cm5zIHthbnl9XG4gKi9cbmZ1bmN0aW9uIGZvckVhY2gob2JqLCBmbiwge2FsbE93bktleXMgPSBmYWxzZX0gPSB7fSkge1xuICAvLyBEb24ndCBib3RoZXIgaWYgbm8gdmFsdWUgcHJvdmlkZWRcbiAgaWYgKG9iaiA9PT0gbnVsbCB8fCB0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBpO1xuICBsZXQgbDtcblxuICAvLyBGb3JjZSBhbiBhcnJheSBpZiBub3QgYWxyZWFkeSBzb21ldGhpbmcgaXRlcmFibGVcbiAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSB7XG4gICAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gICAgb2JqID0gW29ial07XG4gIH1cblxuICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgLy8gSXRlcmF0ZSBvdmVyIGFycmF5IHZhbHVlc1xuICAgIGZvciAoaSA9IDAsIGwgPSBvYmoubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIG9ialtpXSwgaSwgb2JqKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gSXRlcmF0ZSBvdmVyIG9iamVjdCBrZXlzXG4gICAgY29uc3Qga2V5cyA9IGFsbE93bktleXMgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhvYmopIDogT2JqZWN0LmtleXMob2JqKTtcbiAgICBjb25zdCBsZW4gPSBrZXlzLmxlbmd0aDtcbiAgICBsZXQga2V5O1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgZm4uY2FsbChudWxsLCBvYmpba2V5XSwga2V5LCBvYmopO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kS2V5KG9iaiwga2V5KSB7XG4gIGtleSA9IGtleS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgbGV0IGkgPSBrZXlzLmxlbmd0aDtcbiAgbGV0IF9rZXk7XG4gIHdoaWxlIChpLS0gPiAwKSB7XG4gICAgX2tleSA9IGtleXNbaV07XG4gICAgaWYgKGtleSA9PT0gX2tleS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICByZXR1cm4gX2tleTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmNvbnN0IF9nbG9iYWwgPSAoKCkgPT4ge1xuICAvKmVzbGludCBuby11bmRlZjowKi9cbiAgaWYgKHR5cGVvZiBnbG9iYWxUaGlzICE9PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gZ2xvYmFsVGhpcztcbiAgcmV0dXJuIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6ICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IGdsb2JhbClcbn0pKCk7XG5cbmNvbnN0IGlzQ29udGV4dERlZmluZWQgPSAoY29udGV4dCkgPT4gIWlzVW5kZWZpbmVkKGNvbnRleHQpICYmIGNvbnRleHQgIT09IF9nbG9iYWw7XG5cbi8qKlxuICogQWNjZXB0cyB2YXJhcmdzIGV4cGVjdGluZyBlYWNoIGFyZ3VtZW50IHRvIGJlIGFuIG9iamVjdCwgdGhlblxuICogaW1tdXRhYmx5IG1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiBlYWNoIG9iamVjdCBhbmQgcmV0dXJucyByZXN1bHQuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUga2V5IHRoZSBsYXRlciBvYmplY3QgaW5cbiAqIHRoZSBhcmd1bWVudHMgbGlzdCB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiB2YXIgcmVzdWx0ID0gbWVyZ2Uoe2ZvbzogMTIzfSwge2ZvbzogNDU2fSk7XG4gKiBjb25zb2xlLmxvZyhyZXN1bHQuZm9vKTsgLy8gb3V0cHV0cyA0NTZcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmoxIE9iamVjdCB0byBtZXJnZVxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IFJlc3VsdCBvZiBhbGwgbWVyZ2UgcHJvcGVydGllc1xuICovXG5mdW5jdGlvbiBtZXJnZSgvKiBvYmoxLCBvYmoyLCBvYmozLCAuLi4gKi8pIHtcbiAgY29uc3Qge2Nhc2VsZXNzfSA9IGlzQ29udGV4dERlZmluZWQodGhpcykgJiYgdGhpcyB8fCB7fTtcbiAgY29uc3QgcmVzdWx0ID0ge307XG4gIGNvbnN0IGFzc2lnblZhbHVlID0gKHZhbCwga2V5KSA9PiB7XG4gICAgY29uc3QgdGFyZ2V0S2V5ID0gY2FzZWxlc3MgJiYgZmluZEtleShyZXN1bHQsIGtleSkgfHwga2V5O1xuICAgIGlmIChpc1BsYWluT2JqZWN0KHJlc3VsdFt0YXJnZXRLZXldKSAmJiBpc1BsYWluT2JqZWN0KHZhbCkpIHtcbiAgICAgIHJlc3VsdFt0YXJnZXRLZXldID0gbWVyZ2UocmVzdWx0W3RhcmdldEtleV0sIHZhbCk7XG4gICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHZhbCkpIHtcbiAgICAgIHJlc3VsdFt0YXJnZXRLZXldID0gbWVyZ2Uoe30sIHZhbCk7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KHZhbCkpIHtcbiAgICAgIHJlc3VsdFt0YXJnZXRLZXldID0gdmFsLnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdFt0YXJnZXRLZXldID0gdmFsO1xuICAgIH1cbiAgfTtcblxuICBmb3IgKGxldCBpID0gMCwgbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBhcmd1bWVudHNbaV0gJiYgZm9yRWFjaChhcmd1bWVudHNbaV0sIGFzc2lnblZhbHVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEV4dGVuZHMgb2JqZWN0IGEgYnkgbXV0YWJseSBhZGRpbmcgdG8gaXQgdGhlIHByb3BlcnRpZXMgb2Ygb2JqZWN0IGIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGEgVGhlIG9iamVjdCB0byBiZSBleHRlbmRlZFxuICogQHBhcmFtIHtPYmplY3R9IGIgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbVxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgVGhlIG9iamVjdCB0byBiaW5kIGZ1bmN0aW9uIHRvXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBbYWxsT3duS2V5c11cbiAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSByZXN1bHRpbmcgdmFsdWUgb2Ygb2JqZWN0IGFcbiAqL1xuY29uc3QgZXh0ZW5kID0gKGEsIGIsIHRoaXNBcmcsIHthbGxPd25LZXlzfT0ge30pID0+IHtcbiAgZm9yRWFjaChiLCAodmFsLCBrZXkpID0+IHtcbiAgICBpZiAodGhpc0FyZyAmJiBpc0Z1bmN0aW9uKHZhbCkpIHtcbiAgICAgIGFba2V5XSA9IGJpbmQodmFsLCB0aGlzQXJnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYVtrZXldID0gdmFsO1xuICAgIH1cbiAgfSwge2FsbE93bktleXN9KTtcbiAgcmV0dXJuIGE7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBieXRlIG9yZGVyIG1hcmtlci4gVGhpcyBjYXRjaGVzIEVGIEJCIEJGICh0aGUgVVRGLTggQk9NKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IHdpdGggQk9NXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gY29udGVudCB2YWx1ZSB3aXRob3V0IEJPTVxuICovXG5jb25zdCBzdHJpcEJPTSA9IChjb250ZW50KSA9PiB7XG4gIGlmIChjb250ZW50LmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgIGNvbnRlbnQgPSBjb250ZW50LnNsaWNlKDEpO1xuICB9XG4gIHJldHVybiBjb250ZW50O1xufTtcblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gW3Byb3BzXVxuICogQHBhcmFtIHtvYmplY3R9IFtkZXNjcmlwdG9yc11cbiAqXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuY29uc3QgaW5oZXJpdHMgPSAoY29uc3RydWN0b3IsIHN1cGVyQ29uc3RydWN0b3IsIHByb3BzLCBkZXNjcmlwdG9ycykgPT4ge1xuICBjb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ29uc3RydWN0b3IucHJvdG90eXBlLCBkZXNjcmlwdG9ycyk7XG4gIGNvbnN0cnVjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGNvbnN0cnVjdG9yO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RydWN0b3IsICdzdXBlcicsIHtcbiAgICB2YWx1ZTogc3VwZXJDb25zdHJ1Y3Rvci5wcm90b3R5cGVcbiAgfSk7XG4gIHByb3BzICYmIE9iamVjdC5hc3NpZ24oY29uc3RydWN0b3IucHJvdG90eXBlLCBwcm9wcyk7XG59O1xuXG4vKipcbiAqIFJlc29sdmUgb2JqZWN0IHdpdGggZGVlcCBwcm90b3R5cGUgY2hhaW4gdG8gYSBmbGF0IG9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZU9iaiBzb3VyY2Ugb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gW2Rlc3RPYmpdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufEJvb2xlYW59IFtmaWx0ZXJdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJvcEZpbHRlcl1cbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5jb25zdCB0b0ZsYXRPYmplY3QgPSAoc291cmNlT2JqLCBkZXN0T2JqLCBmaWx0ZXIsIHByb3BGaWx0ZXIpID0+IHtcbiAgbGV0IHByb3BzO1xuICBsZXQgaTtcbiAgbGV0IHByb3A7XG4gIGNvbnN0IG1lcmdlZCA9IHt9O1xuXG4gIGRlc3RPYmogPSBkZXN0T2JqIHx8IHt9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCxlcWVxZXFcbiAgaWYgKHNvdXJjZU9iaiA9PSBudWxsKSByZXR1cm4gZGVzdE9iajtcblxuICBkbyB7XG4gICAgcHJvcHMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhzb3VyY2VPYmopO1xuICAgIGkgPSBwcm9wcy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgIHByb3AgPSBwcm9wc1tpXTtcbiAgICAgIGlmICgoIXByb3BGaWx0ZXIgfHwgcHJvcEZpbHRlcihwcm9wLCBzb3VyY2VPYmosIGRlc3RPYmopKSAmJiAhbWVyZ2VkW3Byb3BdKSB7XG4gICAgICAgIGRlc3RPYmpbcHJvcF0gPSBzb3VyY2VPYmpbcHJvcF07XG4gICAgICAgIG1lcmdlZFtwcm9wXSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHNvdXJjZU9iaiA9IGZpbHRlciAhPT0gZmFsc2UgJiYgZ2V0UHJvdG90eXBlT2Yoc291cmNlT2JqKTtcbiAgfSB3aGlsZSAoc291cmNlT2JqICYmICghZmlsdGVyIHx8IGZpbHRlcihzb3VyY2VPYmosIGRlc3RPYmopKSAmJiBzb3VyY2VPYmogIT09IE9iamVjdC5wcm90b3R5cGUpO1xuXG4gIHJldHVybiBkZXN0T2JqO1xufTtcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBzdHJpbmcgZW5kcyB3aXRoIHRoZSBjaGFyYWN0ZXJzIG9mIGEgc3BlY2lmaWVkIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWFyY2hTdHJpbmdcbiAqIEBwYXJhbSB7TnVtYmVyfSBbcG9zaXRpb249IDBdXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmNvbnN0IGVuZHNXaXRoID0gKHN0ciwgc2VhcmNoU3RyaW5nLCBwb3NpdGlvbikgPT4ge1xuICBzdHIgPSBTdHJpbmcoc3RyKTtcbiAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQgfHwgcG9zaXRpb24gPiBzdHIubGVuZ3RoKSB7XG4gICAgcG9zaXRpb24gPSBzdHIubGVuZ3RoO1xuICB9XG4gIHBvc2l0aW9uIC09IHNlYXJjaFN0cmluZy5sZW5ndGg7XG4gIGNvbnN0IGxhc3RJbmRleCA9IHN0ci5pbmRleE9mKHNlYXJjaFN0cmluZywgcG9zaXRpb24pO1xuICByZXR1cm4gbGFzdEluZGV4ICE9PSAtMSAmJiBsYXN0SW5kZXggPT09IHBvc2l0aW9uO1xufTtcblxuXG4vKipcbiAqIFJldHVybnMgbmV3IGFycmF5IGZyb20gYXJyYXkgbGlrZSBvYmplY3Qgb3IgbnVsbCBpZiBmYWlsZWRcbiAqXG4gKiBAcGFyYW0geyp9IFt0aGluZ11cbiAqXG4gKiBAcmV0dXJucyB7P0FycmF5fVxuICovXG5jb25zdCB0b0FycmF5ID0gKHRoaW5nKSA9PiB7XG4gIGlmICghdGhpbmcpIHJldHVybiBudWxsO1xuICBpZiAoaXNBcnJheSh0aGluZykpIHJldHVybiB0aGluZztcbiAgbGV0IGkgPSB0aGluZy5sZW5ndGg7XG4gIGlmICghaXNOdW1iZXIoaSkpIHJldHVybiBudWxsO1xuICBjb25zdCBhcnIgPSBuZXcgQXJyYXkoaSk7XG4gIHdoaWxlIChpLS0gPiAwKSB7XG4gICAgYXJyW2ldID0gdGhpbmdbaV07XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG5cbi8qKlxuICogQ2hlY2tpbmcgaWYgdGhlIFVpbnQ4QXJyYXkgZXhpc3RzIGFuZCBpZiBpdCBkb2VzLCBpdCByZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjaGVja3MgaWYgdGhlXG4gKiB0aGluZyBwYXNzZWQgaW4gaXMgYW4gaW5zdGFuY2Ugb2YgVWludDhBcnJheVxuICpcbiAqIEBwYXJhbSB7VHlwZWRBcnJheX1cbiAqXG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG5jb25zdCBpc1R5cGVkQXJyYXkgPSAoVHlwZWRBcnJheSA9PiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHJldHVybiB0aGluZyA9PiB7XG4gICAgcmV0dXJuIFR5cGVkQXJyYXkgJiYgdGhpbmcgaW5zdGFuY2VvZiBUeXBlZEFycmF5O1xuICB9O1xufSkodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnICYmIGdldFByb3RvdHlwZU9mKFVpbnQ4QXJyYXkpKTtcblxuLyoqXG4gKiBGb3IgZWFjaCBlbnRyeSBpbiB0aGUgb2JqZWN0LCBjYWxsIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSBrZXkgYW5kIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PGFueSwgYW55Pn0gb2JqIC0gVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGVudHJ5LlxuICpcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5jb25zdCBmb3JFYWNoRW50cnkgPSAob2JqLCBmbikgPT4ge1xuICBjb25zdCBnZW5lcmF0b3IgPSBvYmogJiYgb2JqW1N5bWJvbC5pdGVyYXRvcl07XG5cbiAgY29uc3QgaXRlcmF0b3IgPSBnZW5lcmF0b3IuY2FsbChvYmopO1xuXG4gIGxldCByZXN1bHQ7XG5cbiAgd2hpbGUgKChyZXN1bHQgPSBpdGVyYXRvci5uZXh0KCkpICYmICFyZXN1bHQuZG9uZSkge1xuICAgIGNvbnN0IHBhaXIgPSByZXN1bHQudmFsdWU7XG4gICAgZm4uY2FsbChvYmosIHBhaXJbMF0sIHBhaXJbMV0pO1xuICB9XG59O1xuXG4vKipcbiAqIEl0IHRha2VzIGEgcmVndWxhciBleHByZXNzaW9uIGFuZCBhIHN0cmluZywgYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgYWxsIHRoZSBtYXRjaGVzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZ0V4cCAtIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdG8gbWF0Y2ggYWdhaW5zdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgc3RyaW5nIHRvIHNlYXJjaC5cbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8Ym9vbGVhbj59XG4gKi9cbmNvbnN0IG1hdGNoQWxsID0gKHJlZ0V4cCwgc3RyKSA9PiB7XG4gIGxldCBtYXRjaGVzO1xuICBjb25zdCBhcnIgPSBbXTtcblxuICB3aGlsZSAoKG1hdGNoZXMgPSByZWdFeHAuZXhlYyhzdHIpKSAhPT0gbnVsbCkge1xuICAgIGFyci5wdXNoKG1hdGNoZXMpO1xuICB9XG5cbiAgcmV0dXJuIGFycjtcbn07XG5cbi8qIENoZWNraW5nIGlmIHRoZSBraW5kT2ZUZXN0IGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB3aGVuIHBhc3NlZCBhbiBIVE1MRm9ybUVsZW1lbnQuICovXG5jb25zdCBpc0hUTUxGb3JtID0ga2luZE9mVGVzdCgnSFRNTEZvcm1FbGVtZW50Jyk7XG5cbmNvbnN0IHRvQ2FtZWxDYXNlID0gc3RyID0+IHtcbiAgcmV0dXJuIHN0ci50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1stX1xcc10oW2EtelxcZF0pKFxcdyopL2csXG4gICAgZnVuY3Rpb24gcmVwbGFjZXIobSwgcDEsIHAyKSB7XG4gICAgICByZXR1cm4gcDEudG9VcHBlckNhc2UoKSArIHAyO1xuICAgIH1cbiAgKTtcbn07XG5cbi8qIENyZWF0aW5nIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGNoZWNrIGlmIGFuIG9iamVjdCBoYXMgYSBwcm9wZXJ0eS4gKi9cbmNvbnN0IGhhc093blByb3BlcnR5ID0gKCh7aGFzT3duUHJvcGVydHl9KSA9PiAob2JqLCBwcm9wKSA9PiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkpKE9iamVjdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgUmVnRXhwIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuY29uc3QgaXNSZWdFeHAgPSBraW5kT2ZUZXN0KCdSZWdFeHAnKTtcblxuY29uc3QgcmVkdWNlRGVzY3JpcHRvcnMgPSAob2JqLCByZWR1Y2VyKSA9PiB7XG4gIGNvbnN0IGRlc2NyaXB0b3JzID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMob2JqKTtcbiAgY29uc3QgcmVkdWNlZERlc2NyaXB0b3JzID0ge307XG5cbiAgZm9yRWFjaChkZXNjcmlwdG9ycywgKGRlc2NyaXB0b3IsIG5hbWUpID0+IHtcbiAgICBsZXQgcmV0O1xuICAgIGlmICgocmV0ID0gcmVkdWNlcihkZXNjcmlwdG9yLCBuYW1lLCBvYmopKSAhPT0gZmFsc2UpIHtcbiAgICAgIHJlZHVjZWREZXNjcmlwdG9yc1tuYW1lXSA9IHJldCB8fCBkZXNjcmlwdG9yO1xuICAgIH1cbiAgfSk7XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMob2JqLCByZWR1Y2VkRGVzY3JpcHRvcnMpO1xufTtcblxuLyoqXG4gKiBNYWtlcyBhbGwgbWV0aG9kcyByZWFkLW9ubHlcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuXG5jb25zdCBmcmVlemVNZXRob2RzID0gKG9iaikgPT4ge1xuICByZWR1Y2VEZXNjcmlwdG9ycyhvYmosIChkZXNjcmlwdG9yLCBuYW1lKSA9PiB7XG4gICAgLy8gc2tpcCByZXN0cmljdGVkIHByb3BzIGluIHN0cmljdCBtb2RlXG4gICAgaWYgKGlzRnVuY3Rpb24ob2JqKSAmJiBbJ2FyZ3VtZW50cycsICdjYWxsZXInLCAnY2FsbGVlJ10uaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZSA9IG9ialtuYW1lXTtcblxuICAgIGlmICghaXNGdW5jdGlvbih2YWx1ZSkpIHJldHVybjtcblxuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGZhbHNlO1xuXG4gICAgaWYgKCd3cml0YWJsZScgaW4gZGVzY3JpcHRvcikge1xuICAgICAgZGVzY3JpcHRvci53cml0YWJsZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghZGVzY3JpcHRvci5zZXQpIHtcbiAgICAgIGRlc2NyaXB0b3Iuc2V0ID0gKCkgPT4ge1xuICAgICAgICB0aHJvdyBFcnJvcignQ2FuIG5vdCByZXdyaXRlIHJlYWQtb25seSBtZXRob2QgXFwnJyArIG5hbWUgKyAnXFwnJyk7XG4gICAgICB9O1xuICAgIH1cbiAgfSk7XG59O1xuXG5jb25zdCB0b09iamVjdFNldCA9IChhcnJheU9yU3RyaW5nLCBkZWxpbWl0ZXIpID0+IHtcbiAgY29uc3Qgb2JqID0ge307XG5cbiAgY29uc3QgZGVmaW5lID0gKGFycikgPT4ge1xuICAgIGFyci5mb3JFYWNoKHZhbHVlID0+IHtcbiAgICAgIG9ialt2YWx1ZV0gPSB0cnVlO1xuICAgIH0pO1xuICB9O1xuXG4gIGlzQXJyYXkoYXJyYXlPclN0cmluZykgPyBkZWZpbmUoYXJyYXlPclN0cmluZykgOiBkZWZpbmUoU3RyaW5nKGFycmF5T3JTdHJpbmcpLnNwbGl0KGRlbGltaXRlcikpO1xuXG4gIHJldHVybiBvYmo7XG59O1xuXG5jb25zdCBub29wID0gKCkgPT4ge307XG5cbmNvbnN0IHRvRmluaXRlTnVtYmVyID0gKHZhbHVlLCBkZWZhdWx0VmFsdWUpID0+IHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlID0gK3ZhbHVlKSA/IHZhbHVlIDogZGVmYXVsdFZhbHVlO1xufTtcblxuLyoqXG4gKiBJZiB0aGUgdGhpbmcgaXMgYSBGb3JtRGF0YSBvYmplY3QsIHJldHVybiB0cnVlLCBvdGhlcndpc2UgcmV0dXJuIGZhbHNlLlxuICpcbiAqIEBwYXJhbSB7dW5rbm93bn0gdGhpbmcgLSBUaGUgdGhpbmcgdG8gY2hlY2suXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzU3BlY0NvbXBsaWFudEZvcm0odGhpbmcpIHtcbiAgcmV0dXJuICEhKHRoaW5nICYmIGlzRnVuY3Rpb24odGhpbmcuYXBwZW5kKSAmJiB0aGluZ1tTeW1ib2wudG9TdHJpbmdUYWddID09PSAnRm9ybURhdGEnICYmIHRoaW5nW1N5bWJvbC5pdGVyYXRvcl0pO1xufVxuXG5jb25zdCB0b0pTT05PYmplY3QgPSAob2JqKSA9PiB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IEFycmF5KDEwKTtcblxuICBjb25zdCB2aXNpdCA9IChzb3VyY2UsIGkpID0+IHtcblxuICAgIGlmIChpc09iamVjdChzb3VyY2UpKSB7XG4gICAgICBpZiAoc3RhY2suaW5kZXhPZihzb3VyY2UpID49IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZighKCd0b0pTT04nIGluIHNvdXJjZSkpIHtcbiAgICAgICAgc3RhY2tbaV0gPSBzb3VyY2U7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IGlzQXJyYXkoc291cmNlKSA/IFtdIDoge307XG5cbiAgICAgICAgZm9yRWFjaChzb3VyY2UsICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVkdWNlZFZhbHVlID0gdmlzaXQodmFsdWUsIGkgKyAxKTtcbiAgICAgICAgICAhaXNVbmRlZmluZWQocmVkdWNlZFZhbHVlKSAmJiAodGFyZ2V0W2tleV0gPSByZWR1Y2VkVmFsdWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdGFja1tpXSA9IHVuZGVmaW5lZDtcblxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzb3VyY2U7XG4gIH07XG5cbiAgcmV0dXJuIHZpc2l0KG9iaiwgMCk7XG59O1xuXG5jb25zdCBpc0FzeW5jRm4gPSBraW5kT2ZUZXN0KCdBc3luY0Z1bmN0aW9uJyk7XG5cbmNvbnN0IGlzVGhlbmFibGUgPSAodGhpbmcpID0+XG4gIHRoaW5nICYmIChpc09iamVjdCh0aGluZykgfHwgaXNGdW5jdGlvbih0aGluZykpICYmIGlzRnVuY3Rpb24odGhpbmcudGhlbikgJiYgaXNGdW5jdGlvbih0aGluZy5jYXRjaCk7XG5cbi8vIG9yaWdpbmFsIGNvZGVcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9EaWdpdGFsQnJhaW5KUy9BeGlvc1Byb21pc2UvYmxvYi8xNmRlYWIxMzcxMGVjMDk3Nzk5MjIxMzFmM2ZhNTk1NDMyMGY4M2FiL2xpYi91dGlscy5qcyNMMTEtTDM0XG5cbmNvbnN0IF9zZXRJbW1lZGlhdGUgPSAoKHNldEltbWVkaWF0ZVN1cHBvcnRlZCwgcG9zdE1lc3NhZ2VTdXBwb3J0ZWQpID0+IHtcbiAgaWYgKHNldEltbWVkaWF0ZVN1cHBvcnRlZCkge1xuICAgIHJldHVybiBzZXRJbW1lZGlhdGU7XG4gIH1cblxuICByZXR1cm4gcG9zdE1lc3NhZ2VTdXBwb3J0ZWQgPyAoKHRva2VuLCBjYWxsYmFja3MpID0+IHtcbiAgICBfZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsICh7c291cmNlLCBkYXRhfSkgPT4ge1xuICAgICAgaWYgKHNvdXJjZSA9PT0gX2dsb2JhbCAmJiBkYXRhID09PSB0b2tlbikge1xuICAgICAgICBjYWxsYmFja3MubGVuZ3RoICYmIGNhbGxiYWNrcy5zaGlmdCgpKCk7XG4gICAgICB9XG4gICAgfSwgZmFsc2UpO1xuXG4gICAgcmV0dXJuIChjYikgPT4ge1xuICAgICAgY2FsbGJhY2tzLnB1c2goY2IpO1xuICAgICAgX2dsb2JhbC5wb3N0TWVzc2FnZSh0b2tlbiwgXCIqXCIpO1xuICAgIH1cbiAgfSkoYGF4aW9zQCR7TWF0aC5yYW5kb20oKX1gLCBbXSkgOiAoY2IpID0+IHNldFRpbWVvdXQoY2IpO1xufSkoXG4gIHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicsXG4gIGlzRnVuY3Rpb24oX2dsb2JhbC5wb3N0TWVzc2FnZSlcbik7XG5cbmNvbnN0IGFzYXAgPSB0eXBlb2YgcXVldWVNaWNyb3Rhc2sgIT09ICd1bmRlZmluZWQnID9cbiAgcXVldWVNaWNyb3Rhc2suYmluZChfZ2xvYmFsKSA6ICggdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MubmV4dFRpY2sgfHwgX3NldEltbWVkaWF0ZSk7XG5cbi8vICoqKioqKioqKioqKioqKioqKioqKlxuXG52YXIgdXRpbHMkMSA9IHtcbiAgaXNBcnJheSxcbiAgaXNBcnJheUJ1ZmZlcixcbiAgaXNCdWZmZXIsXG4gIGlzRm9ybURhdGEsXG4gIGlzQXJyYXlCdWZmZXJWaWV3LFxuICBpc1N0cmluZyxcbiAgaXNOdW1iZXIsXG4gIGlzQm9vbGVhbixcbiAgaXNPYmplY3QsXG4gIGlzUGxhaW5PYmplY3QsXG4gIGlzUmVhZGFibGVTdHJlYW0sXG4gIGlzUmVxdWVzdCxcbiAgaXNSZXNwb25zZSxcbiAgaXNIZWFkZXJzLFxuICBpc1VuZGVmaW5lZCxcbiAgaXNEYXRlLFxuICBpc0ZpbGUsXG4gIGlzQmxvYixcbiAgaXNSZWdFeHAsXG4gIGlzRnVuY3Rpb24sXG4gIGlzU3RyZWFtLFxuICBpc1VSTFNlYXJjaFBhcmFtcyxcbiAgaXNUeXBlZEFycmF5LFxuICBpc0ZpbGVMaXN0LFxuICBmb3JFYWNoLFxuICBtZXJnZSxcbiAgZXh0ZW5kLFxuICB0cmltLFxuICBzdHJpcEJPTSxcbiAgaW5oZXJpdHMsXG4gIHRvRmxhdE9iamVjdCxcbiAga2luZE9mLFxuICBraW5kT2ZUZXN0LFxuICBlbmRzV2l0aCxcbiAgdG9BcnJheSxcbiAgZm9yRWFjaEVudHJ5LFxuICBtYXRjaEFsbCxcbiAgaXNIVE1MRm9ybSxcbiAgaGFzT3duUHJvcGVydHksXG4gIGhhc093blByb3A6IGhhc093blByb3BlcnR5LCAvLyBhbiBhbGlhcyB0byBhdm9pZCBFU0xpbnQgbm8tcHJvdG90eXBlLWJ1aWx0aW5zIGRldGVjdGlvblxuICByZWR1Y2VEZXNjcmlwdG9ycyxcbiAgZnJlZXplTWV0aG9kcyxcbiAgdG9PYmplY3RTZXQsXG4gIHRvQ2FtZWxDYXNlLFxuICBub29wLFxuICB0b0Zpbml0ZU51bWJlcixcbiAgZmluZEtleSxcbiAgZ2xvYmFsOiBfZ2xvYmFsLFxuICBpc0NvbnRleHREZWZpbmVkLFxuICBpc1NwZWNDb21wbGlhbnRGb3JtLFxuICB0b0pTT05PYmplY3QsXG4gIGlzQXN5bmNGbixcbiAgaXNUaGVuYWJsZSxcbiAgc2V0SW1tZWRpYXRlOiBfc2V0SW1tZWRpYXRlLFxuICBhc2FwXG59O1xuXG4vKipcbiAqIENyZWF0ZSBhbiBFcnJvciB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSwgY29uZmlnLCBlcnJvciBjb2RlLCByZXF1ZXN0IGFuZCByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbY29kZV0gVGhlIGVycm9yIGNvZGUgKGZvciBleGFtcGxlLCAnRUNPTk5BQk9SVEVEJykuXG4gKiBAcGFyYW0ge09iamVjdH0gW2NvbmZpZ10gVGhlIGNvbmZpZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVxdWVzdF0gVGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Jlc3BvbnNlXSBUaGUgcmVzcG9uc2UuXG4gKlxuICogQHJldHVybnMge0Vycm9yfSBUaGUgY3JlYXRlZCBlcnJvci5cbiAqL1xuZnVuY3Rpb24gQXhpb3NFcnJvcihtZXNzYWdlLCBjb2RlLCBjb25maWcsIHJlcXVlc3QsIHJlc3BvbnNlKSB7XG4gIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3Rvcik7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5zdGFjayA9IChuZXcgRXJyb3IoKSkuc3RhY2s7XG4gIH1cblxuICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICB0aGlzLm5hbWUgPSAnQXhpb3NFcnJvcic7XG4gIGNvZGUgJiYgKHRoaXMuY29kZSA9IGNvZGUpO1xuICBjb25maWcgJiYgKHRoaXMuY29uZmlnID0gY29uZmlnKTtcbiAgcmVxdWVzdCAmJiAodGhpcy5yZXF1ZXN0ID0gcmVxdWVzdCk7XG4gIGlmIChyZXNwb25zZSkge1xuICAgIHRoaXMucmVzcG9uc2UgPSByZXNwb25zZTtcbiAgICB0aGlzLnN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cyA/IHJlc3BvbnNlLnN0YXR1cyA6IG51bGw7XG4gIH1cbn1cblxudXRpbHMkMS5pbmhlcml0cyhBeGlvc0Vycm9yLCBFcnJvciwge1xuICB0b0pTT046IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLy8gU3RhbmRhcmRcbiAgICAgIG1lc3NhZ2U6IHRoaXMubWVzc2FnZSxcbiAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgIC8vIE1pY3Jvc29mdFxuICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICBudW1iZXI6IHRoaXMubnVtYmVyLFxuICAgICAgLy8gTW96aWxsYVxuICAgICAgZmlsZU5hbWU6IHRoaXMuZmlsZU5hbWUsXG4gICAgICBsaW5lTnVtYmVyOiB0aGlzLmxpbmVOdW1iZXIsXG4gICAgICBjb2x1bW5OdW1iZXI6IHRoaXMuY29sdW1uTnVtYmVyLFxuICAgICAgc3RhY2s6IHRoaXMuc3RhY2ssXG4gICAgICAvLyBBeGlvc1xuICAgICAgY29uZmlnOiB1dGlscyQxLnRvSlNPTk9iamVjdCh0aGlzLmNvbmZpZyksXG4gICAgICBjb2RlOiB0aGlzLmNvZGUsXG4gICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzXG4gICAgfTtcbiAgfVxufSk7XG5cbmNvbnN0IHByb3RvdHlwZSQxID0gQXhpb3NFcnJvci5wcm90b3R5cGU7XG5jb25zdCBkZXNjcmlwdG9ycyA9IHt9O1xuXG5bXG4gICdFUlJfQkFEX09QVElPTl9WQUxVRScsXG4gICdFUlJfQkFEX09QVElPTicsXG4gICdFQ09OTkFCT1JURUQnLFxuICAnRVRJTUVET1VUJyxcbiAgJ0VSUl9ORVRXT1JLJyxcbiAgJ0VSUl9GUl9UT09fTUFOWV9SRURJUkVDVFMnLFxuICAnRVJSX0RFUFJFQ0FURUQnLFxuICAnRVJSX0JBRF9SRVNQT05TRScsXG4gICdFUlJfQkFEX1JFUVVFU1QnLFxuICAnRVJSX0NBTkNFTEVEJyxcbiAgJ0VSUl9OT1RfU1VQUE9SVCcsXG4gICdFUlJfSU5WQUxJRF9VUkwnXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuXS5mb3JFYWNoKGNvZGUgPT4ge1xuICBkZXNjcmlwdG9yc1tjb2RlXSA9IHt2YWx1ZTogY29kZX07XG59KTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoQXhpb3NFcnJvciwgZGVzY3JpcHRvcnMpO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvdHlwZSQxLCAnaXNBeGlvc0Vycm9yJywge3ZhbHVlOiB0cnVlfSk7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG5BeGlvc0Vycm9yLmZyb20gPSAoZXJyb3IsIGNvZGUsIGNvbmZpZywgcmVxdWVzdCwgcmVzcG9uc2UsIGN1c3RvbVByb3BzKSA9PiB7XG4gIGNvbnN0IGF4aW9zRXJyb3IgPSBPYmplY3QuY3JlYXRlKHByb3RvdHlwZSQxKTtcblxuICB1dGlscyQxLnRvRmxhdE9iamVjdChlcnJvciwgYXhpb3NFcnJvciwgZnVuY3Rpb24gZmlsdGVyKG9iaikge1xuICAgIHJldHVybiBvYmogIT09IEVycm9yLnByb3RvdHlwZTtcbiAgfSwgcHJvcCA9PiB7XG4gICAgcmV0dXJuIHByb3AgIT09ICdpc0F4aW9zRXJyb3InO1xuICB9KTtcblxuICBBeGlvc0Vycm9yLmNhbGwoYXhpb3NFcnJvciwgZXJyb3IubWVzc2FnZSwgY29kZSwgY29uZmlnLCByZXF1ZXN0LCByZXNwb25zZSk7XG5cbiAgYXhpb3NFcnJvci5jYXVzZSA9IGVycm9yO1xuXG4gIGF4aW9zRXJyb3IubmFtZSA9IGVycm9yLm5hbWU7XG5cbiAgY3VzdG9tUHJvcHMgJiYgT2JqZWN0LmFzc2lnbihheGlvc0Vycm9yLCBjdXN0b21Qcm9wcyk7XG5cbiAgcmV0dXJuIGF4aW9zRXJyb3I7XG59O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc3RyaWN0XG52YXIgaHR0cEFkYXB0ZXIgPSBudWxsO1xuXG4vKipcbiAqIERldGVybWluZXMgaWYgdGhlIGdpdmVuIHRoaW5nIGlzIGEgYXJyYXkgb3IganMgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0aGluZyAtIFRoZSBvYmplY3Qgb3IgYXJyYXkgdG8gYmUgdmlzaXRlZC5cbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaXNWaXNpdGFibGUodGhpbmcpIHtcbiAgcmV0dXJuIHV0aWxzJDEuaXNQbGFpbk9iamVjdCh0aGluZykgfHwgdXRpbHMkMS5pc0FycmF5KHRoaW5nKTtcbn1cblxuLyoqXG4gKiBJdCByZW1vdmVzIHRoZSBicmFja2V0cyBmcm9tIHRoZSBlbmQgb2YgYSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGtleSBvZiB0aGUgcGFyYW1ldGVyLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBrZXkgd2l0aG91dCB0aGUgYnJhY2tldHMuXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZUJyYWNrZXRzKGtleSkge1xuICByZXR1cm4gdXRpbHMkMS5lbmRzV2l0aChrZXksICdbXScpID8ga2V5LnNsaWNlKDAsIC0yKSA6IGtleTtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIHBhdGgsIGEga2V5LCBhbmQgYSBib29sZWFuLCBhbmQgcmV0dXJucyBhIHN0cmluZ1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIGN1cnJlbnQga2V5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgb2YgdGhlIGN1cnJlbnQgb2JqZWN0IGJlaW5nIGl0ZXJhdGVkIG92ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gZG90cyAtIElmIHRydWUsIHRoZSBrZXkgd2lsbCBiZSByZW5kZXJlZCB3aXRoIGRvdHMgaW5zdGVhZCBvZiBicmFja2V0cy5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgcGF0aCB0byB0aGUgY3VycmVudCBrZXkuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlcktleShwYXRoLCBrZXksIGRvdHMpIHtcbiAgaWYgKCFwYXRoKSByZXR1cm4ga2V5O1xuICByZXR1cm4gcGF0aC5jb25jYXQoa2V5KS5tYXAoZnVuY3Rpb24gZWFjaCh0b2tlbiwgaSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgIHRva2VuID0gcmVtb3ZlQnJhY2tldHModG9rZW4pO1xuICAgIHJldHVybiAhZG90cyAmJiBpID8gJ1snICsgdG9rZW4gKyAnXScgOiB0b2tlbjtcbiAgfSkuam9pbihkb3RzID8gJy4nIDogJycpO1xufVxuXG4vKipcbiAqIElmIHRoZSBhcnJheSBpcyBhbiBhcnJheSBhbmQgbm9uZSBvZiBpdHMgZWxlbWVudHMgYXJlIHZpc2l0YWJsZSwgdGhlbiBpdCdzIGEgZmxhdCBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGFueT59IGFyciAtIFRoZSBhcnJheSB0byBjaGVja1xuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBpc0ZsYXRBcnJheShhcnIpIHtcbiAgcmV0dXJuIHV0aWxzJDEuaXNBcnJheShhcnIpICYmICFhcnIuc29tZShpc1Zpc2l0YWJsZSk7XG59XG5cbmNvbnN0IHByZWRpY2F0ZXMgPSB1dGlscyQxLnRvRmxhdE9iamVjdCh1dGlscyQxLCB7fSwgbnVsbCwgZnVuY3Rpb24gZmlsdGVyKHByb3ApIHtcbiAgcmV0dXJuIC9eaXNbQS1aXS8udGVzdChwcm9wKTtcbn0pO1xuXG4vKipcbiAqIENvbnZlcnQgYSBkYXRhIG9iamVjdCB0byBGb3JtRGF0YVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7P09iamVjdH0gW2Zvcm1EYXRhXVxuICogQHBhcmFtIHs/T2JqZWN0fSBbb3B0aW9uc11cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRpb25zLnZpc2l0b3JdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLm1ldGFUb2tlbnMgPSB0cnVlXVxuICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5kb3RzID0gZmFsc2VdXG4gKiBAcGFyYW0gez9Cb29sZWFufSBbb3B0aW9ucy5pbmRleGVzID0gZmFsc2VdXG4gKlxuICogQHJldHVybnMge09iamVjdH1cbiAqKi9cblxuLyoqXG4gKiBJdCBjb252ZXJ0cyBhbiBvYmplY3QgaW50byBhIEZvcm1EYXRhIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PGFueSwgYW55Pn0gb2JqIC0gVGhlIG9iamVjdCB0byBjb252ZXJ0IHRvIGZvcm0gZGF0YS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtRGF0YSAtIFRoZSBGb3JtRGF0YSBvYmplY3QgdG8gYXBwZW5kIHRvLlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBvcHRpb25zXG4gKlxuICogQHJldHVybnNcbiAqL1xuZnVuY3Rpb24gdG9Gb3JtRGF0YShvYmosIGZvcm1EYXRhLCBvcHRpb25zKSB7XG4gIGlmICghdXRpbHMkMS5pc09iamVjdChvYmopKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGFyZ2V0IG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgZm9ybURhdGEgPSBmb3JtRGF0YSB8fCBuZXcgKEZvcm1EYXRhKSgpO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICBvcHRpb25zID0gdXRpbHMkMS50b0ZsYXRPYmplY3Qob3B0aW9ucywge1xuICAgIG1ldGFUb2tlbnM6IHRydWUsXG4gICAgZG90czogZmFsc2UsXG4gICAgaW5kZXhlczogZmFsc2VcbiAgfSwgZmFsc2UsIGZ1bmN0aW9uIGRlZmluZWQob3B0aW9uLCBzb3VyY2UpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXEtbnVsbCxlcWVxZXFcbiAgICByZXR1cm4gIXV0aWxzJDEuaXNVbmRlZmluZWQoc291cmNlW29wdGlvbl0pO1xuICB9KTtcblxuICBjb25zdCBtZXRhVG9rZW5zID0gb3B0aW9ucy5tZXRhVG9rZW5zO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgY29uc3QgdmlzaXRvciA9IG9wdGlvbnMudmlzaXRvciB8fCBkZWZhdWx0VmlzaXRvcjtcbiAgY29uc3QgZG90cyA9IG9wdGlvbnMuZG90cztcbiAgY29uc3QgaW5kZXhlcyA9IG9wdGlvbnMuaW5kZXhlcztcbiAgY29uc3QgX0Jsb2IgPSBvcHRpb25zLkJsb2IgfHwgdHlwZW9mIEJsb2IgIT09ICd1bmRlZmluZWQnICYmIEJsb2I7XG4gIGNvbnN0IHVzZUJsb2IgPSBfQmxvYiAmJiB1dGlscyQxLmlzU3BlY0NvbXBsaWFudEZvcm0oZm9ybURhdGEpO1xuXG4gIGlmICghdXRpbHMkMS5pc0Z1bmN0aW9uKHZpc2l0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmlzaXRvciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnZlcnRWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuICcnO1xuXG4gICAgaWYgKHV0aWxzJDEuaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHZhbHVlLnRvSVNPU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VCbG9iICYmIHV0aWxzJDEuaXNCbG9iKHZhbHVlKSkge1xuICAgICAgdGhyb3cgbmV3IEF4aW9zRXJyb3IoJ0Jsb2IgaXMgbm90IHN1cHBvcnRlZC4gVXNlIGEgQnVmZmVyIGluc3RlYWQuJyk7XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzJDEuaXNBcnJheUJ1ZmZlcih2YWx1ZSkgfHwgdXRpbHMkMS5pc1R5cGVkQXJyYXkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdXNlQmxvYiAmJiB0eXBlb2YgQmxvYiA9PT0gJ2Z1bmN0aW9uJyA/IG5ldyBCbG9iKFt2YWx1ZV0pIDogQnVmZmVyLmZyb20odmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZhdWx0IHZpc2l0b3IuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSBrZXlcbiAgICogQHBhcmFtIHtBcnJheTxTdHJpbmd8TnVtYmVyPn0gcGF0aFxuICAgKiBAdGhpcyB7Rm9ybURhdGF9XG4gICAqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSByZXR1cm4gdHJ1ZSB0byB2aXNpdCB0aGUgZWFjaCBwcm9wIG9mIHRoZSB2YWx1ZSByZWN1cnNpdmVseVxuICAgKi9cbiAgZnVuY3Rpb24gZGVmYXVsdFZpc2l0b3IodmFsdWUsIGtleSwgcGF0aCkge1xuICAgIGxldCBhcnIgPSB2YWx1ZTtcblxuICAgIGlmICh2YWx1ZSAmJiAhcGF0aCAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAodXRpbHMkMS5lbmRzV2l0aChrZXksICd7fScpKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgICAgICBrZXkgPSBtZXRhVG9rZW5zID8ga2V5IDoga2V5LnNsaWNlKDAsIC0yKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgKHV0aWxzJDEuaXNBcnJheSh2YWx1ZSkgJiYgaXNGbGF0QXJyYXkodmFsdWUpKSB8fFxuICAgICAgICAoKHV0aWxzJDEuaXNGaWxlTGlzdCh2YWx1ZSkgfHwgdXRpbHMkMS5lbmRzV2l0aChrZXksICdbXScpKSAmJiAoYXJyID0gdXRpbHMkMS50b0FycmF5KHZhbHVlKSlcbiAgICAgICAgKSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAga2V5ID0gcmVtb3ZlQnJhY2tldHMoa2V5KTtcblxuICAgICAgICBhcnIuZm9yRWFjaChmdW5jdGlvbiBlYWNoKGVsLCBpbmRleCkge1xuICAgICAgICAgICEodXRpbHMkMS5pc1VuZGVmaW5lZChlbCkgfHwgZWwgPT09IG51bGwpICYmIGZvcm1EYXRhLmFwcGVuZChcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXN0ZWQtdGVybmFyeVxuICAgICAgICAgICAgaW5kZXhlcyA9PT0gdHJ1ZSA/IHJlbmRlcktleShba2V5XSwgaW5kZXgsIGRvdHMpIDogKGluZGV4ZXMgPT09IG51bGwgPyBrZXkgOiBrZXkgKyAnW10nKSxcbiAgICAgICAgICAgIGNvbnZlcnRWYWx1ZShlbClcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc1Zpc2l0YWJsZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZvcm1EYXRhLmFwcGVuZChyZW5kZXJLZXkocGF0aCwga2V5LCBkb3RzKSwgY29udmVydFZhbHVlKHZhbHVlKSk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBzdGFjayA9IFtdO1xuXG4gIGNvbnN0IGV4cG9zZWRIZWxwZXJzID0gT2JqZWN0LmFzc2lnbihwcmVkaWNhdGVzLCB7XG4gICAgZGVmYXVsdFZpc2l0b3IsXG4gICAgY29udmVydFZhbHVlLFxuICAgIGlzVmlzaXRhYmxlXG4gIH0pO1xuXG4gIGZ1bmN0aW9uIGJ1aWxkKHZhbHVlLCBwYXRoKSB7XG4gICAgaWYgKHV0aWxzJDEuaXNVbmRlZmluZWQodmFsdWUpKSByZXR1cm47XG5cbiAgICBpZiAoc3RhY2suaW5kZXhPZih2YWx1ZSkgIT09IC0xKSB7XG4gICAgICB0aHJvdyBFcnJvcignQ2lyY3VsYXIgcmVmZXJlbmNlIGRldGVjdGVkIGluICcgKyBwYXRoLmpvaW4oJy4nKSk7XG4gICAgfVxuXG4gICAgc3RhY2sucHVzaCh2YWx1ZSk7XG5cbiAgICB1dGlscyQxLmZvckVhY2godmFsdWUsIGZ1bmN0aW9uIGVhY2goZWwsIGtleSkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gISh1dGlscyQxLmlzVW5kZWZpbmVkKGVsKSB8fCBlbCA9PT0gbnVsbCkgJiYgdmlzaXRvci5jYWxsKFxuICAgICAgICBmb3JtRGF0YSwgZWwsIHV0aWxzJDEuaXNTdHJpbmcoa2V5KSA/IGtleS50cmltKCkgOiBrZXksIHBhdGgsIGV4cG9zZWRIZWxwZXJzXG4gICAgICApO1xuXG4gICAgICBpZiAocmVzdWx0ID09PSB0cnVlKSB7XG4gICAgICAgIGJ1aWxkKGVsLCBwYXRoID8gcGF0aC5jb25jYXQoa2V5KSA6IFtrZXldKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHN0YWNrLnBvcCgpO1xuICB9XG5cbiAgaWYgKCF1dGlscyQxLmlzT2JqZWN0KG9iaikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIG11c3QgYmUgYW4gb2JqZWN0Jyk7XG4gIH1cblxuICBidWlsZChvYmopO1xuXG4gIHJldHVybiBmb3JtRGF0YTtcbn1cblxuLyoqXG4gKiBJdCBlbmNvZGVzIGEgc3RyaW5nIGJ5IHJlcGxhY2luZyBhbGwgY2hhcmFjdGVycyB0aGF0IGFyZSBub3QgaW4gdGhlIHVucmVzZXJ2ZWQgc2V0IHdpdGhcbiAqIHRoZWlyIHBlcmNlbnQtZW5jb2RlZCBlcXVpdmFsZW50c1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgc3RyaW5nIHRvIGVuY29kZS5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZW5jb2RlZCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZSQxKHN0cikge1xuICBjb25zdCBjaGFyTWFwID0ge1xuICAgICchJzogJyUyMScsXG4gICAgXCInXCI6ICclMjcnLFxuICAgICcoJzogJyUyOCcsXG4gICAgJyknOiAnJTI5JyxcbiAgICAnfic6ICclN0UnLFxuICAgICclMjAnOiAnKycsXG4gICAgJyUwMCc6ICdcXHgwMCdcbiAgfTtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpLnJlcGxhY2UoL1shJygpfl18JTIwfCUwMC9nLCBmdW5jdGlvbiByZXBsYWNlcihtYXRjaCkge1xuICAgIHJldHVybiBjaGFyTWFwW21hdGNoXTtcbiAgfSk7XG59XG5cbi8qKlxuICogSXQgdGFrZXMgYSBwYXJhbXMgb2JqZWN0IGFuZCBjb252ZXJ0cyBpdCB0byBhIEZvcm1EYXRhIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgYW55Pn0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgdG8gYmUgY29udmVydGVkIHRvIGEgRm9ybURhdGEgb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgb2JqZWN0IHBhc3NlZCB0byB0aGUgQXhpb3MgY29uc3RydWN0b3IuXG4gKlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIEF4aW9zVVJMU2VhcmNoUGFyYW1zKHBhcmFtcywgb3B0aW9ucykge1xuICB0aGlzLl9wYWlycyA9IFtdO1xuXG4gIHBhcmFtcyAmJiB0b0Zvcm1EYXRhKHBhcmFtcywgdGhpcywgb3B0aW9ucyk7XG59XG5cbmNvbnN0IHByb3RvdHlwZSA9IEF4aW9zVVJMU2VhcmNoUGFyYW1zLnByb3RvdHlwZTtcblxucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZChuYW1lLCB2YWx1ZSkge1xuICB0aGlzLl9wYWlycy5wdXNoKFtuYW1lLCB2YWx1ZV0pO1xufTtcblxucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoZW5jb2Rlcikge1xuICBjb25zdCBfZW5jb2RlID0gZW5jb2RlciA/IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIGVuY29kZXIuY2FsbCh0aGlzLCB2YWx1ZSwgZW5jb2RlJDEpO1xuICB9IDogZW5jb2RlJDE7XG5cbiAgcmV0dXJuIHRoaXMuX3BhaXJzLm1hcChmdW5jdGlvbiBlYWNoKHBhaXIpIHtcbiAgICByZXR1cm4gX2VuY29kZShwYWlyWzBdKSArICc9JyArIF9lbmNvZGUocGFpclsxXSk7XG4gIH0sICcnKS5qb2luKCcmJyk7XG59O1xuXG4vKipcbiAqIEl0IHJlcGxhY2VzIGFsbCBpbnN0YW5jZXMgb2YgdGhlIGNoYXJhY3RlcnMgYDpgLCBgJGAsIGAsYCwgYCtgLCBgW2AsIGFuZCBgXWAgd2l0aCB0aGVpclxuICogVVJJIGVuY29kZWQgY291bnRlcnBhcnRzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbCBUaGUgdmFsdWUgdG8gYmUgZW5jb2RlZC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZW5jb2RlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gZW5jb2RlKHZhbCkge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkuXG4gICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLlxuICAgIHJlcGxhY2UoLyUyNC9nLCAnJCcpLlxuICAgIHJlcGxhY2UoLyUyQy9naSwgJywnKS5cbiAgICByZXBsYWNlKC8lMjAvZywgJysnKS5cbiAgICByZXBsYWNlKC8lNUIvZ2ksICdbJykuXG4gICAgcmVwbGFjZSgvJTVEL2dpLCAnXScpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgVVJMIGJ5IGFwcGVuZGluZyBwYXJhbXMgdG8gdGhlIGVuZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIGJhc2Ugb2YgdGhlIHVybCAoZS5nLiwgaHR0cDovL3d3dy5nb29nbGUuY29tKVxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXNdIFRoZSBwYXJhbXMgdG8gYmUgYXBwZW5kZWRcbiAqIEBwYXJhbSB7PyhvYmplY3R8RnVuY3Rpb24pfSBvcHRpb25zXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGZvcm1hdHRlZCB1cmxcbiAqL1xuZnVuY3Rpb24gYnVpbGRVUkwodXJsLCBwYXJhbXMsIG9wdGlvbnMpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIGlmICghcGFyYW1zKSB7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuICBcbiAgY29uc3QgX2VuY29kZSA9IG9wdGlvbnMgJiYgb3B0aW9ucy5lbmNvZGUgfHwgZW5jb2RlO1xuXG4gIGlmICh1dGlscyQxLmlzRnVuY3Rpb24ob3B0aW9ucykpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgc2VyaWFsaXplOiBvcHRpb25zXG4gICAgfTtcbiAgfSBcblxuICBjb25zdCBzZXJpYWxpemVGbiA9IG9wdGlvbnMgJiYgb3B0aW9ucy5zZXJpYWxpemU7XG5cbiAgbGV0IHNlcmlhbGl6ZWRQYXJhbXM7XG5cbiAgaWYgKHNlcmlhbGl6ZUZuKSB7XG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHNlcmlhbGl6ZUZuKHBhcmFtcywgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHV0aWxzJDEuaXNVUkxTZWFyY2hQYXJhbXMocGFyYW1zKSA/XG4gICAgICBwYXJhbXMudG9TdHJpbmcoKSA6XG4gICAgICBuZXcgQXhpb3NVUkxTZWFyY2hQYXJhbXMocGFyYW1zLCBvcHRpb25zKS50b1N0cmluZyhfZW5jb2RlKTtcbiAgfVxuXG4gIGlmIChzZXJpYWxpemVkUGFyYW1zKSB7XG4gICAgY29uc3QgaGFzaG1hcmtJbmRleCA9IHVybC5pbmRleE9mKFwiI1wiKTtcblxuICAgIGlmIChoYXNobWFya0luZGV4ICE9PSAtMSkge1xuICAgICAgdXJsID0gdXJsLnNsaWNlKDAsIGhhc2htYXJrSW5kZXgpO1xuICAgIH1cbiAgICB1cmwgKz0gKHVybC5pbmRleE9mKCc/JykgPT09IC0xID8gJz8nIDogJyYnKSArIHNlcmlhbGl6ZWRQYXJhbXM7XG4gIH1cblxuICByZXR1cm4gdXJsO1xufVxuXG5jbGFzcyBJbnRlcmNlcHRvck1hbmFnZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmhhbmRsZXJzID0gW107XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbmV3IGludGVyY2VwdG9yIHRvIHRoZSBzdGFja1xuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdWxmaWxsZWQgVGhlIGZ1bmN0aW9uIHRvIGhhbmRsZSBgdGhlbmAgZm9yIGEgYFByb21pc2VgXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdGVkIFRoZSBmdW5jdGlvbiB0byBoYW5kbGUgYHJlamVjdGAgZm9yIGEgYFByb21pc2VgXG4gICAqXG4gICAqIEByZXR1cm4ge051bWJlcn0gQW4gSUQgdXNlZCB0byByZW1vdmUgaW50ZXJjZXB0b3IgbGF0ZXJcbiAgICovXG4gIHVzZShmdWxmaWxsZWQsIHJlamVjdGVkLCBvcHRpb25zKSB7XG4gICAgdGhpcy5oYW5kbGVycy5wdXNoKHtcbiAgICAgIGZ1bGZpbGxlZCxcbiAgICAgIHJlamVjdGVkLFxuICAgICAgc3luY2hyb25vdXM6IG9wdGlvbnMgPyBvcHRpb25zLnN5bmNocm9ub3VzIDogZmFsc2UsXG4gICAgICBydW5XaGVuOiBvcHRpb25zID8gb3B0aW9ucy5ydW5XaGVuIDogbnVsbFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLmhhbmRsZXJzLmxlbmd0aCAtIDE7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFuIGludGVyY2VwdG9yIGZyb20gdGhlIHN0YWNrXG4gICAqXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpZCBUaGUgSUQgdGhhdCB3YXMgcmV0dXJuZWQgYnkgYHVzZWBcbiAgICpcbiAgICogQHJldHVybnMge0Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgaW50ZXJjZXB0b3Igd2FzIHJlbW92ZWQsIGBmYWxzZWAgb3RoZXJ3aXNlXG4gICAqL1xuICBlamVjdChpZCkge1xuICAgIGlmICh0aGlzLmhhbmRsZXJzW2lkXSkge1xuICAgICAgdGhpcy5oYW5kbGVyc1tpZF0gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgaW50ZXJjZXB0b3JzIGZyb20gdGhlIHN0YWNrXG4gICAqXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY2xlYXIoKSB7XG4gICAgaWYgKHRoaXMuaGFuZGxlcnMpIHtcbiAgICAgIHRoaXMuaGFuZGxlcnMgPSBbXTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZSBvdmVyIGFsbCB0aGUgcmVnaXN0ZXJlZCBpbnRlcmNlcHRvcnNcbiAgICpcbiAgICogVGhpcyBtZXRob2QgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3Igc2tpcHBpbmcgb3ZlciBhbnlcbiAgICogaW50ZXJjZXB0b3JzIHRoYXQgbWF5IGhhdmUgYmVjb21lIGBudWxsYCBjYWxsaW5nIGBlamVjdGAuXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGludGVyY2VwdG9yXG4gICAqXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZm9yRWFjaChmbikge1xuICAgIHV0aWxzJDEuZm9yRWFjaCh0aGlzLmhhbmRsZXJzLCBmdW5jdGlvbiBmb3JFYWNoSGFuZGxlcihoKSB7XG4gICAgICBpZiAoaCAhPT0gbnVsbCkge1xuICAgICAgICBmbihoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG52YXIgSW50ZXJjZXB0b3JNYW5hZ2VyJDEgPSBJbnRlcmNlcHRvck1hbmFnZXI7XG5cbnZhciB0cmFuc2l0aW9uYWxEZWZhdWx0cyA9IHtcbiAgc2lsZW50SlNPTlBhcnNpbmc6IHRydWUsXG4gIGZvcmNlZEpTT05QYXJzaW5nOiB0cnVlLFxuICBjbGFyaWZ5VGltZW91dEVycm9yOiBmYWxzZVxufTtcblxudmFyIFVSTFNlYXJjaFBhcmFtcyQxID0gdHlwZW9mIFVSTFNlYXJjaFBhcmFtcyAhPT0gJ3VuZGVmaW5lZCcgPyBVUkxTZWFyY2hQYXJhbXMgOiBBeGlvc1VSTFNlYXJjaFBhcmFtcztcblxudmFyIEZvcm1EYXRhJDEgPSB0eXBlb2YgRm9ybURhdGEgIT09ICd1bmRlZmluZWQnID8gRm9ybURhdGEgOiBudWxsO1xuXG52YXIgQmxvYiQxID0gdHlwZW9mIEJsb2IgIT09ICd1bmRlZmluZWQnID8gQmxvYiA6IG51bGw7XG5cbnZhciBwbGF0Zm9ybSQxID0ge1xuICBpc0Jyb3dzZXI6IHRydWUsXG4gIGNsYXNzZXM6IHtcbiAgICBVUkxTZWFyY2hQYXJhbXM6IFVSTFNlYXJjaFBhcmFtcyQxLFxuICAgIEZvcm1EYXRhOiBGb3JtRGF0YSQxLFxuICAgIEJsb2I6IEJsb2IkMVxuICB9LFxuICBwcm90b2NvbHM6IFsnaHR0cCcsICdodHRwcycsICdmaWxlJywgJ2Jsb2InLCAndXJsJywgJ2RhdGEnXVxufTtcblxuY29uc3QgaGFzQnJvd3NlckVudiA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XG5cbmNvbnN0IF9uYXZpZ2F0b3IgPSB0eXBlb2YgbmF2aWdhdG9yID09PSAnb2JqZWN0JyAmJiBuYXZpZ2F0b3IgfHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIERldGVybWluZSBpZiB3ZSdyZSBydW5uaW5nIGluIGEgc3RhbmRhcmQgYnJvd3NlciBlbnZpcm9ubWVudFxuICpcbiAqIFRoaXMgYWxsb3dzIGF4aW9zIHRvIHJ1biBpbiBhIHdlYiB3b3JrZXIsIGFuZCByZWFjdC1uYXRpdmUuXG4gKiBCb3RoIGVudmlyb25tZW50cyBzdXBwb3J0IFhNTEh0dHBSZXF1ZXN0LCBidXQgbm90IGZ1bGx5IHN0YW5kYXJkIGdsb2JhbHMuXG4gKlxuICogd2ViIHdvcmtlcnM6XG4gKiAgdHlwZW9mIHdpbmRvdyAtPiB1bmRlZmluZWRcbiAqICB0eXBlb2YgZG9jdW1lbnQgLT4gdW5kZWZpbmVkXG4gKlxuICogcmVhY3QtbmF0aXZlOlxuICogIG5hdmlnYXRvci5wcm9kdWN0IC0+ICdSZWFjdE5hdGl2ZSdcbiAqIG5hdGl2ZXNjcmlwdFxuICogIG5hdmlnYXRvci5wcm9kdWN0IC0+ICdOYXRpdmVTY3JpcHQnIG9yICdOUydcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuY29uc3QgaGFzU3RhbmRhcmRCcm93c2VyRW52ID0gaGFzQnJvd3NlckVudiAmJlxuICAoIV9uYXZpZ2F0b3IgfHwgWydSZWFjdE5hdGl2ZScsICdOYXRpdmVTY3JpcHQnLCAnTlMnXS5pbmRleE9mKF9uYXZpZ2F0b3IucHJvZHVjdCkgPCAwKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgd2UncmUgcnVubmluZyBpbiBhIHN0YW5kYXJkIGJyb3dzZXIgd2ViV29ya2VyIGVudmlyb25tZW50XG4gKlxuICogQWx0aG91Z2ggdGhlIGBpc1N0YW5kYXJkQnJvd3NlckVudmAgbWV0aG9kIGluZGljYXRlcyB0aGF0XG4gKiBgYWxsb3dzIGF4aW9zIHRvIHJ1biBpbiBhIHdlYiB3b3JrZXJgLCB0aGUgV2ViV29ya2VyIHdpbGwgc3RpbGwgYmVcbiAqIGZpbHRlcmVkIG91dCBkdWUgdG8gaXRzIGp1ZGdtZW50IHN0YW5kYXJkXG4gKiBgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJ2AuXG4gKiBUaGlzIGxlYWRzIHRvIGEgcHJvYmxlbSB3aGVuIGF4aW9zIHBvc3QgYEZvcm1EYXRhYCBpbiB3ZWJXb3JrZXJcbiAqL1xuY29uc3QgaGFzU3RhbmRhcmRCcm93c2VyV2ViV29ya2VyRW52ID0gKCgpID0+IHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgV29ya2VyR2xvYmFsU2NvcGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgc2VsZiBpbnN0YW5jZW9mIFdvcmtlckdsb2JhbFNjb3BlICYmXG4gICAgdHlwZW9mIHNlbGYuaW1wb3J0U2NyaXB0cyA9PT0gJ2Z1bmN0aW9uJ1xuICApO1xufSkoKTtcblxuY29uc3Qgb3JpZ2luID0gaGFzQnJvd3NlckVudiAmJiB3aW5kb3cubG9jYXRpb24uaHJlZiB8fCAnaHR0cDovL2xvY2FsaG9zdCc7XG5cbnZhciB1dGlscyA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcbiAgX19wcm90b19fOiBudWxsLFxuICBoYXNCcm93c2VyRW52OiBoYXNCcm93c2VyRW52LFxuICBoYXNTdGFuZGFyZEJyb3dzZXJXZWJXb3JrZXJFbnY6IGhhc1N0YW5kYXJkQnJvd3NlcldlYldvcmtlckVudixcbiAgaGFzU3RhbmRhcmRCcm93c2VyRW52OiBoYXNTdGFuZGFyZEJyb3dzZXJFbnYsXG4gIG5hdmlnYXRvcjogX25hdmlnYXRvcixcbiAgb3JpZ2luOiBvcmlnaW5cbn0pO1xuXG52YXIgcGxhdGZvcm0gPSB7XG4gIC4uLnV0aWxzLFxuICAuLi5wbGF0Zm9ybSQxXG59O1xuXG5mdW5jdGlvbiB0b1VSTEVuY29kZWRGb3JtKGRhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRvRm9ybURhdGEoZGF0YSwgbmV3IHBsYXRmb3JtLmNsYXNzZXMuVVJMU2VhcmNoUGFyYW1zKCksIE9iamVjdC5hc3NpZ24oe1xuICAgIHZpc2l0b3I6IGZ1bmN0aW9uKHZhbHVlLCBrZXksIHBhdGgsIGhlbHBlcnMpIHtcbiAgICAgIGlmIChwbGF0Zm9ybS5pc05vZGUgJiYgdXRpbHMkMS5pc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICAgICAgdGhpcy5hcHBlbmQoa2V5LCB2YWx1ZS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBoZWxwZXJzLmRlZmF1bHRWaXNpdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9LCBvcHRpb25zKSk7XG59XG5cbi8qKlxuICogSXQgdGFrZXMgYSBzdHJpbmcgbGlrZSBgZm9vW3hdW3ldW3pdYCBhbmQgcmV0dXJucyBhbiBhcnJheSBsaWtlIGBbJ2ZvbycsICd4JywgJ3knLCAneiddXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICpcbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHN0cmluZ3MuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUHJvcFBhdGgobmFtZSkge1xuICAvLyBmb29beF1beV1bel1cbiAgLy8gZm9vLngueS56XG4gIC8vIGZvby14LXktelxuICAvLyBmb28geCB5IHpcbiAgcmV0dXJuIHV0aWxzJDEubWF0Y2hBbGwoL1xcdyt8XFxbKFxcdyopXS9nLCBuYW1lKS5tYXAobWF0Y2ggPT4ge1xuICAgIHJldHVybiBtYXRjaFswXSA9PT0gJ1tdJyA/ICcnIDogbWF0Y2hbMV0gfHwgbWF0Y2hbMF07XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYW4gYXJyYXkgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gYXJyIC0gVGhlIGFycmF5IHRvIGNvbnZlcnQgdG8gYW4gb2JqZWN0LlxuICpcbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGtleXMgYW5kIHZhbHVlcyBhcyB0aGUgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5VG9PYmplY3QoYXJyKSB7XG4gIGNvbnN0IG9iaiA9IHt9O1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYXJyKTtcbiAgbGV0IGk7XG4gIGNvbnN0IGxlbiA9IGtleXMubGVuZ3RoO1xuICBsZXQga2V5O1xuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBrZXkgPSBrZXlzW2ldO1xuICAgIG9ialtrZXldID0gYXJyW2tleV07XG4gIH1cbiAgcmV0dXJuIG9iajtcbn1cblxuLyoqXG4gKiBJdCB0YWtlcyBhIEZvcm1EYXRhIG9iamVjdCBhbmQgcmV0dXJucyBhIEphdmFTY3JpcHQgb2JqZWN0XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1EYXRhIFRoZSBGb3JtRGF0YSBvYmplY3QgdG8gY29udmVydCB0byBKU09OLlxuICpcbiAqIEByZXR1cm5zIHtPYmplY3Q8c3RyaW5nLCBhbnk+IHwgbnVsbH0gVGhlIGNvbnZlcnRlZCBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGZvcm1EYXRhVG9KU09OKGZvcm1EYXRhKSB7XG4gIGZ1bmN0aW9uIGJ1aWxkUGF0aChwYXRoLCB2YWx1ZSwgdGFyZ2V0LCBpbmRleCkge1xuICAgIGxldCBuYW1lID0gcGF0aFtpbmRleCsrXTtcblxuICAgIGlmIChuYW1lID09PSAnX19wcm90b19fJykgcmV0dXJuIHRydWU7XG5cbiAgICBjb25zdCBpc051bWVyaWNLZXkgPSBOdW1iZXIuaXNGaW5pdGUoK25hbWUpO1xuICAgIGNvbnN0IGlzTGFzdCA9IGluZGV4ID49IHBhdGgubGVuZ3RoO1xuICAgIG5hbWUgPSAhbmFtZSAmJiB1dGlscyQxLmlzQXJyYXkodGFyZ2V0KSA/IHRhcmdldC5sZW5ndGggOiBuYW1lO1xuXG4gICAgaWYgKGlzTGFzdCkge1xuICAgICAgaWYgKHV0aWxzJDEuaGFzT3duUHJvcCh0YXJnZXQsIG5hbWUpKSB7XG4gICAgICAgIHRhcmdldFtuYW1lXSA9IFt0YXJnZXRbbmFtZV0sIHZhbHVlXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldFtuYW1lXSA9IHZhbHVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gIWlzTnVtZXJpY0tleTtcbiAgICB9XG5cbiAgICBpZiAoIXRhcmdldFtuYW1lXSB8fCAhdXRpbHMkMS5pc09iamVjdCh0YXJnZXRbbmFtZV0pKSB7XG4gICAgICB0YXJnZXRbbmFtZV0gPSBbXTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBidWlsZFBhdGgocGF0aCwgdmFsdWUsIHRhcmdldFtuYW1lXSwgaW5kZXgpO1xuXG4gICAgaWYgKHJlc3VsdCAmJiB1dGlscyQxLmlzQXJyYXkodGFyZ2V0W25hbWVdKSkge1xuICAgICAgdGFyZ2V0W25hbWVdID0gYXJyYXlUb09iamVjdCh0YXJnZXRbbmFtZV0pO1xuICAgIH1cblxuICAgIHJldHVybiAhaXNOdW1lcmljS2V5O1xuICB9XG5cbiAgaWYgKHV0aWxzJDEuaXNGb3JtRGF0YShmb3JtRGF0YSkgJiYgdXRpbHMkMS5pc0Z1bmN0aW9uKGZvcm1EYXRhLmVudHJpZXMpKSB7XG4gICAgY29uc3Qgb2JqID0ge307XG5cbiAgICB1dGlscyQxLmZvckVhY2hFbnRyeShmb3JtRGF0YSwgKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBidWlsZFBhdGgocGFyc2VQcm9wUGF0aChuYW1lKSwgdmFsdWUsIG9iaiwgMCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogSXQgdGFrZXMgYSBzdHJpbmcsIHRyaWVzIHRvIHBhcnNlIGl0LCBhbmQgaWYgaXQgZmFpbHMsIGl0IHJldHVybnMgdGhlIHN0cmluZ2lmaWVkIHZlcnNpb25cbiAqIG9mIHRoZSBpbnB1dFxuICpcbiAqIEBwYXJhbSB7YW55fSByYXdWYWx1ZSAtIFRoZSB2YWx1ZSB0byBiZSBzdHJpbmdpZmllZC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHBhcnNlciAtIEEgZnVuY3Rpb24gdGhhdCBwYXJzZXMgYSBzdHJpbmcgaW50byBhIEphdmFTY3JpcHQgb2JqZWN0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZW5jb2RlciAtIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIHZhbHVlIGFuZCByZXR1cm5zIGEgc3RyaW5nLlxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IEEgc3RyaW5naWZpZWQgdmVyc2lvbiBvZiB0aGUgcmF3VmFsdWUuXG4gKi9cbmZ1bmN0aW9uIHN0cmluZ2lmeVNhZmVseShyYXdWYWx1ZSwgcGFyc2VyLCBlbmNvZGVyKSB7XG4gIGlmICh1dGlscyQxLmlzU3RyaW5nKHJhd1ZhbHVlKSkge1xuICAgIHRyeSB7XG4gICAgICAocGFyc2VyIHx8IEpTT04ucGFyc2UpKHJhd1ZhbHVlKTtcbiAgICAgIHJldHVybiB1dGlscyQxLnRyaW0ocmF3VmFsdWUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdTeW50YXhFcnJvcicpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gKGVuY29kZXIgfHwgSlNPTi5zdHJpbmdpZnkpKHJhd1ZhbHVlKTtcbn1cblxuY29uc3QgZGVmYXVsdHMgPSB7XG5cbiAgdHJhbnNpdGlvbmFsOiB0cmFuc2l0aW9uYWxEZWZhdWx0cyxcblxuICBhZGFwdGVyOiBbJ3hocicsICdodHRwJywgJ2ZldGNoJ10sXG5cbiAgdHJhbnNmb3JtUmVxdWVzdDogW2Z1bmN0aW9uIHRyYW5zZm9ybVJlcXVlc3QoZGF0YSwgaGVhZGVycykge1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gaGVhZGVycy5nZXRDb250ZW50VHlwZSgpIHx8ICcnO1xuICAgIGNvbnN0IGhhc0pTT05Db250ZW50VHlwZSA9IGNvbnRlbnRUeXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA+IC0xO1xuICAgIGNvbnN0IGlzT2JqZWN0UGF5bG9hZCA9IHV0aWxzJDEuaXNPYmplY3QoZGF0YSk7XG5cbiAgICBpZiAoaXNPYmplY3RQYXlsb2FkICYmIHV0aWxzJDEuaXNIVE1MRm9ybShkYXRhKSkge1xuICAgICAgZGF0YSA9IG5ldyBGb3JtRGF0YShkYXRhKTtcbiAgICB9XG5cbiAgICBjb25zdCBpc0Zvcm1EYXRhID0gdXRpbHMkMS5pc0Zvcm1EYXRhKGRhdGEpO1xuXG4gICAgaWYgKGlzRm9ybURhdGEpIHtcbiAgICAgIHJldHVybiBoYXNKU09OQ29udGVudFR5cGUgPyBKU09OLnN0cmluZ2lmeShmb3JtRGF0YVRvSlNPTihkYXRhKSkgOiBkYXRhO1xuICAgIH1cblxuICAgIGlmICh1dGlscyQxLmlzQXJyYXlCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzJDEuaXNCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzJDEuaXNTdHJlYW0oZGF0YSkgfHxcbiAgICAgIHV0aWxzJDEuaXNGaWxlKGRhdGEpIHx8XG4gICAgICB1dGlscyQxLmlzQmxvYihkYXRhKSB8fFxuICAgICAgdXRpbHMkMS5pc1JlYWRhYmxlU3RyZWFtKGRhdGEpXG4gICAgKSB7XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgaWYgKHV0aWxzJDEuaXNBcnJheUJ1ZmZlclZpZXcoZGF0YSkpIHtcbiAgICAgIHJldHVybiBkYXRhLmJ1ZmZlcjtcbiAgICB9XG4gICAgaWYgKHV0aWxzJDEuaXNVUkxTZWFyY2hQYXJhbXMoZGF0YSkpIHtcbiAgICAgIGhlYWRlcnMuc2V0Q29udGVudFR5cGUoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PXV0Zi04JywgZmFsc2UpO1xuICAgICAgcmV0dXJuIGRhdGEudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBsZXQgaXNGaWxlTGlzdDtcblxuICAgIGlmIChpc09iamVjdFBheWxvYWQpIHtcbiAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0b1VSTEVuY29kZWRGb3JtKGRhdGEsIHRoaXMuZm9ybVNlcmlhbGl6ZXIpLnRvU3RyaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICgoaXNGaWxlTGlzdCA9IHV0aWxzJDEuaXNGaWxlTGlzdChkYXRhKSkgfHwgY29udGVudFR5cGUuaW5kZXhPZignbXVsdGlwYXJ0L2Zvcm0tZGF0YScpID4gLTEpIHtcbiAgICAgICAgY29uc3QgX0Zvcm1EYXRhID0gdGhpcy5lbnYgJiYgdGhpcy5lbnYuRm9ybURhdGE7XG5cbiAgICAgICAgcmV0dXJuIHRvRm9ybURhdGEoXG4gICAgICAgICAgaXNGaWxlTGlzdCA/IHsnZmlsZXNbXSc6IGRhdGF9IDogZGF0YSxcbiAgICAgICAgICBfRm9ybURhdGEgJiYgbmV3IF9Gb3JtRGF0YSgpLFxuICAgICAgICAgIHRoaXMuZm9ybVNlcmlhbGl6ZXJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNPYmplY3RQYXlsb2FkIHx8IGhhc0pTT05Db250ZW50VHlwZSApIHtcbiAgICAgIGhlYWRlcnMuc2V0Q29udGVudFR5cGUoJ2FwcGxpY2F0aW9uL2pzb24nLCBmYWxzZSk7XG4gICAgICByZXR1cm4gc3RyaW5naWZ5U2FmZWx5KGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9XSxcblxuICB0cmFuc2Zvcm1SZXNwb25zZTogW2Z1bmN0aW9uIHRyYW5zZm9ybVJlc3BvbnNlKGRhdGEpIHtcbiAgICBjb25zdCB0cmFuc2l0aW9uYWwgPSB0aGlzLnRyYW5zaXRpb25hbCB8fCBkZWZhdWx0cy50cmFuc2l0aW9uYWw7XG4gICAgY29uc3QgZm9yY2VkSlNPTlBhcnNpbmcgPSB0cmFuc2l0aW9uYWwgJiYgdHJhbnNpdGlvbmFsLmZvcmNlZEpTT05QYXJzaW5nO1xuICAgIGNvbnN0IEpTT05SZXF1ZXN0ZWQgPSB0aGlzLnJlc3BvbnNlVHlwZSA9PT0gJ2pzb24nO1xuXG4gICAgaWYgKHV0aWxzJDEuaXNSZXNwb25zZShkYXRhKSB8fCB1dGlscyQxLmlzUmVhZGFibGVTdHJlYW0oZGF0YSkpIHtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIGlmIChkYXRhICYmIHV0aWxzJDEuaXNTdHJpbmcoZGF0YSkgJiYgKChmb3JjZWRKU09OUGFyc2luZyAmJiAhdGhpcy5yZXNwb25zZVR5cGUpIHx8IEpTT05SZXF1ZXN0ZWQpKSB7XG4gICAgICBjb25zdCBzaWxlbnRKU09OUGFyc2luZyA9IHRyYW5zaXRpb25hbCAmJiB0cmFuc2l0aW9uYWwuc2lsZW50SlNPTlBhcnNpbmc7XG4gICAgICBjb25zdCBzdHJpY3RKU09OUGFyc2luZyA9ICFzaWxlbnRKU09OUGFyc2luZyAmJiBKU09OUmVxdWVzdGVkO1xuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHN0cmljdEpTT05QYXJzaW5nKSB7XG4gICAgICAgICAgaWYgKGUubmFtZSA9PT0gJ1N5bnRheEVycm9yJykge1xuICAgICAgICAgICAgdGhyb3cgQXhpb3NFcnJvci5mcm9tKGUsIEF4aW9zRXJyb3IuRVJSX0JBRF9SRVNQT05TRSwgdGhpcywgbnVsbCwgdGhpcy5yZXNwb25zZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfV0sXG5cbiAgLyoqXG4gICAqIEEgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgdG8gYWJvcnQgYSByZXF1ZXN0LiBJZiBzZXQgdG8gMCAoZGVmYXVsdCkgYVxuICAgKiB0aW1lb3V0IGlzIG5vdCBjcmVhdGVkLlxuICAgKi9cbiAgdGltZW91dDogMCxcblxuICB4c3JmQ29va2llTmFtZTogJ1hTUkYtVE9LRU4nLFxuICB4c3JmSGVhZGVyTmFtZTogJ1gtWFNSRi1UT0tFTicsXG5cbiAgbWF4Q29udGVudExlbmd0aDogLTEsXG4gIG1heEJvZHlMZW5ndGg6IC0xLFxuXG4gIGVudjoge1xuICAgIEZvcm1EYXRhOiBwbGF0Zm9ybS5jbGFzc2VzLkZvcm1EYXRhLFxuICAgIEJsb2I6IHBsYXRmb3JtLmNsYXNzZXMuQmxvYlxuICB9LFxuXG4gIHZhbGlkYXRlU3RhdHVzOiBmdW5jdGlvbiB2YWxpZGF0ZVN0YXR1cyhzdGF0dXMpIHtcbiAgICByZXR1cm4gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDA7XG4gIH0sXG5cbiAgaGVhZGVyczoge1xuICAgIGNvbW1vbjoge1xuICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyonLFxuICAgICAgJ0NvbnRlbnQtVHlwZSc6IHVuZGVmaW5lZFxuICAgIH1cbiAgfVxufTtcblxudXRpbHMkMS5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10sIChtZXRob2QpID0+IHtcbiAgZGVmYXVsdHMuaGVhZGVyc1ttZXRob2RdID0ge307XG59KTtcblxudmFyIGRlZmF1bHRzJDEgPSBkZWZhdWx0cztcblxuLy8gUmF3QXhpb3NIZWFkZXJzIHdob3NlIGR1cGxpY2F0ZXMgYXJlIGlnbm9yZWQgYnkgbm9kZVxuLy8gYy5mLiBodHRwczovL25vZGVqcy5vcmcvYXBpL2h0dHAuaHRtbCNodHRwX21lc3NhZ2VfaGVhZGVyc1xuY29uc3QgaWdub3JlRHVwbGljYXRlT2YgPSB1dGlscyQxLnRvT2JqZWN0U2V0KFtcbiAgJ2FnZScsICdhdXRob3JpemF0aW9uJywgJ2NvbnRlbnQtbGVuZ3RoJywgJ2NvbnRlbnQtdHlwZScsICdldGFnJyxcbiAgJ2V4cGlyZXMnLCAnZnJvbScsICdob3N0JywgJ2lmLW1vZGlmaWVkLXNpbmNlJywgJ2lmLXVubW9kaWZpZWQtc2luY2UnLFxuICAnbGFzdC1tb2RpZmllZCcsICdsb2NhdGlvbicsICdtYXgtZm9yd2FyZHMnLCAncHJveHktYXV0aG9yaXphdGlvbicsXG4gICdyZWZlcmVyJywgJ3JldHJ5LWFmdGVyJywgJ3VzZXItYWdlbnQnXG5dKTtcblxuLyoqXG4gKiBQYXJzZSBoZWFkZXJzIGludG8gYW4gb2JqZWN0XG4gKlxuICogYGBgXG4gKiBEYXRlOiBXZWQsIDI3IEF1ZyAyMDE0IDA4OjU4OjQ5IEdNVFxuICogQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uXG4gKiBDb25uZWN0aW9uOiBrZWVwLWFsaXZlXG4gKiBUcmFuc2Zlci1FbmNvZGluZzogY2h1bmtlZFxuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJhd0hlYWRlcnMgSGVhZGVycyBuZWVkaW5nIHRvIGJlIHBhcnNlZFxuICpcbiAqIEByZXR1cm5zIHtPYmplY3R9IEhlYWRlcnMgcGFyc2VkIGludG8gYW4gb2JqZWN0XG4gKi9cbnZhciBwYXJzZUhlYWRlcnMgPSByYXdIZWFkZXJzID0+IHtcbiAgY29uc3QgcGFyc2VkID0ge307XG4gIGxldCBrZXk7XG4gIGxldCB2YWw7XG4gIGxldCBpO1xuXG4gIHJhd0hlYWRlcnMgJiYgcmF3SGVhZGVycy5zcGxpdCgnXFxuJykuZm9yRWFjaChmdW5jdGlvbiBwYXJzZXIobGluZSkge1xuICAgIGkgPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBrZXkgPSBsaW5lLnN1YnN0cmluZygwLCBpKS50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICB2YWwgPSBsaW5lLnN1YnN0cmluZyhpICsgMSkudHJpbSgpO1xuXG4gICAgaWYgKCFrZXkgfHwgKHBhcnNlZFtrZXldICYmIGlnbm9yZUR1cGxpY2F0ZU9mW2tleV0pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGtleSA9PT0gJ3NldC1jb29raWUnKSB7XG4gICAgICBpZiAocGFyc2VkW2tleV0pIHtcbiAgICAgICAgcGFyc2VkW2tleV0ucHVzaCh2YWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyc2VkW2tleV0gPSBbdmFsXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcGFyc2VkW2tleV0gPSBwYXJzZWRba2V5XSA/IHBhcnNlZFtrZXldICsgJywgJyArIHZhbCA6IHZhbDtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwYXJzZWQ7XG59O1xuXG5jb25zdCAkaW50ZXJuYWxzID0gU3ltYm9sKCdpbnRlcm5hbHMnKTtcblxuZnVuY3Rpb24gbm9ybWFsaXplSGVhZGVyKGhlYWRlcikge1xuICByZXR1cm4gaGVhZGVyICYmIFN0cmluZyhoZWFkZXIpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xufVxuXG5mdW5jdGlvbiBub3JtYWxpemVWYWx1ZSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IGZhbHNlIHx8IHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gdXRpbHMkMS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLm1hcChub3JtYWxpemVWYWx1ZSkgOiBTdHJpbmcodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVRva2VucyhzdHIpIHtcbiAgY29uc3QgdG9rZW5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgY29uc3QgdG9rZW5zUkUgPSAvKFteXFxzLDs9XSspXFxzKig/Oj1cXHMqKFteLDtdKykpPy9nO1xuICBsZXQgbWF0Y2g7XG5cbiAgd2hpbGUgKChtYXRjaCA9IHRva2Vuc1JFLmV4ZWMoc3RyKSkpIHtcbiAgICB0b2tlbnNbbWF0Y2hbMV1dID0gbWF0Y2hbMl07XG4gIH1cblxuICByZXR1cm4gdG9rZW5zO1xufVxuXG5jb25zdCBpc1ZhbGlkSGVhZGVyTmFtZSA9IChzdHIpID0+IC9eWy1fYS16QS1aMC05XmB8fiwhIyQlJicqKy5dKyQvLnRlc3Qoc3RyLnRyaW0oKSk7XG5cbmZ1bmN0aW9uIG1hdGNoSGVhZGVyVmFsdWUoY29udGV4dCwgdmFsdWUsIGhlYWRlciwgZmlsdGVyLCBpc0hlYWRlck5hbWVGaWx0ZXIpIHtcbiAgaWYgKHV0aWxzJDEuaXNGdW5jdGlvbihmaWx0ZXIpKSB7XG4gICAgcmV0dXJuIGZpbHRlci5jYWxsKHRoaXMsIHZhbHVlLCBoZWFkZXIpO1xuICB9XG5cbiAgaWYgKGlzSGVhZGVyTmFtZUZpbHRlcikge1xuICAgIHZhbHVlID0gaGVhZGVyO1xuICB9XG5cbiAgaWYgKCF1dGlscyQxLmlzU3RyaW5nKHZhbHVlKSkgcmV0dXJuO1xuXG4gIGlmICh1dGlscyQxLmlzU3RyaW5nKGZpbHRlcikpIHtcbiAgICByZXR1cm4gdmFsdWUuaW5kZXhPZihmaWx0ZXIpICE9PSAtMTtcbiAgfVxuXG4gIGlmICh1dGlscyQxLmlzUmVnRXhwKGZpbHRlcikpIHtcbiAgICByZXR1cm4gZmlsdGVyLnRlc3QodmFsdWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEhlYWRlcihoZWFkZXIpIHtcbiAgcmV0dXJuIGhlYWRlci50cmltKClcbiAgICAudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8oW2EtelxcZF0pKFxcdyopL2csICh3LCBjaGFyLCBzdHIpID0+IHtcbiAgICAgIHJldHVybiBjaGFyLnRvVXBwZXJDYXNlKCkgKyBzdHI7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkQWNjZXNzb3JzKG9iaiwgaGVhZGVyKSB7XG4gIGNvbnN0IGFjY2Vzc29yTmFtZSA9IHV0aWxzJDEudG9DYW1lbENhc2UoJyAnICsgaGVhZGVyKTtcblxuICBbJ2dldCcsICdzZXQnLCAnaGFzJ10uZm9yRWFjaChtZXRob2ROYW1lID0+IHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqLCBtZXRob2ROYW1lICsgYWNjZXNzb3JOYW1lLCB7XG4gICAgICB2YWx1ZTogZnVuY3Rpb24oYXJnMSwgYXJnMiwgYXJnMykge1xuICAgICAgICByZXR1cm4gdGhpc1ttZXRob2ROYW1lXS5jYWxsKHRoaXMsIGhlYWRlciwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gICAgICB9LFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0pO1xufVxuXG5jbGFzcyBBeGlvc0hlYWRlcnMge1xuICBjb25zdHJ1Y3RvcihoZWFkZXJzKSB7XG4gICAgaGVhZGVycyAmJiB0aGlzLnNldChoZWFkZXJzKTtcbiAgfVxuXG4gIHNldChoZWFkZXIsIHZhbHVlT3JSZXdyaXRlLCByZXdyaXRlKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBmdW5jdGlvbiBzZXRIZWFkZXIoX3ZhbHVlLCBfaGVhZGVyLCBfcmV3cml0ZSkge1xuICAgICAgY29uc3QgbEhlYWRlciA9IG5vcm1hbGl6ZUhlYWRlcihfaGVhZGVyKTtcblxuICAgICAgaWYgKCFsSGVhZGVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaGVhZGVyIG5hbWUgbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qga2V5ID0gdXRpbHMkMS5maW5kS2V5KHNlbGYsIGxIZWFkZXIpO1xuXG4gICAgICBpZigha2V5IHx8IHNlbGZba2V5XSA9PT0gdW5kZWZpbmVkIHx8IF9yZXdyaXRlID09PSB0cnVlIHx8IChfcmV3cml0ZSA9PT0gdW5kZWZpbmVkICYmIHNlbGZba2V5XSAhPT0gZmFsc2UpKSB7XG4gICAgICAgIHNlbGZba2V5IHx8IF9oZWFkZXJdID0gbm9ybWFsaXplVmFsdWUoX3ZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzZXRIZWFkZXJzID0gKGhlYWRlcnMsIF9yZXdyaXRlKSA9PlxuICAgICAgdXRpbHMkMS5mb3JFYWNoKGhlYWRlcnMsIChfdmFsdWUsIF9oZWFkZXIpID0+IHNldEhlYWRlcihfdmFsdWUsIF9oZWFkZXIsIF9yZXdyaXRlKSk7XG5cbiAgICBpZiAodXRpbHMkMS5pc1BsYWluT2JqZWN0KGhlYWRlcikgfHwgaGVhZGVyIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3Rvcikge1xuICAgICAgc2V0SGVhZGVycyhoZWFkZXIsIHZhbHVlT3JSZXdyaXRlKTtcbiAgICB9IGVsc2UgaWYodXRpbHMkMS5pc1N0cmluZyhoZWFkZXIpICYmIChoZWFkZXIgPSBoZWFkZXIudHJpbSgpKSAmJiAhaXNWYWxpZEhlYWRlck5hbWUoaGVhZGVyKSkge1xuICAgICAgc2V0SGVhZGVycyhwYXJzZUhlYWRlcnMoaGVhZGVyKSwgdmFsdWVPclJld3JpdGUpO1xuICAgIH0gZWxzZSBpZiAodXRpbHMkMS5pc0hlYWRlcnMoaGVhZGVyKSkge1xuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgaGVhZGVyLmVudHJpZXMoKSkge1xuICAgICAgICBzZXRIZWFkZXIodmFsdWUsIGtleSwgcmV3cml0ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGhlYWRlciAhPSBudWxsICYmIHNldEhlYWRlcih2YWx1ZU9yUmV3cml0ZSwgaGVhZGVyLCByZXdyaXRlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldChoZWFkZXIsIHBhcnNlcikge1xuICAgIGhlYWRlciA9IG5vcm1hbGl6ZUhlYWRlcihoZWFkZXIpO1xuXG4gICAgaWYgKGhlYWRlcikge1xuICAgICAgY29uc3Qga2V5ID0gdXRpbHMkMS5maW5kS2V5KHRoaXMsIGhlYWRlcik7XG5cbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzW2tleV07XG5cbiAgICAgICAgaWYgKCFwYXJzZXIpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFyc2VyID09PSB0cnVlKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5zKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1dGlscyQxLmlzRnVuY3Rpb24ocGFyc2VyKSkge1xuICAgICAgICAgIHJldHVybiBwYXJzZXIuY2FsbCh0aGlzLCB2YWx1ZSwga2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh1dGlscyQxLmlzUmVnRXhwKHBhcnNlcikpIHtcbiAgICAgICAgICByZXR1cm4gcGFyc2VyLmV4ZWModmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncGFyc2VyIG11c3QgYmUgYm9vbGVhbnxyZWdleHB8ZnVuY3Rpb24nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYXMoaGVhZGVyLCBtYXRjaGVyKSB7XG4gICAgaGVhZGVyID0gbm9ybWFsaXplSGVhZGVyKGhlYWRlcik7XG5cbiAgICBpZiAoaGVhZGVyKSB7XG4gICAgICBjb25zdCBrZXkgPSB1dGlscyQxLmZpbmRLZXkodGhpcywgaGVhZGVyKTtcblxuICAgICAgcmV0dXJuICEhKGtleSAmJiB0aGlzW2tleV0gIT09IHVuZGVmaW5lZCAmJiAoIW1hdGNoZXIgfHwgbWF0Y2hIZWFkZXJWYWx1ZSh0aGlzLCB0aGlzW2tleV0sIGtleSwgbWF0Y2hlcikpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBkZWxldGUoaGVhZGVyLCBtYXRjaGVyKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgbGV0IGRlbGV0ZWQgPSBmYWxzZTtcblxuICAgIGZ1bmN0aW9uIGRlbGV0ZUhlYWRlcihfaGVhZGVyKSB7XG4gICAgICBfaGVhZGVyID0gbm9ybWFsaXplSGVhZGVyKF9oZWFkZXIpO1xuXG4gICAgICBpZiAoX2hlYWRlcikge1xuICAgICAgICBjb25zdCBrZXkgPSB1dGlscyQxLmZpbmRLZXkoc2VsZiwgX2hlYWRlcik7XG5cbiAgICAgICAgaWYgKGtleSAmJiAoIW1hdGNoZXIgfHwgbWF0Y2hIZWFkZXJWYWx1ZShzZWxmLCBzZWxmW2tleV0sIGtleSwgbWF0Y2hlcikpKSB7XG4gICAgICAgICAgZGVsZXRlIHNlbGZba2V5XTtcblxuICAgICAgICAgIGRlbGV0ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHV0aWxzJDEuaXNBcnJheShoZWFkZXIpKSB7XG4gICAgICBoZWFkZXIuZm9yRWFjaChkZWxldGVIZWFkZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGVIZWFkZXIoaGVhZGVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVsZXRlZDtcbiAgfVxuXG4gIGNsZWFyKG1hdGNoZXIpIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXModGhpcyk7XG4gICAgbGV0IGkgPSBrZXlzLmxlbmd0aDtcbiAgICBsZXQgZGVsZXRlZCA9IGZhbHNlO1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcbiAgICAgIGlmKCFtYXRjaGVyIHx8IG1hdGNoSGVhZGVyVmFsdWUodGhpcywgdGhpc1trZXldLCBrZXksIG1hdGNoZXIsIHRydWUpKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzW2tleV07XG4gICAgICAgIGRlbGV0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkZWxldGVkO1xuICB9XG5cbiAgbm9ybWFsaXplKGZvcm1hdCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IGhlYWRlcnMgPSB7fTtcblxuICAgIHV0aWxzJDEuZm9yRWFjaCh0aGlzLCAodmFsdWUsIGhlYWRlcikgPT4ge1xuICAgICAgY29uc3Qga2V5ID0gdXRpbHMkMS5maW5kS2V5KGhlYWRlcnMsIGhlYWRlcik7XG5cbiAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgc2VsZltrZXldID0gbm9ybWFsaXplVmFsdWUodmFsdWUpO1xuICAgICAgICBkZWxldGUgc2VsZltoZWFkZXJdO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBmb3JtYXQgPyBmb3JtYXRIZWFkZXIoaGVhZGVyKSA6IFN0cmluZyhoZWFkZXIpLnRyaW0oKTtcblxuICAgICAgaWYgKG5vcm1hbGl6ZWQgIT09IGhlYWRlcikge1xuICAgICAgICBkZWxldGUgc2VsZltoZWFkZXJdO1xuICAgICAgfVxuXG4gICAgICBzZWxmW25vcm1hbGl6ZWRdID0gbm9ybWFsaXplVmFsdWUodmFsdWUpO1xuXG4gICAgICBoZWFkZXJzW25vcm1hbGl6ZWRdID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgY29uY2F0KC4uLnRhcmdldHMpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5jb25jYXQodGhpcywgLi4udGFyZ2V0cyk7XG4gIH1cblxuICB0b0pTT04oYXNTdHJpbmdzKSB7XG4gICAgY29uc3Qgb2JqID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgIHV0aWxzJDEuZm9yRWFjaCh0aGlzLCAodmFsdWUsIGhlYWRlcikgPT4ge1xuICAgICAgdmFsdWUgIT0gbnVsbCAmJiB2YWx1ZSAhPT0gZmFsc2UgJiYgKG9ialtoZWFkZXJdID0gYXNTdHJpbmdzICYmIHV0aWxzJDEuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5qb2luKCcsICcpIDogdmFsdWUpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIFtTeW1ib2wuaXRlcmF0b3JdKCkge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh0aGlzLnRvSlNPTigpKVtTeW1ib2wuaXRlcmF0b3JdKCk7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModGhpcy50b0pTT04oKSkubWFwKChbaGVhZGVyLCB2YWx1ZV0pID0+IGhlYWRlciArICc6ICcgKyB2YWx1ZSkuam9pbignXFxuJyk7XG4gIH1cblxuICBnZXQgW1N5bWJvbC50b1N0cmluZ1RhZ10oKSB7XG4gICAgcmV0dXJuICdBeGlvc0hlYWRlcnMnO1xuICB9XG5cbiAgc3RhdGljIGZyb20odGhpbmcpIHtcbiAgICByZXR1cm4gdGhpbmcgaW5zdGFuY2VvZiB0aGlzID8gdGhpbmcgOiBuZXcgdGhpcyh0aGluZyk7XG4gIH1cblxuICBzdGF0aWMgY29uY2F0KGZpcnN0LCAuLi50YXJnZXRzKSB7XG4gICAgY29uc3QgY29tcHV0ZWQgPSBuZXcgdGhpcyhmaXJzdCk7XG5cbiAgICB0YXJnZXRzLmZvckVhY2goKHRhcmdldCkgPT4gY29tcHV0ZWQuc2V0KHRhcmdldCkpO1xuXG4gICAgcmV0dXJuIGNvbXB1dGVkO1xuICB9XG5cbiAgc3RhdGljIGFjY2Vzc29yKGhlYWRlcikge1xuICAgIGNvbnN0IGludGVybmFscyA9IHRoaXNbJGludGVybmFsc10gPSAodGhpc1skaW50ZXJuYWxzXSA9IHtcbiAgICAgIGFjY2Vzc29yczoge31cbiAgICB9KTtcblxuICAgIGNvbnN0IGFjY2Vzc29ycyA9IGludGVybmFscy5hY2Nlc3NvcnM7XG4gICAgY29uc3QgcHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG5cbiAgICBmdW5jdGlvbiBkZWZpbmVBY2Nlc3NvcihfaGVhZGVyKSB7XG4gICAgICBjb25zdCBsSGVhZGVyID0gbm9ybWFsaXplSGVhZGVyKF9oZWFkZXIpO1xuXG4gICAgICBpZiAoIWFjY2Vzc29yc1tsSGVhZGVyXSkge1xuICAgICAgICBidWlsZEFjY2Vzc29ycyhwcm90b3R5cGUsIF9oZWFkZXIpO1xuICAgICAgICBhY2Nlc3NvcnNbbEhlYWRlcl0gPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHV0aWxzJDEuaXNBcnJheShoZWFkZXIpID8gaGVhZGVyLmZvckVhY2goZGVmaW5lQWNjZXNzb3IpIDogZGVmaW5lQWNjZXNzb3IoaGVhZGVyKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG59XG5cbkF4aW9zSGVhZGVycy5hY2Nlc3NvcihbJ0NvbnRlbnQtVHlwZScsICdDb250ZW50LUxlbmd0aCcsICdBY2NlcHQnLCAnQWNjZXB0LUVuY29kaW5nJywgJ1VzZXItQWdlbnQnLCAnQXV0aG9yaXphdGlvbiddKTtcblxuLy8gcmVzZXJ2ZWQgbmFtZXMgaG90Zml4XG51dGlscyQxLnJlZHVjZURlc2NyaXB0b3JzKEF4aW9zSGVhZGVycy5wcm90b3R5cGUsICh7dmFsdWV9LCBrZXkpID0+IHtcbiAgbGV0IG1hcHBlZCA9IGtleVswXS50b1VwcGVyQ2FzZSgpICsga2V5LnNsaWNlKDEpOyAvLyBtYXAgYHNldGAgPT4gYFNldGBcbiAgcmV0dXJuIHtcbiAgICBnZXQ6ICgpID0+IHZhbHVlLFxuICAgIHNldChoZWFkZXJWYWx1ZSkge1xuICAgICAgdGhpc1ttYXBwZWRdID0gaGVhZGVyVmFsdWU7XG4gICAgfVxuICB9XG59KTtcblxudXRpbHMkMS5mcmVlemVNZXRob2RzKEF4aW9zSGVhZGVycyk7XG5cbnZhciBBeGlvc0hlYWRlcnMkMSA9IEF4aW9zSGVhZGVycztcblxuLyoqXG4gKiBUcmFuc2Zvcm0gdGhlIGRhdGEgZm9yIGEgcmVxdWVzdCBvciBhIHJlc3BvbnNlXG4gKlxuICogQHBhcmFtIHtBcnJheXxGdW5jdGlvbn0gZm5zIEEgc2luZ2xlIGZ1bmN0aW9uIG9yIEFycmF5IG9mIGZ1bmN0aW9uc1xuICogQHBhcmFtIHs/T2JqZWN0fSByZXNwb25zZSBUaGUgcmVzcG9uc2Ugb2JqZWN0XG4gKlxuICogQHJldHVybnMgeyp9IFRoZSByZXN1bHRpbmcgdHJhbnNmb3JtZWQgZGF0YVxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm1EYXRhKGZucywgcmVzcG9uc2UpIHtcbiAgY29uc3QgY29uZmlnID0gdGhpcyB8fCBkZWZhdWx0cyQxO1xuICBjb25zdCBjb250ZXh0ID0gcmVzcG9uc2UgfHwgY29uZmlnO1xuICBjb25zdCBoZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShjb250ZXh0LmhlYWRlcnMpO1xuICBsZXQgZGF0YSA9IGNvbnRleHQuZGF0YTtcblxuICB1dGlscyQxLmZvckVhY2goZm5zLCBmdW5jdGlvbiB0cmFuc2Zvcm0oZm4pIHtcbiAgICBkYXRhID0gZm4uY2FsbChjb25maWcsIGRhdGEsIGhlYWRlcnMubm9ybWFsaXplKCksIHJlc3BvbnNlID8gcmVzcG9uc2Uuc3RhdHVzIDogdW5kZWZpbmVkKTtcbiAgfSk7XG5cbiAgaGVhZGVycy5ub3JtYWxpemUoKTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gaXNDYW5jZWwodmFsdWUpIHtcbiAgcmV0dXJuICEhKHZhbHVlICYmIHZhbHVlLl9fQ0FOQ0VMX18pO1xufVxuXG4vKipcbiAqIEEgYENhbmNlbGVkRXJyb3JgIGlzIGFuIG9iamVjdCB0aGF0IGlzIHRocm93biB3aGVuIGFuIG9wZXJhdGlvbiBpcyBjYW5jZWxlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZz19IG1lc3NhZ2UgVGhlIG1lc3NhZ2UuXG4gKiBAcGFyYW0ge09iamVjdD19IGNvbmZpZyBUaGUgY29uZmlnLlxuICogQHBhcmFtIHtPYmplY3Q9fSByZXF1ZXN0IFRoZSByZXF1ZXN0LlxuICpcbiAqIEByZXR1cm5zIHtDYW5jZWxlZEVycm9yfSBUaGUgY3JlYXRlZCBlcnJvci5cbiAqL1xuZnVuY3Rpb24gQ2FuY2VsZWRFcnJvcihtZXNzYWdlLCBjb25maWcsIHJlcXVlc3QpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVxLW51bGwsZXFlcWVxXG4gIEF4aW9zRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlID09IG51bGwgPyAnY2FuY2VsZWQnIDogbWVzc2FnZSwgQXhpb3NFcnJvci5FUlJfQ0FOQ0VMRUQsIGNvbmZpZywgcmVxdWVzdCk7XG4gIHRoaXMubmFtZSA9ICdDYW5jZWxlZEVycm9yJztcbn1cblxudXRpbHMkMS5pbmhlcml0cyhDYW5jZWxlZEVycm9yLCBBeGlvc0Vycm9yLCB7XG4gIF9fQ0FOQ0VMX186IHRydWVcbn0pO1xuXG4vKipcbiAqIFJlc29sdmUgb3IgcmVqZWN0IGEgUHJvbWlzZSBiYXNlZCBvbiByZXNwb25zZSBzdGF0dXMuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZSBBIGZ1bmN0aW9uIHRoYXQgcmVzb2x2ZXMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3QgQSBmdW5jdGlvbiB0aGF0IHJlamVjdHMgdGhlIHByb21pc2UuXG4gKiBAcGFyYW0ge29iamVjdH0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSByZXNwb25zZS5cbiAqL1xuZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgcmVzcG9uc2UpIHtcbiAgY29uc3QgdmFsaWRhdGVTdGF0dXMgPSByZXNwb25zZS5jb25maWcudmFsaWRhdGVTdGF0dXM7XG4gIGlmICghcmVzcG9uc2Uuc3RhdHVzIHx8ICF2YWxpZGF0ZVN0YXR1cyB8fCB2YWxpZGF0ZVN0YXR1cyhyZXNwb25zZS5zdGF0dXMpKSB7XG4gICAgcmVzb2x2ZShyZXNwb25zZSk7XG4gIH0gZWxzZSB7XG4gICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKFxuICAgICAgJ1JlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzIGNvZGUgJyArIHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIFtBeGlvc0Vycm9yLkVSUl9CQURfUkVRVUVTVCwgQXhpb3NFcnJvci5FUlJfQkFEX1JFU1BPTlNFXVtNYXRoLmZsb29yKHJlc3BvbnNlLnN0YXR1cyAvIDEwMCkgLSA0XSxcbiAgICAgIHJlc3BvbnNlLmNvbmZpZyxcbiAgICAgIHJlc3BvbnNlLnJlcXVlc3QsXG4gICAgICByZXNwb25zZVxuICAgICkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlUHJvdG9jb2wodXJsKSB7XG4gIGNvbnN0IG1hdGNoID0gL14oWy0rXFx3XXsxLDI1fSkoOj9cXC9cXC98OikvLmV4ZWModXJsKTtcbiAgcmV0dXJuIG1hdGNoICYmIG1hdGNoWzFdIHx8ICcnO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBkYXRhIG1heFJhdGVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbc2FtcGxlc0NvdW50PSAxMF1cbiAqIEBwYXJhbSB7TnVtYmVyfSBbbWluPSAxMDAwXVxuICogQHJldHVybnMge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBzcGVlZG9tZXRlcihzYW1wbGVzQ291bnQsIG1pbikge1xuICBzYW1wbGVzQ291bnQgPSBzYW1wbGVzQ291bnQgfHwgMTA7XG4gIGNvbnN0IGJ5dGVzID0gbmV3IEFycmF5KHNhbXBsZXNDb3VudCk7XG4gIGNvbnN0IHRpbWVzdGFtcHMgPSBuZXcgQXJyYXkoc2FtcGxlc0NvdW50KTtcbiAgbGV0IGhlYWQgPSAwO1xuICBsZXQgdGFpbCA9IDA7XG4gIGxldCBmaXJzdFNhbXBsZVRTO1xuXG4gIG1pbiA9IG1pbiAhPT0gdW5kZWZpbmVkID8gbWluIDogMTAwMDtcblxuICByZXR1cm4gZnVuY3Rpb24gcHVzaChjaHVua0xlbmd0aCkge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICBjb25zdCBzdGFydGVkQXQgPSB0aW1lc3RhbXBzW3RhaWxdO1xuXG4gICAgaWYgKCFmaXJzdFNhbXBsZVRTKSB7XG4gICAgICBmaXJzdFNhbXBsZVRTID0gbm93O1xuICAgIH1cblxuICAgIGJ5dGVzW2hlYWRdID0gY2h1bmtMZW5ndGg7XG4gICAgdGltZXN0YW1wc1toZWFkXSA9IG5vdztcblxuICAgIGxldCBpID0gdGFpbDtcbiAgICBsZXQgYnl0ZXNDb3VudCA9IDA7XG5cbiAgICB3aGlsZSAoaSAhPT0gaGVhZCkge1xuICAgICAgYnl0ZXNDb3VudCArPSBieXRlc1tpKytdO1xuICAgICAgaSA9IGkgJSBzYW1wbGVzQ291bnQ7XG4gICAgfVxuXG4gICAgaGVhZCA9IChoZWFkICsgMSkgJSBzYW1wbGVzQ291bnQ7XG5cbiAgICBpZiAoaGVhZCA9PT0gdGFpbCkge1xuICAgICAgdGFpbCA9ICh0YWlsICsgMSkgJSBzYW1wbGVzQ291bnQ7XG4gICAgfVxuXG4gICAgaWYgKG5vdyAtIGZpcnN0U2FtcGxlVFMgPCBtaW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXNzZWQgPSBzdGFydGVkQXQgJiYgbm93IC0gc3RhcnRlZEF0O1xuXG4gICAgcmV0dXJuIHBhc3NlZCA/IE1hdGgucm91bmQoYnl0ZXNDb3VudCAqIDEwMDAgLyBwYXNzZWQpIDogdW5kZWZpbmVkO1xuICB9O1xufVxuXG4vKipcbiAqIFRocm90dGxlIGRlY29yYXRvclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEBwYXJhbSB7TnVtYmVyfSBmcmVxXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gdGhyb3R0bGUoZm4sIGZyZXEpIHtcbiAgbGV0IHRpbWVzdGFtcCA9IDA7XG4gIGxldCB0aHJlc2hvbGQgPSAxMDAwIC8gZnJlcTtcbiAgbGV0IGxhc3RBcmdzO1xuICBsZXQgdGltZXI7XG5cbiAgY29uc3QgaW52b2tlID0gKGFyZ3MsIG5vdyA9IERhdGUubm93KCkpID0+IHtcbiAgICB0aW1lc3RhbXAgPSBub3c7XG4gICAgbGFzdEFyZ3MgPSBudWxsO1xuICAgIGlmICh0aW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIHRpbWVyID0gbnVsbDtcbiAgICB9XG4gICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gIH07XG5cbiAgY29uc3QgdGhyb3R0bGVkID0gKC4uLmFyZ3MpID0+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHBhc3NlZCA9IG5vdyAtIHRpbWVzdGFtcDtcbiAgICBpZiAoIHBhc3NlZCA+PSB0aHJlc2hvbGQpIHtcbiAgICAgIGludm9rZShhcmdzLCBub3cpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0QXJncyA9IGFyZ3M7XG4gICAgICBpZiAoIXRpbWVyKSB7XG4gICAgICAgIHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICAgIGludm9rZShsYXN0QXJncyk7XG4gICAgICAgIH0sIHRocmVzaG9sZCAtIHBhc3NlZCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGZsdXNoID0gKCkgPT4gbGFzdEFyZ3MgJiYgaW52b2tlKGxhc3RBcmdzKTtcblxuICByZXR1cm4gW3Rocm90dGxlZCwgZmx1c2hdO1xufVxuXG5jb25zdCBwcm9ncmVzc0V2ZW50UmVkdWNlciA9IChsaXN0ZW5lciwgaXNEb3dubG9hZFN0cmVhbSwgZnJlcSA9IDMpID0+IHtcbiAgbGV0IGJ5dGVzTm90aWZpZWQgPSAwO1xuICBjb25zdCBfc3BlZWRvbWV0ZXIgPSBzcGVlZG9tZXRlcig1MCwgMjUwKTtcblxuICByZXR1cm4gdGhyb3R0bGUoZSA9PiB7XG4gICAgY29uc3QgbG9hZGVkID0gZS5sb2FkZWQ7XG4gICAgY29uc3QgdG90YWwgPSBlLmxlbmd0aENvbXB1dGFibGUgPyBlLnRvdGFsIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHByb2dyZXNzQnl0ZXMgPSBsb2FkZWQgLSBieXRlc05vdGlmaWVkO1xuICAgIGNvbnN0IHJhdGUgPSBfc3BlZWRvbWV0ZXIocHJvZ3Jlc3NCeXRlcyk7XG4gICAgY29uc3QgaW5SYW5nZSA9IGxvYWRlZCA8PSB0b3RhbDtcblxuICAgIGJ5dGVzTm90aWZpZWQgPSBsb2FkZWQ7XG5cbiAgICBjb25zdCBkYXRhID0ge1xuICAgICAgbG9hZGVkLFxuICAgICAgdG90YWwsXG4gICAgICBwcm9ncmVzczogdG90YWwgPyAobG9hZGVkIC8gdG90YWwpIDogdW5kZWZpbmVkLFxuICAgICAgYnl0ZXM6IHByb2dyZXNzQnl0ZXMsXG4gICAgICByYXRlOiByYXRlID8gcmF0ZSA6IHVuZGVmaW5lZCxcbiAgICAgIGVzdGltYXRlZDogcmF0ZSAmJiB0b3RhbCAmJiBpblJhbmdlID8gKHRvdGFsIC0gbG9hZGVkKSAvIHJhdGUgOiB1bmRlZmluZWQsXG4gICAgICBldmVudDogZSxcbiAgICAgIGxlbmd0aENvbXB1dGFibGU6IHRvdGFsICE9IG51bGwsXG4gICAgICBbaXNEb3dubG9hZFN0cmVhbSA/ICdkb3dubG9hZCcgOiAndXBsb2FkJ106IHRydWVcbiAgICB9O1xuXG4gICAgbGlzdGVuZXIoZGF0YSk7XG4gIH0sIGZyZXEpO1xufTtcblxuY29uc3QgcHJvZ3Jlc3NFdmVudERlY29yYXRvciA9ICh0b3RhbCwgdGhyb3R0bGVkKSA9PiB7XG4gIGNvbnN0IGxlbmd0aENvbXB1dGFibGUgPSB0b3RhbCAhPSBudWxsO1xuXG4gIHJldHVybiBbKGxvYWRlZCkgPT4gdGhyb3R0bGVkWzBdKHtcbiAgICBsZW5ndGhDb21wdXRhYmxlLFxuICAgIHRvdGFsLFxuICAgIGxvYWRlZFxuICB9KSwgdGhyb3R0bGVkWzFdXTtcbn07XG5cbmNvbnN0IGFzeW5jRGVjb3JhdG9yID0gKGZuKSA9PiAoLi4uYXJncykgPT4gdXRpbHMkMS5hc2FwKCgpID0+IGZuKC4uLmFyZ3MpKTtcblxudmFyIGlzVVJMU2FtZU9yaWdpbiA9IHBsYXRmb3JtLmhhc1N0YW5kYXJkQnJvd3NlckVudiA/ICgob3JpZ2luLCBpc01TSUUpID0+ICh1cmwpID0+IHtcbiAgdXJsID0gbmV3IFVSTCh1cmwsIHBsYXRmb3JtLm9yaWdpbik7XG5cbiAgcmV0dXJuIChcbiAgICBvcmlnaW4ucHJvdG9jb2wgPT09IHVybC5wcm90b2NvbCAmJlxuICAgIG9yaWdpbi5ob3N0ID09PSB1cmwuaG9zdCAmJlxuICAgIChpc01TSUUgfHwgb3JpZ2luLnBvcnQgPT09IHVybC5wb3J0KVxuICApO1xufSkoXG4gIG5ldyBVUkwocGxhdGZvcm0ub3JpZ2luKSxcbiAgcGxhdGZvcm0ubmF2aWdhdG9yICYmIC8obXNpZXx0cmlkZW50KS9pLnRlc3QocGxhdGZvcm0ubmF2aWdhdG9yLnVzZXJBZ2VudClcbikgOiAoKSA9PiB0cnVlO1xuXG52YXIgY29va2llcyA9IHBsYXRmb3JtLmhhc1N0YW5kYXJkQnJvd3NlckVudiA/XG5cbiAgLy8gU3RhbmRhcmQgYnJvd3NlciBlbnZzIHN1cHBvcnQgZG9jdW1lbnQuY29va2llXG4gIHtcbiAgICB3cml0ZShuYW1lLCB2YWx1ZSwgZXhwaXJlcywgcGF0aCwgZG9tYWluLCBzZWN1cmUpIHtcbiAgICAgIGNvbnN0IGNvb2tpZSA9IFtuYW1lICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKV07XG5cbiAgICAgIHV0aWxzJDEuaXNOdW1iZXIoZXhwaXJlcykgJiYgY29va2llLnB1c2goJ2V4cGlyZXM9JyArIG5ldyBEYXRlKGV4cGlyZXMpLnRvR01UU3RyaW5nKCkpO1xuXG4gICAgICB1dGlscyQxLmlzU3RyaW5nKHBhdGgpICYmIGNvb2tpZS5wdXNoKCdwYXRoPScgKyBwYXRoKTtcblxuICAgICAgdXRpbHMkMS5pc1N0cmluZyhkb21haW4pICYmIGNvb2tpZS5wdXNoKCdkb21haW49JyArIGRvbWFpbik7XG5cbiAgICAgIHNlY3VyZSA9PT0gdHJ1ZSAmJiBjb29raWUucHVzaCgnc2VjdXJlJyk7XG5cbiAgICAgIGRvY3VtZW50LmNvb2tpZSA9IGNvb2tpZS5qb2luKCc7ICcpO1xuICAgIH0sXG5cbiAgICByZWFkKG5hbWUpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoJyhefDtcXFxccyopKCcgKyBuYW1lICsgJyk9KFteO10qKScpKTtcbiAgICAgIHJldHVybiAobWF0Y2ggPyBkZWNvZGVVUklDb21wb25lbnQobWF0Y2hbM10pIDogbnVsbCk7XG4gICAgfSxcblxuICAgIHJlbW92ZShuYW1lKSB7XG4gICAgICB0aGlzLndyaXRlKG5hbWUsICcnLCBEYXRlLm5vdygpIC0gODY0MDAwMDApO1xuICAgIH1cbiAgfVxuXG4gIDpcblxuICAvLyBOb24tc3RhbmRhcmQgYnJvd3NlciBlbnYgKHdlYiB3b3JrZXJzLCByZWFjdC1uYXRpdmUpIGxhY2sgbmVlZGVkIHN1cHBvcnQuXG4gIHtcbiAgICB3cml0ZSgpIHt9LFxuICAgIHJlYWQoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICAgIHJlbW92ZSgpIHt9XG4gIH07XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIHRlc3RcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIFVSTCBpcyBhYnNvbHV0ZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQWJzb2x1dGVVUkwodXJsKSB7XG4gIC8vIEEgVVJMIGlzIGNvbnNpZGVyZWQgYWJzb2x1dGUgaWYgaXQgYmVnaW5zIHdpdGggXCI8c2NoZW1lPjovL1wiIG9yIFwiLy9cIiAocHJvdG9jb2wtcmVsYXRpdmUgVVJMKS5cbiAgLy8gUkZDIDM5ODYgZGVmaW5lcyBzY2hlbWUgbmFtZSBhcyBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgYmVnaW5uaW5nIHdpdGggYSBsZXR0ZXIgYW5kIGZvbGxvd2VkXG4gIC8vIGJ5IGFueSBjb21iaW5hdGlvbiBvZiBsZXR0ZXJzLCBkaWdpdHMsIHBsdXMsIHBlcmlvZCwgb3IgaHlwaGVuLlxuICByZXR1cm4gL14oW2Etel1bYS16XFxkK1xcLS5dKjopP1xcL1xcLy9pLnRlc3QodXJsKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFVSTCBieSBjb21iaW5pbmcgdGhlIHNwZWNpZmllZCBVUkxzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVsYXRpdmVVUkwgVGhlIHJlbGF0aXZlIFVSTFxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb21iaW5lZCBVUkxcbiAqL1xuZnVuY3Rpb24gY29tYmluZVVSTHMoYmFzZVVSTCwgcmVsYXRpdmVVUkwpIHtcbiAgcmV0dXJuIHJlbGF0aXZlVVJMXG4gICAgPyBiYXNlVVJMLnJlcGxhY2UoL1xcLz9cXC8kLywgJycpICsgJy8nICsgcmVsYXRpdmVVUkwucmVwbGFjZSgvXlxcLysvLCAnJylcbiAgICA6IGJhc2VVUkw7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBVUkwgYnkgY29tYmluaW5nIHRoZSBiYXNlVVJMIHdpdGggdGhlIHJlcXVlc3RlZFVSTCxcbiAqIG9ubHkgd2hlbiB0aGUgcmVxdWVzdGVkVVJMIGlzIG5vdCBhbHJlYWR5IGFuIGFic29sdXRlIFVSTC5cbiAqIElmIHRoZSByZXF1ZXN0VVJMIGlzIGFic29sdXRlLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIHJlcXVlc3RlZFVSTCB1bnRvdWNoZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2VVUkwgVGhlIGJhc2UgVVJMXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVxdWVzdGVkVVJMIEFic29sdXRlIG9yIHJlbGF0aXZlIFVSTCB0byBjb21iaW5lXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbWJpbmVkIGZ1bGwgcGF0aFxuICovXG5mdW5jdGlvbiBidWlsZEZ1bGxQYXRoKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCwgYWxsb3dBYnNvbHV0ZVVybHMpIHtcbiAgbGV0IGlzUmVsYXRpdmVVcmwgPSAhaXNBYnNvbHV0ZVVSTChyZXF1ZXN0ZWRVUkwpO1xuICBpZiAoYmFzZVVSTCAmJiAoaXNSZWxhdGl2ZVVybCB8fCBhbGxvd0Fic29sdXRlVXJscyA9PSBmYWxzZSkpIHtcbiAgICByZXR1cm4gY29tYmluZVVSTHMoYmFzZVVSTCwgcmVxdWVzdGVkVVJMKTtcbiAgfVxuICByZXR1cm4gcmVxdWVzdGVkVVJMO1xufVxuXG5jb25zdCBoZWFkZXJzVG9PYmplY3QgPSAodGhpbmcpID0+IHRoaW5nIGluc3RhbmNlb2YgQXhpb3NIZWFkZXJzJDEgPyB7IC4uLnRoaW5nIH0gOiB0aGluZztcblxuLyoqXG4gKiBDb25maWctc3BlY2lmaWMgbWVyZ2UtZnVuY3Rpb24gd2hpY2ggY3JlYXRlcyBhIG5ldyBjb25maWctb2JqZWN0XG4gKiBieSBtZXJnaW5nIHR3byBjb25maWd1cmF0aW9uIG9iamVjdHMgdG9nZXRoZXIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZzFcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcyXG4gKlxuICogQHJldHVybnMge09iamVjdH0gTmV3IG9iamVjdCByZXN1bHRpbmcgZnJvbSBtZXJnaW5nIGNvbmZpZzIgdG8gY29uZmlnMVxuICovXG5mdW5jdGlvbiBtZXJnZUNvbmZpZyhjb25maWcxLCBjb25maWcyKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICBjb25maWcyID0gY29uZmlnMiB8fCB7fTtcbiAgY29uc3QgY29uZmlnID0ge307XG5cbiAgZnVuY3Rpb24gZ2V0TWVyZ2VkVmFsdWUodGFyZ2V0LCBzb3VyY2UsIHByb3AsIGNhc2VsZXNzKSB7XG4gICAgaWYgKHV0aWxzJDEuaXNQbGFpbk9iamVjdCh0YXJnZXQpICYmIHV0aWxzJDEuaXNQbGFpbk9iamVjdChzb3VyY2UpKSB7XG4gICAgICByZXR1cm4gdXRpbHMkMS5tZXJnZS5jYWxsKHtjYXNlbGVzc30sIHRhcmdldCwgc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKHV0aWxzJDEuaXNQbGFpbk9iamVjdChzb3VyY2UpKSB7XG4gICAgICByZXR1cm4gdXRpbHMkMS5tZXJnZSh7fSwgc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKHV0aWxzJDEuaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICByZXR1cm4gc291cmNlLnNsaWNlKCk7XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2U7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgZnVuY3Rpb24gbWVyZ2VEZWVwUHJvcGVydGllcyhhLCBiLCBwcm9wICwgY2FzZWxlc3MpIHtcbiAgICBpZiAoIXV0aWxzJDEuaXNVbmRlZmluZWQoYikpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZShhLCBiLCBwcm9wICwgY2FzZWxlc3MpO1xuICAgIH0gZWxzZSBpZiAoIXV0aWxzJDEuaXNVbmRlZmluZWQoYSkpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZSh1bmRlZmluZWQsIGEsIHByb3AgLCBjYXNlbGVzcyk7XG4gICAgfVxuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gIGZ1bmN0aW9uIHZhbHVlRnJvbUNvbmZpZzIoYSwgYikge1xuICAgIGlmICghdXRpbHMkMS5pc1VuZGVmaW5lZChiKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYik7XG4gICAgfVxuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gIGZ1bmN0aW9uIGRlZmF1bHRUb0NvbmZpZzIoYSwgYikge1xuICAgIGlmICghdXRpbHMkMS5pc1VuZGVmaW5lZChiKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYik7XG4gICAgfSBlbHNlIGlmICghdXRpbHMkMS5pc1VuZGVmaW5lZChhKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgYSk7XG4gICAgfVxuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gIGZ1bmN0aW9uIG1lcmdlRGlyZWN0S2V5cyhhLCBiLCBwcm9wKSB7XG4gICAgaWYgKHByb3AgaW4gY29uZmlnMikge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKGEsIGIpO1xuICAgIH0gZWxzZSBpZiAocHJvcCBpbiBjb25maWcxKSB7XG4gICAgICByZXR1cm4gZ2V0TWVyZ2VkVmFsdWUodW5kZWZpbmVkLCBhKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBtZXJnZU1hcCA9IHtcbiAgICB1cmw6IHZhbHVlRnJvbUNvbmZpZzIsXG4gICAgbWV0aG9kOiB2YWx1ZUZyb21Db25maWcyLFxuICAgIGRhdGE6IHZhbHVlRnJvbUNvbmZpZzIsXG4gICAgYmFzZVVSTDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB0cmFuc2Zvcm1SZXF1ZXN0OiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHRyYW5zZm9ybVJlc3BvbnNlOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHBhcmFtc1NlcmlhbGl6ZXI6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgdGltZW91dDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB0aW1lb3V0TWVzc2FnZTogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB3aXRoQ3JlZGVudGlhbHM6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgd2l0aFhTUkZUb2tlbjogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBhZGFwdGVyOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHJlc3BvbnNlVHlwZTogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB4c3JmQ29va2llTmFtZTogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB4c3JmSGVhZGVyTmFtZTogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBvblVwbG9hZFByb2dyZXNzOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIG9uRG93bmxvYWRQcm9ncmVzczogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBkZWNvbXByZXNzOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIG1heENvbnRlbnRMZW5ndGg6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgbWF4Qm9keUxlbmd0aDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICBiZWZvcmVSZWRpcmVjdDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICB0cmFuc3BvcnQ6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgaHR0cEFnZW50OiBkZWZhdWx0VG9Db25maWcyLFxuICAgIGh0dHBzQWdlbnQ6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgY2FuY2VsVG9rZW46IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgc29ja2V0UGF0aDogZGVmYXVsdFRvQ29uZmlnMixcbiAgICByZXNwb25zZUVuY29kaW5nOiBkZWZhdWx0VG9Db25maWcyLFxuICAgIHZhbGlkYXRlU3RhdHVzOiBtZXJnZURpcmVjdEtleXMsXG4gICAgaGVhZGVyczogKGEsIGIgLCBwcm9wKSA9PiBtZXJnZURlZXBQcm9wZXJ0aWVzKGhlYWRlcnNUb09iamVjdChhKSwgaGVhZGVyc1RvT2JqZWN0KGIpLHByb3AsIHRydWUpXG4gIH07XG5cbiAgdXRpbHMkMS5mb3JFYWNoKE9iamVjdC5rZXlzKE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZzEsIGNvbmZpZzIpKSwgZnVuY3Rpb24gY29tcHV0ZUNvbmZpZ1ZhbHVlKHByb3ApIHtcbiAgICBjb25zdCBtZXJnZSA9IG1lcmdlTWFwW3Byb3BdIHx8IG1lcmdlRGVlcFByb3BlcnRpZXM7XG4gICAgY29uc3QgY29uZmlnVmFsdWUgPSBtZXJnZShjb25maWcxW3Byb3BdLCBjb25maWcyW3Byb3BdLCBwcm9wKTtcbiAgICAodXRpbHMkMS5pc1VuZGVmaW5lZChjb25maWdWYWx1ZSkgJiYgbWVyZ2UgIT09IG1lcmdlRGlyZWN0S2V5cykgfHwgKGNvbmZpZ1twcm9wXSA9IGNvbmZpZ1ZhbHVlKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGNvbmZpZztcbn1cblxudmFyIHJlc29sdmVDb25maWcgPSAoY29uZmlnKSA9PiB7XG4gIGNvbnN0IG5ld0NvbmZpZyA9IG1lcmdlQ29uZmlnKHt9LCBjb25maWcpO1xuXG4gIGxldCB7ZGF0YSwgd2l0aFhTUkZUb2tlbiwgeHNyZkhlYWRlck5hbWUsIHhzcmZDb29raWVOYW1lLCBoZWFkZXJzLCBhdXRofSA9IG5ld0NvbmZpZztcblxuICBuZXdDb25maWcuaGVhZGVycyA9IGhlYWRlcnMgPSBBeGlvc0hlYWRlcnMkMS5mcm9tKGhlYWRlcnMpO1xuXG4gIG5ld0NvbmZpZy51cmwgPSBidWlsZFVSTChidWlsZEZ1bGxQYXRoKG5ld0NvbmZpZy5iYXNlVVJMLCBuZXdDb25maWcudXJsLCBuZXdDb25maWcuYWxsb3dBYnNvbHV0ZVVybHMpLCBjb25maWcucGFyYW1zLCBjb25maWcucGFyYW1zU2VyaWFsaXplcik7XG5cbiAgLy8gSFRUUCBiYXNpYyBhdXRoZW50aWNhdGlvblxuICBpZiAoYXV0aCkge1xuICAgIGhlYWRlcnMuc2V0KCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgK1xuICAgICAgYnRvYSgoYXV0aC51c2VybmFtZSB8fCAnJykgKyAnOicgKyAoYXV0aC5wYXNzd29yZCA/IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChhdXRoLnBhc3N3b3JkKSkgOiAnJykpXG4gICAgKTtcbiAgfVxuXG4gIGxldCBjb250ZW50VHlwZTtcblxuICBpZiAodXRpbHMkMS5pc0Zvcm1EYXRhKGRhdGEpKSB7XG4gICAgaWYgKHBsYXRmb3JtLmhhc1N0YW5kYXJkQnJvd3NlckVudiB8fCBwbGF0Zm9ybS5oYXNTdGFuZGFyZEJyb3dzZXJXZWJXb3JrZXJFbnYpIHtcbiAgICAgIGhlYWRlcnMuc2V0Q29udGVudFR5cGUodW5kZWZpbmVkKTsgLy8gTGV0IHRoZSBicm93c2VyIHNldCBpdFxuICAgIH0gZWxzZSBpZiAoKGNvbnRlbnRUeXBlID0gaGVhZGVycy5nZXRDb250ZW50VHlwZSgpKSAhPT0gZmFsc2UpIHtcbiAgICAgIC8vIGZpeCBzZW1pY29sb24gZHVwbGljYXRpb24gaXNzdWUgZm9yIFJlYWN0TmF0aXZlIEZvcm1EYXRhIGltcGxlbWVudGF0aW9uXG4gICAgICBjb25zdCBbdHlwZSwgLi4udG9rZW5zXSA9IGNvbnRlbnRUeXBlID8gY29udGVudFR5cGUuc3BsaXQoJzsnKS5tYXAodG9rZW4gPT4gdG9rZW4udHJpbSgpKS5maWx0ZXIoQm9vbGVhbikgOiBbXTtcbiAgICAgIGhlYWRlcnMuc2V0Q29udGVudFR5cGUoW3R5cGUgfHwgJ211bHRpcGFydC9mb3JtLWRhdGEnLCAuLi50b2tlbnNdLmpvaW4oJzsgJykpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFkZCB4c3JmIGhlYWRlclxuICAvLyBUaGlzIGlzIG9ubHkgZG9uZSBpZiBydW5uaW5nIGluIGEgc3RhbmRhcmQgYnJvd3NlciBlbnZpcm9ubWVudC5cbiAgLy8gU3BlY2lmaWNhbGx5IG5vdCBpZiB3ZSdyZSBpbiBhIHdlYiB3b3JrZXIsIG9yIHJlYWN0LW5hdGl2ZS5cblxuICBpZiAocGxhdGZvcm0uaGFzU3RhbmRhcmRCcm93c2VyRW52KSB7XG4gICAgd2l0aFhTUkZUb2tlbiAmJiB1dGlscyQxLmlzRnVuY3Rpb24od2l0aFhTUkZUb2tlbikgJiYgKHdpdGhYU1JGVG9rZW4gPSB3aXRoWFNSRlRva2VuKG5ld0NvbmZpZykpO1xuXG4gICAgaWYgKHdpdGhYU1JGVG9rZW4gfHwgKHdpdGhYU1JGVG9rZW4gIT09IGZhbHNlICYmIGlzVVJMU2FtZU9yaWdpbihuZXdDb25maWcudXJsKSkpIHtcbiAgICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgICAgY29uc3QgeHNyZlZhbHVlID0geHNyZkhlYWRlck5hbWUgJiYgeHNyZkNvb2tpZU5hbWUgJiYgY29va2llcy5yZWFkKHhzcmZDb29raWVOYW1lKTtcblxuICAgICAgaWYgKHhzcmZWYWx1ZSkge1xuICAgICAgICBoZWFkZXJzLnNldCh4c3JmSGVhZGVyTmFtZSwgeHNyZlZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3Q29uZmlnO1xufTtcblxuY29uc3QgaXNYSFJBZGFwdGVyU3VwcG9ydGVkID0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICE9PSAndW5kZWZpbmVkJztcblxudmFyIHhockFkYXB0ZXIgPSBpc1hIUkFkYXB0ZXJTdXBwb3J0ZWQgJiYgZnVuY3Rpb24gKGNvbmZpZykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gZGlzcGF0Y2hYaHJSZXF1ZXN0KHJlc29sdmUsIHJlamVjdCkge1xuICAgIGNvbnN0IF9jb25maWcgPSByZXNvbHZlQ29uZmlnKGNvbmZpZyk7XG4gICAgbGV0IHJlcXVlc3REYXRhID0gX2NvbmZpZy5kYXRhO1xuICAgIGNvbnN0IHJlcXVlc3RIZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShfY29uZmlnLmhlYWRlcnMpLm5vcm1hbGl6ZSgpO1xuICAgIGxldCB7cmVzcG9uc2VUeXBlLCBvblVwbG9hZFByb2dyZXNzLCBvbkRvd25sb2FkUHJvZ3Jlc3N9ID0gX2NvbmZpZztcbiAgICBsZXQgb25DYW5jZWxlZDtcbiAgICBsZXQgdXBsb2FkVGhyb3R0bGVkLCBkb3dubG9hZFRocm90dGxlZDtcbiAgICBsZXQgZmx1c2hVcGxvYWQsIGZsdXNoRG93bmxvYWQ7XG5cbiAgICBmdW5jdGlvbiBkb25lKCkge1xuICAgICAgZmx1c2hVcGxvYWQgJiYgZmx1c2hVcGxvYWQoKTsgLy8gZmx1c2ggZXZlbnRzXG4gICAgICBmbHVzaERvd25sb2FkICYmIGZsdXNoRG93bmxvYWQoKTsgLy8gZmx1c2ggZXZlbnRzXG5cbiAgICAgIF9jb25maWcuY2FuY2VsVG9rZW4gJiYgX2NvbmZpZy5jYW5jZWxUb2tlbi51bnN1YnNjcmliZShvbkNhbmNlbGVkKTtcblxuICAgICAgX2NvbmZpZy5zaWduYWwgJiYgX2NvbmZpZy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkNhbmNlbGVkKTtcbiAgICB9XG5cbiAgICBsZXQgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXG4gICAgcmVxdWVzdC5vcGVuKF9jb25maWcubWV0aG9kLnRvVXBwZXJDYXNlKCksIF9jb25maWcudXJsLCB0cnVlKTtcblxuICAgIC8vIFNldCB0aGUgcmVxdWVzdCB0aW1lb3V0IGluIE1TXG4gICAgcmVxdWVzdC50aW1lb3V0ID0gX2NvbmZpZy50aW1lb3V0O1xuXG4gICAgZnVuY3Rpb24gb25sb2FkZW5kKCkge1xuICAgICAgaWYgKCFyZXF1ZXN0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIFByZXBhcmUgdGhlIHJlc3BvbnNlXG4gICAgICBjb25zdCByZXNwb25zZUhlYWRlcnMgPSBBeGlvc0hlYWRlcnMkMS5mcm9tKFxuICAgICAgICAnZ2V0QWxsUmVzcG9uc2VIZWFkZXJzJyBpbiByZXF1ZXN0ICYmIHJlcXVlc3QuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcbiAgICAgICk7XG4gICAgICBjb25zdCByZXNwb25zZURhdGEgPSAhcmVzcG9uc2VUeXBlIHx8IHJlc3BvbnNlVHlwZSA9PT0gJ3RleHQnIHx8IHJlc3BvbnNlVHlwZSA9PT0gJ2pzb24nID9cbiAgICAgICAgcmVxdWVzdC5yZXNwb25zZVRleHQgOiByZXF1ZXN0LnJlc3BvbnNlO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICAgIGRhdGE6IHJlc3BvbnNlRGF0YSxcbiAgICAgICAgc3RhdHVzOiByZXF1ZXN0LnN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dDogcmVxdWVzdC5zdGF0dXNUZXh0LFxuICAgICAgICBoZWFkZXJzOiByZXNwb25zZUhlYWRlcnMsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxdWVzdFxuICAgICAgfTtcblxuICAgICAgc2V0dGxlKGZ1bmN0aW9uIF9yZXNvbHZlKHZhbHVlKSB7XG4gICAgICAgIHJlc29sdmUodmFsdWUpO1xuICAgICAgICBkb25lKCk7XG4gICAgICB9LCBmdW5jdGlvbiBfcmVqZWN0KGVycikge1xuICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSwgcmVzcG9uc2UpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoJ29ubG9hZGVuZCcgaW4gcmVxdWVzdCkge1xuICAgICAgLy8gVXNlIG9ubG9hZGVuZCBpZiBhdmFpbGFibGVcbiAgICAgIHJlcXVlc3Qub25sb2FkZW5kID0gb25sb2FkZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBMaXN0ZW4gZm9yIHJlYWR5IHN0YXRlIHRvIGVtdWxhdGUgb25sb2FkZW5kXG4gICAgICByZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uIGhhbmRsZUxvYWQoKSB7XG4gICAgICAgIGlmICghcmVxdWVzdCB8fCByZXF1ZXN0LnJlYWR5U3RhdGUgIT09IDQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGUgcmVxdWVzdCBlcnJvcmVkIG91dCBhbmQgd2UgZGlkbid0IGdldCBhIHJlc3BvbnNlLCB0aGlzIHdpbGwgYmVcbiAgICAgICAgLy8gaGFuZGxlZCBieSBvbmVycm9yIGluc3RlYWRcbiAgICAgICAgLy8gV2l0aCBvbmUgZXhjZXB0aW9uOiByZXF1ZXN0IHRoYXQgdXNpbmcgZmlsZTogcHJvdG9jb2wsIG1vc3QgYnJvd3NlcnNcbiAgICAgICAgLy8gd2lsbCByZXR1cm4gc3RhdHVzIGFzIDAgZXZlbiB0aG91Z2ggaXQncyBhIHN1Y2Nlc3NmdWwgcmVxdWVzdFxuICAgICAgICBpZiAocmVxdWVzdC5zdGF0dXMgPT09IDAgJiYgIShyZXF1ZXN0LnJlc3BvbnNlVVJMICYmIHJlcXVlc3QucmVzcG9uc2VVUkwuaW5kZXhPZignZmlsZTonKSA9PT0gMCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVhZHlzdGF0ZSBoYW5kbGVyIGlzIGNhbGxpbmcgYmVmb3JlIG9uZXJyb3Igb3Igb250aW1lb3V0IGhhbmRsZXJzLFxuICAgICAgICAvLyBzbyB3ZSBzaG91bGQgY2FsbCBvbmxvYWRlbmQgb24gdGhlIG5leHQgJ3RpY2snXG4gICAgICAgIHNldFRpbWVvdXQob25sb2FkZW5kKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGJyb3dzZXIgcmVxdWVzdCBjYW5jZWxsYXRpb24gKGFzIG9wcG9zZWQgdG8gYSBtYW51YWwgY2FuY2VsbGF0aW9uKVxuICAgIHJlcXVlc3Qub25hYm9ydCA9IGZ1bmN0aW9uIGhhbmRsZUFib3J0KCkge1xuICAgICAgaWYgKCFyZXF1ZXN0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKCdSZXF1ZXN0IGFib3J0ZWQnLCBBeGlvc0Vycm9yLkVDT05OQUJPUlRFRCwgY29uZmlnLCByZXF1ZXN0KSk7XG5cbiAgICAgIC8vIENsZWFuIHVwIHJlcXVlc3RcbiAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgIH07XG5cbiAgICAvLyBIYW5kbGUgbG93IGxldmVsIG5ldHdvcmsgZXJyb3JzXG4gICAgcmVxdWVzdC5vbmVycm9yID0gZnVuY3Rpb24gaGFuZGxlRXJyb3IoKSB7XG4gICAgICAvLyBSZWFsIGVycm9ycyBhcmUgaGlkZGVuIGZyb20gdXMgYnkgdGhlIGJyb3dzZXJcbiAgICAgIC8vIG9uZXJyb3Igc2hvdWxkIG9ubHkgZmlyZSBpZiBpdCdzIGEgbmV0d29yayBlcnJvclxuICAgICAgcmVqZWN0KG5ldyBBeGlvc0Vycm9yKCdOZXR3b3JrIEVycm9yJywgQXhpb3NFcnJvci5FUlJfTkVUV09SSywgY29uZmlnLCByZXF1ZXN0KSk7XG5cbiAgICAgIC8vIENsZWFuIHVwIHJlcXVlc3RcbiAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgIH07XG5cbiAgICAvLyBIYW5kbGUgdGltZW91dFxuICAgIHJlcXVlc3Qub250aW1lb3V0ID0gZnVuY3Rpb24gaGFuZGxlVGltZW91dCgpIHtcbiAgICAgIGxldCB0aW1lb3V0RXJyb3JNZXNzYWdlID0gX2NvbmZpZy50aW1lb3V0ID8gJ3RpbWVvdXQgb2YgJyArIF9jb25maWcudGltZW91dCArICdtcyBleGNlZWRlZCcgOiAndGltZW91dCBleGNlZWRlZCc7XG4gICAgICBjb25zdCB0cmFuc2l0aW9uYWwgPSBfY29uZmlnLnRyYW5zaXRpb25hbCB8fCB0cmFuc2l0aW9uYWxEZWZhdWx0cztcbiAgICAgIGlmIChfY29uZmlnLnRpbWVvdXRFcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgdGltZW91dEVycm9yTWVzc2FnZSA9IF9jb25maWcudGltZW91dEVycm9yTWVzc2FnZTtcbiAgICAgIH1cbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgdGltZW91dEVycm9yTWVzc2FnZSxcbiAgICAgICAgdHJhbnNpdGlvbmFsLmNsYXJpZnlUaW1lb3V0RXJyb3IgPyBBeGlvc0Vycm9yLkVUSU1FRE9VVCA6IEF4aW9zRXJyb3IuRUNPTk5BQk9SVEVELFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3QpKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIFJlbW92ZSBDb250ZW50LVR5cGUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgICByZXF1ZXN0RGF0YSA9PT0gdW5kZWZpbmVkICYmIHJlcXVlc3RIZWFkZXJzLnNldENvbnRlbnRUeXBlKG51bGwpO1xuXG4gICAgLy8gQWRkIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3RcbiAgICBpZiAoJ3NldFJlcXVlc3RIZWFkZXInIGluIHJlcXVlc3QpIHtcbiAgICAgIHV0aWxzJDEuZm9yRWFjaChyZXF1ZXN0SGVhZGVycy50b0pTT04oKSwgZnVuY3Rpb24gc2V0UmVxdWVzdEhlYWRlcih2YWwsIGtleSkge1xuICAgICAgICByZXF1ZXN0LnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWwpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHdpdGhDcmVkZW50aWFscyB0byByZXF1ZXN0IGlmIG5lZWRlZFxuICAgIGlmICghdXRpbHMkMS5pc1VuZGVmaW5lZChfY29uZmlnLndpdGhDcmVkZW50aWFscykpIHtcbiAgICAgIHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gISFfY29uZmlnLndpdGhDcmVkZW50aWFscztcbiAgICB9XG5cbiAgICAvLyBBZGQgcmVzcG9uc2VUeXBlIHRvIHJlcXVlc3QgaWYgbmVlZGVkXG4gICAgaWYgKHJlc3BvbnNlVHlwZSAmJiByZXNwb25zZVR5cGUgIT09ICdqc29uJykge1xuICAgICAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSBfY29uZmlnLnJlc3BvbnNlVHlwZTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgcHJvZ3Jlc3MgaWYgbmVlZGVkXG4gICAgaWYgKG9uRG93bmxvYWRQcm9ncmVzcykge1xuICAgICAgKFtkb3dubG9hZFRocm90dGxlZCwgZmx1c2hEb3dubG9hZF0gPSBwcm9ncmVzc0V2ZW50UmVkdWNlcihvbkRvd25sb2FkUHJvZ3Jlc3MsIHRydWUpKTtcbiAgICAgIHJlcXVlc3QuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBkb3dubG9hZFRocm90dGxlZCk7XG4gICAgfVxuXG4gICAgLy8gTm90IGFsbCBicm93c2VycyBzdXBwb3J0IHVwbG9hZCBldmVudHNcbiAgICBpZiAob25VcGxvYWRQcm9ncmVzcyAmJiByZXF1ZXN0LnVwbG9hZCkge1xuICAgICAgKFt1cGxvYWRUaHJvdHRsZWQsIGZsdXNoVXBsb2FkXSA9IHByb2dyZXNzRXZlbnRSZWR1Y2VyKG9uVXBsb2FkUHJvZ3Jlc3MpKTtcblxuICAgICAgcmVxdWVzdC51cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCB1cGxvYWRUaHJvdHRsZWQpO1xuXG4gICAgICByZXF1ZXN0LnVwbG9hZC5hZGRFdmVudExpc3RlbmVyKCdsb2FkZW5kJywgZmx1c2hVcGxvYWQpO1xuICAgIH1cblxuICAgIGlmIChfY29uZmlnLmNhbmNlbFRva2VuIHx8IF9jb25maWcuc2lnbmFsKSB7XG4gICAgICAvLyBIYW5kbGUgY2FuY2VsbGF0aW9uXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICAgICAgb25DYW5jZWxlZCA9IGNhbmNlbCA9PiB7XG4gICAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QoIWNhbmNlbCB8fCBjYW5jZWwudHlwZSA/IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZywgcmVxdWVzdCkgOiBjYW5jZWwpO1xuICAgICAgICByZXF1ZXN0LmFib3J0KCk7XG4gICAgICAgIHJlcXVlc3QgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgX2NvbmZpZy5jYW5jZWxUb2tlbiAmJiBfY29uZmlnLmNhbmNlbFRva2VuLnN1YnNjcmliZShvbkNhbmNlbGVkKTtcbiAgICAgIGlmIChfY29uZmlnLnNpZ25hbCkge1xuICAgICAgICBfY29uZmlnLnNpZ25hbC5hYm9ydGVkID8gb25DYW5jZWxlZCgpIDogX2NvbmZpZy5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkNhbmNlbGVkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwcm90b2NvbCA9IHBhcnNlUHJvdG9jb2woX2NvbmZpZy51cmwpO1xuXG4gICAgaWYgKHByb3RvY29sICYmIHBsYXRmb3JtLnByb3RvY29scy5pbmRleE9mKHByb3RvY29sKSA9PT0gLTEpIHtcbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJyArIHByb3RvY29sICsgJzonLCBBeGlvc0Vycm9yLkVSUl9CQURfUkVRVUVTVCwgY29uZmlnKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG5cbiAgICAvLyBTZW5kIHRoZSByZXF1ZXN0XG4gICAgcmVxdWVzdC5zZW5kKHJlcXVlc3REYXRhIHx8IG51bGwpO1xuICB9KTtcbn07XG5cbmNvbnN0IGNvbXBvc2VTaWduYWxzID0gKHNpZ25hbHMsIHRpbWVvdXQpID0+IHtcbiAgY29uc3Qge2xlbmd0aH0gPSAoc2lnbmFscyA9IHNpZ25hbHMgPyBzaWduYWxzLmZpbHRlcihCb29sZWFuKSA6IFtdKTtcblxuICBpZiAodGltZW91dCB8fCBsZW5ndGgpIHtcbiAgICBsZXQgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgIGxldCBhYm9ydGVkO1xuXG4gICAgY29uc3Qgb25hYm9ydCA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIGlmICghYWJvcnRlZCkge1xuICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgdW5zdWJzY3JpYmUoKTtcbiAgICAgICAgY29uc3QgZXJyID0gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiB0aGlzLnJlYXNvbjtcbiAgICAgICAgY29udHJvbGxlci5hYm9ydChlcnIgaW5zdGFuY2VvZiBBeGlvc0Vycm9yID8gZXJyIDogbmV3IENhbmNlbGVkRXJyb3IoZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IGVycikpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBsZXQgdGltZXIgPSB0aW1lb3V0ICYmIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgb25hYm9ydChuZXcgQXhpb3NFcnJvcihgdGltZW91dCAke3RpbWVvdXR9IG9mIG1zIGV4Y2VlZGVkYCwgQXhpb3NFcnJvci5FVElNRURPVVQpKTtcbiAgICB9LCB0aW1lb3V0KTtcblxuICAgIGNvbnN0IHVuc3Vic2NyaWJlID0gKCkgPT4ge1xuICAgICAgaWYgKHNpZ25hbHMpIHtcbiAgICAgICAgdGltZXIgJiYgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgICBzaWduYWxzLmZvckVhY2goc2lnbmFsID0+IHtcbiAgICAgICAgICBzaWduYWwudW5zdWJzY3JpYmUgPyBzaWduYWwudW5zdWJzY3JpYmUob25hYm9ydCkgOiBzaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbmFib3J0KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNpZ25hbHMgPSBudWxsO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBzaWduYWxzLmZvckVhY2goKHNpZ25hbCkgPT4gc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2Fib3J0Jywgb25hYm9ydCkpO1xuXG4gICAgY29uc3Qge3NpZ25hbH0gPSBjb250cm9sbGVyO1xuXG4gICAgc2lnbmFsLnVuc3Vic2NyaWJlID0gKCkgPT4gdXRpbHMkMS5hc2FwKHVuc3Vic2NyaWJlKTtcblxuICAgIHJldHVybiBzaWduYWw7XG4gIH1cbn07XG5cbnZhciBjb21wb3NlU2lnbmFscyQxID0gY29tcG9zZVNpZ25hbHM7XG5cbmNvbnN0IHN0cmVhbUNodW5rID0gZnVuY3Rpb24qIChjaHVuaywgY2h1bmtTaXplKSB7XG4gIGxldCBsZW4gPSBjaHVuay5ieXRlTGVuZ3RoO1xuXG4gIGlmICghY2h1bmtTaXplIHx8IGxlbiA8IGNodW5rU2l6ZSkge1xuICAgIHlpZWxkIGNodW5rO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBwb3MgPSAwO1xuICBsZXQgZW5kO1xuXG4gIHdoaWxlIChwb3MgPCBsZW4pIHtcbiAgICBlbmQgPSBwb3MgKyBjaHVua1NpemU7XG4gICAgeWllbGQgY2h1bmsuc2xpY2UocG9zLCBlbmQpO1xuICAgIHBvcyA9IGVuZDtcbiAgfVxufTtcblxuY29uc3QgcmVhZEJ5dGVzID0gYXN5bmMgZnVuY3Rpb24qIChpdGVyYWJsZSwgY2h1bmtTaXplKSB7XG4gIGZvciBhd2FpdCAoY29uc3QgY2h1bmsgb2YgcmVhZFN0cmVhbShpdGVyYWJsZSkpIHtcbiAgICB5aWVsZCogc3RyZWFtQ2h1bmsoY2h1bmssIGNodW5rU2l6ZSk7XG4gIH1cbn07XG5cbmNvbnN0IHJlYWRTdHJlYW0gPSBhc3luYyBmdW5jdGlvbiogKHN0cmVhbSkge1xuICBpZiAoc3RyZWFtW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSkge1xuICAgIHlpZWxkKiBzdHJlYW07XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICB0cnkge1xuICAgIGZvciAoOzspIHtcbiAgICAgIGNvbnN0IHtkb25lLCB2YWx1ZX0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB5aWVsZCB2YWx1ZTtcbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgYXdhaXQgcmVhZGVyLmNhbmNlbCgpO1xuICB9XG59O1xuXG5jb25zdCB0cmFja1N0cmVhbSA9IChzdHJlYW0sIGNodW5rU2l6ZSwgb25Qcm9ncmVzcywgb25GaW5pc2gpID0+IHtcbiAgY29uc3QgaXRlcmF0b3IgPSByZWFkQnl0ZXMoc3RyZWFtLCBjaHVua1NpemUpO1xuXG4gIGxldCBieXRlcyA9IDA7XG4gIGxldCBkb25lO1xuICBsZXQgX29uRmluaXNoID0gKGUpID0+IHtcbiAgICBpZiAoIWRvbmUpIHtcbiAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgb25GaW5pc2ggJiYgb25GaW5pc2goZSk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgIGFzeW5jIHB1bGwoY29udHJvbGxlcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qge2RvbmUsIHZhbHVlfSA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcblxuICAgICAgICBpZiAoZG9uZSkge1xuICAgICAgICAgX29uRmluaXNoKCk7XG4gICAgICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBsZW4gPSB2YWx1ZS5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob25Qcm9ncmVzcykge1xuICAgICAgICAgIGxldCBsb2FkZWRCeXRlcyA9IGJ5dGVzICs9IGxlbjtcbiAgICAgICAgICBvblByb2dyZXNzKGxvYWRlZEJ5dGVzKTtcbiAgICAgICAgfVxuICAgICAgICBjb250cm9sbGVyLmVucXVldWUobmV3IFVpbnQ4QXJyYXkodmFsdWUpKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBfb25GaW5pc2goZXJyKTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH0sXG4gICAgY2FuY2VsKHJlYXNvbikge1xuICAgICAgX29uRmluaXNoKHJlYXNvbik7XG4gICAgICByZXR1cm4gaXRlcmF0b3IucmV0dXJuKCk7XG4gICAgfVxuICB9LCB7XG4gICAgaGlnaFdhdGVyTWFyazogMlxuICB9KVxufTtcblxuY29uc3QgaXNGZXRjaFN1cHBvcnRlZCA9IHR5cGVvZiBmZXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgUmVxdWVzdCA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgUmVzcG9uc2UgPT09ICdmdW5jdGlvbic7XG5jb25zdCBpc1JlYWRhYmxlU3RyZWFtU3VwcG9ydGVkID0gaXNGZXRjaFN1cHBvcnRlZCAmJiB0eXBlb2YgUmVhZGFibGVTdHJlYW0gPT09ICdmdW5jdGlvbic7XG5cbi8vIHVzZWQgb25seSBpbnNpZGUgdGhlIGZldGNoIGFkYXB0ZXJcbmNvbnN0IGVuY29kZVRleHQgPSBpc0ZldGNoU3VwcG9ydGVkICYmICh0eXBlb2YgVGV4dEVuY29kZXIgPT09ICdmdW5jdGlvbicgP1xuICAgICgoZW5jb2RlcikgPT4gKHN0cikgPT4gZW5jb2Rlci5lbmNvZGUoc3RyKSkobmV3IFRleHRFbmNvZGVyKCkpIDpcbiAgICBhc3luYyAoc3RyKSA9PiBuZXcgVWludDhBcnJheShhd2FpdCBuZXcgUmVzcG9uc2Uoc3RyKS5hcnJheUJ1ZmZlcigpKVxuKTtcblxuY29uc3QgdGVzdCA9IChmbiwgLi4uYXJncykgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiAhIWZuKC4uLmFyZ3MpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn07XG5cbmNvbnN0IHN1cHBvcnRzUmVxdWVzdFN0cmVhbSA9IGlzUmVhZGFibGVTdHJlYW1TdXBwb3J0ZWQgJiYgdGVzdCgoKSA9PiB7XG4gIGxldCBkdXBsZXhBY2Nlc3NlZCA9IGZhbHNlO1xuXG4gIGNvbnN0IGhhc0NvbnRlbnRUeXBlID0gbmV3IFJlcXVlc3QocGxhdGZvcm0ub3JpZ2luLCB7XG4gICAgYm9keTogbmV3IFJlYWRhYmxlU3RyZWFtKCksXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgZ2V0IGR1cGxleCgpIHtcbiAgICAgIGR1cGxleEFjY2Vzc2VkID0gdHJ1ZTtcbiAgICAgIHJldHVybiAnaGFsZic7XG4gICAgfSxcbiAgfSkuaGVhZGVycy5oYXMoJ0NvbnRlbnQtVHlwZScpO1xuXG4gIHJldHVybiBkdXBsZXhBY2Nlc3NlZCAmJiAhaGFzQ29udGVudFR5cGU7XG59KTtcblxuY29uc3QgREVGQVVMVF9DSFVOS19TSVpFID0gNjQgKiAxMDI0O1xuXG5jb25zdCBzdXBwb3J0c1Jlc3BvbnNlU3RyZWFtID0gaXNSZWFkYWJsZVN0cmVhbVN1cHBvcnRlZCAmJlxuICB0ZXN0KCgpID0+IHV0aWxzJDEuaXNSZWFkYWJsZVN0cmVhbShuZXcgUmVzcG9uc2UoJycpLmJvZHkpKTtcblxuXG5jb25zdCByZXNvbHZlcnMgPSB7XG4gIHN0cmVhbTogc3VwcG9ydHNSZXNwb25zZVN0cmVhbSAmJiAoKHJlcykgPT4gcmVzLmJvZHkpXG59O1xuXG5pc0ZldGNoU3VwcG9ydGVkICYmICgoKHJlcykgPT4ge1xuICBbJ3RleHQnLCAnYXJyYXlCdWZmZXInLCAnYmxvYicsICdmb3JtRGF0YScsICdzdHJlYW0nXS5mb3JFYWNoKHR5cGUgPT4ge1xuICAgICFyZXNvbHZlcnNbdHlwZV0gJiYgKHJlc29sdmVyc1t0eXBlXSA9IHV0aWxzJDEuaXNGdW5jdGlvbihyZXNbdHlwZV0pID8gKHJlcykgPT4gcmVzW3R5cGVdKCkgOlxuICAgICAgKF8sIGNvbmZpZykgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihgUmVzcG9uc2UgdHlwZSAnJHt0eXBlfScgaXMgbm90IHN1cHBvcnRlZGAsIEF4aW9zRXJyb3IuRVJSX05PVF9TVVBQT1JULCBjb25maWcpO1xuICAgICAgfSk7XG4gIH0pO1xufSkobmV3IFJlc3BvbnNlKSk7XG5cbmNvbnN0IGdldEJvZHlMZW5ndGggPSBhc3luYyAoYm9keSkgPT4ge1xuICBpZiAoYm9keSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBpZih1dGlscyQxLmlzQmxvYihib2R5KSkge1xuICAgIHJldHVybiBib2R5LnNpemU7XG4gIH1cblxuICBpZih1dGlscyQxLmlzU3BlY0NvbXBsaWFudEZvcm0oYm9keSkpIHtcbiAgICBjb25zdCBfcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KHBsYXRmb3JtLm9yaWdpbiwge1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBib2R5LFxuICAgIH0pO1xuICAgIHJldHVybiAoYXdhaXQgX3JlcXVlc3QuYXJyYXlCdWZmZXIoKSkuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIGlmKHV0aWxzJDEuaXNBcnJheUJ1ZmZlclZpZXcoYm9keSkgfHwgdXRpbHMkMS5pc0FycmF5QnVmZmVyKGJvZHkpKSB7XG4gICAgcmV0dXJuIGJvZHkuYnl0ZUxlbmd0aDtcbiAgfVxuXG4gIGlmKHV0aWxzJDEuaXNVUkxTZWFyY2hQYXJhbXMoYm9keSkpIHtcbiAgICBib2R5ID0gYm9keSArICcnO1xuICB9XG5cbiAgaWYodXRpbHMkMS5pc1N0cmluZyhib2R5KSkge1xuICAgIHJldHVybiAoYXdhaXQgZW5jb2RlVGV4dChib2R5KSkuYnl0ZUxlbmd0aDtcbiAgfVxufTtcblxuY29uc3QgcmVzb2x2ZUJvZHlMZW5ndGggPSBhc3luYyAoaGVhZGVycywgYm9keSkgPT4ge1xuICBjb25zdCBsZW5ndGggPSB1dGlscyQxLnRvRmluaXRlTnVtYmVyKGhlYWRlcnMuZ2V0Q29udGVudExlbmd0aCgpKTtcblxuICByZXR1cm4gbGVuZ3RoID09IG51bGwgPyBnZXRCb2R5TGVuZ3RoKGJvZHkpIDogbGVuZ3RoO1xufTtcblxudmFyIGZldGNoQWRhcHRlciA9IGlzRmV0Y2hTdXBwb3J0ZWQgJiYgKGFzeW5jIChjb25maWcpID0+IHtcbiAgbGV0IHtcbiAgICB1cmwsXG4gICAgbWV0aG9kLFxuICAgIGRhdGEsXG4gICAgc2lnbmFsLFxuICAgIGNhbmNlbFRva2VuLFxuICAgIHRpbWVvdXQsXG4gICAgb25Eb3dubG9hZFByb2dyZXNzLFxuICAgIG9uVXBsb2FkUHJvZ3Jlc3MsXG4gICAgcmVzcG9uc2VUeXBlLFxuICAgIGhlYWRlcnMsXG4gICAgd2l0aENyZWRlbnRpYWxzID0gJ3NhbWUtb3JpZ2luJyxcbiAgICBmZXRjaE9wdGlvbnNcbiAgfSA9IHJlc29sdmVDb25maWcoY29uZmlnKTtcblxuICByZXNwb25zZVR5cGUgPSByZXNwb25zZVR5cGUgPyAocmVzcG9uc2VUeXBlICsgJycpLnRvTG93ZXJDYXNlKCkgOiAndGV4dCc7XG5cbiAgbGV0IGNvbXBvc2VkU2lnbmFsID0gY29tcG9zZVNpZ25hbHMkMShbc2lnbmFsLCBjYW5jZWxUb2tlbiAmJiBjYW5jZWxUb2tlbi50b0Fib3J0U2lnbmFsKCldLCB0aW1lb3V0KTtcblxuICBsZXQgcmVxdWVzdDtcblxuICBjb25zdCB1bnN1YnNjcmliZSA9IGNvbXBvc2VkU2lnbmFsICYmIGNvbXBvc2VkU2lnbmFsLnVuc3Vic2NyaWJlICYmICgoKSA9PiB7XG4gICAgICBjb21wb3NlZFNpZ25hbC51bnN1YnNjcmliZSgpO1xuICB9KTtcblxuICBsZXQgcmVxdWVzdENvbnRlbnRMZW5ndGg7XG5cbiAgdHJ5IHtcbiAgICBpZiAoXG4gICAgICBvblVwbG9hZFByb2dyZXNzICYmIHN1cHBvcnRzUmVxdWVzdFN0cmVhbSAmJiBtZXRob2QgIT09ICdnZXQnICYmIG1ldGhvZCAhPT0gJ2hlYWQnICYmXG4gICAgICAocmVxdWVzdENvbnRlbnRMZW5ndGggPSBhd2FpdCByZXNvbHZlQm9keUxlbmd0aChoZWFkZXJzLCBkYXRhKSkgIT09IDBcbiAgICApIHtcbiAgICAgIGxldCBfcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KHVybCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keTogZGF0YSxcbiAgICAgICAgZHVwbGV4OiBcImhhbGZcIlxuICAgICAgfSk7XG5cbiAgICAgIGxldCBjb250ZW50VHlwZUhlYWRlcjtcblxuICAgICAgaWYgKHV0aWxzJDEuaXNGb3JtRGF0YShkYXRhKSAmJiAoY29udGVudFR5cGVIZWFkZXIgPSBfcmVxdWVzdC5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJykpKSB7XG4gICAgICAgIGhlYWRlcnMuc2V0Q29udGVudFR5cGUoY29udGVudFR5cGVIZWFkZXIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoX3JlcXVlc3QuYm9keSkge1xuICAgICAgICBjb25zdCBbb25Qcm9ncmVzcywgZmx1c2hdID0gcHJvZ3Jlc3NFdmVudERlY29yYXRvcihcbiAgICAgICAgICByZXF1ZXN0Q29udGVudExlbmd0aCxcbiAgICAgICAgICBwcm9ncmVzc0V2ZW50UmVkdWNlcihhc3luY0RlY29yYXRvcihvblVwbG9hZFByb2dyZXNzKSlcbiAgICAgICAgKTtcblxuICAgICAgICBkYXRhID0gdHJhY2tTdHJlYW0oX3JlcXVlc3QuYm9keSwgREVGQVVMVF9DSFVOS19TSVpFLCBvblByb2dyZXNzLCBmbHVzaCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF1dGlscyQxLmlzU3RyaW5nKHdpdGhDcmVkZW50aWFscykpIHtcbiAgICAgIHdpdGhDcmVkZW50aWFscyA9IHdpdGhDcmVkZW50aWFscyA/ICdpbmNsdWRlJyA6ICdvbWl0JztcbiAgICB9XG5cbiAgICAvLyBDbG91ZGZsYXJlIFdvcmtlcnMgdGhyb3dzIHdoZW4gY3JlZGVudGlhbHMgYXJlIGRlZmluZWRcbiAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Nsb3VkZmxhcmUvd29ya2VyZC9pc3N1ZXMvOTAyXG4gICAgY29uc3QgaXNDcmVkZW50aWFsc1N1cHBvcnRlZCA9IFwiY3JlZGVudGlhbHNcIiBpbiBSZXF1ZXN0LnByb3RvdHlwZTtcbiAgICByZXF1ZXN0ID0gbmV3IFJlcXVlc3QodXJsLCB7XG4gICAgICAuLi5mZXRjaE9wdGlvbnMsXG4gICAgICBzaWduYWw6IGNvbXBvc2VkU2lnbmFsLFxuICAgICAgbWV0aG9kOiBtZXRob2QudG9VcHBlckNhc2UoKSxcbiAgICAgIGhlYWRlcnM6IGhlYWRlcnMubm9ybWFsaXplKCkudG9KU09OKCksXG4gICAgICBib2R5OiBkYXRhLFxuICAgICAgZHVwbGV4OiBcImhhbGZcIixcbiAgICAgIGNyZWRlbnRpYWxzOiBpc0NyZWRlbnRpYWxzU3VwcG9ydGVkID8gd2l0aENyZWRlbnRpYWxzIDogdW5kZWZpbmVkXG4gICAgfSk7XG5cbiAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChyZXF1ZXN0KTtcblxuICAgIGNvbnN0IGlzU3RyZWFtUmVzcG9uc2UgPSBzdXBwb3J0c1Jlc3BvbnNlU3RyZWFtICYmIChyZXNwb25zZVR5cGUgPT09ICdzdHJlYW0nIHx8IHJlc3BvbnNlVHlwZSA9PT0gJ3Jlc3BvbnNlJyk7XG5cbiAgICBpZiAoc3VwcG9ydHNSZXNwb25zZVN0cmVhbSAmJiAob25Eb3dubG9hZFByb2dyZXNzIHx8IChpc1N0cmVhbVJlc3BvbnNlICYmIHVuc3Vic2NyaWJlKSkpIHtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcblxuICAgICAgWydzdGF0dXMnLCAnc3RhdHVzVGV4dCcsICdoZWFkZXJzJ10uZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgb3B0aW9uc1twcm9wXSA9IHJlc3BvbnNlW3Byb3BdO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlQ29udGVudExlbmd0aCA9IHV0aWxzJDEudG9GaW5pdGVOdW1iZXIocmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJykpO1xuXG4gICAgICBjb25zdCBbb25Qcm9ncmVzcywgZmx1c2hdID0gb25Eb3dubG9hZFByb2dyZXNzICYmIHByb2dyZXNzRXZlbnREZWNvcmF0b3IoXG4gICAgICAgIHJlc3BvbnNlQ29udGVudExlbmd0aCxcbiAgICAgICAgcHJvZ3Jlc3NFdmVudFJlZHVjZXIoYXN5bmNEZWNvcmF0b3Iob25Eb3dubG9hZFByb2dyZXNzKSwgdHJ1ZSlcbiAgICAgICkgfHwgW107XG5cbiAgICAgIHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKFxuICAgICAgICB0cmFja1N0cmVhbShyZXNwb25zZS5ib2R5LCBERUZBVUxUX0NIVU5LX1NJWkUsIG9uUHJvZ3Jlc3MsICgpID0+IHtcbiAgICAgICAgICBmbHVzaCAmJiBmbHVzaCgpO1xuICAgICAgICAgIHVuc3Vic2NyaWJlICYmIHVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH0pLFxuICAgICAgICBvcHRpb25zXG4gICAgICApO1xuICAgIH1cblxuICAgIHJlc3BvbnNlVHlwZSA9IHJlc3BvbnNlVHlwZSB8fCAndGV4dCc7XG5cbiAgICBsZXQgcmVzcG9uc2VEYXRhID0gYXdhaXQgcmVzb2x2ZXJzW3V0aWxzJDEuZmluZEtleShyZXNvbHZlcnMsIHJlc3BvbnNlVHlwZSkgfHwgJ3RleHQnXShyZXNwb25zZSwgY29uZmlnKTtcblxuICAgICFpc1N0cmVhbVJlc3BvbnNlICYmIHVuc3Vic2NyaWJlICYmIHVuc3Vic2NyaWJlKCk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwge1xuICAgICAgICBkYXRhOiByZXNwb25zZURhdGEsXG4gICAgICAgIGhlYWRlcnM6IEF4aW9zSGVhZGVycyQxLmZyb20ocmVzcG9uc2UuaGVhZGVycyksXG4gICAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiByZXNwb25zZS5zdGF0dXNUZXh0LFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3RcbiAgICAgIH0pO1xuICAgIH0pXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHVuc3Vic2NyaWJlICYmIHVuc3Vic2NyaWJlKCk7XG5cbiAgICBpZiAoZXJyICYmIGVyci5uYW1lID09PSAnVHlwZUVycm9yJyAmJiAvZmV0Y2gvaS50ZXN0KGVyci5tZXNzYWdlKSkge1xuICAgICAgdGhyb3cgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgbmV3IEF4aW9zRXJyb3IoJ05ldHdvcmsgRXJyb3InLCBBeGlvc0Vycm9yLkVSUl9ORVRXT1JLLCBjb25maWcsIHJlcXVlc3QpLFxuICAgICAgICB7XG4gICAgICAgICAgY2F1c2U6IGVyci5jYXVzZSB8fCBlcnJcbiAgICAgICAgfVxuICAgICAgKVxuICAgIH1cblxuICAgIHRocm93IEF4aW9zRXJyb3IuZnJvbShlcnIsIGVyciAmJiBlcnIuY29kZSwgY29uZmlnLCByZXF1ZXN0KTtcbiAgfVxufSk7XG5cbmNvbnN0IGtub3duQWRhcHRlcnMgPSB7XG4gIGh0dHA6IGh0dHBBZGFwdGVyLFxuICB4aHI6IHhockFkYXB0ZXIsXG4gIGZldGNoOiBmZXRjaEFkYXB0ZXJcbn07XG5cbnV0aWxzJDEuZm9yRWFjaChrbm93bkFkYXB0ZXJzLCAoZm4sIHZhbHVlKSA9PiB7XG4gIGlmIChmbikge1xuICAgIHRyeSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZm4sICduYW1lJywge3ZhbHVlfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmbiwgJ2FkYXB0ZXJOYW1lJywge3ZhbHVlfSk7XG4gIH1cbn0pO1xuXG5jb25zdCByZW5kZXJSZWFzb24gPSAocmVhc29uKSA9PiBgLSAke3JlYXNvbn1gO1xuXG5jb25zdCBpc1Jlc29sdmVkSGFuZGxlID0gKGFkYXB0ZXIpID0+IHV0aWxzJDEuaXNGdW5jdGlvbihhZGFwdGVyKSB8fCBhZGFwdGVyID09PSBudWxsIHx8IGFkYXB0ZXIgPT09IGZhbHNlO1xuXG52YXIgYWRhcHRlcnMgPSB7XG4gIGdldEFkYXB0ZXI6IChhZGFwdGVycykgPT4ge1xuICAgIGFkYXB0ZXJzID0gdXRpbHMkMS5pc0FycmF5KGFkYXB0ZXJzKSA/IGFkYXB0ZXJzIDogW2FkYXB0ZXJzXTtcblxuICAgIGNvbnN0IHtsZW5ndGh9ID0gYWRhcHRlcnM7XG4gICAgbGV0IG5hbWVPckFkYXB0ZXI7XG4gICAgbGV0IGFkYXB0ZXI7XG5cbiAgICBjb25zdCByZWplY3RlZFJlYXNvbnMgPSB7fTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIG5hbWVPckFkYXB0ZXIgPSBhZGFwdGVyc1tpXTtcbiAgICAgIGxldCBpZDtcblxuICAgICAgYWRhcHRlciA9IG5hbWVPckFkYXB0ZXI7XG5cbiAgICAgIGlmICghaXNSZXNvbHZlZEhhbmRsZShuYW1lT3JBZGFwdGVyKSkge1xuICAgICAgICBhZGFwdGVyID0ga25vd25BZGFwdGVyc1soaWQgPSBTdHJpbmcobmFtZU9yQWRhcHRlcikpLnRvTG93ZXJDYXNlKCldO1xuXG4gICAgICAgIGlmIChhZGFwdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihgVW5rbm93biBhZGFwdGVyICcke2lkfSdgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoYWRhcHRlcikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmVqZWN0ZWRSZWFzb25zW2lkIHx8ICcjJyArIGldID0gYWRhcHRlcjtcbiAgICB9XG5cbiAgICBpZiAoIWFkYXB0ZXIpIHtcblxuICAgICAgY29uc3QgcmVhc29ucyA9IE9iamVjdC5lbnRyaWVzKHJlamVjdGVkUmVhc29ucylcbiAgICAgICAgLm1hcCgoW2lkLCBzdGF0ZV0pID0+IGBhZGFwdGVyICR7aWR9IGAgK1xuICAgICAgICAgIChzdGF0ZSA9PT0gZmFsc2UgPyAnaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQnIDogJ2lzIG5vdCBhdmFpbGFibGUgaW4gdGhlIGJ1aWxkJylcbiAgICAgICAgKTtcblxuICAgICAgbGV0IHMgPSBsZW5ndGggP1xuICAgICAgICAocmVhc29ucy5sZW5ndGggPiAxID8gJ3NpbmNlIDpcXG4nICsgcmVhc29ucy5tYXAocmVuZGVyUmVhc29uKS5qb2luKCdcXG4nKSA6ICcgJyArIHJlbmRlclJlYXNvbihyZWFzb25zWzBdKSkgOlxuICAgICAgICAnYXMgbm8gYWRhcHRlciBzcGVjaWZpZWQnO1xuXG4gICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgYFRoZXJlIGlzIG5vIHN1aXRhYmxlIGFkYXB0ZXIgdG8gZGlzcGF0Y2ggdGhlIHJlcXVlc3QgYCArIHMsXG4gICAgICAgICdFUlJfTk9UX1NVUFBPUlQnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhZGFwdGVyO1xuICB9LFxuICBhZGFwdGVyczoga25vd25BZGFwdGVyc1xufTtcblxuLyoqXG4gKiBUaHJvd3MgYSBgQ2FuY2VsZWRFcnJvcmAgaWYgY2FuY2VsbGF0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnIFRoZSBjb25maWcgdGhhdCBpcyB0byBiZSB1c2VkIGZvciB0aGUgcmVxdWVzdFxuICpcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZykge1xuICBpZiAoY29uZmlnLmNhbmNlbFRva2VuKSB7XG4gICAgY29uZmlnLmNhbmNlbFRva2VuLnRocm93SWZSZXF1ZXN0ZWQoKTtcbiAgfVxuXG4gIGlmIChjb25maWcuc2lnbmFsICYmIGNvbmZpZy5zaWduYWwuYWJvcnRlZCkge1xuICAgIHRocm93IG5ldyBDYW5jZWxlZEVycm9yKG51bGwsIGNvbmZpZyk7XG4gIH1cbn1cblxuLyoqXG4gKiBEaXNwYXRjaCBhIHJlcXVlc3QgdG8gdGhlIHNlcnZlciB1c2luZyB0aGUgY29uZmlndXJlZCBhZGFwdGVyLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb25maWcgVGhlIGNvbmZpZyB0aGF0IGlzIHRvIGJlIHVzZWQgZm9yIHRoZSByZXF1ZXN0XG4gKlxuICogQHJldHVybnMge1Byb21pc2V9IFRoZSBQcm9taXNlIHRvIGJlIGZ1bGZpbGxlZFxuICovXG5mdW5jdGlvbiBkaXNwYXRjaFJlcXVlc3QoY29uZmlnKSB7XG4gIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICBjb25maWcuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20oY29uZmlnLmhlYWRlcnMpO1xuXG4gIC8vIFRyYW5zZm9ybSByZXF1ZXN0IGRhdGFcbiAgY29uZmlnLmRhdGEgPSB0cmFuc2Zvcm1EYXRhLmNhbGwoXG4gICAgY29uZmlnLFxuICAgIGNvbmZpZy50cmFuc2Zvcm1SZXF1ZXN0XG4gICk7XG5cbiAgaWYgKFsncG9zdCcsICdwdXQnLCAncGF0Y2gnXS5pbmRleE9mKGNvbmZpZy5tZXRob2QpICE9PSAtMSkge1xuICAgIGNvbmZpZy5oZWFkZXJzLnNldENvbnRlbnRUeXBlKCdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLCBmYWxzZSk7XG4gIH1cblxuICBjb25zdCBhZGFwdGVyID0gYWRhcHRlcnMuZ2V0QWRhcHRlcihjb25maWcuYWRhcHRlciB8fCBkZWZhdWx0cyQxLmFkYXB0ZXIpO1xuXG4gIHJldHVybiBhZGFwdGVyKGNvbmZpZykudGhlbihmdW5jdGlvbiBvbkFkYXB0ZXJSZXNvbHV0aW9uKHJlc3BvbnNlKSB7XG4gICAgdGhyb3dJZkNhbmNlbGxhdGlvblJlcXVlc3RlZChjb25maWcpO1xuXG4gICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICByZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgY29uZmlnLFxuICAgICAgY29uZmlnLnRyYW5zZm9ybVJlc3BvbnNlLFxuICAgICAgcmVzcG9uc2VcbiAgICApO1xuXG4gICAgcmVzcG9uc2UuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmZyb20ocmVzcG9uc2UuaGVhZGVycyk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH0sIGZ1bmN0aW9uIG9uQWRhcHRlclJlamVjdGlvbihyZWFzb24pIHtcbiAgICBpZiAoIWlzQ2FuY2VsKHJlYXNvbikpIHtcbiAgICAgIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAgICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICAgIGlmIChyZWFzb24gJiYgcmVhc29uLnJlc3BvbnNlKSB7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjb25maWcudHJhbnNmb3JtUmVzcG9uc2UsXG4gICAgICAgICAgcmVhc29uLnJlc3BvbnNlXG4gICAgICAgICk7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5oZWFkZXJzID0gQXhpb3NIZWFkZXJzJDEuZnJvbShyZWFzb24ucmVzcG9uc2UuaGVhZGVycyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHJlYXNvbik7XG4gIH0pO1xufVxuXG5jb25zdCBWRVJTSU9OID0gXCIxLjguNFwiO1xuXG5jb25zdCB2YWxpZGF0b3JzJDEgPSB7fTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcblsnb2JqZWN0JywgJ2Jvb2xlYW4nLCAnbnVtYmVyJywgJ2Z1bmN0aW9uJywgJ3N0cmluZycsICdzeW1ib2wnXS5mb3JFYWNoKCh0eXBlLCBpKSA9PiB7XG4gIHZhbGlkYXRvcnMkMVt0eXBlXSA9IGZ1bmN0aW9uIHZhbGlkYXRvcih0aGluZykge1xuICAgIHJldHVybiB0eXBlb2YgdGhpbmcgPT09IHR5cGUgfHwgJ2EnICsgKGkgPCAxID8gJ24gJyA6ICcgJykgKyB0eXBlO1xuICB9O1xufSk7XG5cbmNvbnN0IGRlcHJlY2F0ZWRXYXJuaW5ncyA9IHt9O1xuXG4vKipcbiAqIFRyYW5zaXRpb25hbCBvcHRpb24gdmFsaWRhdG9yXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbnxib29sZWFuP30gdmFsaWRhdG9yIC0gc2V0IHRvIGZhbHNlIGlmIHRoZSB0cmFuc2l0aW9uYWwgb3B0aW9uIGhhcyBiZWVuIHJlbW92ZWRcbiAqIEBwYXJhbSB7c3RyaW5nP30gdmVyc2lvbiAtIGRlcHJlY2F0ZWQgdmVyc2lvbiAvIHJlbW92ZWQgc2luY2UgdmVyc2lvblxuICogQHBhcmFtIHtzdHJpbmc/fSBtZXNzYWdlIC0gc29tZSBtZXNzYWdlIHdpdGggYWRkaXRpb25hbCBpbmZvXG4gKlxuICogQHJldHVybnMge2Z1bmN0aW9ufVxuICovXG52YWxpZGF0b3JzJDEudHJhbnNpdGlvbmFsID0gZnVuY3Rpb24gdHJhbnNpdGlvbmFsKHZhbGlkYXRvciwgdmVyc2lvbiwgbWVzc2FnZSkge1xuICBmdW5jdGlvbiBmb3JtYXRNZXNzYWdlKG9wdCwgZGVzYykge1xuICAgIHJldHVybiAnW0F4aW9zIHYnICsgVkVSU0lPTiArICddIFRyYW5zaXRpb25hbCBvcHRpb24gXFwnJyArIG9wdCArICdcXCcnICsgZGVzYyArIChtZXNzYWdlID8gJy4gJyArIG1lc3NhZ2UgOiAnJyk7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICByZXR1cm4gKHZhbHVlLCBvcHQsIG9wdHMpID0+IHtcbiAgICBpZiAodmFsaWRhdG9yID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEF4aW9zRXJyb3IoXG4gICAgICAgIGZvcm1hdE1lc3NhZ2Uob3B0LCAnIGhhcyBiZWVuIHJlbW92ZWQnICsgKHZlcnNpb24gPyAnIGluICcgKyB2ZXJzaW9uIDogJycpKSxcbiAgICAgICAgQXhpb3NFcnJvci5FUlJfREVQUkVDQVRFRFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodmVyc2lvbiAmJiAhZGVwcmVjYXRlZFdhcm5pbmdzW29wdF0pIHtcbiAgICAgIGRlcHJlY2F0ZWRXYXJuaW5nc1tvcHRdID0gdHJ1ZTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGZvcm1hdE1lc3NhZ2UoXG4gICAgICAgICAgb3B0LFxuICAgICAgICAgICcgaGFzIGJlZW4gZGVwcmVjYXRlZCBzaW5jZSB2JyArIHZlcnNpb24gKyAnIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIG5lYXIgZnV0dXJlJ1xuICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB2YWxpZGF0b3IgPyB2YWxpZGF0b3IodmFsdWUsIG9wdCwgb3B0cykgOiB0cnVlO1xuICB9O1xufTtcblxudmFsaWRhdG9ycyQxLnNwZWxsaW5nID0gZnVuY3Rpb24gc3BlbGxpbmcoY29ycmVjdFNwZWxsaW5nKSB7XG4gIHJldHVybiAodmFsdWUsIG9wdCkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS53YXJuKGAke29wdH0gaXMgbGlrZWx5IGEgbWlzc3BlbGxpbmcgb2YgJHtjb3JyZWN0U3BlbGxpbmd9YCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbi8qKlxuICogQXNzZXJ0IG9iamVjdCdzIHByb3BlcnRpZXMgdHlwZVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge29iamVjdH0gc2NoZW1hXG4gKiBAcGFyYW0ge2Jvb2xlYW4/fSBhbGxvd1Vua25vd25cbiAqXG4gKiBAcmV0dXJucyB7b2JqZWN0fVxuICovXG5cbmZ1bmN0aW9uIGFzc2VydE9wdGlvbnMob3B0aW9ucywgc2NoZW1hLCBhbGxvd1Vua25vd24pIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0JywgQXhpb3NFcnJvci5FUlJfQkFEX09QVElPTl9WQUxVRSk7XG4gIH1cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG9wdGlvbnMpO1xuICBsZXQgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tID4gMCkge1xuICAgIGNvbnN0IG9wdCA9IGtleXNbaV07XG4gICAgY29uc3QgdmFsaWRhdG9yID0gc2NoZW1hW29wdF07XG4gICAgaWYgKHZhbGlkYXRvcikge1xuICAgICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW29wdF07XG4gICAgICBjb25zdCByZXN1bHQgPSB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbGlkYXRvcih2YWx1ZSwgb3B0LCBvcHRpb25zKTtcbiAgICAgIGlmIChyZXN1bHQgIT09IHRydWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEF4aW9zRXJyb3IoJ29wdGlvbiAnICsgb3B0ICsgJyBtdXN0IGJlICcgKyByZXN1bHQsIEF4aW9zRXJyb3IuRVJSX0JBRF9PUFRJT05fVkFMVUUpO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChhbGxvd1Vua25vd24gIT09IHRydWUpIHtcbiAgICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdVbmtub3duIG9wdGlvbiAnICsgb3B0LCBBeGlvc0Vycm9yLkVSUl9CQURfT1BUSU9OKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHZhbGlkYXRvciA9IHtcbiAgYXNzZXJ0T3B0aW9ucyxcbiAgdmFsaWRhdG9yczogdmFsaWRhdG9ycyQxXG59O1xuXG5jb25zdCB2YWxpZGF0b3JzID0gdmFsaWRhdG9yLnZhbGlkYXRvcnM7XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGluc3RhbmNlQ29uZmlnIFRoZSBkZWZhdWx0IGNvbmZpZyBmb3IgdGhlIGluc3RhbmNlXG4gKlxuICogQHJldHVybiB7QXhpb3N9IEEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKi9cbmNsYXNzIEF4aW9zIHtcbiAgY29uc3RydWN0b3IoaW5zdGFuY2VDb25maWcpIHtcbiAgICB0aGlzLmRlZmF1bHRzID0gaW5zdGFuY2VDb25maWc7XG4gICAgdGhpcy5pbnRlcmNlcHRvcnMgPSB7XG4gICAgICByZXF1ZXN0OiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyJDEoKSxcbiAgICAgIHJlc3BvbnNlOiBuZXcgSW50ZXJjZXB0b3JNYW5hZ2VyJDEoKVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYSByZXF1ZXN0XG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gY29uZmlnT3JVcmwgVGhlIGNvbmZpZyBzcGVjaWZpYyBmb3IgdGhpcyByZXF1ZXN0IChtZXJnZWQgd2l0aCB0aGlzLmRlZmF1bHRzKVxuICAgKiBAcGFyYW0gez9PYmplY3R9IGNvbmZpZ1xuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gVGhlIFByb21pc2UgdG8gYmUgZnVsZmlsbGVkXG4gICAqL1xuICBhc3luYyByZXF1ZXN0KGNvbmZpZ09yVXJsLCBjb25maWcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3JlcXVlc3QoY29uZmlnT3JVcmwsIGNvbmZpZyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgbGV0IGR1bW15ID0ge307XG5cbiAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UgPyBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZShkdW1teSkgOiAoZHVtbXkgPSBuZXcgRXJyb3IoKSk7XG5cbiAgICAgICAgLy8gc2xpY2Ugb2ZmIHRoZSBFcnJvcjogLi4uIGxpbmVcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBkdW1teS5zdGFjayA/IGR1bW15LnN0YWNrLnJlcGxhY2UoL14uK1xcbi8sICcnKSA6ICcnO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmICghZXJyLnN0YWNrKSB7XG4gICAgICAgICAgICBlcnIuc3RhY2sgPSBzdGFjaztcbiAgICAgICAgICAgIC8vIG1hdGNoIHdpdGhvdXQgdGhlIDIgdG9wIHN0YWNrIGxpbmVzXG4gICAgICAgICAgfSBlbHNlIGlmIChzdGFjayAmJiAhU3RyaW5nKGVyci5zdGFjaykuZW5kc1dpdGgoc3RhY2sucmVwbGFjZSgvXi4rXFxuLitcXG4vLCAnJykpKSB7XG4gICAgICAgICAgICBlcnIuc3RhY2sgKz0gJ1xcbicgKyBzdGFjaztcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvLyBpZ25vcmUgdGhlIGNhc2Ugd2hlcmUgXCJzdGFja1wiIGlzIGFuIHVuLXdyaXRhYmxlIHByb3BlcnR5XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIF9yZXF1ZXN0KGNvbmZpZ09yVXJsLCBjb25maWcpIHtcbiAgICAvKmVzbGludCBuby1wYXJhbS1yZWFzc2lnbjowKi9cbiAgICAvLyBBbGxvdyBmb3IgYXhpb3MoJ2V4YW1wbGUvdXJsJ1ssIGNvbmZpZ10pIGEgbGEgZmV0Y2ggQVBJXG4gICAgaWYgKHR5cGVvZiBjb25maWdPclVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICAgIGNvbmZpZy51cmwgPSBjb25maWdPclVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnID0gY29uZmlnT3JVcmwgfHwge307XG4gICAgfVxuXG4gICAgY29uZmlnID0gbWVyZ2VDb25maWcodGhpcy5kZWZhdWx0cywgY29uZmlnKTtcblxuICAgIGNvbnN0IHt0cmFuc2l0aW9uYWwsIHBhcmFtc1NlcmlhbGl6ZXIsIGhlYWRlcnN9ID0gY29uZmlnO1xuXG4gICAgaWYgKHRyYW5zaXRpb25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWxpZGF0b3IuYXNzZXJ0T3B0aW9ucyh0cmFuc2l0aW9uYWwsIHtcbiAgICAgICAgc2lsZW50SlNPTlBhcnNpbmc6IHZhbGlkYXRvcnMudHJhbnNpdGlvbmFsKHZhbGlkYXRvcnMuYm9vbGVhbiksXG4gICAgICAgIGZvcmNlZEpTT05QYXJzaW5nOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pLFxuICAgICAgICBjbGFyaWZ5VGltZW91dEVycm9yOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pXG4gICAgICB9LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtc1NlcmlhbGl6ZXIgIT0gbnVsbCkge1xuICAgICAgaWYgKHV0aWxzJDEuaXNGdW5jdGlvbihwYXJhbXNTZXJpYWxpemVyKSkge1xuICAgICAgICBjb25maWcucGFyYW1zU2VyaWFsaXplciA9IHtcbiAgICAgICAgICBzZXJpYWxpemU6IHBhcmFtc1NlcmlhbGl6ZXJcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbGlkYXRvci5hc3NlcnRPcHRpb25zKHBhcmFtc1NlcmlhbGl6ZXIsIHtcbiAgICAgICAgICBlbmNvZGU6IHZhbGlkYXRvcnMuZnVuY3Rpb24sXG4gICAgICAgICAgc2VyaWFsaXplOiB2YWxpZGF0b3JzLmZ1bmN0aW9uXG4gICAgICAgIH0sIHRydWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNldCBjb25maWcuYWxsb3dBYnNvbHV0ZVVybHNcbiAgICBpZiAoY29uZmlnLmFsbG93QWJzb2x1dGVVcmxzICE9PSB1bmRlZmluZWQpIDsgZWxzZSBpZiAodGhpcy5kZWZhdWx0cy5hbGxvd0Fic29sdXRlVXJscyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25maWcuYWxsb3dBYnNvbHV0ZVVybHMgPSB0aGlzLmRlZmF1bHRzLmFsbG93QWJzb2x1dGVVcmxzO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25maWcuYWxsb3dBYnNvbHV0ZVVybHMgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhbGlkYXRvci5hc3NlcnRPcHRpb25zKGNvbmZpZywge1xuICAgICAgYmFzZVVybDogdmFsaWRhdG9ycy5zcGVsbGluZygnYmFzZVVSTCcpLFxuICAgICAgd2l0aFhzcmZUb2tlbjogdmFsaWRhdG9ycy5zcGVsbGluZygnd2l0aFhTUkZUb2tlbicpXG4gICAgfSwgdHJ1ZSk7XG5cbiAgICAvLyBTZXQgY29uZmlnLm1ldGhvZFxuICAgIGNvbmZpZy5tZXRob2QgPSAoY29uZmlnLm1ldGhvZCB8fCB0aGlzLmRlZmF1bHRzLm1ldGhvZCB8fCAnZ2V0JykudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIEZsYXR0ZW4gaGVhZGVyc1xuICAgIGxldCBjb250ZXh0SGVhZGVycyA9IGhlYWRlcnMgJiYgdXRpbHMkMS5tZXJnZShcbiAgICAgIGhlYWRlcnMuY29tbW9uLFxuICAgICAgaGVhZGVyc1tjb25maWcubWV0aG9kXVxuICAgICk7XG5cbiAgICBoZWFkZXJzICYmIHV0aWxzJDEuZm9yRWFjaChcbiAgICAgIFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJywgJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJywgJ2NvbW1vbiddLFxuICAgICAgKG1ldGhvZCkgPT4ge1xuICAgICAgICBkZWxldGUgaGVhZGVyc1ttZXRob2RdO1xuICAgICAgfVxuICAgICk7XG5cbiAgICBjb25maWcuaGVhZGVycyA9IEF4aW9zSGVhZGVycyQxLmNvbmNhdChjb250ZXh0SGVhZGVycywgaGVhZGVycyk7XG5cbiAgICAvLyBmaWx0ZXIgb3V0IHNraXBwZWQgaW50ZXJjZXB0b3JzXG4gICAgY29uc3QgcmVxdWVzdEludGVyY2VwdG9yQ2hhaW4gPSBbXTtcbiAgICBsZXQgc3luY2hyb25vdXNSZXF1ZXN0SW50ZXJjZXB0b3JzID0gdHJ1ZTtcbiAgICB0aGlzLmludGVyY2VwdG9ycy5yZXF1ZXN0LmZvckVhY2goZnVuY3Rpb24gdW5zaGlmdFJlcXVlc3RJbnRlcmNlcHRvcnMoaW50ZXJjZXB0b3IpIHtcbiAgICAgIGlmICh0eXBlb2YgaW50ZXJjZXB0b3IucnVuV2hlbiA9PT0gJ2Z1bmN0aW9uJyAmJiBpbnRlcmNlcHRvci5ydW5XaGVuKGNvbmZpZykgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgc3luY2hyb25vdXNSZXF1ZXN0SW50ZXJjZXB0b3JzID0gc3luY2hyb25vdXNSZXF1ZXN0SW50ZXJjZXB0b3JzICYmIGludGVyY2VwdG9yLnN5bmNocm9ub3VzO1xuXG4gICAgICByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbi51bnNoaWZ0KGludGVyY2VwdG9yLmZ1bGZpbGxlZCwgaW50ZXJjZXB0b3IucmVqZWN0ZWQpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2VJbnRlcmNlcHRvckNoYWluID0gW107XG4gICAgdGhpcy5pbnRlcmNlcHRvcnMucmVzcG9uc2UuZm9yRWFjaChmdW5jdGlvbiBwdXNoUmVzcG9uc2VJbnRlcmNlcHRvcnMoaW50ZXJjZXB0b3IpIHtcbiAgICAgIHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbi5wdXNoKGludGVyY2VwdG9yLmZ1bGZpbGxlZCwgaW50ZXJjZXB0b3IucmVqZWN0ZWQpO1xuICAgIH0pO1xuXG4gICAgbGV0IHByb21pc2U7XG4gICAgbGV0IGkgPSAwO1xuICAgIGxldCBsZW47XG5cbiAgICBpZiAoIXN5bmNocm9ub3VzUmVxdWVzdEludGVyY2VwdG9ycykge1xuICAgICAgY29uc3QgY2hhaW4gPSBbZGlzcGF0Y2hSZXF1ZXN0LmJpbmQodGhpcyksIHVuZGVmaW5lZF07XG4gICAgICBjaGFpbi51bnNoaWZ0LmFwcGx5KGNoYWluLCByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbik7XG4gICAgICBjaGFpbi5wdXNoLmFwcGx5KGNoYWluLCByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4pO1xuICAgICAgbGVuID0gY2hhaW4ubGVuZ3RoO1xuXG4gICAgICBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGNvbmZpZyk7XG5cbiAgICAgIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4oY2hhaW5baSsrXSwgY2hhaW5baSsrXSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIGxlbiA9IHJlcXVlc3RJbnRlcmNlcHRvckNoYWluLmxlbmd0aDtcblxuICAgIGxldCBuZXdDb25maWcgPSBjb25maWc7XG5cbiAgICBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgICBjb25zdCBvbkZ1bGZpbGxlZCA9IHJlcXVlc3RJbnRlcmNlcHRvckNoYWluW2krK107XG4gICAgICBjb25zdCBvblJlamVjdGVkID0gcmVxdWVzdEludGVyY2VwdG9yQ2hhaW5baSsrXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIG5ld0NvbmZpZyA9IG9uRnVsZmlsbGVkKG5ld0NvbmZpZyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBvblJlamVjdGVkLmNhbGwodGhpcywgZXJyb3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcHJvbWlzZSA9IGRpc3BhdGNoUmVxdWVzdC5jYWxsKHRoaXMsIG5ld0NvbmZpZyk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgfVxuXG4gICAgaSA9IDA7XG4gICAgbGVuID0gcmVzcG9uc2VJbnRlcmNlcHRvckNoYWluLmxlbmd0aDtcblxuICAgIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgICBwcm9taXNlID0gcHJvbWlzZS50aGVuKHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbltpKytdLCByZXNwb25zZUludGVyY2VwdG9yQ2hhaW5baSsrXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICBnZXRVcmkoY29uZmlnKSB7XG4gICAgY29uZmlnID0gbWVyZ2VDb25maWcodGhpcy5kZWZhdWx0cywgY29uZmlnKTtcbiAgICBjb25zdCBmdWxsUGF0aCA9IGJ1aWxkRnVsbFBhdGgoY29uZmlnLmJhc2VVUkwsIGNvbmZpZy51cmwsIGNvbmZpZy5hbGxvd0Fic29sdXRlVXJscyk7XG4gICAgcmV0dXJuIGJ1aWxkVVJMKGZ1bGxQYXRoLCBjb25maWcucGFyYW1zLCBjb25maWcucGFyYW1zU2VyaWFsaXplcik7XG4gIH1cbn1cblxuLy8gUHJvdmlkZSBhbGlhc2VzIGZvciBzdXBwb3J0ZWQgcmVxdWVzdCBtZXRob2RzXG51dGlscyQxLmZvckVhY2goWydkZWxldGUnLCAnZ2V0JywgJ2hlYWQnLCAnb3B0aW9ucyddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kTm9EYXRhKG1ldGhvZCkge1xuICAvKmVzbGludCBmdW5jLW5hbWVzOjAqL1xuICBBeGlvcy5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKHVybCwgY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXJnZUNvbmZpZyhjb25maWcgfHwge30sIHtcbiAgICAgIG1ldGhvZCxcbiAgICAgIHVybCxcbiAgICAgIGRhdGE6IChjb25maWcgfHwge30pLmRhdGFcbiAgICB9KSk7XG4gIH07XG59KTtcblxudXRpbHMkMS5mb3JFYWNoKFsncG9zdCcsICdwdXQnLCAncGF0Y2gnXSwgZnVuY3Rpb24gZm9yRWFjaE1ldGhvZFdpdGhEYXRhKG1ldGhvZCkge1xuICAvKmVzbGludCBmdW5jLW5hbWVzOjAqL1xuXG4gIGZ1bmN0aW9uIGdlbmVyYXRlSFRUUE1ldGhvZChpc0Zvcm0pIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gaHR0cE1ldGhvZCh1cmwsIGRhdGEsIGNvbmZpZykge1xuICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdChtZXJnZUNvbmZpZyhjb25maWcgfHwge30sIHtcbiAgICAgICAgbWV0aG9kLFxuICAgICAgICBoZWFkZXJzOiBpc0Zvcm0gPyB7XG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdtdWx0aXBhcnQvZm9ybS1kYXRhJ1xuICAgICAgICB9IDoge30sXG4gICAgICAgIHVybCxcbiAgICAgICAgZGF0YVxuICAgICAgfSkpO1xuICAgIH07XG4gIH1cblxuICBBeGlvcy5wcm90b3R5cGVbbWV0aG9kXSA9IGdlbmVyYXRlSFRUUE1ldGhvZCgpO1xuXG4gIEF4aW9zLnByb3RvdHlwZVttZXRob2QgKyAnRm9ybSddID0gZ2VuZXJhdGVIVFRQTWV0aG9kKHRydWUpO1xufSk7XG5cbnZhciBBeGlvcyQxID0gQXhpb3M7XG5cbi8qKlxuICogQSBgQ2FuY2VsVG9rZW5gIGlzIGFuIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIHJlcXVlc3QgY2FuY2VsbGF0aW9uIG9mIGFuIG9wZXJhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBleGVjdXRvciBUaGUgZXhlY3V0b3IgZnVuY3Rpb24uXG4gKlxuICogQHJldHVybnMge0NhbmNlbFRva2VufVxuICovXG5jbGFzcyBDYW5jZWxUb2tlbiB7XG4gIGNvbnN0cnVjdG9yKGV4ZWN1dG9yKSB7XG4gICAgaWYgKHR5cGVvZiBleGVjdXRvciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZXhlY3V0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uLicpO1xuICAgIH1cblxuICAgIGxldCByZXNvbHZlUHJvbWlzZTtcblxuICAgIHRoaXMucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIHByb21pc2VFeGVjdXRvcihyZXNvbHZlKSB7XG4gICAgICByZXNvbHZlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG5cbiAgICBjb25zdCB0b2tlbiA9IHRoaXM7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICAgIHRoaXMucHJvbWlzZS50aGVuKGNhbmNlbCA9PiB7XG4gICAgICBpZiAoIXRva2VuLl9saXN0ZW5lcnMpIHJldHVybjtcblxuICAgICAgbGV0IGkgPSB0b2tlbi5fbGlzdGVuZXJzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGktLSA+IDApIHtcbiAgICAgICAgdG9rZW4uX2xpc3RlbmVyc1tpXShjYW5jZWwpO1xuICAgICAgfVxuICAgICAgdG9rZW4uX2xpc3RlbmVycyA9IG51bGw7XG4gICAgfSk7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICAgIHRoaXMucHJvbWlzZS50aGVuID0gb25mdWxmaWxsZWQgPT4ge1xuICAgICAgbGV0IF9yZXNvbHZlO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgdG9rZW4uc3Vic2NyaWJlKHJlc29sdmUpO1xuICAgICAgICBfcmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICB9KS50aGVuKG9uZnVsZmlsbGVkKTtcblxuICAgICAgcHJvbWlzZS5jYW5jZWwgPSBmdW5jdGlvbiByZWplY3QoKSB7XG4gICAgICAgIHRva2VuLnVuc3Vic2NyaWJlKF9yZXNvbHZlKTtcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH07XG5cbiAgICBleGVjdXRvcihmdW5jdGlvbiBjYW5jZWwobWVzc2FnZSwgY29uZmlnLCByZXF1ZXN0KSB7XG4gICAgICBpZiAodG9rZW4ucmVhc29uKSB7XG4gICAgICAgIC8vIENhbmNlbGxhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIHJlcXVlc3RlZFxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRva2VuLnJlYXNvbiA9IG5ldyBDYW5jZWxlZEVycm9yKG1lc3NhZ2UsIGNvbmZpZywgcmVxdWVzdCk7XG4gICAgICByZXNvbHZlUHJvbWlzZSh0b2tlbi5yZWFzb24pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRocm93cyBhIGBDYW5jZWxlZEVycm9yYCBpZiBjYW5jZWxsYXRpb24gaGFzIGJlZW4gcmVxdWVzdGVkLlxuICAgKi9cbiAgdGhyb3dJZlJlcXVlc3RlZCgpIHtcbiAgICBpZiAodGhpcy5yZWFzb24pIHtcbiAgICAgIHRocm93IHRoaXMucmVhc29uO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmUgdG8gdGhlIGNhbmNlbCBzaWduYWxcbiAgICovXG5cbiAgc3Vic2NyaWJlKGxpc3RlbmVyKSB7XG4gICAgaWYgKHRoaXMucmVhc29uKSB7XG4gICAgICBsaXN0ZW5lcih0aGlzLnJlYXNvbik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2xpc3RlbmVycykge1xuICAgICAgdGhpcy5fbGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9saXN0ZW5lcnMgPSBbbGlzdGVuZXJdO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbnN1YnNjcmliZSBmcm9tIHRoZSBjYW5jZWwgc2lnbmFsXG4gICAqL1xuXG4gIHVuc3Vic2NyaWJlKGxpc3RlbmVyKSB7XG4gICAgaWYgKCF0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9saXN0ZW5lcnMuaW5kZXhPZihsaXN0ZW5lcik7XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuICB9XG5cbiAgdG9BYm9ydFNpZ25hbCgpIHtcbiAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gICAgY29uc3QgYWJvcnQgPSAoZXJyKSA9PiB7XG4gICAgICBjb250cm9sbGVyLmFib3J0KGVycik7XG4gICAgfTtcblxuICAgIHRoaXMuc3Vic2NyaWJlKGFib3J0KTtcblxuICAgIGNvbnRyb2xsZXIuc2lnbmFsLnVuc3Vic2NyaWJlID0gKCkgPT4gdGhpcy51bnN1YnNjcmliZShhYm9ydCk7XG5cbiAgICByZXR1cm4gY29udHJvbGxlci5zaWduYWw7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhIG5ldyBgQ2FuY2VsVG9rZW5gIGFuZCBhIGZ1bmN0aW9uIHRoYXQsIHdoZW4gY2FsbGVkLFxuICAgKiBjYW5jZWxzIHRoZSBgQ2FuY2VsVG9rZW5gLlxuICAgKi9cbiAgc3RhdGljIHNvdXJjZSgpIHtcbiAgICBsZXQgY2FuY2VsO1xuICAgIGNvbnN0IHRva2VuID0gbmV3IENhbmNlbFRva2VuKGZ1bmN0aW9uIGV4ZWN1dG9yKGMpIHtcbiAgICAgIGNhbmNlbCA9IGM7XG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRva2VuLFxuICAgICAgY2FuY2VsXG4gICAgfTtcbiAgfVxufVxuXG52YXIgQ2FuY2VsVG9rZW4kMSA9IENhbmNlbFRva2VuO1xuXG4vKipcbiAqIFN5bnRhY3RpYyBzdWdhciBmb3IgaW52b2tpbmcgYSBmdW5jdGlvbiBhbmQgZXhwYW5kaW5nIGFuIGFycmF5IGZvciBhcmd1bWVudHMuXG4gKlxuICogQ29tbW9uIHVzZSBjYXNlIHdvdWxkIGJlIHRvIHVzZSBgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5YC5cbiAqXG4gKiAgYGBganNcbiAqICBmdW5jdGlvbiBmKHgsIHksIHopIHt9XG4gKiAgdmFyIGFyZ3MgPSBbMSwgMiwgM107XG4gKiAgZi5hcHBseShudWxsLCBhcmdzKTtcbiAqICBgYGBcbiAqXG4gKiBXaXRoIGBzcHJlYWRgIHRoaXMgZXhhbXBsZSBjYW4gYmUgcmUtd3JpdHRlbi5cbiAqXG4gKiAgYGBganNcbiAqICBzcHJlYWQoZnVuY3Rpb24oeCwgeSwgeikge30pKFsxLCAyLCAzXSk7XG4gKiAgYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIHNwcmVhZChjYWxsYmFjaykge1xuICByZXR1cm4gZnVuY3Rpb24gd3JhcChhcnIpIHtcbiAgICByZXR1cm4gY2FsbGJhY2suYXBwbHkobnVsbCwgYXJyKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIHBheWxvYWQgaXMgYW4gZXJyb3IgdGhyb3duIGJ5IEF4aW9zXG4gKlxuICogQHBhcmFtIHsqfSBwYXlsb2FkIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHBheWxvYWQgaXMgYW4gZXJyb3IgdGhyb3duIGJ5IEF4aW9zLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBeGlvc0Vycm9yKHBheWxvYWQpIHtcbiAgcmV0dXJuIHV0aWxzJDEuaXNPYmplY3QocGF5bG9hZCkgJiYgKHBheWxvYWQuaXNBeGlvc0Vycm9yID09PSB0cnVlKTtcbn1cblxuY29uc3QgSHR0cFN0YXR1c0NvZGUgPSB7XG4gIENvbnRpbnVlOiAxMDAsXG4gIFN3aXRjaGluZ1Byb3RvY29sczogMTAxLFxuICBQcm9jZXNzaW5nOiAxMDIsXG4gIEVhcmx5SGludHM6IDEwMyxcbiAgT2s6IDIwMCxcbiAgQ3JlYXRlZDogMjAxLFxuICBBY2NlcHRlZDogMjAyLFxuICBOb25BdXRob3JpdGF0aXZlSW5mb3JtYXRpb246IDIwMyxcbiAgTm9Db250ZW50OiAyMDQsXG4gIFJlc2V0Q29udGVudDogMjA1LFxuICBQYXJ0aWFsQ29udGVudDogMjA2LFxuICBNdWx0aVN0YXR1czogMjA3LFxuICBBbHJlYWR5UmVwb3J0ZWQ6IDIwOCxcbiAgSW1Vc2VkOiAyMjYsXG4gIE11bHRpcGxlQ2hvaWNlczogMzAwLFxuICBNb3ZlZFBlcm1hbmVudGx5OiAzMDEsXG4gIEZvdW5kOiAzMDIsXG4gIFNlZU90aGVyOiAzMDMsXG4gIE5vdE1vZGlmaWVkOiAzMDQsXG4gIFVzZVByb3h5OiAzMDUsXG4gIFVudXNlZDogMzA2LFxuICBUZW1wb3JhcnlSZWRpcmVjdDogMzA3LFxuICBQZXJtYW5lbnRSZWRpcmVjdDogMzA4LFxuICBCYWRSZXF1ZXN0OiA0MDAsXG4gIFVuYXV0aG9yaXplZDogNDAxLFxuICBQYXltZW50UmVxdWlyZWQ6IDQwMixcbiAgRm9yYmlkZGVuOiA0MDMsXG4gIE5vdEZvdW5kOiA0MDQsXG4gIE1ldGhvZE5vdEFsbG93ZWQ6IDQwNSxcbiAgTm90QWNjZXB0YWJsZTogNDA2LFxuICBQcm94eUF1dGhlbnRpY2F0aW9uUmVxdWlyZWQ6IDQwNyxcbiAgUmVxdWVzdFRpbWVvdXQ6IDQwOCxcbiAgQ29uZmxpY3Q6IDQwOSxcbiAgR29uZTogNDEwLFxuICBMZW5ndGhSZXF1aXJlZDogNDExLFxuICBQcmVjb25kaXRpb25GYWlsZWQ6IDQxMixcbiAgUGF5bG9hZFRvb0xhcmdlOiA0MTMsXG4gIFVyaVRvb0xvbmc6IDQxNCxcbiAgVW5zdXBwb3J0ZWRNZWRpYVR5cGU6IDQxNSxcbiAgUmFuZ2VOb3RTYXRpc2ZpYWJsZTogNDE2LFxuICBFeHBlY3RhdGlvbkZhaWxlZDogNDE3LFxuICBJbUFUZWFwb3Q6IDQxOCxcbiAgTWlzZGlyZWN0ZWRSZXF1ZXN0OiA0MjEsXG4gIFVucHJvY2Vzc2FibGVFbnRpdHk6IDQyMixcbiAgTG9ja2VkOiA0MjMsXG4gIEZhaWxlZERlcGVuZGVuY3k6IDQyNCxcbiAgVG9vRWFybHk6IDQyNSxcbiAgVXBncmFkZVJlcXVpcmVkOiA0MjYsXG4gIFByZWNvbmRpdGlvblJlcXVpcmVkOiA0MjgsXG4gIFRvb01hbnlSZXF1ZXN0czogNDI5LFxuICBSZXF1ZXN0SGVhZGVyRmllbGRzVG9vTGFyZ2U6IDQzMSxcbiAgVW5hdmFpbGFibGVGb3JMZWdhbFJlYXNvbnM6IDQ1MSxcbiAgSW50ZXJuYWxTZXJ2ZXJFcnJvcjogNTAwLFxuICBOb3RJbXBsZW1lbnRlZDogNTAxLFxuICBCYWRHYXRld2F5OiA1MDIsXG4gIFNlcnZpY2VVbmF2YWlsYWJsZTogNTAzLFxuICBHYXRld2F5VGltZW91dDogNTA0LFxuICBIdHRwVmVyc2lvbk5vdFN1cHBvcnRlZDogNTA1LFxuICBWYXJpYW50QWxzb05lZ290aWF0ZXM6IDUwNixcbiAgSW5zdWZmaWNpZW50U3RvcmFnZTogNTA3LFxuICBMb29wRGV0ZWN0ZWQ6IDUwOCxcbiAgTm90RXh0ZW5kZWQ6IDUxMCxcbiAgTmV0d29ya0F1dGhlbnRpY2F0aW9uUmVxdWlyZWQ6IDUxMSxcbn07XG5cbk9iamVjdC5lbnRyaWVzKEh0dHBTdGF0dXNDb2RlKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgSHR0cFN0YXR1c0NvZGVbdmFsdWVdID0ga2V5O1xufSk7XG5cbnZhciBIdHRwU3RhdHVzQ29kZSQxID0gSHR0cFN0YXR1c0NvZGU7XG5cbi8qKlxuICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIEF4aW9zXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRlZmF1bHRDb25maWcgVGhlIGRlZmF1bHQgY29uZmlnIGZvciB0aGUgaW5zdGFuY2VcbiAqXG4gKiBAcmV0dXJucyB7QXhpb3N9IEEgbmV3IGluc3RhbmNlIG9mIEF4aW9zXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUluc3RhbmNlKGRlZmF1bHRDb25maWcpIHtcbiAgY29uc3QgY29udGV4dCA9IG5ldyBBeGlvcyQxKGRlZmF1bHRDb25maWcpO1xuICBjb25zdCBpbnN0YW5jZSA9IGJpbmQoQXhpb3MkMS5wcm90b3R5cGUucmVxdWVzdCwgY29udGV4dCk7XG5cbiAgLy8gQ29weSBheGlvcy5wcm90b3R5cGUgdG8gaW5zdGFuY2VcbiAgdXRpbHMkMS5leHRlbmQoaW5zdGFuY2UsIEF4aW9zJDEucHJvdG90eXBlLCBjb250ZXh0LCB7YWxsT3duS2V5czogdHJ1ZX0pO1xuXG4gIC8vIENvcHkgY29udGV4dCB0byBpbnN0YW5jZVxuICB1dGlscyQxLmV4dGVuZChpbnN0YW5jZSwgY29udGV4dCwgbnVsbCwge2FsbE93bktleXM6IHRydWV9KTtcblxuICAvLyBGYWN0b3J5IGZvciBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXG4gIGluc3RhbmNlLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpbnN0YW5jZUNvbmZpZykge1xuICAgIHJldHVybiBjcmVhdGVJbnN0YW5jZShtZXJnZUNvbmZpZyhkZWZhdWx0Q29uZmlnLCBpbnN0YW5jZUNvbmZpZykpO1xuICB9O1xuXG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuLy8gQ3JlYXRlIHRoZSBkZWZhdWx0IGluc3RhbmNlIHRvIGJlIGV4cG9ydGVkXG5jb25zdCBheGlvcyA9IGNyZWF0ZUluc3RhbmNlKGRlZmF1bHRzJDEpO1xuXG4vLyBFeHBvc2UgQXhpb3MgY2xhc3MgdG8gYWxsb3cgY2xhc3MgaW5oZXJpdGFuY2VcbmF4aW9zLkF4aW9zID0gQXhpb3MkMTtcblxuLy8gRXhwb3NlIENhbmNlbCAmIENhbmNlbFRva2VuXG5heGlvcy5DYW5jZWxlZEVycm9yID0gQ2FuY2VsZWRFcnJvcjtcbmF4aW9zLkNhbmNlbFRva2VuID0gQ2FuY2VsVG9rZW4kMTtcbmF4aW9zLmlzQ2FuY2VsID0gaXNDYW5jZWw7XG5heGlvcy5WRVJTSU9OID0gVkVSU0lPTjtcbmF4aW9zLnRvRm9ybURhdGEgPSB0b0Zvcm1EYXRhO1xuXG4vLyBFeHBvc2UgQXhpb3NFcnJvciBjbGFzc1xuYXhpb3MuQXhpb3NFcnJvciA9IEF4aW9zRXJyb3I7XG5cbi8vIGFsaWFzIGZvciBDYW5jZWxlZEVycm9yIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5heGlvcy5DYW5jZWwgPSBheGlvcy5DYW5jZWxlZEVycm9yO1xuXG4vLyBFeHBvc2UgYWxsL3NwcmVhZFxuYXhpb3MuYWxsID0gZnVuY3Rpb24gYWxsKHByb21pc2VzKSB7XG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59O1xuXG5heGlvcy5zcHJlYWQgPSBzcHJlYWQ7XG5cbi8vIEV4cG9zZSBpc0F4aW9zRXJyb3JcbmF4aW9zLmlzQXhpb3NFcnJvciA9IGlzQXhpb3NFcnJvcjtcblxuLy8gRXhwb3NlIG1lcmdlQ29uZmlnXG5heGlvcy5tZXJnZUNvbmZpZyA9IG1lcmdlQ29uZmlnO1xuXG5heGlvcy5BeGlvc0hlYWRlcnMgPSBBeGlvc0hlYWRlcnMkMTtcblxuYXhpb3MuZm9ybVRvSlNPTiA9IHRoaW5nID0+IGZvcm1EYXRhVG9KU09OKHV0aWxzJDEuaXNIVE1MRm9ybSh0aGluZykgPyBuZXcgRm9ybURhdGEodGhpbmcpIDogdGhpbmcpO1xuXG5heGlvcy5nZXRBZGFwdGVyID0gYWRhcHRlcnMuZ2V0QWRhcHRlcjtcblxuYXhpb3MuSHR0cFN0YXR1c0NvZGUgPSBIdHRwU3RhdHVzQ29kZSQxO1xuXG5heGlvcy5kZWZhdWx0ID0gYXhpb3M7XG5cbm1vZHVsZS5leHBvcnRzID0gYXhpb3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1heGlvcy5janMubWFwXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/axios/dist/browser/axios.cjs\n"); /***/ }), /***/ "./node_modules/base64-js/index.js": /*!*****************************************!*\ !*** ./node_modules/base64-js/index.js ***! \*****************************************/ /***/ ((__unused_webpack_module, exports) => { "use strict"; eval("\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n lookup[i] = code[i]\n revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n var len = b64.length\n\n if (len % 4 > 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwibWFwcGluZ3MiOiJBQUFZOztBQUVaLGtCQUFrQjtBQUNsQixtQkFBbUI7QUFDbkIscUJBQXFCOztBQUVyQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQ0FBbUMsU0FBUztBQUM1QztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLFNBQVM7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixTQUFTO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkNBQTJDLFVBQVU7QUFDckQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanM/Mzc3MCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICB2YXIgaVxuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsodWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKSkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/base64-js/index.js\n"); /***/ }), /***/ "./node_modules/buffer/index.js": /*!**************************************!*\ !*** ./node_modules/buffer/index.js ***! \**************************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; eval("/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"./node_modules/base64-js/index.js\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"./node_modules/ieee754/index.js\")\nvar isArray = __webpack_require__(/*! isarray */ \"./node_modules/isarray/index.js\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = __webpack_require__.g.TYPED_ARRAY_SUPPORT !== undefined\n ? __webpack_require__.g.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVZOztBQUVaLGFBQWEsbUJBQU8sQ0FBQyxvREFBVztBQUNoQyxjQUFjLG1CQUFPLENBQUMsZ0RBQVM7QUFDL0IsY0FBYyxtQkFBTyxDQUFDLGdEQUFTOztBQUUvQixjQUFjO0FBQ2Qsa0JBQWtCO0FBQ2xCLHlCQUF5Qjs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIscUJBQU07QUFDbkMsSUFBSSxxQkFBTTtBQUNWOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG9EQUFvRDtBQUN6RTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFVBQVU7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFlBQVk7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQSx3Q0FBd0MsU0FBUztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJBQWlCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYyxpQkFBaUI7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFNBQVM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixTQUFTO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixTQUFTO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELEVBQUU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsa0JBQWtCLFNBQVM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLGVBQWU7QUFDeEM7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EseUJBQXlCLFFBQVE7QUFDakM7QUFDQSxzQkFBc0IsZUFBZTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsWUFBWTtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsc0JBQXNCLFNBQVM7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHNCQUFzQixTQUFTO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQixTQUFTO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixrQkFBa0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLG9CQUFvQixjQUFjO0FBQ2xDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3REFBd0QsT0FBTztBQUMvRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0RBQXdELE9BQU87QUFDL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CO0FBQ25CO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0JBQXNCLFFBQVE7QUFDOUI7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLGdCQUFnQixTQUFTO0FBQ3pCO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0IsWUFBWTtBQUM5Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWtCLFlBQVk7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzPzkwMWUiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQgIT09IHVuZGVmaW5lZFxuICA/IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gIDogdHlwZWRBcnJheVN1cHBvcnQoKVxuXG4vKlxuICogRXhwb3J0IGtNYXhMZW5ndGggYWZ0ZXIgdHlwZWQgYXJyYXkgc3VwcG9ydCBpcyBkZXRlcm1pbmVkLlxuICovXG5leHBvcnRzLmtNYXhMZW5ndGggPSBrTWF4TGVuZ3RoKClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7X19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9fVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChrTWF4TGVuZ3RoKCkgPCBsZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGgnKVxuICB9XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIGlmICh0aGF0ID09PSBudWxsKSB7XG4gICAgICB0aGF0ID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gICAgfVxuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLCBhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tICh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhhdCwgdmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20obnVsbCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IHRoYXQud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIHRoYXQgPSB0aGF0LnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKHRoYXQsIGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGgoKWAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChpc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmXG4gICAgICAgIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgKytpKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDQpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKGNvZGUgPCAyNTYpIHtcbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IHV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLCBlbmNvZGluZykudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gaXNuYW4gKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2YWwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/buffer/index.js\n"); /***/ }), /***/ "./node_modules/flyonui/flyonui.js": /*!*****************************************!*\ !*** ./node_modules/flyonui/flyonui.js ***! \*****************************************/ /***/ ((module) => { eval("!function(e,t){if(true)module.exports=t();else { var s, i; }}(self,(()=>(()=>{\"use strict\";var e={12:function(e,t,i){\n/*\n * HSCopyMarkup\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t){super(e,t),this.count=0;const i=e.getAttribute(\"data-copy-markup\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.targetSelector=(null==n?void 0:n.targetSelector)||null,this.wrapperSelector=(null==n?void 0:n.wrapperSelector)||null,this.limit=(null==n?void 0:n.limit)||null,this.items=[],this.targetSelector&&this.init()}elementClick(){this.copy()}deleteItemButtonClick(e){this.delete(e)}init(){this.createCollection(window.$hsCopyMarkupCollection,this),this.onElementClickListener=()=>this.elementClick(),this.setTarget(),this.setWrapper(),this.addPredefinedItems(),this.el.addEventListener(\"click\",this.onElementClickListener)}copy(){if(this.limit&&this.items.length>=this.limit)return!1;this.el.hasAttribute(\"disabled\")&&this.el.setAttribute(\"disabled\",\"\");const e=this.target.cloneNode(!0),t=`${this.target.id}-${this.count++}`;e.setAttribute(\"id\",t),this.addToItems(e),this.limit&&this.items.length>=this.limit&&this.el.setAttribute(\"disabled\",\"disabled\"),this.fireEvent(\"copy\",e),(0,n.dispatch)(\"copy.copyMarkup\",e,e)}addPredefinedItems(){Array.from(this.wrapper.children).filter((e=>!e.classList.contains(\"[--ignore-for-count]\"))).forEach((e=>{this.addToItems(e)})),this.limit&&this.items.length>=this.limit&&this.el.setAttribute(\"disabled\",\"disabled\")}setTarget(){const e=\"string\"==typeof this.targetSelector?document.querySelector(this.targetSelector).cloneNode(!0):this.targetSelector.cloneNode(!0);this.target=e}setWrapper(){this.wrapper=\"string\"==typeof this.wrapperSelector?document.querySelector(this.wrapperSelector):this.wrapperSelector}addToItems(e){const t=e.querySelector(\"[data-copy-markup-delete-item]\");this.wrapper?this.wrapper.append(e):this.el.before(e),t&&(this.onDeleteItemButtonClickListener=()=>this.deleteItemButtonClick(e),t.addEventListener(\"click\",this.onDeleteItemButtonClickListener)),this.items.push(e)}delete(e){if(e){const t=this.items.indexOf(e);-1!==t&&this.items.splice(t,1),e.remove(),this.fireEvent(\"delete\",e),(0,n.dispatch)(\"delete.copyMarkup\",e,e),this.limit&&this.items.lengthe.removeEventListener(\"click\",this.onDeleteItemButtonClickListener))),this.el.removeAttribute(\"disabled\"),this.target=null,this.wrapper=null,this.items=null,window.$hsCopyMarkupCollection=window.$hsCopyMarkupCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsCopyMarkupCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsCopyMarkupCollection||(window.$hsCopyMarkupCollection=[]),window.$hsCopyMarkupCollection&&(window.$hsCopyMarkupCollection=window.$hsCopyMarkupCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-copy-markup]:not(.--prevent-on-load-init)\").forEach((e=>{if(!window.$hsCopyMarkupCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))){const t=e.getAttribute(\"data-copy-markup\"),i=t?JSON.parse(t):{};new l(e,i)}}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSCopyMarkup=l),t.default=l},75:function(e,t,i){\n/*\n * HSComboBox\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(n,o){function l(e){try{a(s.next(e))}catch(e){o(e)}}function r(e){try{a(s.throw(e))}catch(e){o(e)}}function a(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(l,r)}a((s=s.apply(e,t||[])).next())}))},n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const o=i(806),l=n(i(287)),r=i(917);class a extends l.default{constructor(e,t,i){var s,n,o,l,r,a,c,d,h,u,p,m,g,f,v,w,y,b,C,S,L,I,E,T,x,k,A,O;super(e,t,i),this.isSearchLengthExceeded=!1;const P=e.getAttribute(\"data-combo-box\"),$=P?JSON.parse(P):{},B=Object.assign(Object.assign({},$),t);this.gap=6,this.viewport=null!==(s=\"string\"==typeof(null==B?void 0:B.viewport)?document.querySelector(null==B?void 0:B.viewport):null==B?void 0:B.viewport)&&void 0!==s?s:null,this.preventVisibility=null!==(n=null==B?void 0:B.preventVisibility)&&void 0!==n&&n,this.minSearchLength=null!==(o=null==B?void 0:B.minSearchLength)&&void 0!==o?o:0,this.apiUrl=null!==(l=null==B?void 0:B.apiUrl)&&void 0!==l?l:null,this.apiDataPart=null!==(r=null==B?void 0:B.apiDataPart)&&void 0!==r?r:null,this.apiQuery=null!==(a=null==B?void 0:B.apiQuery)&&void 0!==a?a:null,this.apiSearchQuery=null!==(c=null==B?void 0:B.apiSearchQuery)&&void 0!==c?c:null,this.apiSearchPath=null!==(d=null==B?void 0:B.apiSearchPath)&&void 0!==d?d:null,this.apiSearchDefaultPath=null!==(h=null==B?void 0:B.apiSearchDefaultPath)&&void 0!==h?h:null,this.apiHeaders=null!==(u=null==B?void 0:B.apiHeaders)&&void 0!==u?u:{},this.apiGroupField=null!==(p=null==B?void 0:B.apiGroupField)&&void 0!==p?p:null,this.outputItemTemplate=null!==(m=null==B?void 0:B.outputItemTemplate)&&void 0!==m?m:'
\\n\\t\\t\\t\\t
\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n \\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t
\\n\\t\\t\\t
',this.outputEmptyTemplate=null!==(g=null==B?void 0:B.outputEmptyTemplate)&&void 0!==g?g:'
Nothing found...
',this.outputLoaderTemplate=null!==(f=null==B?void 0:B.outputLoaderTemplate)&&void 0!==f?f:'',this.groupingType=null!==(v=null==B?void 0:B.groupingType)&&void 0!==v?v:null,this.groupingTitleTemplate=null!==(w=null==B?void 0:B.groupingTitleTemplate)&&void 0!==w?w:\"default\"===this.groupingType?'
':'',this.tabsWrapperTemplate=null!==(y=null==B?void 0:B.tabsWrapperTemplate)&&void 0!==y?y:'
',this.preventSelection=null!==(b=null==B?void 0:B.preventSelection)&&void 0!==b&&b,this.preventAutoPosition=null!==(C=null==B?void 0:B.preventAutoPosition)&&void 0!==C&&C,this.isOpenOnFocus=null!==(S=null==B?void 0:B.isOpenOnFocus)&&void 0!==S&&S,this.input=null!==(L=this.el.querySelector(\"[data-combo-box-input]\"))&&void 0!==L?L:null,this.output=null!==(I=this.el.querySelector(\"[data-combo-box-output]\"))&&void 0!==I?I:null,this.itemsWrapper=null!==(E=this.el.querySelector(\"[data-combo-box-output-items-wrapper]\"))&&void 0!==E?E:null,this.items=null!==(T=Array.from(this.el.querySelectorAll(\"[data-combo-box-output-item]\")))&&void 0!==T?T:[],this.tabs=[],this.toggle=null!==(x=this.el.querySelector(\"[data-combo-box-toggle]\"))&&void 0!==x?x:null,this.toggleClose=null!==(k=this.el.querySelector(\"[data-combo-box-close]\"))&&void 0!==k?k:null,this.toggleOpen=null!==(A=this.el.querySelector(\"[data-combo-box-open]\"))&&void 0!==A?A:null,this.outputPlaceholder=null,this.selected=this.value=null!==(O=this.el.querySelector(\"[data-combo-box-input]\").value)&&void 0!==O?O:\"\",this.currentData=null,this.isOpened=!1,this.isCurrent=!1,this.animationInProcess=!1,this.selectedGroup=\"all\",this.init()}inputFocus(){this.isOpened||(this.setResultAndRender(),this.open())}inputInput(e){const t=e.target.value.trim();t.length<=this.minSearchLength?this.setResultAndRender(\"\"):this.setResultAndRender(t),\"\"!==this.input.value?this.el.classList.add(\"has-value\"):this.el.classList.remove(\"has-value\"),this.isOpened||this.open()}toggleClick(){this.isOpened?this.close():this.open(this.toggle.getAttribute(\"data-combo-box-toggle\"))}toggleCloseClick(){this.close()}toggleOpenClick(){this.open()}init(){this.createCollection(window.$hsComboBoxCollection,this),this.build()}build(){this.buildInput(),this.groupingType&&this.setGroups(),this.buildItems(),this.preventVisibility&&(this.preventAutoPosition||this.recalculateDirection()),this.toggle&&this.buildToggle(),this.toggleClose&&this.buildToggleClose(),this.toggleOpen&&this.buildToggleOpen()}getNestedProperty(e,t){return t.split(\".\").reduce(((e,t)=>e&&e[t]),e)}setValue(e,t=null){this.selected=e,this.value=e,this.input.value=e,t&&(this.currentData=t),this.fireEvent(\"select\",this.currentData),(0,o.dispatch)(\"select.combobox\",this.el,this.currentData)}setValueAndOpen(e){this.value=e,this.items.length&&this.setItemsVisibility()}setValueAndClear(e,t=null){e?this.setValue(e,t):this.setValue(this.selected,t),this.outputPlaceholder&&this.destroyOutputPlaceholder()}setSelectedByValue(e){this.items.forEach((t=>{this.isTextExists(t,e)?t.classList.add(\"selected\"):t.classList.remove(\"selected\")}))}setResultAndRender(e=\"\"){let t=this.preventVisibility?this.input.value:e;this.setResults(t),(this.apiSearchQuery||this.apiSearchPath||this.apiSearchDefaultPath)&&this.itemsFromJson(),this.isSearchLengthExceeded=\"\"===t}setResults(e){this.value=e,this.resultItems(),this.hasVisibleItems()?this.destroyOutputPlaceholder():this.buildOutputPlaceholder()}setGroups(){const e=[];this.items.forEach((t=>{const{group:i}=JSON.parse(t.getAttribute(\"data-combo-box-output-item\"));e.some((e=>(null==e?void 0:e.name)===i.name))||e.push(i)})),this.groups=e}setApiGroups(e){const t=[];e.forEach((e=>{const i=e[this.apiGroupField];t.some((e=>e.name===i))||t.push({name:i,title:i})})),this.groups=t}setItemsVisibility(){\"tabs\"===this.groupingType&&\"all\"!==this.selectedGroup&&this.items.forEach((e=>{e.style.display=\"none\"}));const e=\"tabs\"===this.groupingType?\"all\"===this.selectedGroup?this.items:this.items.filter((e=>{const{group:t}=JSON.parse(e.getAttribute(\"data-combo-box-output-item\"));return t.name===this.selectedGroup})):this.items;\"tabs\"===this.groupingType&&\"all\"!==this.selectedGroup&&e.forEach((e=>{e.style.display=\"block\"})),e.forEach((e=>{this.isTextExistsAny(e,this.value)?e.style.display=\"block\":e.style.display=\"none\"})),\"default\"===this.groupingType&&this.output.querySelectorAll(\"[data-combo-box-group-title]\").forEach((e=>{const t=e.getAttribute(\"data-combo-box-group-title\");this.items.filter((e=>{const{group:i}=JSON.parse(e.getAttribute(\"data-combo-box-output-item\"));return i.name===t&&\"block\"===e.style.display})).length?e.style.display=\"block\":e.style.display=\"none\"}))}isTextExists(e,t){const i=t.map((e=>e.toLowerCase()));return Array.from(e.querySelectorAll(\"[data-combo-box-search-text]\")).some((e=>i.includes(e.getAttribute(\"data-combo-box-search-text\").toLowerCase())))}isTextExistsAny(e,t){return Array.from(e.querySelectorAll(\"[data-combo-box-search-text]\")).some((e=>e.getAttribute(\"data-combo-box-search-text\").toLowerCase().includes(t.toLowerCase())))}hasVisibleItems(){return!!this.items.length&&this.items.some((e=>\"block\"===e.style.display))}valuesBySelector(e){return Array.from(e.querySelectorAll(\"[data-combo-box-search-text]\")).reduce(((e,t)=>[...e,t.getAttribute(\"data-combo-box-search-text\")]),[])}sortItems(){return this.items.sort(((e,t)=>{const i=e.querySelector(\"[data-combo-box-value]\").getAttribute(\"data-combo-box-search-text\"),s=t.querySelector(\"[data-combo-box-value]\").getAttribute(\"data-combo-box-search-text\");return is?1:0}))}buildInput(){this.isOpenOnFocus&&(this.onInputFocusListener=()=>this.inputFocus(),this.input.addEventListener(\"focus\",this.onInputFocusListener)),this.onInputInputListener=(0,o.debounce)((e=>this.inputInput(e))),this.input.addEventListener(\"input\",this.onInputInputListener)}buildItems(){return s(this,void 0,void 0,(function*(){this.output.role=\"listbox\",this.output.tabIndex=-1,this.output.ariaOrientation=\"vertical\",this.apiUrl?yield this.itemsFromJson():(this.itemsWrapper?this.itemsWrapper.innerHTML=\"\":this.output.innerHTML=\"\",this.itemsFromHtml()),(null==this?void 0:this.items.length)&&this.items[0].classList.contains(\"selected\")&&(this.currentData=JSON.parse(this.items[0].getAttribute(\"data-combo-box-item-stored-data\")))}))}buildOutputLoader(){if(this.outputLoader)return!1;this.outputLoader=(0,o.htmlToElement)(this.outputLoaderTemplate),this.items.length||this.outputPlaceholder?(this.outputLoader.style.position=\"absolute\",this.outputLoader.style.top=\"0\",this.outputLoader.style.bottom=\"0\",this.outputLoader.style.left=\"0\",this.outputLoader.style.right=\"0\",this.outputLoader.style.zIndex=\"2\"):(this.outputLoader.style.position=\"\",this.outputLoader.style.top=\"\",this.outputLoader.style.bottom=\"\",this.outputLoader.style.left=\"\",this.outputLoader.style.right=\"\",this.outputLoader.style.zIndex=\"\",this.outputLoader.style.height=\"30px\"),this.output.append(this.outputLoader)}buildToggle(){var e,t,i,s;this.isOpened?((null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.toggle.ariaExpanded=\"true\"),(null===(t=null==this?void 0:this.input)||void 0===t?void 0:t.ariaExpanded)&&(this.input.ariaExpanded=\"true\")):((null===(i=null==this?void 0:this.toggle)||void 0===i?void 0:i.ariaExpanded)&&(this.toggle.ariaExpanded=\"false\"),(null===(s=null==this?void 0:this.input)||void 0===s?void 0:s.ariaExpanded)&&(this.input.ariaExpanded=\"false\")),this.onToggleClickListener=()=>this.toggleClick(),this.toggle.addEventListener(\"click\",this.onToggleClickListener)}buildToggleClose(){this.onToggleCloseClickListener=()=>this.toggleCloseClick(),this.toggleClose.addEventListener(\"click\",this.onToggleCloseClickListener)}buildToggleOpen(){this.onToggleOpenClickListener=()=>this.toggleOpenClick(),this.toggleOpen.addEventListener(\"click\",this.onToggleOpenClickListener)}buildOutputPlaceholder(){this.outputPlaceholder||(this.outputPlaceholder=(0,o.htmlToElement)(this.outputEmptyTemplate)),this.appendItemsToWrapper(this.outputPlaceholder)}destroyOutputLoader(){this.outputLoader&&this.outputLoader.remove(),this.outputLoader=null}itemRender(e){var t;const i=e.querySelector(\"[data-combo-box-value]\").getAttribute(\"data-combo-box-search-text\"),s=null!==(t=JSON.parse(e.getAttribute(\"data-combo-box-item-stored-data\")))&&void 0!==t?t:null;this.itemsWrapper?this.itemsWrapper.append(e):this.output.append(e),this.preventSelection||e.addEventListener(\"click\",(()=>{this.close(i,s),this.setSelectedByValue(this.valuesBySelector(e))}))}plainRender(e){e.forEach((e=>{this.itemRender(e)}))}jsonItemsRender(e){e.forEach(((e,t)=>{const i=(0,o.htmlToElement)(this.outputItemTemplate);i.setAttribute(\"data-combo-box-item-stored-data\",JSON.stringify(e)),i.querySelectorAll(\"[data-combo-box-output-item-field]\").forEach((t=>{const i=this.getNestedProperty(e,t.getAttribute(\"data-combo-box-output-item-field\")),s=t.hasAttribute(\"data-combo-box-output-item-hide-if-empty\");t.textContent=null!=i?i:\"\",!i&&s&&(t.style.display=\"none\")})),i.querySelectorAll(\"[data-combo-box-search-text]\").forEach((t=>{const i=this.getNestedProperty(e,t.getAttribute(\"data-combo-box-output-item-field\"));t.setAttribute(\"data-combo-box-search-text\",null!=i?i:\"\")})),i.querySelectorAll(\"[data-combo-box-output-item-attr]\").forEach((t=>{JSON.parse(t.getAttribute(\"data-combo-box-output-item-attr\")).forEach((i=>{t.setAttribute(i.attr,e[i.valueFrom])}))})),i.setAttribute(\"tabIndex\",`${t}`),\"tabs\"!==this.groupingType&&\"default\"!==this.groupingType||i.setAttribute(\"data-combo-box-output-item\",`{\"group\": {\"name\": \"${e[this.apiGroupField]}\", \"title\": \"${e[this.apiGroupField]}\"}}`),this.items=[...this.items,i],this.preventSelection||i.addEventListener(\"click\",(()=>{this.close(i.querySelector(\"[data-combo-box-value]\").getAttribute(\"data-combo-box-search-text\"),JSON.parse(i.getAttribute(\"data-combo-box-item-stored-data\"))),this.setSelectedByValue(this.valuesBySelector(i))})),this.appendItemsToWrapper(i)}))}groupDefaultRender(){this.groups.forEach((e=>{const t=(0,o.htmlToElement)(this.groupingTitleTemplate);t.setAttribute(\"data-combo-box-group-title\",e.name),t.classList.add(\"--exclude-accessibility\"),t.innerText=e.title,this.itemsWrapper?this.itemsWrapper.append(t):this.output.append(t);const i=this.sortItems().filter((t=>{const{group:i}=JSON.parse(t.getAttribute(\"data-combo-box-output-item\"));return i.name===e.name}));this.plainRender(i)}))}groupTabsRender(){const e=(0,o.htmlToElement)(this.tabsWrapperTemplate),t=(0,o.htmlToElement)('
');e.append(t),this.output.insertBefore(e,this.output.firstChild);const i=(0,o.htmlToElement)(this.groupingTitleTemplate);i.setAttribute(\"data-combo-box-group-title\",\"all\"),i.classList.add(\"--exclude-accessibility\",\"active\"),i.innerText=\"All\",this.tabs=[...this.tabs,i],t.append(i),i.addEventListener(\"click\",(()=>{this.selectedGroup=\"all\";const e=this.tabs.find((e=>e.getAttribute(\"data-combo-box-group-title\")===this.selectedGroup));this.tabs.forEach((e=>e.classList.remove(\"active\"))),e.classList.add(\"active\"),this.setItemsVisibility()})),this.groups.forEach((e=>{const i=(0,o.htmlToElement)(this.groupingTitleTemplate);i.setAttribute(\"data-combo-box-group-title\",e.name),i.classList.add(\"--exclude-accessibility\"),i.innerText=e.title,this.tabs=[...this.tabs,i],t.append(i),i.addEventListener(\"click\",(()=>{this.selectedGroup=e.name;const t=this.tabs.find((e=>e.getAttribute(\"data-combo-box-group-title\")===this.selectedGroup));this.tabs.forEach((e=>e.classList.remove(\"active\"))),t.classList.add(\"active\"),this.setItemsVisibility()}))}))}itemsFromHtml(){if(\"default\"===this.groupingType)this.groupDefaultRender();else if(\"tabs\"===this.groupingType){const e=this.sortItems();this.groupTabsRender(),this.plainRender(e)}else{const e=this.sortItems();this.plainRender(e)}this.setResults(this.input.value)}itemsFromJson(){return s(this,void 0,void 0,(function*(){if(this.isSearchLengthExceeded)return!1;this.buildOutputLoader();try{const e=`${this.apiQuery}`;let t,i,s=this.apiUrl;!this.apiSearchQuery&&this.apiSearchPath?(i=this.apiSearchDefaultPath&&\"\"===this.value?`/${this.apiSearchDefaultPath}`:`/${this.apiSearchPath}/${this.value.toLowerCase()}`,(this.apiSearchPath||this.apiSearchDefaultPath)&&(s+=i)):(t=`${this.apiSearchQuery}=${this.value.toLowerCase()}`,this.apiQuery&&this.apiSearchQuery?s+=`?${t}&${e}`:this.apiQuery?s+=`?${e}`:this.apiSearchQuery&&(s+=`?${t}`));const n=yield fetch(s,this.apiHeaders);let l=yield n.json();this.apiDataPart&&(l=l[this.apiDataPart]),(this.apiSearchQuery||this.apiSearchPath)&&(this.items=[]),this.itemsWrapper?this.itemsWrapper.innerHTML=\"\":this.output.innerHTML=\"\",\"tabs\"===this.groupingType?(this.setApiGroups(l),this.groupTabsRender(),this.jsonItemsRender(l)):\"default\"===this.groupingType?(this.setApiGroups(l),this.groups.forEach((e=>{const t=(0,o.htmlToElement)(this.groupingTitleTemplate);t.setAttribute(\"data-combo-box-group-title\",e.name),t.classList.add(\"--exclude-accessibility\"),t.innerText=e.title;const i=l.filter((t=>t[this.apiGroupField]===e.name));this.itemsWrapper?this.itemsWrapper.append(t):this.output.append(t),this.jsonItemsRender(i)}))):this.jsonItemsRender(l),this.setResults(this.input.value.length<=this.minSearchLength?\"\":this.input.value)}catch(e){console.error(e),this.buildOutputPlaceholder()}this.destroyOutputLoader()}))}appendItemsToWrapper(e){this.itemsWrapper?this.itemsWrapper.append(e):this.output.append(e)}resultItems(){if(!this.items.length)return!1;this.setItemsVisibility(),this.setSelectedByValue([this.selected])}destroyOutputPlaceholder(){this.outputPlaceholder&&this.outputPlaceholder.remove(),this.outputPlaceholder=null}getCurrentData(){return this.currentData}setCurrent(){window.$hsComboBoxCollection.length&&(window.$hsComboBoxCollection.map((e=>e.element.isCurrent=!1)),this.isCurrent=!0)}open(e){return!this.animationInProcess&&(void 0!==e&&this.setValueAndOpen(e),!this.preventVisibility&&(this.animationInProcess=!0,this.output.style.display=\"block\",this.preventAutoPosition||this.recalculateDirection(),setTimeout((()=>{var e,t;(null===(e=null==this?void 0:this.input)||void 0===e?void 0:e.ariaExpanded)&&(this.input.ariaExpanded=\"true\"),(null===(t=null==this?void 0:this.toggle)||void 0===t?void 0:t.ariaExpanded)&&(this.toggle.ariaExpanded=\"true\"),this.el.classList.add(\"active\"),this.animationInProcess=!1})),void(this.isOpened=!0)))}close(e,t=null){var i,s;return!this.animationInProcess&&(this.preventVisibility?(this.setValueAndClear(e,t),\"\"!==this.input.value?this.el.classList.add(\"has-value\"):this.el.classList.remove(\"has-value\"),!1):(this.animationInProcess=!0,(null===(i=null==this?void 0:this.input)||void 0===i?void 0:i.ariaExpanded)&&(this.input.ariaExpanded=\"false\"),(null===(s=null==this?void 0:this.toggle)||void 0===s?void 0:s.ariaExpanded)&&(this.toggle.ariaExpanded=\"false\"),this.el.classList.remove(\"active\"),this.preventAutoPosition||(this.output.classList.remove(\"bottom-full\",\"top-full\"),this.output.style.marginTop=\"\",this.output.style.marginBottom=\"\"),(0,o.afterTransition)(this.output,(()=>{this.output.style.display=\"none\",this.setValueAndClear(e,t||null),this.animationInProcess=!1})),\"\"!==this.input.value?this.el.classList.add(\"has-value\"):this.el.classList.remove(\"has-value\"),void(this.isOpened=!1)))}recalculateDirection(){(0,o.isEnoughSpace)(this.output,this.input,\"bottom\",this.gap,this.viewport)?(this.output.classList.remove(\"bottom-full\"),this.output.style.marginBottom=\"\",this.output.classList.add(\"top-full\"),this.output.style.marginTop=`${this.gap}px`):(this.output.classList.remove(\"top-full\"),this.output.style.marginTop=\"\",this.output.classList.add(\"bottom-full\"),this.output.style.marginBottom=`${this.gap}px`)}destroy(){this.input.removeEventListener(\"focus\",this.onInputFocusListener),this.input.removeEventListener(\"input\",this.onInputInputListener),this.toggle.removeEventListener(\"click\",this.onToggleClickListener),this.toggleClose&&this.toggleClose.removeEventListener(\"click\",this.onToggleCloseClickListener),this.toggleOpen&&this.toggleOpen.removeEventListener(\"click\",this.onToggleOpenClickListener),this.el.classList.remove(\"has-value\",\"active\"),this.items.length&&this.items.forEach((e=>{e.classList.remove(\"selected\"),e.style.display=\"\"})),this.output.removeAttribute(\"role\"),this.output.removeAttribute(\"tabindex\"),this.output.removeAttribute(\"aria-orientation\"),this.outputLoader&&(this.outputLoader.remove(),this.outputLoader=null),this.outputPlaceholder&&(this.outputPlaceholder.remove(),this.outputPlaceholder=null),this.apiUrl&&(this.output.innerHTML=\"\"),this.items=[],window.$hsComboBoxCollection=window.$hsComboBoxCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsComboBoxCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsComboBoxCollection||(window.$hsComboBoxCollection=[],window.addEventListener(\"click\",(e=>{const t=e.target;a.closeCurrentlyOpened(t)})),document.addEventListener(\"keydown\",(e=>a.accessibility(e)))),window.$hsComboBoxCollection&&(window.$hsComboBoxCollection=window.$hsComboBoxCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-combo-box]:not(.--prevent-on-load-init)\").forEach((e=>{if(!window.$hsComboBoxCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))){const t=e.getAttribute(\"data-combo-box\"),i=t?JSON.parse(t):{};new a(e,i)}}))}static close(e){const t=window.$hsComboBoxCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));t&&t.element.isOpened&&t.element.close()}static closeCurrentlyOpened(e=null){if(!e.closest(\"[data-combo-box].active\")){const e=window.$hsComboBoxCollection.filter((e=>e.element.isOpened))||null;e&&e.forEach((e=>{e.element.close()}))}}static getPreparedItems(e=!1,t){if(!t)return null;return(e?Array.from(t.querySelectorAll(\":scope > *:not(.--exclude-accessibility)\")).filter((e=>\"none\"!==e.style.display)).reverse():Array.from(t.querySelectorAll(\":scope > *:not(.--exclude-accessibility)\")).filter((e=>\"none\"!==e.style.display))).filter((e=>!e.classList.contains(\"disabled\")))}static setHighlighted(e,t,i){t.focus(),i.value=t.querySelector(\"[data-combo-box-value]\").getAttribute(\"data-combo-box-search-text\"),e&&e.classList.remove(\"combo-box-output-item-highlighted\"),t.classList.add(\"combo-box-output-item-highlighted\")}static accessibility(e){if(window.$hsComboBoxCollection.find((e=>e.element.preventVisibility?e.element.isCurrent:e.element.isOpened))&&r.COMBO_BOX_ACCESSIBILITY_KEY_SET.includes(e.code)&&!e.metaKey)switch(e.code){case\"Escape\":e.preventDefault(),this.onEscape();break;case\"ArrowUp\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrow();break;case\"ArrowDown\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrow(!1);break;case\"Home\":e.preventDefault(),e.stopImmediatePropagation(),this.onStartEnd();break;case\"End\":e.preventDefault(),e.stopImmediatePropagation(),this.onStartEnd(!1);break;case\"Enter\":e.preventDefault(),this.onEnter(e)}}static onEscape(){const e=window.$hsComboBoxCollection.find((e=>!e.element.preventVisibility&&e.element.isOpened));e&&(e.element.close(),e.element.input.blur())}static onArrow(e=!0){var t;const i=window.$hsComboBoxCollection.find((e=>e.element.preventVisibility?e.element.isCurrent:e.element.isOpened));if(i){const s=null!==(t=i.element.itemsWrapper)&&void 0!==t?t:i.element.output;if(!s)return!1;const n=a.getPreparedItems(e,s),o=s.querySelector(\".combo-box-output-item-highlighted\");let l=null;o||n[0].classList.add(\"combo-box-output-item-highlighted\");let r=n.findIndex((e=>e===o));r+1e.element.preventVisibility?e.element.isCurrent:e.element.isOpened));if(i){const s=null!==(t=i.element.itemsWrapper)&&void 0!==t?t:i.element.output;if(!s)return!1;const n=a.getPreparedItems(e,s),o=s.querySelector(\".combo-box-output-item-highlighted\");n.length&&a.setHighlighted(o,n[0],i.element.input)}}static onEnter(e){var t;const i=e.target,s=window.$hsComboBoxCollection.find((t=>!(0,o.isParentOrElementHidden)(t.element.el)&&e.target.closest(\"[data-combo-box]\")===t.element.el)),n=s.element.el.querySelector(\".combo-box-output-item-highlighted a\");i.hasAttribute(\"data-combo-box-input\")?(s.element.close(),i.blur()):(s.element.preventSelection||s.element.setSelectedByValue(s.element.valuesBySelector(e.target)),s.element.preventSelection&&n&&window.location.assign(n.getAttribute(\"href\")),s.element.close(s.element.preventSelection?null:e.target.querySelector(\"[data-combo-box-value]\").getAttribute(\"data-combo-box-search-text\"),null!==(t=JSON.parse(e.target.getAttribute(\"data-combo-box-item-stored-data\")))&&void 0!==t?t:null))}}window.addEventListener(\"load\",(()=>{a.autoInit()})),document.addEventListener(\"scroll\",(()=>{if(!window.$hsComboBoxCollection)return!1;const e=window.$hsComboBoxCollection.find((e=>e.element.isOpened));e&&!e.element.preventAutoPosition&&e.element.recalculateDirection()})),\"undefined\"!=typeof window&&(window.HSComboBox=a),t.default=a},86:function(e,t,i){\n/*\n * HSInputNumber\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t){super(e,t),this.input=this.el.querySelector(\"[data-input-number-input]\")||null,this.increment=this.el.querySelector(\"[data-input-number-increment]\")||null,this.decrement=this.el.querySelector(\"[data-input-number-decrement]\")||null,this.input&&this.checkIsNumberAndConvert();const i=this.el.dataset.inputNumber,s=i?JSON.parse(i):{step:1},n=Object.assign(Object.assign({},s),t);this.minInputValue=\"min\"in n?n.min:0,this.maxInputValue=\"max\"in n?n.max:null,this.step=\"step\"in n&&n.step>0?n.step:1,this.init()}inputInput(){this.changeValue()}incrementClick(){this.changeValue(\"increment\")}decrementClick(){this.changeValue(\"decrement\")}init(){this.createCollection(window.$hsInputNumberCollection,this),this.input&&this.increment&&this.build()}checkIsNumberAndConvert(){const e=this.input.value.trim(),t=this.cleanAndExtractNumber(e);null!==t?(this.inputValue=t,this.input.value=t.toString()):(this.inputValue=0,this.input.value=\"0\")}cleanAndExtractNumber(e){const t=[];let i=!1;e.split(\"\").forEach((e=>{e>=\"0\"&&e<=\"9\"?t.push(e):\".\"!==e||i||(t.push(e),i=!0)}));const s=t.join(\"\"),n=parseFloat(s);return isNaN(n)?null:n}build(){this.input&&this.buildInput(),this.increment&&this.buildIncrement(),this.decrement&&this.buildDecrement(),this.inputValue<=this.minInputValue&&(this.inputValue=this.minInputValue,this.input.value=`${this.minInputValue}`),this.inputValue<=this.minInputValue&&this.changeValue(),this.input.hasAttribute(\"disabled\")&&this.disableButtons()}buildInput(){this.onInputInputListener=()=>this.inputInput(),this.input.addEventListener(\"input\",this.onInputInputListener)}buildIncrement(){this.onIncrementClickListener=()=>this.incrementClick(),this.increment.addEventListener(\"click\",this.onIncrementClickListener)}buildDecrement(){this.onDecrementClickListener=()=>this.decrementClick(),this.decrement.addEventListener(\"click\",this.onDecrementClickListener)}changeValue(e=\"none\"){var t,i;const s={inputValue:this.inputValue},o=null!==(t=this.minInputValue)&&void 0!==t?t:Number.MIN_SAFE_INTEGER,l=null!==(i=this.maxInputValue)&&void 0!==i?i:Number.MAX_SAFE_INTEGER;switch(this.inputValue=isNaN(this.inputValue)?0:this.inputValue,e){case\"increment\":const e=this.inputValue+this.step;this.inputValue=e>=o&&e<=l?e:l,this.input.value=this.inputValue.toString();break;case\"decrement\":const t=this.inputValue-this.step;this.inputValue=t>=o&&t<=l?t:o,this.input.value=this.inputValue.toString();break;default:const i=isNaN(parseInt(this.input.value))?0:parseInt(this.input.value);this.inputValue=i>=l?l:i<=o?o:i,this.inputValue<=o&&(this.input.value=this.inputValue.toString())}s.inputValue=this.inputValue,this.inputValue===o?(this.el.classList.add(\"disabled\"),this.decrement&&this.disableButtons(\"decrement\")):(this.el.classList.remove(\"disabled\"),this.decrement&&this.enableButtons(\"decrement\")),this.inputValue===l?(this.el.classList.add(\"disabled\"),this.increment&&this.disableButtons(\"increment\")):(this.el.classList.remove(\"disabled\"),this.increment&&this.enableButtons(\"increment\")),this.fireEvent(\"change\",s),(0,n.dispatch)(\"change.inputNumber\",this.el,s)}disableButtons(e=\"all\"){\"all\"===e?(\"BUTTON\"!==this.increment.tagName&&\"INPUT\"!==this.increment.tagName||this.increment.setAttribute(\"disabled\",\"disabled\"),\"BUTTON\"!==this.decrement.tagName&&\"INPUT\"!==this.decrement.tagName||this.decrement.setAttribute(\"disabled\",\"disabled\")):\"increment\"===e?\"BUTTON\"!==this.increment.tagName&&\"INPUT\"!==this.increment.tagName||this.increment.setAttribute(\"disabled\",\"disabled\"):\"decrement\"===e&&(\"BUTTON\"!==this.decrement.tagName&&\"INPUT\"!==this.decrement.tagName||this.decrement.setAttribute(\"disabled\",\"disabled\"))}enableButtons(e=\"all\"){\"all\"===e?(\"BUTTON\"!==this.increment.tagName&&\"INPUT\"!==this.increment.tagName||this.increment.removeAttribute(\"disabled\"),\"BUTTON\"!==this.decrement.tagName&&\"INPUT\"!==this.decrement.tagName||this.decrement.removeAttribute(\"disabled\")):\"increment\"===e?\"BUTTON\"!==this.increment.tagName&&\"INPUT\"!==this.increment.tagName||this.increment.removeAttribute(\"disabled\"):\"decrement\"===e&&(\"BUTTON\"!==this.decrement.tagName&&\"INPUT\"!==this.decrement.tagName||this.decrement.removeAttribute(\"disabled\"))}destroy(){this.el.classList.remove(\"disabled\"),this.increment.removeAttribute(\"disabled\"),this.decrement.removeAttribute(\"disabled\"),this.input.removeEventListener(\"input\",this.onInputInputListener),this.increment.removeEventListener(\"click\",this.onIncrementClickListener),this.decrement.removeEventListener(\"click\",this.onDecrementClickListener),window.$hsInputNumberCollection=window.$hsInputNumberCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsInputNumberCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsInputNumberCollection||(window.$hsInputNumberCollection=[]),window.$hsInputNumberCollection&&(window.$hsInputNumberCollection=window.$hsInputNumberCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-input-number]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsInputNumberCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSInputNumber=l),t.default=l},113:function(e,t,i){\n/*\n * HSRemoveElement\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t){super(e,t);const i=e.getAttribute(\"data-remove-element-options\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.removeTargetId=this.el.getAttribute(\"data-remove-element\"),this.removeTarget=document.querySelector(this.removeTargetId),this.removeTargetAnimationClass=(null==n?void 0:n.removeTargetAnimationClass)||\"removing\",this.removeTarget&&this.init()}elementClick(){this.remove()}init(){this.createCollection(window.$hsRemoveElementCollection,this),this.onElementClickListener=()=>this.elementClick(),this.el.addEventListener(\"click\",this.onElementClickListener)}remove(){if(!this.removeTarget)return!1;this.removeTarget.classList.add(this.removeTargetAnimationClass),(0,n.afterTransition)(this.removeTarget,(()=>setTimeout((()=>this.removeTarget.remove()))))}destroy(){this.removeTarget.classList.remove(this.removeTargetAnimationClass),this.el.removeEventListener(\"click\",this.onElementClickListener),window.$hsRemoveElementCollection=window.$hsRemoveElementCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsRemoveElementCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)||t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsRemoveElementCollection||(window.$hsRemoveElementCollection=[]),window.$hsRemoveElementCollection&&(window.$hsRemoveElementCollection=window.$hsRemoveElementCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-remove-element]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsRemoveElementCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSRemoveElement=l),t.default=l},126:function(e,t,i){\n/*\n * HSToggleCount\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=s(i(287));class o extends n.default{constructor(e,t){super(e,t);const i=e.getAttribute(\"data-toggle-count\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.target=(null==n?void 0:n.target)?\"string\"==typeof(null==n?void 0:n.target)?document.querySelector(n.target):n.target:null,this.min=(null==n?void 0:n.min)||0,this.max=(null==n?void 0:n.max)||0,this.duration=(null==n?void 0:n.duration)||700,this.isChecked=this.target.checked||!1,this.target&&this.init()}toggleChange(){this.isChecked=!this.isChecked,this.toggle()}init(){this.createCollection(window.$hsToggleCountCollection,this),this.isChecked&&(this.el.innerText=String(this.max)),this.onToggleChangeListener=()=>this.toggleChange(),this.target.addEventListener(\"change\",this.onToggleChangeListener)}toggle(){this.isChecked?this.countUp():this.countDown()}animate(e,t){let i=0;const s=n=>{i||(i=n);const o=Math.min((n-i)/this.duration,1);this.el.innerText=String(Math.floor(o*(t-e)+e)),o<1&&window.requestAnimationFrame(s)};window.requestAnimationFrame(s)}countUp(){this.animate(this.min,this.max)}countDown(){this.animate(this.max,this.min)}destroy(){this.target.removeEventListener(\"change\",this.onToggleChangeListener),window.$hsToggleCountCollection=window.$hsToggleCountCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsToggleCountCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsToggleCountCollection||(window.$hsToggleCountCollection=[]),window.$hsToggleCountCollection&&(window.$hsToggleCountCollection=window.$hsToggleCountCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-toggle-count]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsToggleCountCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new o(e)}))}}window.addEventListener(\"load\",(()=>{o.autoInit()})),\"undefined\"!=typeof window&&(window.HSToggleCount=o),t.default=o},164:function(e,t,i){\n/*\n * HSOverlay\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=i(917),l=s(i(287));class r extends l.default{constructor(e,t,i){var s,l,r,a,c,d;super(e,t,i),this.initialZIndex=0,this.toggleButtons=Array.from(document.querySelectorAll(`[data-overlay=\"#${this.el.id}\"]`));const h=this.collectToggleParameters(this.toggleButtons),u=e.getAttribute(\"data-overlay-options\"),p=u?JSON.parse(u):{},m=Object.assign(Object.assign(Object.assign({},p),h),t);this.hiddenClass=(null==m?void 0:m.hiddenClass)||\"hidden\",this.emulateScrollbarSpace=(null==m?void 0:m.emulateScrollbarSpace)||!1,this.isClosePrev=null===(s=null==m?void 0:m.isClosePrev)||void 0===s||s,this.backdropClasses=null!==(l=null==m?void 0:m.backdropClasses)&&void 0!==l?l:\"overlay-backdrop transition duration-300 fixed inset-0 bg-base-300/60 overflow-y-auto\",this.backdropParent=\"string\"==typeof m.backdropParent?document.querySelector(m.backdropParent):document.body,this.backdropExtraClasses=null!==(r=null==m?void 0:m.backdropExtraClasses)&&void 0!==r?r:\"\",this.moveOverlayToBody=(null==m?void 0:m.moveOverlayToBody)||null,this.openNextOverlay=!1,this.autoHide=null,this.initContainer=(null===(a=this.el)||void 0===a?void 0:a.parentElement)||null,this.isCloseWhenClickInside=(0,n.stringToBoolean)((0,n.getClassProperty)(this.el,\"--close-when-click-inside\",\"false\")||\"false\"),this.isTabAccessibilityLimited=(0,n.stringToBoolean)((0,n.getClassProperty)(this.el,\"--tab-accessibility-limited\",\"true\")||\"true\"),this.isLayoutAffect=(0,n.stringToBoolean)((0,n.getClassProperty)(this.el,\"--is-layout-affect\",\"false\")||\"false\"),this.hasAutofocus=(0,n.stringToBoolean)((0,n.getClassProperty)(this.el,\"--has-autofocus\",\"true\")||\"true\"),this.hasDynamicZIndex=(0,n.stringToBoolean)((0,n.getClassProperty)(this.el,\"--has-dynamic-z-index\",\"false\")||\"false\"),this.hasAbilityToCloseOnBackdropClick=(0,n.stringToBoolean)(this.el.getAttribute(\"data-overlay-keyboard\")||\"true\");const g=(0,n.getClassProperty)(this.el,\"--auto-close\"),f=(0,n.getClassProperty)(this.el,\"--auto-close-equality-type\"),v=(0,n.getClassProperty)(this.el,\"--opened\");this.autoClose=!isNaN(+g)&&isFinite(+g)?+g:o.BREAKPOINTS[g]||null,this.autoCloseEqualityType=null!==(c=f)&&void 0!==c?c:null,this.openedBreakpoint=(!isNaN(+v)&&isFinite(+v)?+v:o.BREAKPOINTS[v])||null,this.animationTarget=(null===(d=null==this?void 0:this.el)||void 0===d?void 0:d.querySelector(\".overlay-animation-target\"))||this.el,this.initialZIndex=parseInt(getComputedStyle(this.el).zIndex,10),this.onElementClickListener=[],this.init()}elementClick(){const e=()=>{const e={el:this.el,isOpened:!!this.el.classList.contains(\"open\")};this.fireEvent(\"toggleClicked\",e),(0,n.dispatch)(\"toggleClicked.overlay\",this.el,e)};this.el.classList.contains(\"opened\")?this.close(!1,e):this.open(e)}overlayClick(e){e.target.id&&`#${e.target.id}`===this.el.id&&this.isCloseWhenClickInside&&this.hasAbilityToCloseOnBackdropClick&&this.close()}backdropClick(){this.close()}init(){if(this.createCollection(window.$hsOverlayCollection,this),this.isLayoutAffect&&this.openedBreakpoint){const e=r.getInstance(this.el,!0);r.setOpened(this.openedBreakpoint,e)}this.onOverlayClickListener=e=>this.overlayClick(e),this.el.addEventListener(\"click\",this.onOverlayClickListener),this.toggleButtons.length&&this.buildToggleButtons()}getElementsByZIndex(){return window.$hsOverlayCollection.filter((e=>e.element.initialZIndex===this.initialZIndex))}buildToggleButtons(){this.toggleButtons.forEach((e=>{this.el.classList.contains(\"opened\")?e.ariaExpanded=\"true\":e.ariaExpanded=\"false\",this.onElementClickListener.push({el:e,fn:()=>this.elementClick()}),e.addEventListener(\"click\",this.onElementClickListener.find((t=>t.el===e)).fn)}))}hideAuto(){const e=parseInt((0,n.getClassProperty)(this.el,\"--auto-hide\",\"0\"));e&&(this.autoHide=setTimeout((()=>{this.close()}),e))}checkTimer(){this.autoHide&&(clearTimeout(this.autoHide),this.autoHide=null)}buildBackdrop(){const e=this.el.classList.value.split(\" \"),t=parseInt(window.getComputedStyle(this.el).getPropertyValue(\"z-index\")),i=this.el.getAttribute(\"data-overlay-backdrop-container\")||!1;this.backdrop=document.createElement(\"div\");let s=`${this.backdropClasses} ${this.backdropExtraClasses}`;const o=\"static\"!==(0,n.getClassProperty)(this.el,\"--overlay-backdrop\",\"true\"),l=\"false\"===(0,n.getClassProperty)(this.el,\"--overlay-backdrop\",\"true\");this.backdrop.id=`${this.el.id}-backdrop`,\"style\"in this.backdrop&&(this.backdrop.style.zIndex=\"\"+(t-1));for(const t of e)(t.startsWith(\"overlay-backdrop-open:\")||t.includes(\":overlay-backdrop-open:\"))&&(s+=` ${t}`);l||(i&&(this.backdrop=document.querySelector(i).cloneNode(!0),this.backdrop.classList.remove(\"hidden\"),s=`${this.backdrop.classList.toString()}`,this.backdrop.classList.value=\"\"),o&&(this.onBackdropClickListener=()=>this.backdropClick(),this.backdrop.addEventListener(\"click\",this.onBackdropClickListener,!0)),this.backdrop.setAttribute(\"data-overlay-backdrop-template\",\"\"),this.backdropParent.appendChild(this.backdrop),setTimeout((()=>{this.backdrop.classList.value=s})))}destroyBackdrop(){const e=document.querySelector(`#${this.el.id}-backdrop`);e&&(this.openNextOverlay&&(e.style.transitionDuration=1.8*parseFloat(window.getComputedStyle(e).transitionDuration.replace(/[^\\d.-]/g,\"\"))+\"s\"),e.classList.add(\"opacity-0\"),(0,n.afterTransition)(e,(()=>{e.remove()})))}focusElement(){const e=this.el.querySelector(\"[autofocus]\");if(!e)return!1;e.focus()}getScrollbarSize(){let e=document.createElement(\"div\");e.style.overflow=\"scroll\",e.style.width=\"100px\",e.style.height=\"100px\",document.body.appendChild(e);let t=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),t}collectToggleParameters(e){let t={};return e.forEach((e=>{const i=e.getAttribute(\"data-overlay-options\"),s=i?JSON.parse(i):{};t=Object.assign(Object.assign({},t),s)})),t}open(e=null){this.hasDynamicZIndex&&(r.currentZIndexArray.from(t).includes(e.element.el)&&!e.element.isLayoutAffect)),s=document.querySelectorAll(`[data-overlay=\"#${this.el.id}\"]`),o=\"true\"!==(0,n.getClassProperty)(this.el,\"--body-scroll\",\"false\");if(this.isClosePrev&&i)return this.openNextOverlay=!0,i.element.close().then((()=>{this.open(),this.openNextOverlay=!1}));o&&(document.body.style.overflow=\"hidden\",this.emulateScrollbarSpace&&(document.body.style.paddingRight=`${this.getScrollbarSize()}px`)),this.buildBackdrop(),this.checkTimer(),this.hideAuto(),s.forEach((e=>{e.ariaExpanded&&(e.ariaExpanded=\"true\")})),this.el.classList.remove(this.hiddenClass),this.el.setAttribute(\"aria-overlay\",\"true\"),this.el.setAttribute(\"tabindex\",\"-1\"),setTimeout((()=>{if(this.el.classList.contains(\"opened\"))return!1;this.el.classList.add(\"open\",\"opened\"),this.isLayoutAffect&&document.body.classList.add(\"overlay-body-open\"),this.fireEvent(\"open\",this.el),(0,n.dispatch)(\"open.overlay\",this.el,this.el),this.hasAutofocus&&this.focusElement(),\"function\"==typeof e&&e(),r.openedItemsQty++}),50)}close(e=!1,t=null){r.openedItemsQty=r.openedItemsQty<=0?0:r.openedItemsQty-1,0===r.openedItemsQty&&this.isLayoutAffect&&document.body.classList.remove(\"overlay-body-open\");const i=e=>{if(this.el.classList.contains(\"open\"))return!1;document.querySelectorAll(`[data-overlay=\"#${this.el.id}\"]`).forEach((e=>{e.ariaExpanded&&(e.ariaExpanded=\"false\")})),this.el.classList.add(this.hiddenClass),this.hasDynamicZIndex&&(this.el.style.zIndex=\"\"),this.destroyBackdrop(),this.fireEvent(\"close\",this.el),(0,n.dispatch)(\"close.overlay\",this.el,this.el),document.querySelector(\".overlay.opened\")||(document.body.style.overflow=\"\",this.emulateScrollbarSpace&&(document.body.style.paddingRight=\"\")),e(this.el),\"function\"==typeof t&&t(),0===r.openedItemsQty&&(document.body.classList.remove(\"overlay-body-open\"),this.hasDynamicZIndex&&(r.currentZIndex=0))};return new Promise((t=>{this.el.classList.remove(\"open\",\"opened\"),this.el.removeAttribute(\"aria-overlay\"),this.el.removeAttribute(\"tabindex\"),e?i(t):(0,n.afterTransition)(this.animationTarget,(()=>i(t)))}))}destroy(){this.el.classList.remove(\"open\",\"opened\",this.hiddenClass),this.isLayoutAffect&&document.body.classList.remove(\"overlay-body-open\"),this.el.removeEventListener(\"click\",this.onOverlayClickListener),this.onElementClickListener.length&&(this.onElementClickListener.forEach((({el:e,fn:t})=>{e.removeEventListener(\"click\",t)})),this.onElementClickListener=null),this.backdrop&&this.backdrop.removeEventListener(\"click\",this.onBackdropClickListener),this.backdrop&&(this.backdrop.remove(),this.backdrop=null),window.$hsOverlayCollection=window.$hsOverlayCollection.filter((({element:e})=>e.el!==this.el))}static findInCollection(e){return window.$hsOverlayCollection.find((t=>e instanceof r?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static getInstance(e,t){const i=\"string\"==typeof e?document.querySelector(e):e,s=(null==i?void 0:i.getAttribute(\"data-overlay\"))?i.getAttribute(\"data-overlay\"):e,n=window.$hsOverlayCollection.find((e=>e.element.el===(\"string\"==typeof s?document.querySelector(s):s)||e.element.el===(\"string\"==typeof s?document.querySelector(s):s)));return n?t?n:n.element.el:null}static autoInit(){window.$hsOverlayCollection||(window.$hsOverlayCollection=[],document.addEventListener(\"keydown\",(e=>r.accessibility(e)))),window.$hsOverlayCollection&&(window.$hsOverlayCollection=window.$hsOverlayCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\".overlay:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsOverlayCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new r(e)}))}static open(e){const t=r.findInCollection(e);t&&t.element.el.classList.contains(t.element.hiddenClass)&&t.element.open()}static close(e){const t=r.findInCollection(e);t&&!t.element.el.classList.contains(t.element.hiddenClass)&&t.element.close()}static setOpened(e,t){document.body.clientWidth>=e?(document.body.classList.add(\"overlay-body-open\"),t.element.open()):t.element.close(!0)}static accessibility(e){var t,i;const s=document.querySelectorAll(\".overlay.open\"),o=(0,n.getHighestZIndex)(Array.from(s)),l=window.$hsOverlayCollection.filter((e=>e.element.el.classList.contains(\"open\"))).find((e=>window.getComputedStyle(e.element.el).getPropertyValue(\"z-index\")===`${o}`)),r=null===(i=null===(t=null==l?void 0:l.element)||void 0===t?void 0:t.el)||void 0===i?void 0:i.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'),a=[];(null==r?void 0:r.length)&&r.forEach((e=>{(0,n.isParentOrElementHidden)(e)||a.push(e)}));const c=l&&!e.metaKey;if(c&&!l.element.isTabAccessibilityLimited&&\"Tab\"===e.code)return!1;c&&a.length&&\"Tab\"===e.code&&(e.preventDefault(),this.onTab(l)),c&&\"Escape\"===e.code&&(e.preventDefault(),this.onEscape(l))}static onEscape(e){e&&e.element.hasAbilityToCloseOnBackdropClick&&e.element.close()}static onTab(e){const t=e.element.el,i=Array.from(t.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'));if(0===i.length)return!1;const s=t.querySelector(\":focus\");if(s){let e=!1;for(const t of i){if(e)return void t.focus();t===s&&(e=!0)}i[0].focus()}else i[0].focus()}static on(e,t,i){const s=r.findInCollection(t);s&&(s.element.events[e]=i)}}r.openedItemsQty=0,r.currentZIndex=0;const a=()=>{if(!window.$hsOverlayCollection.length||!window.$hsOverlayCollection.find((e=>e.element.moveOverlayToBody)))return!1;window.$hsOverlayCollection.filter((e=>e.element.moveOverlayToBody)).forEach((e=>{const t=e.element.moveOverlayToBody,i=e.element.initContainer,s=document.querySelector(\"body\"),o=e.element.el;if(!i&&o)return!1;document.body.clientWidth<=t&&!(0,n.isDirectChild)(s,o)?s.appendChild(o):document.body.clientWidth>t&&!i.contains(o)&&i.appendChild(o)}))};window.addEventListener(\"load\",(()=>{r.autoInit(),a()})),window.addEventListener(\"resize\",(()=>{(()=>{if(!window.$hsOverlayCollection.length||!window.$hsOverlayCollection.find((e=>e.element.autoClose)))return!1;window.$hsOverlayCollection.filter((e=>e.element.autoClose)).forEach((e=>{const{autoCloseEqualityType:t,autoClose:i}=e.element;(\"less-than\"===t?document.body.clientWidth<=i:document.body.clientWidth>=i)?e.element.close(!0):e.element.isLayoutAffect&&document.body.classList.add(\"overlay-body-open\")}))})(),a(),(()=>{if(!window.$hsOverlayCollection.length||!window.$hsOverlayCollection.find((e=>e.element.autoClose)))return!1;window.$hsOverlayCollection.filter((e=>e.element.autoClose)).forEach((e=>{const{autoCloseEqualityType:t,autoClose:i}=e.element;(\"less-than\"===t?document.body.clientWidth<=i:document.body.clientWidth>=i)&&e.element.close(!0)}))})(),(()=>{if(!window.$hsOverlayCollection.length||!window.$hsOverlayCollection.find((e=>e.element.el.classList.contains(\"opened\"))))return!1;window.$hsOverlayCollection.filter((e=>e.element.el.classList.contains(\"opened\"))).forEach((e=>{const t=parseInt(window.getComputedStyle(e.element.el).getPropertyValue(\"z-index\")),i=document.querySelector(`#${e.element.el.id}-backdrop`);return!!i&&(t!==parseInt(window.getComputedStyle(i).getPropertyValue(\"z-index\"))+1&&(\"style\"in i&&(i.style.zIndex=\"\"+(t-1)),void document.body.classList.add(\"overlay-body-open\")))}))})()})),\"undefined\"!=typeof window&&(window.HSOverlay=r),t.default=r},192:function(e,t,i){\n/*\n * HSFileUpload\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));\"undefined\"!=typeof Dropzone&&(Dropzone.autoDiscover=!1);class l extends o.default{constructor(e,t,i){var s;super(e,t,i),this.extensions={},this.el=\"string\"==typeof e?document.querySelector(e):e;const n=this.el.getAttribute(\"data-file-upload\"),o=n?JSON.parse(n):{};this.previewTemplate=(null===(s=this.el.querySelector(\"[data-file-upload-preview]\"))||void 0===s?void 0:s.innerHTML)||'
\\n
\\n
\\n \\n \\n \\n
\\n

\\n .\\n

\\n

\\n
\\n
\\n
\\n \\n
\\n
\\n
\\n
\\n
\\n
\\n \\n 0%\\n \\n
\\n
',this.extensions=_.merge({default:{icon:'',class:\"shrink-0 size-5\"},xls:{icon:'',class:\"shrink-0 size-5\"},doc:{icon:'',class:\"shrink-0 size-5\"},zip:{icon:'',class:\"shrink-0 size-5\"}},o.extensions),this.singleton=o.singleton,this.concatOptions=Object.assign(Object.assign({clickable:this.el.querySelector(\"[data-file-upload-trigger]\"),previewsContainer:this.el.querySelector(\"[data-file-upload-previews]\"),addRemoveLinks:!1,previewTemplate:this.previewTemplate,autoHideTrigger:!1},o),t),this.onReloadButtonClickListener=[],this.onTempFileInputChangeListener=[],this.init()}tempFileInputChange(e,t){var i;const s=null===(i=e.target.files)||void 0===i?void 0:i[0];if(s){const e=s;e.status=Dropzone.ADDED,e.accepted=!0,e.previewElement=t.previewElement,e.previewTemplate=t.previewTemplate,e.previewsContainer=t.previewsContainer,this.dropzone.removeFile(t),this.dropzone.addFile(e)}}reloadButtonClick(e,t){e.preventDefault(),e.stopPropagation();const i=document.createElement(\"input\");i.type=\"file\",this.onTempFileInputChangeListener.push({el:i,fn:e=>this.tempFileInputChange(e,t)}),i.click(),i.addEventListener(\"change\",this.onTempFileInputChangeListener.find((e=>e.el===i)).fn)}init(){this.createCollection(window.$hsFileUploadCollection,this),this.initDropzone()}initDropzone(){const e=this.el.querySelector(\"[data-file-upload-clear]\"),t=Array.from(this.el.querySelectorAll(\"[data-file-upload-pseudo-trigger]\"));this.dropzone=new Dropzone(this.el,this.concatOptions),this.dropzone.on(\"addedfile\",(e=>this.onAddFile(e))),this.dropzone.on(\"removedfile\",(()=>this.onRemoveFile())),this.dropzone.on(\"uploadprogress\",((e,t)=>this.onUploadProgress(e,t))),this.dropzone.on(\"complete\",(e=>this.onComplete(e))),e&&(e.onclick=()=>{this.dropzone.files.length&&this.dropzone.removeAllFiles(!0)}),t.length&&t.forEach((e=>{e.onclick=()=>{var e,t;(null===(e=this.concatOptions)||void 0===e?void 0:e.clickable)&&(null===(t=this.concatOptions)||void 0===t?void 0:t.clickable).click()}}))}destroy(){this.onTempFileInputChangeListener.forEach((e=>{e.el.removeEventListener(\"change\",e.fn)})),this.onTempFileInputChangeListener=null,this.onReloadButtonClickListener.forEach((e=>{e.el.removeEventListener(\"click\",e.fn)})),this.onReloadButtonClickListener=null,this.dropzone.destroy(),window.$hsFileUploadCollection=window.$hsFileUploadCollection.filter((({element:e})=>e.el!==this.el))}onAddFile(e){const{previewElement:t}=e,i=e.previewElement.querySelector(\"[data-file-upload-reload]\");if(!t)return!1;this.singleton&&this.dropzone.files.length>1&&this.dropzone.removeFile(this.dropzone.files[0]),i&&(this.onReloadButtonClickListener.push({el:i,fn:t=>this.reloadButtonClick(t,e)}),i.addEventListener(\"click\",this.onReloadButtonClickListener.find((e=>e.el===i)).fn)),this.previewAccepted(e)}previewAccepted(e){const{previewElement:t}=e,i=this.splitFileName(e.name),s=t.querySelector(\"[data-file-upload-file-name]\"),n=t.querySelector(\"[data-file-upload-file-ext]\"),o=t.querySelector(\"[data-file-upload-file-size]\"),l=t.querySelector(\"[data-file-upload-file-icon]\"),r=this.el.querySelector(\"[data-file-upload-trigger]\"),a=t.querySelector(\"[data-dz-thumbnail]\"),c=t.querySelector(\"[data-file-upload-remove]\");s&&(s.textContent=i.name),n&&(n.textContent=i.extension),o&&(o.textContent=this.formatFileSize(e.size)),a&&(e.type.includes(\"image/\")?a.classList.remove(\"hidden\"):this.setIcon(i.extension,l)),this.dropzone.files.length>0&&this.concatOptions.autoHideTrigger&&(r.style.display=\"none\"),c&&(c.onclick=()=>this.dropzone.removeFile(e))}onRemoveFile(){const e=this.el.querySelector(\"[data-file-upload-trigger]\");0===this.dropzone.files.length&&this.concatOptions.autoHideTrigger&&(e.style.display=\"\")}onUploadProgress(e,t){const{previewElement:i}=e;if(!i)return!1;const s=i.querySelector(\"[data-file-upload-progress-bar]\"),n=i.querySelector(\"[data-file-upload-progress-bar-pane]\"),o=i.querySelector(\"[data-file-upload-progress-bar-value]\"),l=Math.floor(t);s&&s.setAttribute(\"aria-valuenow\",`${l}`),n&&(n.style.width=`${l}%`),o&&(o.innerText=`${l}`)}onComplete(e){const{previewElement:t}=e;if(!t)return!1;t.classList.add(\"complete\")}setIcon(e,t){const i=this.createIcon(e);t.append(i)}createIcon(e){var t,i;const s=(null===(t=this.extensions[e])||void 0===t?void 0:t.icon)?(0,n.htmlToElement)(this.extensions[e].icon):(0,n.htmlToElement)(this.extensions.default.icon);return(0,n.classToClassList)((null===(i=this.extensions[e])||void 0===i?void 0:i.class)?this.extensions[e].class:this.extensions.default.class,s),s}formatFileSize(e){return e<1024?e.toFixed(2)+\" B\":e<1048576?(e/1024).toFixed(2)+\" KB\":e<1073741824?(e/1048576).toFixed(2)+\" MB\":e<1099511627776?(e/1073741824).toFixed(2)+\" GB\":(e/1099511627776).toFixed(2)+\" TB\"}splitFileName(e){let t=e.lastIndexOf(\".\");return-1==t?{name:e,extension:\"\"}:{name:e.substring(0,t),extension:e.substring(t+1)}}static getInstance(e,t){const i=window.$hsFileUploadCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsFileUploadCollection||(window.$hsFileUploadCollection=[]),window.$hsFileUploadCollection&&(window.$hsFileUploadCollection=window.$hsFileUploadCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-file-upload]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsFileUploadCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{document.querySelectorAll(\"[data-file-upload]:not(.--prevent-on-load-init)\").length&&(\"undefined\"==typeof _&&console.error(\"HSFileUpload: Lodash is not available, please add it to the page.\"),\"undefined\"==typeof Dropzone&&console.error(\"HSFileUpload: Dropzone is not available, please add it to the page.\")),\"undefined\"!=typeof _&&\"undefined\"!=typeof Dropzone&&l.autoInit()})),\"undefined\"!=typeof window&&(window.HSFileUpload=l),t.default=l},207:function(e,t,i){\n/*\n * HSStrongPassword\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t){super(e,t),this.isOpened=!1,this.strength=0,this.passedRules=new Set;const i=e.getAttribute(\"data-strong-password\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.target=(null==n?void 0:n.target)?\"string\"==typeof(null==n?void 0:n.target)?document.querySelector(n.target):n.target:null,this.hints=(null==n?void 0:n.hints)?\"string\"==typeof(null==n?void 0:n.hints)?document.querySelector(n.hints):n.hints:null,this.stripClasses=(null==n?void 0:n.stripClasses)||null,this.minLength=(null==n?void 0:n.minLength)||6,this.mode=(null==n?void 0:n.mode)||\"default\",this.popoverSpace=(null==n?void 0:n.popoverSpace)||10,this.checksExclude=(null==n?void 0:n.checksExclude)||[],this.availableChecks=[\"lowercase\",\"uppercase\",\"numbers\",\"special-characters\",\"min-length\"].filter((e=>!this.checksExclude.includes(e))),this.specialCharactersSet=(null==n?void 0:n.specialCharactersSet)||\"!\\\"#$%&'()*+,-./:;<=>?@[\\\\\\\\\\\\]^_`{|}~\",this.target&&this.init()}targetInput(e){this.setStrength(e.target.value)}targetFocus(){this.isOpened=!0,this.hints.classList.remove(\"hidden\"),this.hints.classList.add(\"block\"),this.recalculateDirection()}targetBlur(){this.isOpened=!1,this.hints.classList.remove(\"block\",\"bottom-full\",\"top-full\"),this.hints.classList.add(\"hidden\"),this.hints.style.marginTop=\"\",this.hints.style.marginBottom=\"\"}targetInputSecond(){this.setWeaknessText()}targetInputThird(){this.setRulesText()}init(){this.createCollection(window.$hsStrongPasswordCollection,this),this.availableChecks.length&&this.build()}build(){this.buildStrips(),this.hints&&this.buildHints(),this.setStrength(this.target.value),this.onTargetInputListener=e=>this.targetInput(e),this.target.addEventListener(\"input\",this.onTargetInputListener)}buildStrips(){if(this.el.innerHTML=\"\",this.stripClasses)for(let e=0;e\");(0,n.classToClassList)(this.stripClasses,e),this.el.append(e)}}buildHints(){this.weakness=this.hints.querySelector(\"[data-pw-strength-hint]\")||null,this.rules=Array.from(this.hints.querySelectorAll(\"[data-pw-strength-rule]\"))||null,this.rules.forEach((e=>{var t;const i=e.getAttribute(\"data-pw-strength-rule\");(null===(t=this.checksExclude)||void 0===t?void 0:t.includes(i))&&e.remove()})),this.weakness&&this.buildWeakness(),this.rules&&this.buildRules(),\"popover\"===this.mode&&(this.onTargetFocusListener=()=>this.targetFocus(),this.onTargetBlurListener=()=>this.targetBlur(),this.target.addEventListener(\"focus\",this.onTargetFocusListener),this.target.addEventListener(\"blur\",this.onTargetBlurListener))}buildWeakness(){this.checkStrength(this.target.value),this.setWeaknessText(),this.onTargetInputSecondListener=()=>setTimeout((()=>this.targetInputSecond())),this.target.addEventListener(\"input\",this.onTargetInputSecondListener)}buildRules(){this.setRulesText(),this.onTargetInputThirdListener=()=>setTimeout((()=>this.targetInputThird())),this.target.addEventListener(\"input\",this.onTargetInputThirdListener)}setWeaknessText(){const e=this.weakness.getAttribute(\"data-pw-strength-hint\"),t=JSON.parse(e);this.weakness.textContent=t[this.strength]}setRulesText(){this.rules.forEach((e=>{const t=e.getAttribute(\"data-pw-strength-rule\");this.checkIfPassed(e,this.passedRules.has(t))}))}togglePopover(){const e=this.el.querySelector(\".popover\");e&&e.classList.toggle(\"show\")}checkStrength(e){const t=new Set,i={lowercase:/[a-z]+/,uppercase:/[A-Z]+/,numbers:/[0-9]+/,\"special-characters\":new RegExp(`[${this.specialCharactersSet}]`)};let s=0;return this.availableChecks.includes(\"lowercase\")&&e.match(i.lowercase)&&(s+=1,t.add(\"lowercase\")),this.availableChecks.includes(\"uppercase\")&&e.match(i.uppercase)&&(s+=1,t.add(\"uppercase\")),this.availableChecks.includes(\"numbers\")&&e.match(i.numbers)&&(s+=1,t.add(\"numbers\")),this.availableChecks.includes(\"special-characters\")&&e.match(i[\"special-characters\"])&&(s+=1,t.add(\"special-characters\")),this.availableChecks.includes(\"min-length\")&&e.length>=this.minLength&&(s+=1,t.add(\"min-length\")),e.length||(s=0),s===this.availableChecks.length?this.el.classList.add(\"accepted\"):this.el.classList.remove(\"accepted\"),this.strength=s,this.passedRules=t,{strength:this.strength,rules:this.passedRules}}checkIfPassed(e,t=!1){const i=e.querySelector(\"[data-check]\"),s=e.querySelector(\"[data-uncheck]\");t?(e.classList.add(\"active\"),i.classList.remove(\"hidden\"),s.classList.add(\"hidden\")):(e.classList.remove(\"active\"),i.classList.add(\"hidden\"),s.classList.remove(\"hidden\"))}setStrength(e){const{strength:t,rules:i}=this.checkStrength(e),s={strength:t,rules:i};this.hideStrips(t),this.fireEvent(\"change\",s),(0,n.dispatch)(\"change.strongPassword\",this.el,s)}hideStrips(e){Array.from(this.el.children).forEach(((t,i)=>{ie.el!==this.el))}static getInstance(e,t){const i=window.$hsStrongPasswordCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsStrongPasswordCollection||(window.$hsStrongPasswordCollection=[]),window.$hsStrongPasswordCollection&&(window.$hsStrongPasswordCollection=window.$hsStrongPasswordCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-strong-password]:not(.--prevent-on-load-init)\").forEach((e=>{if(!window.$hsStrongPasswordCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))){const t=e.getAttribute(\"data-strong-password\"),i=t?JSON.parse(t):{};new l(e,i)}}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),document.addEventListener(\"scroll\",(()=>{if(!window.$hsStrongPasswordCollection)return!1;const e=window.$hsStrongPasswordCollection.find((e=>e.element.isOpened));e&&e.element.recalculateDirection()})),\"undefined\"!=typeof window&&(window.HSStrongPassword=l),t.default=l},213:function(e,t,i){\n/*\n * HSStepper\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t){super(e,t);const i=e.getAttribute(\"data-stepper\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.currentIndex=(null==n?void 0:n.currentIndex)||1,this.mode=(null==n?void 0:n.mode)||\"linear\",this.isCompleted=void 0!==(null==n?void 0:n.isCompleted)&&(null==n?void 0:n.isCompleted),this.totalSteps=1,this.navItems=[],this.contentItems=[],this.onNavItemClickListener=[],this.init()}navItemClick(e){this.handleNavItemClick(e)}backClick(){if(this.handleBackButtonClick(),\"linear\"===this.mode){const e=this.navItems.find((({index:e})=>e===this.currentIndex)),t=this.contentItems.find((({index:e})=>e===this.currentIndex));if(!e||!t)return;e.isCompleted&&(e.isCompleted=!1,e.isSkip=!1,e.el.classList.remove(\"is-valid\",\"skipped\")),t.isCompleted&&(t.isCompleted=!1,t.isSkip=!1,t.el.classList.remove(\"is-valid\",\"skipped\")),\"linear\"===this.mode&&this.currentIndex!==this.totalSteps&&(this.nextBtn&&(this.nextBtn.style.display=\"\"),this.completeStepBtn&&(this.completeStepBtn.style.display=\"\")),this.showSkipButton(),this.showFinishButton(),this.showCompleteStepButton()}}nextClick(){var e;if(this.fireEvent(\"beforeNext\",this.currentIndex),(0,n.dispatch)(\"beforeNext.stepper\",this.el,this.currentIndex),null===(e=this.getNavItem(this.currentIndex))||void 0===e?void 0:e.isProcessed)return this.disableAll(),!1;this.goToNext()}skipClick(){this.handleSkipButtonClick(),\"linear\"===this.mode&&this.currentIndex===this.totalSteps&&(this.nextBtn&&(this.nextBtn.style.display=\"none\"),this.completeStepBtn&&(this.completeStepBtn.style.display=\"none\"),this.finishBtn&&(this.finishBtn.style.display=\"\"))}completeStepBtnClick(){this.handleCompleteStepButtonClick()}finishBtnClick(){var e;if(this.fireEvent(\"beforeFinish\",this.currentIndex),(0,n.dispatch)(\"beforeFinish.stepper\",this.el,this.currentIndex),null===(e=this.getNavItem(this.currentIndex))||void 0===e?void 0:e.isProcessed)return this.disableAll(),!1;this.handleFinishButtonClick()}resetBtnClick(){this.handleResetButtonClick()}init(){this.createCollection(window.$hsStepperCollection,this),this.buildNav(),this.buildContent(),this.buildButtons(),this.setTotalSteps()}getUncompletedSteps(e=!1){return this.navItems.filter((({isCompleted:t,isSkip:i})=>e?!t||i:!t&&!i))}setTotalSteps(){this.navItems.forEach((e=>{const{index:t}=e;t>this.totalSteps&&(this.totalSteps=t)}))}buildNav(){this.el.querySelectorAll(\"[data-stepper-nav-item]\").forEach((e=>this.addNavItem(e))),this.navItems.forEach((e=>this.buildNavItem(e)))}buildNavItem(e){const{index:t,isDisabled:i,el:s}=e;t===this.currentIndex&&this.setCurrentNavItem(),(\"linear\"!==this.mode||i)&&(this.onNavItemClickListener.push({el:s,fn:()=>this.navItemClick(e)}),s.addEventListener(\"click\",this.onNavItemClickListener.find((e=>e.el===s)).fn))}addNavItem(e){const{index:t,isFinal:i=!1,isCompleted:s=!1,isSkip:n=!1,isOptional:o=!1,isDisabled:l=!1,isProcessed:r=!1,isInvalid:a=!1}=JSON.parse(e.getAttribute(\"data-stepper-nav-item\"));s&&e.classList.add(\"is-valid\"),n&&e.classList.add(\"skipped\"),l&&(\"BUTTON\"!==e.tagName&&\"INPUT\"!==e.tagName||e.setAttribute(\"disabled\",\"disabled\"),e.classList.add(\"disabled\")),a&&e.classList.add(\"is-invalid\"),this.navItems.push({index:t,isFinal:i,isCompleted:s,isSkip:n,isOptional:o,isDisabled:l,isProcessed:r,isInvalid:a,el:e})}setCurrentNavItem(){this.navItems.forEach((e=>{const{index:t,el:i}=e;t===this.currentIndex?this.setCurrentNavItemActions(i):this.unsetCurrentNavItemActions(i)}))}setCurrentNavItemActions(e){e.classList.add(\"active\"),this.fireEvent(\"active\",this.currentIndex),(0,n.dispatch)(\"active.stepper\",this.el,this.currentIndex)}getNavItem(e=this.currentIndex){return this.navItems.find((({index:t})=>t===e))}setProcessedNavItemActions(e){e.isProcessed=!0,e.el.classList.add(\"processed\")}setErrorNavItemActions(e){e.isInvalid=!0,e.el.classList.add(\"is-invalid\")}unsetCurrentNavItemActions(e){e.classList.remove(\"active\")}handleNavItemClick(e){const{index:t}=e;this.currentIndex=t,this.setCurrentNavItem(),this.setCurrentContentItem(),this.checkForTheFirstStep()}buildContent(){this.el.querySelectorAll(\"[data-stepper-content-item]\").forEach((e=>this.addContentItem(e))),this.navItems.forEach((e=>this.buildContentItem(e)))}buildContentItem(e){const{index:t}=e;t===this.currentIndex&&this.setCurrentContentItem()}addContentItem(e){const{index:t,isFinal:i=!1,isCompleted:s=!1,isSkip:n=!1}=JSON.parse(e.getAttribute(\"data-stepper-content-item\"));s&&e.classList.add(\"is-valid\"),n&&e.classList.add(\"skipped\"),this.contentItems.push({index:t,isFinal:i,isCompleted:s,isSkip:n,el:e})}setCurrentContentItem(){if(this.isCompleted){const e=this.contentItems.find((({isFinal:e})=>e)),t=this.contentItems.filter((({isFinal:e})=>!e));return e.el.style.display=\"\",t.forEach((({el:e})=>e.style.display=\"none\")),!1}this.contentItems.forEach((e=>{const{index:t,el:i}=e;t===this.currentIndex?this.setCurrentContentItemActions(i):this.unsetCurrentContentItemActions(i)}))}hideAllContentItems(){this.contentItems.forEach((({el:e})=>e.style.display=\"none\"))}setCurrentContentItemActions(e){e.style.display=\"\"}unsetCurrentContentItemActions(e){e.style.display=\"none\"}disableAll(){const e=this.getNavItem(this.currentIndex);e.isInvalid=!1,e.isCompleted=!1,e.isDisabled=!1,e.el.classList.remove(\"is-invalid\",\"is-valid\"),this.disableButtons()}disableNavItemActions(e){e.isDisabled=!0,e.el.classList.add(\"disabled\")}enableNavItemActions(e){e.isDisabled=!1,e.el.classList.remove(\"disabled\")}buildButtons(){this.backBtn=this.el.querySelector(\"[data-stepper-back-btn]\"),this.nextBtn=this.el.querySelector(\"[data-stepper-next-btn]\"),this.skipBtn=this.el.querySelector(\"[data-stepper-skip-btn]\"),this.completeStepBtn=this.el.querySelector(\"[data-stepper-complete-step-btn]\"),this.finishBtn=this.el.querySelector(\"[data-stepper-finish-btn]\"),this.resetBtn=this.el.querySelector(\"[data-stepper-reset-btn]\"),this.buildBackButton(),this.buildNextButton(),this.buildSkipButton(),this.buildCompleteStepButton(),this.buildFinishButton(),this.buildResetButton()}buildBackButton(){this.backBtn&&(this.checkForTheFirstStep(),this.onBackClickListener=()=>this.backClick(),this.backBtn.addEventListener(\"click\",this.onBackClickListener))}handleBackButtonClick(){1!==this.currentIndex&&(\"linear\"===this.mode&&this.removeOptionalClasses(),this.currentIndex--,\"linear\"===this.mode&&this.removeOptionalClasses(),this.setCurrentNavItem(),this.setCurrentContentItem(),this.checkForTheFirstStep(),this.completeStepBtn&&this.changeTextAndDisableCompleteButtonIfStepCompleted(),this.fireEvent(\"back\",this.currentIndex),(0,n.dispatch)(\"back.stepper\",this.el,this.currentIndex))}checkForTheFirstStep(){1===this.currentIndex?this.setToDisabled(this.backBtn):this.setToNonDisabled(this.backBtn)}setToDisabled(e){\"BUTTON\"!==e.tagName&&\"INPUT\"!==e.tagName||e.setAttribute(\"disabled\",\"disabled\"),e.classList.add(\"disabled\")}setToNonDisabled(e){\"BUTTON\"!==e.tagName&&\"INPUT\"!==e.tagName||e.removeAttribute(\"disabled\"),e.classList.remove(\"disabled\")}buildNextButton(){this.nextBtn&&(this.onNextClickListener=()=>this.nextClick(),this.nextBtn.addEventListener(\"click\",this.onNextClickListener))}unsetProcessedNavItemActions(e){e.isProcessed=!1,e.el.classList.remove(\"processed\")}handleNextButtonClick(e=!0){if(e)this.currentIndex===this.totalSteps?this.currentIndex=1:this.currentIndex++;else{const e=this.getUncompletedSteps();if(1===e.length){const{index:t}=e[0];this.currentIndex=t}else{if(this.currentIndex===this.totalSteps)return;this.currentIndex++}}\"linear\"===this.mode&&this.removeOptionalClasses(),this.setCurrentNavItem(),this.setCurrentContentItem(),this.checkForTheFirstStep(),this.completeStepBtn&&this.changeTextAndDisableCompleteButtonIfStepCompleted(),this.showSkipButton(),this.showFinishButton(),this.showCompleteStepButton(),this.fireEvent(\"next\",this.currentIndex),(0,n.dispatch)(\"next.stepper\",this.el,this.currentIndex)}removeOptionalClasses(){const e=this.navItems.find((({index:e})=>e===this.currentIndex)),t=this.contentItems.find((({index:e})=>e===this.currentIndex));e.isSkip=!1,e.isInvalid=!1,e.isDisabled=!1,t.isSkip=!1,e.el.classList.remove(\"skipped\",\"is-valid\",\"is-invalid\"),t.el.classList.remove(\"skipped\",\"is-valid\",\"is-invalid\")}buildSkipButton(){this.skipBtn&&(this.showSkipButton(),this.onSkipClickListener=()=>this.skipClick(),this.skipBtn.addEventListener(\"click\",this.onSkipClickListener))}setSkipItem(e){const t=this.navItems.find((({index:t})=>t===(e||this.currentIndex))),i=this.contentItems.find((({index:t})=>t===(e||this.currentIndex)));t&&i&&(this.setSkipItemActions(t),this.setSkipItemActions(i))}setSkipItemActions(e){e.isSkip=!0,e.el.classList.add(\"skipped\")}showSkipButton(){if(!this.skipBtn)return;const{isOptional:e}=this.navItems.find((({index:e})=>e===this.currentIndex));this.skipBtn.style.display=e?\"\":\"none\"}handleSkipButtonClick(){this.setSkipItem(),this.handleNextButtonClick(),this.fireEvent(\"skip\",this.currentIndex),(0,n.dispatch)(\"skip.stepper\",this.el,this.currentIndex)}buildCompleteStepButton(){this.completeStepBtn&&(this.completeStepBtnDefaultText=this.completeStepBtn.innerText,this.onCompleteStepBtnClickListener=()=>this.completeStepBtnClick(),this.completeStepBtn.addEventListener(\"click\",this.onCompleteStepBtnClickListener))}changeTextAndDisableCompleteButtonIfStepCompleted(){const e=this.navItems.find((({index:e})=>e===this.currentIndex)),{completedText:t}=JSON.parse(this.completeStepBtn.getAttribute(\"data-stepper-complete-step-btn\"));e&&(e.isCompleted?(this.completeStepBtn.innerText=t||this.completeStepBtnDefaultText,this.completeStepBtn.setAttribute(\"disabled\",\"disabled\"),this.completeStepBtn.classList.add(\"disabled\")):(this.completeStepBtn.innerText=this.completeStepBtnDefaultText,this.completeStepBtn.removeAttribute(\"disabled\"),this.completeStepBtn.classList.remove(\"disabled\")))}setCompleteItem(e){const t=this.navItems.find((({index:t})=>t===(e||this.currentIndex))),i=this.contentItems.find((({index:t})=>t===(e||this.currentIndex)));t&&i&&(this.setCompleteItemActions(t),this.setCompleteItemActions(i))}setCompleteItemActions(e){e.isCompleted=!0,e.el.classList.add(\"is-valid\")}showCompleteStepButton(){if(!this.completeStepBtn)return;1===this.getUncompletedSteps().length?this.completeStepBtn.style.display=\"none\":this.completeStepBtn.style.display=\"\"}handleCompleteStepButtonClick(){this.setCompleteItem(),this.fireEvent(\"complete\",this.currentIndex),(0,n.dispatch)(\"complete.stepper\",this.el,this.currentIndex),this.handleNextButtonClick(!1),this.showFinishButton(),this.showCompleteStepButton(),this.checkForTheFirstStep(),this.completeStepBtn&&this.changeTextAndDisableCompleteButtonIfStepCompleted(),this.showSkipButton()}buildFinishButton(){this.finishBtn&&(this.isCompleted&&this.setCompleted(),this.onFinishBtnClickListener=()=>this.finishBtnClick(),this.finishBtn.addEventListener(\"click\",this.onFinishBtnClickListener))}setCompleted(){this.el.classList.add(\"completed\")}unsetCompleted(){this.el.classList.remove(\"completed\")}showFinishButton(){if(!this.finishBtn)return;1===this.getUncompletedSteps().length?this.finishBtn.style.display=\"\":this.finishBtn.style.display=\"none\"}handleFinishButtonClick(){const e=this.getUncompletedSteps(),t=this.getUncompletedSteps(!0),{el:i}=this.contentItems.find((({isFinal:e})=>e));e.length&&e.forEach((({index:e})=>this.setCompleteItem(e))),this.currentIndex=this.totalSteps,this.setCurrentNavItem(),this.hideAllContentItems();const s=this.navItems.find((({index:e})=>e===this.currentIndex));(s?s.el:null).classList.remove(\"active\"),i.style.display=\"block\",this.backBtn&&(this.backBtn.style.display=\"none\"),this.nextBtn&&(this.nextBtn.style.display=\"none\"),this.skipBtn&&(this.skipBtn.style.display=\"none\"),this.completeStepBtn&&(this.completeStepBtn.style.display=\"none\"),this.finishBtn&&(this.finishBtn.style.display=\"none\"),this.resetBtn&&(this.resetBtn.style.display=\"\"),t.length<=1&&(this.isCompleted=!0,this.setCompleted()),this.fireEvent(\"finish\",this.currentIndex),(0,n.dispatch)(\"finish.stepper\",this.el,this.currentIndex)}buildResetButton(){this.resetBtn&&(this.onResetBtnClickListener=()=>this.resetBtnClick(),this.resetBtn.addEventListener(\"click\",this.onResetBtnClickListener))}handleResetButtonClick(){this.backBtn&&(this.backBtn.style.display=\"\"),this.nextBtn&&(this.nextBtn.style.display=\"\"),this.completeStepBtn&&(this.completeStepBtn.style.display=\"\",this.completeStepBtn.innerText=this.completeStepBtnDefaultText,this.completeStepBtn.removeAttribute(\"disabled\"),this.completeStepBtn.classList.remove(\"disabled\")),this.resetBtn&&(this.resetBtn.style.display=\"none\"),this.navItems.forEach((e=>{const{el:t}=e;e.isSkip=!1,e.isCompleted=!1,this.unsetCurrentNavItemActions(t),t.classList.remove(\"is-valid\",\"skipped\")})),this.contentItems.forEach((e=>{const{el:t}=e;e.isSkip=!1,e.isCompleted=!1,this.unsetCurrentContentItemActions(t),t.classList.remove(\"is-valid\",\"skipped\")})),this.currentIndex=1,this.unsetCompleted(),this.isCompleted=!1,this.showSkipButton(),this.setCurrentNavItem(),this.setCurrentContentItem(),this.showFinishButton(),this.showCompleteStepButton(),this.checkForTheFirstStep(),this.fireEvent(\"reset\",this.currentIndex),(0,n.dispatch)(\"reset.stepper\",this.el,this.currentIndex)}setProcessedNavItem(e){const t=this.getNavItem(e);t&&this.setProcessedNavItemActions(t)}unsetProcessedNavItem(e){const t=this.getNavItem(e);t&&this.unsetProcessedNavItemActions(t)}goToNext(){\"linear\"===this.mode&&this.setCompleteItem(),this.handleNextButtonClick(\"linear\"!==this.mode),\"linear\"===this.mode&&this.currentIndex===this.totalSteps&&(this.nextBtn&&(this.nextBtn.style.display=\"none\"),this.completeStepBtn&&(this.completeStepBtn.style.display=\"none\"))}disableButtons(){this.backBtn&&this.setToDisabled(this.backBtn),this.nextBtn&&this.setToDisabled(this.nextBtn)}enableButtons(){this.backBtn&&this.setToNonDisabled(this.backBtn),this.nextBtn&&this.setToNonDisabled(this.nextBtn)}setErrorNavItem(e){const t=this.getNavItem(e);t&&this.setErrorNavItemActions(t)}destroy(){this.el.classList.remove(\"completed\"),this.el.querySelectorAll(\"[data-stepper-nav-item]\").forEach((e=>{e.classList.remove(\"active\",\"is-valid\",\"skipped\",\"disabled\",\"is-invalid\"),\"BUTTON\"!==e.tagName&&\"INPUT\"!==e.tagName||e.removeAttribute(\"disabled\")})),this.el.querySelectorAll(\"[data-stepper-content-item]\").forEach((e=>{e.classList.remove(\"is-valid\",\"skipped\")})),this.backBtn&&this.backBtn.classList.remove(\"disabled\"),this.nextBtn&&this.nextBtn.classList.remove(\"disabled\"),this.completeStepBtn&&this.completeStepBtn.classList.remove(\"disabled\"),this.backBtn&&(this.backBtn.style.display=\"\"),this.nextBtn&&(this.nextBtn.style.display=\"\"),this.skipBtn&&(this.skipBtn.style.display=\"\"),this.finishBtn&&(this.finishBtn.style.display=\"none\"),this.resetBtn&&(this.resetBtn.style.display=\"none\"),this.onNavItemClickListener.length&&this.onNavItemClickListener.forEach((({el:e,fn:t})=>{e.removeEventListener(\"click\",t)})),this.backBtn&&this.backBtn.removeEventListener(\"click\",this.onBackClickListener),this.nextBtn&&this.nextBtn.removeEventListener(\"click\",this.onNextClickListener),this.skipBtn&&this.skipBtn.removeEventListener(\"click\",this.onSkipClickListener),this.completeStepBtn&&this.completeStepBtn.removeEventListener(\"click\",this.onCompleteStepBtnClickListener),this.finishBtn&&this.finishBtn.removeEventListener(\"click\",this.onFinishBtnClickListener),this.resetBtn&&this.resetBtn.removeEventListener(\"click\",this.onResetBtnClickListener),window.$hsStepperCollection=window.$hsStepperCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsStepperCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsStepperCollection||(window.$hsStepperCollection=[]),window.$hsStepperCollection&&(window.$hsStepperCollection=window.$hsStepperCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-stepper]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsStepperCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSStepper=l),t.default=l},234:function(e,t,i){\n/*\n * HSTogglePassword\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t){super(e,t);const i=e.getAttribute(\"data-toggle-password\"),s=i?JSON.parse(i):{},o=Object.assign(Object.assign({},s),t),l=[];if((null==o?void 0:o.target)&&\"string\"==typeof(null==o?void 0:o.target)){(null==o?void 0:o.target.split(\",\")).forEach((e=>{l.push(document.querySelector(e))}))}else(null==o?void 0:o.target)&&\"object\"==typeof(null==o?void 0:o.target)?o.target.forEach((e=>l.push(document.querySelector(e)))):o.target.forEach((e=>l.push(e)));this.target=l,this.isShown=!!this.el.hasAttribute(\"type\")&&this.el.checked,this.eventType=(0,n.isFormElement)(this.el)?\"change\":\"click\",this.isMultiple=this.target.length>1&&!!this.el.closest(\"[data-toggle-password-group]\"),this.target&&this.init()}elementAction(){this.isShown?this.hide():this.show(),this.fireEvent(\"toggle\",this.target),(0,n.dispatch)(\"toggle.toggle-select\",this.el,this.target)}init(){this.createCollection(window.$hsTogglePasswordCollection,this),this.isShown?this.show():this.hide(),this.onElementActionListener=()=>this.elementAction(),this.el.addEventListener(this.eventType,this.onElementActionListener)}getMultipleToggles(){const e=this.el.closest(\"[data-toggle-password-group]\").querySelectorAll(\"[data-toggle-password]\"),t=[];return e.forEach((e=>{t.push(l.getInstance(e))})),t}show(){if(this.isMultiple){this.getMultipleToggles().forEach((e=>!!e&&(e.isShown=!0))),this.el.closest(\"[data-toggle-password-group]\").classList.add(\"active\")}else this.isShown=!0,this.el.classList.add(\"active\");this.target.forEach((e=>{e.type=\"text\"}))}hide(){if(this.isMultiple){this.getMultipleToggles().forEach((e=>!!e&&(e.isShown=!1))),this.el.closest(\"[data-toggle-password-group]\").classList.remove(\"active\")}else this.isShown=!1,this.el.classList.remove(\"active\");this.target.forEach((e=>{e.type=\"password\"}))}destroy(){this.isMultiple?this.el.closest(\"[data-toggle-password-group]\").classList.remove(\"active\"):this.el.classList.remove(\"active\"),this.target.forEach((e=>{e.type=\"password\"})),this.el.removeEventListener(this.eventType,this.onElementActionListener),this.isShown=!1,window.$hsTogglePasswordCollection=window.$hsTogglePasswordCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsTogglePasswordCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsTogglePasswordCollection||(window.$hsTogglePasswordCollection=[]),window.$hsTogglePasswordCollection&&(window.$hsTogglePasswordCollection=window.$hsTogglePasswordCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-toggle-password]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsTogglePasswordCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSTogglePassword=l),t.default=l},287:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0});t.default=class{constructor(e,t,i){this.el=e,this.options=t,this.events=i,this.el=e,this.options=t,this.events={}}createCollection(e,t){var i;e.push({id:(null===(i=null==t?void 0:t.el)||void 0===i?void 0:i.id)||e.length+1,element:t})}fireEvent(e,t=null){if(this.events.hasOwnProperty(e))return this.events[e](t)}on(e,t){this.events[e]=t}}},302:function(e,t,i){\n/*\n * HSCarousel\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287)),l=i(917);class r extends o.default{constructor(e,t){var i,s,n,o,l;super(e,t);const r=e.getAttribute(\"data-carousel\"),a=r?JSON.parse(r):{},c=Object.assign(Object.assign({},a),t);this.currentIndex=c.currentIndex||0,this.loadingClasses=c.loadingClasses?`${c.loadingClasses}`.split(\",\"):null,this.dotsItemClasses=c.dotsItemClasses?c.dotsItemClasses:null,this.isAutoHeight=void 0!==c.isAutoHeight&&c.isAutoHeight,this.isAutoPlay=void 0!==c.isAutoPlay&&c.isAutoPlay,this.isCentered=void 0!==c.isCentered&&c.isCentered,this.isDraggable=void 0!==c.isDraggable&&c.isDraggable,this.isInfiniteLoop=void 0!==c.isInfiniteLoop&&c.isInfiniteLoop,this.isRTL=void 0!==c.isRTL&&c.isRTL,this.isSnap=void 0!==c.isSnap&&c.isSnap,this.hasSnapSpacers=void 0===c.hasSnapSpacers||c.hasSnapSpacers,this.speed=c.speed||4e3,this.updateDelay=c.updateDelay||0,this.slidesQty=c.slidesQty||1,this.loadingClassesRemove=(null===(i=this.loadingClasses)||void 0===i?void 0:i[0])?this.loadingClasses[0].split(\" \"):\"opacity-0\",this.loadingClassesAdd=(null===(s=this.loadingClasses)||void 0===s?void 0:s[1])?this.loadingClasses[1].split(\" \"):\"\",this.afterLoadingClassesAdd=(null===(n=this.loadingClasses)||void 0===n?void 0:n[2])?this.loadingClasses[2].split(\" \"):\"\",this.container=this.el.querySelector(\".carousel\")||null,this.inner=this.el.querySelector(\".carousel-body\")||null,this.slides=this.el.querySelectorAll(\".carousel-slide\")||[],this.prev=this.el.querySelector(\".carousel-prev\")||null,this.next=this.el.querySelector(\".carousel-next\")||null,this.dots=this.el.querySelector(\".carousel-pagination\")||null,this.info=this.el.querySelector(\".carousel-info\")||null,this.infoTotal=(null===(o=null==this?void 0:this.info)||void 0===o?void 0:o.querySelector(\".carousel-info-total\"))||null,this.infoCurrent=(null===(l=null==this?void 0:this.info)||void 0===l?void 0:l.querySelector(\".carousel-info-current\"))||null,this.sliderWidth=this.el.getBoundingClientRect().width,this.isDragging=!1,this.dragStartX=null,this.initialTranslateX=null,this.touchX={start:0,end:0},this.resizeContainer=document.querySelector(\"body\"),this.resizeContainerWidth=0,this.init()}setIsSnap(){const e=this.container.getBoundingClientRect(),t=e.left+e.width/2;let i=null,s=null,n=1/0;Array.from(this.inner.children).forEach((e=>{const s=e.getBoundingClientRect(),o=this.inner.getBoundingClientRect(),l=s.left+s.width/2-o.left,r=Math.abs(t-(o.left+l));re===i))),this.setIndex(s),this.dots&&this.setCurrentDot()}prevClick(){this.goToPrev(),this.isAutoPlay&&(this.resetTimer(),this.setTimer())}nextClick(){this.goToNext(),this.isAutoPlay&&(this.resetTimer(),this.setTimer())}containerScroll(){clearTimeout(this.isScrolling),this.isScrolling=setTimeout((()=>{this.setIsSnap()}),100)}elementTouchStart(e){this.touchX.start=e.changedTouches[0].screenX}elementTouchEnd(e){this.touchX.end=e.changedTouches[0].screenX,this.detectDirection()}innerMouseDown(e){this.handleDragStart(e)}innerTouchStart(e){this.handleDragStart(e)}documentMouseMove(e){this.handleDragMove(e)}documentTouchMove(e){this.handleDragMove(e)}documentMouseUp(){this.handleDragEnd()}documentTouchEnd(){this.handleDragEnd()}dotClick(e){this.goTo(e),this.isAutoPlay&&(this.resetTimer(),this.setTimer())}init(){this.createCollection(window.$hsCarouselCollection,this),this.inner&&(this.calculateWidth(),this.isDraggable&&!this.isSnap&&this.initDragHandling()),this.prev&&(this.onPrevClickListener=()=>this.prevClick(),this.prev.addEventListener(\"click\",this.onPrevClickListener)),this.next&&(this.onNextClickListener=()=>this.nextClick(),this.next.addEventListener(\"click\",this.onNextClickListener)),this.dots&&this.initDots(),this.info&&this.buildInfo(),this.slides.length&&(this.addCurrentClass(),this.isInfiniteLoop||this.addDisabledClass(),this.isAutoPlay&&this.autoPlay()),setTimeout((()=>{this.isSnap&&this.setIsSnap(),this.loadingClassesRemove&&(\"string\"==typeof this.loadingClassesRemove?this.inner.classList.remove(this.loadingClassesRemove):this.inner.classList.remove(...this.loadingClassesRemove)),this.loadingClassesAdd&&(\"string\"==typeof this.loadingClassesAdd?this.inner.classList.add(this.loadingClassesAdd):this.inner.classList.add(...this.loadingClassesAdd)),this.inner&&this.afterLoadingClassesAdd&&setTimeout((()=>{\"string\"==typeof this.afterLoadingClassesAdd?this.inner.classList.add(this.afterLoadingClassesAdd):this.inner.classList.add(...this.afterLoadingClassesAdd)}))}),400),this.isSnap&&(this.onContainerScrollListener=()=>this.containerScroll(),this.container.addEventListener(\"scroll\",this.onContainerScrollListener)),this.el.classList.add(\"init\"),this.isSnap||(this.onElementTouchStartListener=e=>this.elementTouchStart(e),this.onElementTouchEndListener=e=>this.elementTouchEnd(e),this.el.addEventListener(\"touchstart\",this.onElementTouchStartListener),this.el.addEventListener(\"touchend\",this.onElementTouchEndListener)),this.observeResize()}initDragHandling(){const e=this.inner;this.onInnerMouseDownListener=e=>this.innerMouseDown(e),this.onInnerTouchStartListener=e=>this.innerTouchStart(e),this.onDocumentMouseMoveListener=e=>this.documentMouseMove(e),this.onDocumentTouchMoveListener=e=>this.documentTouchMove(e),this.onDocumentMouseUpListener=()=>this.documentMouseUp(),this.onDocumentTouchEndListener=()=>this.documentTouchEnd(),e&&(e.addEventListener(\"mousedown\",this.onInnerMouseDownListener),e.addEventListener(\"touchstart\",this.onInnerTouchStartListener,{passive:!0}),document.addEventListener(\"mousemove\",this.onDocumentMouseMoveListener),document.addEventListener(\"touchmove\",this.onDocumentTouchMoveListener,{passive:!1}),document.addEventListener(\"mouseup\",this.onDocumentMouseUpListener),document.addEventListener(\"touchend\",this.onDocumentTouchEndListener))}getTranslateXValue(){var e;const t=window.getComputedStyle(this.inner).transform;if(\"none\"!==t){const i=null===(e=t.match(/matrix.*\\((.+)\\)/))||void 0===e?void 0:e[1].split(\", \");if(i){let e=parseFloat(6===i.length?i[4]:i[12]);return this.isRTL&&(e=-e),isNaN(e)||0===e?0:-e}}return 0}removeClickEventWhileDragging(e){e.preventDefault()}handleDragStart(e){e.preventDefault(),this.isDragging=!0,this.dragStartX=this.getEventX(e),this.initialTranslateX=this.isRTL?this.getTranslateXValue():-this.getTranslateXValue(),this.inner.classList.add(\"dragging\")}handleDragMove(e){if(!this.isDragging)return;this.inner.querySelectorAll(\"a:not(.prevented-click)\").forEach((e=>{e.classList.add(\"prevented-click\"),e.addEventListener(\"click\",this.removeClickEventWhileDragging)}));let t=this.getEventX(e)-this.dragStartX;this.isRTL&&(t=-t);const i=this.initialTranslateX+t;this.setTranslate((()=>{let e=this.sliderWidth*this.slides.length/this.getCurrentSlidesQty()-this.sliderWidth;const t=this.sliderWidth,s=(t-t/this.getCurrentSlidesQty())/2,n=this.isCentered?s:0;this.isCentered&&(e+=s);const o=-e;return this.isRTL?ie?o:-i:i>n?n:i<-e?o:i})())}handleDragEnd(){if(!this.isDragging)return;this.isDragging=!1;const e=this.sliderWidth/this.getCurrentSlidesQty(),t=this.getTranslateXValue();let i=Math.round(t/e);this.isRTL&&(i=Math.round(t/e)),this.inner.classList.remove(\"dragging\"),setTimeout((()=>{this.calculateTransform(i),this.dots&&this.setCurrentDot(),this.dragStartX=null,this.initialTranslateX=null,this.inner.querySelectorAll(\"a.prevented-click\").forEach((e=>{e.classList.remove(\"prevented-click\"),e.removeEventListener(\"click\",this.removeClickEventWhileDragging)}))}))}getEventX(e){return e instanceof MouseEvent?e.clientX:e.touches[0].clientX}getCurrentSlidesQty(){if(\"object\"==typeof this.slidesQty){const e=document.body.clientWidth;let t=0;return Object.keys(this.slidesQty).forEach((i=>{e>=(typeof i+1==\"number\"?this.slidesQty[i]:l.BREAKPOINTS[i])&&(t=this.slidesQty[i])})),t}return this.slidesQty}buildSnapSpacers(){const e=this.inner.querySelector(\".snap-before\"),t=this.inner.querySelector(\".snap-after\");e&&e.remove(),t&&t.remove();const i=this.sliderWidth,s=i/2-i/this.getCurrentSlidesQty()/2,o=(0,n.htmlToElement)(`
`),l=(0,n.htmlToElement)(`
`);this.inner.prepend(o),this.inner.appendChild(l)}initDots(){this.el.querySelectorAll(\".carousel-pagination-item\").length?this.setDots():this.buildDots(),this.dots&&this.setCurrentDot()}buildDots(){this.dots.innerHTML=\"\";const e=!this.isCentered&&this.slidesQty?this.slides.length-(this.getCurrentSlidesQty()-1):this.slides.length;for(let t=0;t{const i=e.getAttribute(\"data-carousel-pagination-item-target\");this.singleDotEvents(e,i?+i:t)}))}goToCurrentDot(){const e=this.dots,t=e.getBoundingClientRect(),i=e.scrollLeft,s=e.scrollTop,n=e.clientWidth,o=e.clientHeight,l=this.dotsItems[this.currentIndex],r=l.getBoundingClientRect(),a=r.left-t.left+i,c=a+l.clientWidth,d=r.top-t.top+s,h=d+l.clientHeight;let u=i,p=s;(ai+n)&&(u=c-n),(ds+o)&&(p=h-o),e.scrollTo({left:u,top:p,behavior:\"smooth\"})}buildInfo(){this.infoTotal&&this.setInfoTotal(),this.infoCurrent&&this.setInfoCurrent()}setInfoTotal(){this.infoTotal.innerText=`${this.slides.length}`}setInfoCurrent(){this.infoCurrent.innerText=`${this.currentIndex+1}`}buildSingleDot(e){const t=(0,n.htmlToElement)(\"\");return this.dotsItemClasses&&(0,n.classToClassList)(this.dotsItemClasses,t),this.singleDotEvents(t,e),t}singleDotEvents(e,t){this.onDotClickListener=()=>this.dotClick(t),e.addEventListener(\"click\",this.onDotClickListener)}observeResize(){new ResizeObserver((0,n.debounce)((e=>{for(let t of e){const e=t.contentRect.width;e!==this.resizeContainerWidth&&(this.recalculateWidth(),this.dots&&this.initDots(),this.addCurrentClass(),this.resizeContainerWidth=e)}}),this.updateDelay)).observe(this.resizeContainer)}calculateWidth(){this.isSnap||(this.inner.style.width=this.sliderWidth*this.slides.length/this.getCurrentSlidesQty()+\"px\"),this.slides.forEach((e=>{e.style.width=this.sliderWidth/this.getCurrentSlidesQty()+\"px\"})),this.calculateTransform()}addCurrentClass(){if(this.isSnap){const e=Math.floor(this.getCurrentSlidesQty()/2);for(let t=0;t=this.currentIndex-e?i.classList.add(\"active\"):i.classList.remove(\"active\")}}else{const e=this.isCentered?this.currentIndex+this.getCurrentSlidesQty()+(this.getCurrentSlidesQty()-1):this.currentIndex+this.getCurrentSlidesQty();this.slides.forEach(((t,i)=>{i>=this.currentIndex&&i{let i=!1;const s=Math.floor(this.getCurrentSlidesQty()/2);i=this.isSnap&&!this.hasSnapSpacers?t===(this.getCurrentSlidesQty()%2==0?this.currentIndex-s+1:this.currentIndex-s):t===this.currentIndex,i?e.classList.add(\"active\"):e.classList.remove(\"active\")};this.dotsItems?this.dotsItems.forEach(((t,i)=>e(t,i))):this.dots.querySelectorAll(\":scope > *\").forEach(((t,i)=>e(t,i)))}setElementToDisabled(e){e.classList.add(\"disabled\"),\"BUTTON\"!==e.tagName&&\"INPUT\"!==e.tagName||e.setAttribute(\"disabled\",\"disabled\")}unsetElementToDisabled(e){e.classList.remove(\"disabled\"),\"BUTTON\"!==e.tagName&&\"INPUT\"!==e.tagName||e.removeAttribute(\"disabled\")}addDisabledClass(){if(!this.prev||!this.next)return!1;const e=getComputedStyle(this.inner).getPropertyValue(\"gap\"),t=Math.floor(this.getCurrentSlidesQty()/2);let i=0,s=0,n=!1,o=!1;this.isSnap?(i=this.currentIndex,s=this.hasSnapSpacers?this.slides.length-1:this.slides.length-t-1,n=this.hasSnapSpacers?0===i:this.getCurrentSlidesQty()%2==0?i-t<0:i-t==0,o=i>=s&&this.container.scrollLeft+this.container.clientWidth+(parseFloat(e)||0)>=this.container.scrollWidth):(i=this.currentIndex,s=this.isCentered?this.slides.length-this.getCurrentSlidesQty()+(this.getCurrentSlidesQty()-1):this.slides.length-this.getCurrentSlidesQty(),n=0===i,o=i>=s),n?(this.unsetElementToDisabled(this.next),this.setElementToDisabled(this.prev)):o?(this.unsetElementToDisabled(this.prev),this.setElementToDisabled(this.next)):(this.unsetElementToDisabled(this.prev),this.unsetElementToDisabled(this.next))}autoPlay(){this.setTimer()}setTimer(){this.timer=setInterval((()=>{this.currentIndex===this.slides.length-1?this.goTo(0):this.goToNext()}),this.speed)}resetTimer(){clearInterval(this.timer)}detectDirection(){const{start:e,end:t}=this.touchX;te&&this.goToPrev()}calculateTransform(e){void 0!==e&&(this.currentIndex=e);const t=this.sliderWidth,i=t/this.getCurrentSlidesQty();let s=this.currentIndex*i;if(this.isSnap&&!this.isCentered&&this.container.scrollLeftt&&(this.container.scrollLeft=this.container.scrollWidth),this.isCentered&&!this.isSnap){const e=(t-i)/2;if(0===this.currentIndex)s=-e;else if(this.currentIndex>=this.slides.length-this.getCurrentSlidesQty()+(this.getCurrentSlidesQty()-1)){s=this.slides.length*i-t+e}else s=this.currentIndex*i-e}this.isSnap||this.setTransform(s),this.isAutoHeight&&(this.inner.style.height=`${this.slides[this.currentIndex].clientHeight}px`),this.dotsItems&&this.goToCurrentDot(),this.addCurrentClass(),this.isInfiniteLoop||this.addDisabledClass(),this.isSnap&&this.hasSnapSpacers&&this.buildSnapSpacers(),this.infoCurrent&&this.setInfoCurrent()}setTransform(e){this.slides.length>this.getCurrentSlidesQty()?this.inner.style.transform=this.isRTL?`translate(${e}px, 0px)`:`translate(${-e}px, 0px)`:this.inner.style.transform=\"translate(0px, 0px)\"}setTranslate(e){this.inner.style.transform=this.isRTL?`translate(${-e}px, 0px)`:`translate(${e}px, 0px)`}setIndex(e){this.currentIndex=e,this.addCurrentClass(),this.isInfiniteLoop||this.addDisabledClass()}recalculateWidth(){this.sliderWidth=this.inner.parentElement.getBoundingClientRect().width,this.calculateWidth(),this.sliderWidth!==this.inner.parentElement.getBoundingClientRect().width&&this.recalculateWidth()}goToPrev(){if(this.currentIndex>0?this.currentIndex--:this.currentIndex=this.slides.length-this.getCurrentSlidesQty(),this.isSnap){const e=this.sliderWidth/this.getCurrentSlidesQty();this.container.scrollBy({left:Math.max(-this.container.scrollLeft,-e),behavior:\"smooth\"}),this.addCurrentClass(),this.isInfiniteLoop||this.addDisabledClass()}else this.calculateTransform();this.dots&&this.setCurrentDot()}goToNext(){const e=this.isCentered?this.slides.length-this.getCurrentSlidesQty()+(this.getCurrentSlidesQty()-1):this.slides.length-this.getCurrentSlidesQty();if(this.currentIndexthis.currentIndex?t-this.currentIndex:this.currentIndex-t,s=t>this.currentIndex?-e*i:e*i;this.container.scrollBy({left:s,behavior:\"smooth\"}),this.addCurrentClass(),this.isInfiniteLoop||this.addDisabledClass()}else this.calculateTransform();this.dots&&this.setCurrentDot()}destroy(){var e,t;if(this.loadingClassesAdd&&(\"string\"==typeof this.loadingClassesAdd?this.inner.classList.remove(this.loadingClassesAdd):this.inner.classList.remove(...this.loadingClassesAdd)),this.inner&&this.afterLoadingClassesAdd&&setTimeout((()=>{\"string\"==typeof this.afterLoadingClassesAdd?this.inner.classList.remove(this.afterLoadingClassesAdd):this.inner.classList.remove(...this.afterLoadingClassesAdd)})),this.el.classList.remove(\"init\"),this.inner.classList.remove(\"dragging\"),this.slides.forEach((e=>e.classList.remove(\"active\"))),(null===(e=null==this?void 0:this.dotsItems)||void 0===e?void 0:e.length)&&this.dotsItems.forEach((e=>e.classList.remove(\"active\"))),this.prev.classList.remove(\"disabled\"),this.next.classList.remove(\"disabled\"),this.inner.style.width=\"\",this.slides.forEach((e=>e.style.width=\"\")),this.isSnap||(this.inner.style.transform=\"\"),this.isAutoHeight&&(this.inner.style.height=\"\"),this.prev.removeEventListener(\"click\",this.onPrevClickListener),this.next.removeEventListener(\"click\",this.onNextClickListener),this.container.removeEventListener(\"scroll\",this.onContainerScrollListener),this.el.removeEventListener(\"touchstart\",this.onElementTouchStartListener),this.el.removeEventListener(\"touchend\",this.onElementTouchEndListener),this.inner.removeEventListener(\"mousedown\",this.onInnerMouseDownListener),this.inner.removeEventListener(\"touchstart\",this.onInnerTouchStartListener),document.removeEventListener(\"mousemove\",this.onDocumentMouseMoveListener),document.removeEventListener(\"touchmove\",this.onDocumentTouchMoveListener),document.removeEventListener(\"mouseup\",this.onDocumentMouseUpListener),document.removeEventListener(\"touchend\",this.onDocumentTouchEndListener),this.inner.querySelectorAll(\"a:not(.prevented-click)\").forEach((e=>{e.classList.remove(\"prevented-click\"),e.removeEventListener(\"click\",this.removeClickEventWhileDragging)})),(null===(t=null==this?void 0:this.dotsItems)||void 0===t?void 0:t.length)||this.dots.querySelectorAll(\":scope > *\").length){((null==this?void 0:this.dotsItems)||this.dots.querySelectorAll(\":scope > *\")).forEach((e=>e.removeEventListener(\"click\",this.onDotClickListener))),this.dots.innerHTML=null}this.inner.querySelector(\".snap-before\").remove(),this.inner.querySelector(\".snap-after\").remove(),this.dotsItems=null,this.isDragging=!1,this.dragStartX=null,this.initialTranslateX=null,window.$hsCarouselCollection=window.$hsCarouselCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsCarouselCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsCarouselCollection||(window.$hsCarouselCollection=[]),window.$hsCarouselCollection&&(window.$hsCarouselCollection=window.$hsCarouselCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-carousel]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsCarouselCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new r(e)}))}}window.addEventListener(\"load\",(()=>{r.autoInit()})),\"undefined\"!=typeof window&&(window.HSCarousel=r),t.default=r},306:function(e,t,i){\n/*\n * HSAccordion\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t,i){super(e,t,i),this.toggle=this.el.querySelector(\".accordion-toggle\")||null,this.content=this.el.querySelector(\".accordion-content\")||null,this.group=this.el.closest(\".accordion\")||null,this.update(),this.isToggleStopPropagated=(0,n.stringToBoolean)((0,n.getClassProperty)(this.toggle,\"--stop-propagation\",\"false\")||\"false\"),this.keepOneOpen=!!this.group&&(0,n.stringToBoolean)((0,n.getClassProperty)(this.group,\"--keep-one-open\",\"false\")||\"false\"),this.toggle&&this.content&&this.init()}init(){this.createCollection(window.$hsAccordionCollection,this),this.onToggleClickListener=e=>this.toggleClick(e),this.toggle.addEventListener(\"click\",this.onToggleClickListener)}toggleClick(e){if(this.el.classList.contains(\"active\")&&this.keepOneOpen)return!1;this.isToggleStopPropagated&&e.stopPropagation(),this.el.classList.contains(\"active\")?this.hide():this.show()}show(){var e;if(this.group&&!this.isAlwaysOpened&&this.group.querySelector(\":scope > .accordion-item.active\")&&this.group.querySelector(\":scope > .accordion-item.active\")!==this.el){window.$hsAccordionCollection.find((e=>e.element.el===this.group.querySelector(\":scope > .accordion-item.active\"))).element.hide()}if(this.el.classList.contains(\"active\"))return!1;this.el.classList.add(\"active\"),(null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.toggle.ariaExpanded=\"true\"),this.fireEvent(\"beforeOpen\",this.el),(0,n.dispatch)(\"beforeOpen.accordion.item\",this.el,this.el),this.content.style.display=\"block\",this.content.style.height=\"0\",setTimeout((()=>{this.content.style.height=`${this.content.scrollHeight}px`,(0,n.afterTransition)(this.content,(()=>{this.content.style.display=\"block\",this.content.style.height=\"\",this.fireEvent(\"open\",this.el),(0,n.dispatch)(\"open.accordion.item\",this.el,this.el)}))}))}hide(){var e;if(!this.el.classList.contains(\"active\"))return!1;this.el.classList.remove(\"active\"),(null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.toggle.ariaExpanded=\"false\"),this.fireEvent(\"beforeClose\",this.el),(0,n.dispatch)(\"beforeClose.accordion.item\",this.el,this.el),this.content.style.height=`${this.content.scrollHeight}px`,setTimeout((()=>{this.content.style.height=\"0\"})),(0,n.afterTransition)(this.content,(()=>{this.content.style.display=\"none\",this.content.style.height=\"\",this.fireEvent(\"close\",this.el),(0,n.dispatch)(\"close.accordion.item\",this.el,this.el)}))}update(){if(this.group=this.el.closest(\".accordion\")||null,!this.group)return!1;this.isAlwaysOpened=this.group.hasAttribute(\"data-accordion-always-open\")||!1,window.$hsAccordionCollection.map((e=>(e.id===this.el.id&&(e.element.group=this.group,e.element.isAlwaysOpened=this.isAlwaysOpened),e)))}destroy(){var e;(null===(e=null==l?void 0:l.selectable)||void 0===e?void 0:e.length)&&l.selectable.forEach((e=>{e.listeners.forEach((({el:e,listener:t})=>{e.removeEventListener(\"click\",t)}))})),this.onToggleClickListener&&this.toggle.removeEventListener(\"click\",this.onToggleClickListener),this.toggle=null,this.content=null,this.group=null,this.onToggleClickListener=null,window.$hsAccordionCollection=window.$hsAccordionCollection.filter((({element:e})=>e.el!==this.el))}static findInCollection(e){return window.$hsAccordionCollection.find((t=>e instanceof l?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static autoInit(){window.$hsAccordionCollection||(window.$hsAccordionCollection=[]),window.$hsAccordionCollection&&(window.$hsAccordionCollection=window.$hsAccordionCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\".accordion-item:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsAccordionCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}static getInstance(e,t){const i=window.$hsAccordionCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static show(e){const t=l.findInCollection(e);t&&\"block\"!==t.element.content.style.display&&t.element.show()}static hide(e){const t=l.findInCollection(e),i=t?window.getComputedStyle(t.element.content):null;t&&\"none\"!==i.display&&t.element.hide()}static treeView(){if(!document.querySelectorAll(\".accordion-treeview-root\").length)return!1;this.selectable=[],document.querySelectorAll(\".accordion-treeview-root\").forEach((e=>{const t=null==e?void 0:e.getAttribute(\"data-accordion-options\"),i=t?JSON.parse(t):{};this.selectable.push({el:e,options:Object.assign({},i),listeners:[]})})),this.selectable.length&&this.selectable.forEach((e=>{const{el:t}=e;t.querySelectorAll(\".accordion-selectable\").forEach((t=>{const i=i=>this.onSelectableClick(i,e,t);t.addEventListener(\"click\",i),e.listeners.push({el:t,listener:i})}))}))}static toggleSelected(e,t){t.classList.contains(\"selected\")?t.classList.remove(\"selected\"):(e.el.querySelectorAll(\".accordion-selectable\").forEach((e=>e.classList.remove(\"selected\"))),t.classList.add(\"selected\"))}static on(e,t,i){const s=l.findInCollection(t);s&&(s.element.events[e]=i)}}l.onSelectableClick=(e,t,i)=>{e.stopPropagation(),l.toggleSelected(t,i)},window.addEventListener(\"load\",(()=>{l.autoInit(),document.querySelectorAll(\".accordion-treeview-root\").length&&l.treeView()})),\"undefined\"!=typeof window&&(window.HSAccordion=l),t.default=l},319:(e,t,i)=>{\n/*\n * HSStaticMethods\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nObject.defineProperty(t,\"__esModule\",{value:!0});const s=i(806),n=i(393),o={getClassProperty:s.getClassProperty,afterTransition:s.afterTransition,autoInit(e=\"all\"){\"all\"===e?n.COLLECTIONS.forEach((({fn:e})=>{null==e||e.autoInit()})):n.COLLECTIONS.forEach((({key:t,fn:i})=>{e.includes(t)&&(null==i||i.autoInit())}))},cleanCollection(e=\"all\"){\"all\"===e?n.COLLECTIONS.forEach((({collection:e})=>{window[e]instanceof Array&&(window[e]=[])})):n.COLLECTIONS.forEach((({key:t,collection:i})=>{e.includes(t)&&window[i]instanceof Array&&(window[i]=[])}))}};\"undefined\"!=typeof window&&(window.HSStaticMethods=o),t.default=o},393:function(e,t,i){var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0}),t.COLLECTIONS=void 0;const n=s(i(12)),o=s(i(306)),l=s(i(302)),r=s(i(763)),a=s(i(75)),c=s(i(792)),d=s(i(753)),h=s(i(192)),u=s(i(86)),p=s(i(164)),m=s(i(594)),g=s(i(977)),f=s(i(113)),v=s(i(881)),w=s(i(956)),y=s(i(213)),b=s(i(207)),C=s(i(944)),S=s(i(126)),L=s(i(234)),I=s(i(487)),E=s(i(782));t.COLLECTIONS=[{key:\"copy-markup\",fn:n.default,collection:\"$hsCopyMarkupCollection\"},{key:\"accordion\",fn:o.default,collection:\"$hsAccordionCollection\"},{key:\"carousel\",fn:l.default,collection:\"$hsCarouselCollection\"},{key:\"collapse\",fn:r.default,collection:\"$hsCollapseCollection\"},{key:\"combobox\",fn:a.default,collection:\"$hsComboBoxCollection\"},{key:\"datatable\",fn:c.default,collection:\"$hsDataTableCollection\"},{key:\"dropdown\",fn:d.default,collection:\"$hsDropdownCollection\"},{key:\"file-upload\",fn:h.default,collection:\"$hsFileUploadCollection\"},{key:\"input-number\",fn:u.default,collection:\"$hsInputNumberCollection\"},{key:\"overlay\",fn:p.default,collection:\"$hsOverlayCollection\"},{key:\"pin-input\",fn:m.default,collection:\"$hsPinInputCollection\"},{key:\"range-slider\",fn:g.default,collection:\"$hsRangeSliderCollection\"},{key:\"remove-element\",fn:f.default,collection:\"$hsRemoveElementCollection\"},{key:\"scrollspy\",fn:v.default,collection:\"$hsScrollspyCollection\"},{key:\"select\",fn:w.default,collection:\"$hsSelectCollection\"},{key:\"stepper\",fn:y.default,collection:\"$hsStepperCollection\"},{key:\"strong-password\",fn:b.default,collection:\"$hsStrongPasswordCollection\"},{key:\"tabs\",fn:C.default,collection:\"$hsTabsCollection\"},{key:\"toggle-count\",fn:S.default,collection:\"$hsToggleCountCollection\"},{key:\"toggle-password\",fn:L.default,collection:\"$hsTogglePasswordCollection\"},{key:\"tooltip\",fn:I.default,collection:\"$hsTooltipCollection\"},{key:\"tree-view\",fn:E.default,collection:\"$hsTreeViewCollection\"}]},487:function(e,t,i){\n/*\n * HSTooltip\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(949),o=i(806),l=s(i(287)),r=i(917);class a extends l.default{constructor(e,t,i){super(e,t,i),this.cleanupAutoUpdate=null,this.el&&(this.toggle=this.el.querySelector(\".tooltip-toggle\")||this.el,this.content=this.el.querySelector(\".tooltip-content\"),this.eventMode=(0,o.getClassProperty)(this.el,\"--trigger\")||\"hover\",this.preventFloatingUI=(0,o.getClassProperty)(this.el,\"--prevent-popper\",\"false\"),this.placement=(0,o.getClassProperty)(this.el,\"--placement\"),this.interaction=(0,o.getClassProperty)(this.el,\"--interaction\",\"true\"),this.strategy=(0,o.getClassProperty)(this.el,\"--strategy\"),this.scope=(0,o.getClassProperty)(this.el,\"--scope\")||\"parent\"),this.el&&this.toggle&&this.content&&this.init()}toggleClick(){this.click()}toggleFocus(){this.focus()}toggleMouseEnter(){this.enter()}toggleMouseLeave(){this.leave()}toggleHandle(){this.hide(),this.toggle.removeEventListener(\"click\",this.onToggleHandleListener,!0),this.toggle.removeEventListener(\"blur\",this.onToggleHandleListener,!0)}init(){this.createCollection(window.$hsTooltipCollection,this),\"click\"===this.eventMode?(this.onToggleClickListener=()=>this.toggleClick(),this.toggle.addEventListener(\"click\",this.onToggleClickListener)):\"focus\"===this.eventMode?(this.onToggleFocusListener=()=>this.toggleFocus(),this.toggle.addEventListener(\"click\",this.onToggleFocusListener)):\"hover\"===this.eventMode&&(this.onToggleMouseEnterListener=()=>this.toggleMouseEnter(),this.onToggleMouseLeaveListener=()=>this.toggleMouseLeave(),this.toggle.addEventListener(\"mouseenter\",this.onToggleMouseEnterListener),this.toggle.addEventListener(\"mouseleave\",this.onToggleMouseLeaveListener)),this.buildFloatingUI()}enter(){this._show()}leave(){this.hide()}click(){this.el.classList.contains(\"show\")?this.hide():(this._show(),this.onToggleHandleListener=()=>{setTimeout((()=>this.toggleHandle()))},this.toggle.addEventListener(\"click\",this.onToggleHandleListener,!0),this.toggle.addEventListener(\"blur\",this.onToggleHandleListener,!0))}focus(){var e;if(this._show(),\"true\"===this.interaction){const t=e=>{this.content&&this.content.contains(e.target)&&e.stopPropagation()};null===(e=this.content)||void 0===e||e.addEventListener(\"click\",t);const i=e=>{var t;(null===(t=this.content)||void 0===t?void 0:t.contains(e.target))||this.el.contains(e.target)||this.hide()};document.body.addEventListener(\"click\",i)}else{const e=()=>{this.hide(),this.toggle.removeEventListener(\"blur\",e,!0)};this.toggle.addEventListener(\"blur\",e,!0)}}buildFloatingUI(){var e;\"window\"===this.scope&&document.body.appendChild(this.content);const t=null!==(e=r.POSITIONS[this.placement])&&void 0!==e?e:\"top\",i=new Set([\"top\",\"top-start\",\"top-end\",\"bottom\",\"bottom-start\",\"bottom-end\"]).has(t),s=\"false\"===this.preventFloatingUI,o=s&&i,l=s,a=[(0,n.offset)(0),...o?[(0,n.shift)()]:[],...l?[(0,n.flip)()]:[]];(0,n.computePosition)(this.toggle,this.content,{placement:r.POSITIONS[this.placement]||\"top\",strategy:this.strategy||\"fixed\",middleware:a}).then((({x:e,y:t})=>{Object.assign(this.content.style,{position:this.strategy||\"fixed\",left:`${e}px`,top:`${t}px`})})),this.cleanupAutoUpdate=(0,n.autoUpdate)(this.toggle,this.content,(()=>{(0,n.computePosition)(this.toggle,this.content,{placement:r.POSITIONS[this.placement]||\"top\",strategy:this.strategy||\"fixed\",middleware:a}).then((({x:e,y:t})=>{Object.assign(this.content.style,{left:`${e}px`,top:`${t}px`})}))}))}_show(){this.content.classList.remove(\"hidden\"),\"window\"===this.scope&&this.content.classList.add(\"show\"),this.cleanupAutoUpdate||this.buildFloatingUI(),setTimeout((()=>{this.el.classList.add(\"show\"),this.fireEvent(\"show\",this.el),(0,o.dispatch)(\"show.tooltip\",this.el,this.el)}))}show(){switch(this.eventMode){case\"click\":this.click();break;case\"focus\":this.focus();break;default:this.enter()}this.toggle.focus(),this.toggle.style.outline=\"none\"}hide(){this.el.classList.remove(\"show\"),\"window\"===this.scope&&this.content.classList.remove(\"show\"),this.cleanupAutoUpdate&&(this.cleanupAutoUpdate(),this.cleanupAutoUpdate=null),this.fireEvent(\"hide\",this.el),(0,o.dispatch)(\"hide.tooltip\",this.el,this.el),(0,o.afterTransition)(this.content,(()=>{if(this.el.classList.contains(\"show\"))return!1;this.content.classList.add(\"hidden\"),this.toggle.style.outline=\"\"}))}destroy(){this.el.classList.remove(\"show\"),this.content.classList.add(\"hidden\"),\"click\"===this.eventMode?this.toggle.removeEventListener(\"click\",this.onToggleClickListener):\"focus\"===this.eventMode?this.toggle.removeEventListener(\"click\",this.onToggleFocusListener):\"hover\"===this.eventMode&&(this.toggle.removeEventListener(\"mouseenter\",this.onToggleMouseEnterListener),this.toggle.removeEventListener(\"mouseleave\",this.onToggleMouseLeaveListener)),this.toggle.removeEventListener(\"click\",this.onToggleHandleListener,!0),this.toggle.removeEventListener(\"blur\",this.onToggleHandleListener,!0),this.cleanupAutoUpdate&&(this.cleanupAutoUpdate(),this.cleanupAutoUpdate=null),window.$hsTooltipCollection=window.$hsTooltipCollection.filter((({element:e})=>e.el!==this.el))}static findInCollection(e){return window.$hsTooltipCollection.find((t=>e instanceof a?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static getInstance(e,t=!1){const i=window.$hsTooltipCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsTooltipCollection||(window.$hsTooltipCollection=[]),window.$hsTooltipCollection&&(window.$hsTooltipCollection=window.$hsTooltipCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\".tooltip:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsTooltipCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new a(e)}))}static show(e){const t=a.findInCollection(e);t&&t.element.show()}static hide(e){const t=a.findInCollection(e);t&&t.element.hide()}static on(e,t,i){const s=a.findInCollection(t);s&&(s.element.events[e]=i)}}window.addEventListener(\"load\",(()=>{a.autoInit()})),\"undefined\"!=typeof window&&(window.HSTooltip=a),t.default=a},594:function(e,t,i){\n/*\n * HSPinInput\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{elementInput(e,t){this.onInput(e,t)}elementPaste(e){this.onPaste(e)}elementKeydown(e,t){this.onKeydown(e,t)}elementFocusin(e){this.onFocusIn(e)}elementFocusout(e){this.onFocusOut(e)}constructor(e,t){super(e,t);const i=e.getAttribute(\"data-pin-input\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.items=this.el.querySelectorAll(\"[data-pin-input-item]\"),this.currentItem=null,this.currentValue=new Array(this.items.length).fill(\"\"),this.placeholders=[],this.availableCharsRE=new RegExp((null==n?void 0:n.availableCharsRE)||\"^[a-zA-Z0-9]+$\"),this.onElementInputListener=[],this.onElementPasteListener=[],this.onElementKeydownListener=[],this.onElementFocusinListener=[],this.onElementFocusoutListener=[],this.init()}init(){this.createCollection(window.$hsPinInputCollection,this),this.items.length&&this.build()}build(){this.buildInputItems()}buildInputItems(){this.items.forEach(((e,t)=>{this.placeholders.push(e.getAttribute(\"placeholder\")||\"\"),e.hasAttribute(\"autofocus\")&&this.onFocusIn(t),this.onElementInputListener.push({el:e,fn:e=>this.elementInput(e,t)}),this.onElementPasteListener.push({el:e,fn:e=>this.elementPaste(e)}),this.onElementKeydownListener.push({el:e,fn:e=>this.elementKeydown(e,t)}),this.onElementFocusinListener.push({el:e,fn:()=>this.elementFocusin(t)}),this.onElementFocusoutListener.push({el:e,fn:()=>this.elementFocusout(t)}),e.addEventListener(\"input\",this.onElementInputListener.find((t=>t.el===e)).fn),e.addEventListener(\"paste\",this.onElementPasteListener.find((t=>t.el===e)).fn),e.addEventListener(\"keydown\",this.onElementKeydownListener.find((t=>t.el===e)).fn),e.addEventListener(\"focusin\",this.onElementFocusinListener.find((t=>t.el===e)).fn),e.addEventListener(\"focusout\",this.onElementFocusoutListener.find((t=>t.el===e)).fn)}))}checkIfNumber(e){return e.match(this.availableCharsRE)}autoFillAll(e){Array.from(e).forEach(((e,t)=>{if(!(null==this?void 0:this.items[t]))return!1;this.items[t].value=e,this.items[t].dispatchEvent(new Event(\"input\",{bubbles:!0}))}))}setCurrentValue(){this.currentValue=Array.from(this.items).map((e=>e.value))}toggleCompleted(){this.currentValue.includes(\"\")?this.el.classList.remove(\"active\"):this.el.classList.add(\"active\")}onInput(e,t){const i=e.target.value;if(this.currentItem=e.target,this.currentItem.value=\"\",this.currentItem.value=i[i.length-1],!this.checkIfNumber(this.currentItem.value))return this.currentItem.value=this.currentValue[t]||\"\",!1;if(this.setCurrentValue(),this.currentItem.value){if(t0&&this.items[t-1].focus()}onKeydown(e,t){\"Backspace\"===e.key&&t>0&&(\"\"===this.items[t].value?(this.items[t-1].value=\"\",this.items[t-1].focus()):this.items[t].value=\"\"),this.setCurrentValue(),this.toggleCompleted()}onFocusIn(e){this.items[e].setAttribute(\"placeholder\",\"\")}onFocusOut(e){this.items[e].setAttribute(\"placeholder\",this.placeholders[e])}onPaste(e){e.preventDefault(),this.items.forEach((t=>{document.activeElement===t&&this.autoFillAll(e.clipboardData.getData(\"text\"))}))}destroy(){this.el.classList.remove(\"active\"),this.items.length&&this.items.forEach((e=>{e.removeEventListener(\"input\",this.onElementInputListener.find((t=>t.el===e)).fn),e.removeEventListener(\"paste\",this.onElementPasteListener.find((t=>t.el===e)).fn),e.removeEventListener(\"keydown\",this.onElementKeydownListener.find((t=>t.el===e)).fn),e.removeEventListener(\"focusin\",this.onElementFocusinListener.find((t=>t.el===e)).fn),e.removeEventListener(\"focusout\",this.onElementFocusoutListener.find((t=>t.el===e)).fn)})),this.items=null,this.currentItem=null,this.currentValue=null,window.$hsPinInputCollection=window.$hsPinInputCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsPinInputCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsPinInputCollection||(window.$hsPinInputCollection=[]),window.$hsPinInputCollection&&(window.$hsPinInputCollection=window.$hsPinInputCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-pin-input]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsPinInputCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSPinInput=l),t.default=l},753:function(e,t,i){\n/*\n * HSDropdown\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=i(949),l=s(i(287)),r=i(917);class a extends l.default{constructor(e,t,i){super(e,t,i),this.longPressTimer=null,this.onTouchStartListener=null,this.onTouchEndListener=null,this.toggle=this.el.querySelector(\":scope > .dropdown-toggle\")||this.el.querySelector(\":scope > .dropdown-toggle-wrapper > .dropdown-toggle\")||this.el.children[0],this.closers=Array.from(this.el.querySelectorAll(\":scope .dropdown-close\"))||null,this.menu=this.el.querySelector(\":scope > .dropdown-menu\"),this.eventMode=(0,n.getClassProperty)(this.el,\"--trigger\",\"click\"),this.closeMode=(0,n.getClassProperty)(this.el,\"--auto-close\",\"true\"),this.hasAutofocus=(0,n.stringToBoolean)((0,n.getClassProperty)(this.el,\"--has-autofocus\",\"true\")||\"true\"),this.animationInProcess=!1,this.onCloserClickListener=[],this.toggle&&this.menu&&this.init()}elementMouseEnter(){this.onMouseEnterHandler()}elementMouseLeave(){this.onMouseLeaveHandler()}toggleClick(e){this.onClickHandler(e)}toggleContextMenu(e){e.preventDefault(),this.onContextMenuHandler(e)}handleTouchStart(e){this.longPressTimer=window.setTimeout((()=>{e.preventDefault();const t=e.touches[0],i=new MouseEvent(\"contextmenu\",{bubbles:!0,cancelable:!0,view:window,clientX:t.clientX,clientY:t.clientY});this.toggle&&this.toggle.dispatchEvent(i)}),400)}handleTouchEnd(e){this.longPressTimer&&(clearTimeout(this.longPressTimer),this.longPressTimer=null)}closerClick(){this.close()}init(){if(this.createCollection(window.$hsDropdownCollection,this),this.toggle.disabled)return!1;this.toggle&&this.buildToggle(),this.menu&&this.buildMenu(),this.closers&&this.buildClosers(),(0,n.isIOS)()||(0,n.isIpadOS)()||(this.onElementMouseEnterListener=()=>this.elementMouseEnter(),this.onElementMouseLeaveListener=()=>this.elementMouseLeave(),this.el.addEventListener(\"mouseenter\",this.onElementMouseEnterListener),this.el.addEventListener(\"mouseleave\",this.onElementMouseLeaveListener))}resizeHandler(){this.eventMode=(0,n.getClassProperty)(this.el,\"--trigger\",\"click\"),this.closeMode=(0,n.getClassProperty)(this.el,\"--auto-close\",\"true\")}buildToggle(){var e;(null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.el.classList.contains(\"open\")?this.toggle.ariaExpanded=\"true\":this.toggle.ariaExpanded=\"false\"),\"contextmenu\"===this.eventMode?(this.onToggleContextMenuListener=e=>this.toggleContextMenu(e),this.onTouchStartListener=this.handleTouchStart.bind(this),this.onTouchEndListener=this.handleTouchEnd.bind(this),this.toggle.addEventListener(\"contextmenu\",this.onToggleContextMenuListener),this.toggle.addEventListener(\"touchstart\",this.onTouchStartListener,{passive:!1}),this.toggle.addEventListener(\"touchend\",this.onTouchEndListener),this.toggle.addEventListener(\"touchmove\",this.onTouchEndListener)):(this.onToggleClickListener=e=>this.toggleClick(e),this.toggle.addEventListener(\"click\",this.onToggleClickListener))}buildMenu(){this.menu.role=this.menu.getAttribute(\"role\")||\"menu\";const e=this.menu.querySelectorAll('[role=\"menuitemcheckbox\"]'),t=this.menu.querySelectorAll('[role=\"menuitemradio\"]');e.forEach((e=>e.addEventListener(\"click\",(()=>this.selectCheckbox(e))))),t.forEach((e=>e.addEventListener(\"click\",(()=>this.selectRadio(e)))))}buildClosers(){this.closers.forEach((e=>{this.onCloserClickListener.push({el:e,fn:()=>this.closerClick()}),e.addEventListener(\"click\",this.onCloserClickListener.find((t=>t.el===e)).fn)}))}getScrollbarSize(){let e=document.createElement(\"div\");e.style.overflow=\"scroll\",e.style.width=\"100px\",e.style.height=\"100px\",document.body.appendChild(e);let t=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),t}onContextMenuHandler(e){const t={getBoundingClientRect:(()=>new DOMRect,()=>new DOMRect(e.clientX,e.clientY,0,0))};a.closeCurrentlyOpened(),this.el.classList.contains(\"open\")&&!this.menu.classList.contains(\"hidden\")?(this.close(),document.body.style.overflow=\"\",document.body.style.paddingRight=\"\"):(document.body.style.overflow=\"hidden\",document.body.style.paddingRight=`${this.getScrollbarSize()}px`,this.open(t))}onClickHandler(e){this.el.classList.contains(\"open\")&&!this.menu.classList.contains(\"hidden\")?this.close():this.open()}onMouseEnterHandler(){if(\"hover\"!==this.eventMode)return!1;(!this.el._floatingUI||this.el._floatingUI&&!this.el.classList.contains(\"open\"))&&this.forceClearState(),!this.el.classList.contains(\"open\")&&this.menu.classList.contains(\"hidden\")&&this.open()}onMouseLeaveHandler(){if(\"hover\"!==this.eventMode)return!1;this.el.classList.contains(\"open\")&&!this.menu.classList.contains(\"hidden\")&&this.close()}destroyFloatingUI(){const e=(window.getComputedStyle(this.el).getPropertyValue(\"--scope\")||\"\").trim();this.menu.classList.remove(\"block\"),this.menu.classList.add(\"hidden\"),this.menu.style.inset=null,this.menu.style.position=null,this.el&&this.el._floatingUI&&(this.el._floatingUI.destroy(),this.el._floatingUI=null),\"window\"===e&&this.el.appendChild(this.menu),this.animationInProcess=!1}focusElement(){const e=this.menu.querySelector(\"[autofocus]\");if(!e)return!1;e.focus()}setupFloatingUI(e){const t=e||this.el,i=window.getComputedStyle(this.el),s=(i.getPropertyValue(\"--placement\")||\"\").trim(),n=(i.getPropertyValue(\"--flip\")||\"true\").trim(),l=(i.getPropertyValue(\"--strategy\")||\"fixed\").trim(),a=(i.getPropertyValue(\"--offset\")||\"6\").trim(),c=(i.getPropertyValue(\"--gpu-acceleration\")||\"true\").trim(),d=(window.getComputedStyle(this.el).getPropertyValue(\"--adaptive\")||\"adaptive\").replace(\" \",\"\"),h=l,u=parseInt(a,10),p=r.POSITIONS[s]||\"bottom-start\",m=[...\"true\"===n?[(0,o.flip)()]:[],(0,o.offset)(u)],g={placement:p,strategy:h,middleware:m},f=()=>{(0,o.computePosition)(t,this.menu,g).then((({x:e,y:t,placement:i})=>{\"absolute\"===h&&\"none\"===d?Object.assign(this.menu.style,{position:h,margin:\"0\"}):\"absolute\"===h?Object.assign(this.menu.style,{position:h,transform:`translate3d(${e}px, ${t}px, 0px)`,margin:\"0\"}):\"true\"===c?Object.assign(this.menu.style,{position:h,left:\"\",top:\"\",inset:\"0px auto auto 0px\",margin:\"0\",transform:`translate3d(${\"adaptive\"===d?e:0}px, ${t}px, 0)`}):Object.assign(this.menu.style,{position:h,left:`${e}px`,top:`${t}px`,margin:\"0\",transform:\"\"}),this.menu.setAttribute(\"data-placement\",i)}))};f();return{update:f,destroy:(0,o.autoUpdate)(t,this.menu,f)}}selectCheckbox(e){e.ariaChecked=\"true\"===e.ariaChecked?\"false\":\"true\"}selectRadio(e){if(\"true\"===e.ariaChecked)return!1;const t=e.closest(\".group\").querySelectorAll('[role=\"menuitemradio\"]');Array.from(t).filter((t=>t!==e)).forEach((e=>{e.ariaChecked=\"false\"})),e.ariaChecked=\"true\"}calculateFLoatingUIPosition(e){const t=this.setupFloatingUI(e),i=this.menu.getAttribute(\"data-placement\");return t.update(),t.destroy(),i}open(e){if(this.el.classList.contains(\"open\")||this.animationInProcess)return!1;this.animationInProcess=!0;const t=e||this.el,i=window.getComputedStyle(this.el),s=(i.getPropertyValue(\"--scope\")||\"\").trim(),o=(i.getPropertyValue(\"--strategy\")||\"fixed\").trim();\"window\"===s&&document.body.appendChild(this.menu),\"static\"!==o&&(this.el._floatingUI=this.setupFloatingUI(t)),this.menu.style.margin=null,this.menu.classList.remove(\"hidden\"),this.menu.classList.add(\"block\"),setTimeout((()=>{var e;(null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.toggle.ariaExpanded=\"true\"),this.el.classList.add(\"open\"),\"window\"===s&&this.menu.classList.add(\"open\"),this.animationInProcess=!1,this.hasAutofocus&&this.focusElement(),this.fireEvent(\"open\",this.el),(0,n.dispatch)(\"open.dropdown\",this.el,this.el)}))}close(e=!0){if(this.animationInProcess||!this.el.classList.contains(\"open\"))return!1;const t=(window.getComputedStyle(this.el).getPropertyValue(\"--scope\")||\"\").trim();if(this.animationInProcess=!0,\"window\"===t&&this.menu.classList.remove(\"open\"),e){const e=this.el.querySelector(\"[data-dropdown-transition]\")||this.menu;(0,n.afterTransition)(e,(()=>this.destroyFloatingUI()))}else this.destroyFloatingUI();(()=>{var e;this.menu.style.margin=null,(null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.toggle.ariaExpanded=\"false\"),this.el.classList.remove(\"open\"),this.fireEvent(\"close\",this.el),(0,n.dispatch)(\"close.dropdown\",this.el,this.el)})()}forceClearState(){this.destroyFloatingUI(),this.menu.style.margin=null,this.el.classList.remove(\"open\"),this.menu.classList.add(\"hidden\")}destroy(){(0,n.isIOS)()||(0,n.isIpadOS)()||(this.el.removeEventListener(\"mouseenter\",this.onElementMouseEnterListener),this.el.removeEventListener(\"mouseleave\",(()=>this.onElementMouseLeaveListener)),this.onElementMouseEnterListener=null,this.onElementMouseLeaveListener=null),\"contextmenu\"===this.eventMode?(this.toggle&&(this.toggle.removeEventListener(\"contextmenu\",this.onToggleContextMenuListener),this.toggle.removeEventListener(\"touchstart\",this.onTouchStartListener),this.toggle.removeEventListener(\"touchend\",this.onTouchEndListener),this.toggle.removeEventListener(\"touchmove\",this.onTouchEndListener)),this.onToggleContextMenuListener=null,this.onTouchStartListener=null,this.onTouchEndListener=null):(this.toggle&&this.toggle.removeEventListener(\"click\",this.onToggleClickListener),this.onToggleClickListener=null),this.closers.length&&(this.closers.forEach((e=>{e.removeEventListener(\"click\",this.onCloserClickListener.find((t=>t.el===e)).fn)})),this.onCloserClickListener=null),this.el.classList.remove(\"open\"),this.destroyFloatingUI(),window.$hsDropdownCollection=window.$hsDropdownCollection.filter((({element:e})=>e.el!==this.el))}static findInCollection(e){return window.$hsDropdownCollection.find((t=>e instanceof a?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static getInstance(e,t){const i=window.$hsDropdownCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){if(!window.$hsDropdownCollection){window.$hsDropdownCollection=[],document.addEventListener(\"keydown\",(e=>a.accessibility(e))),window.addEventListener(\"click\",(e=>{const t=e.target;a.closeCurrentlyOpened(t)}));let e=window.innerWidth;window.addEventListener(\"resize\",(()=>{window.innerWidth!==e&&(e=innerWidth,a.closeCurrentlyOpened(null,!1))}))}window.$hsDropdownCollection&&(window.$hsDropdownCollection=window.$hsDropdownCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\".dropdown:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsDropdownCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new a(e)}))}static open(e){const t=a.findInCollection(e);t&&t.element.menu.classList.contains(\"hidden\")&&t.element.open()}static close(e){const t=a.findInCollection(e);t&&!t.element.menu.classList.contains(\"hidden\")&&t.element.close()}static accessibility(e){this.history=n.menuSearchHistory;const t=window.$hsDropdownCollection.find((e=>e.element.el.classList.contains(\"open\")));if(t&&(r.DROPDOWN_ACCESSIBILITY_KEY_SET.includes(e.code)||4===e.code.length&&e.code[e.code.length-1].match(/^[A-Z]*$/))&&!e.metaKey&&!t.element.menu.querySelector(\"input:focus\")&&!t.element.menu.querySelector(\"textarea:focus\"))switch(e.code){case\"Escape\":t.element.menu.querySelector(\".select.active\")||(e.preventDefault(),this.onEscape(e));break;case\"Enter\":t.element.menu.querySelector(\".select button:focus\")||t.element.menu.querySelector(\".collapse-toggle:focus\")||this.onEnter(e);break;case\"ArrowUp\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrow();break;case\"ArrowDown\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrow(!1);break;case\"ArrowRight\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrowX(e,\"right\");break;case\"ArrowLeft\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrowX(e,\"left\");break;case\"Home\":e.preventDefault(),e.stopImmediatePropagation(),this.onStartEnd();break;case\"End\":e.preventDefault(),e.stopImmediatePropagation(),this.onStartEnd(!1);break;default:e.preventDefault(),this.onFirstLetter(e.key)}}static onEscape(e){const t=e.target.closest(\".dropdown.open\");if(window.$hsDropdownCollection.find((e=>e.element.el===t))){const e=window.$hsDropdownCollection.find((e=>e.element.el===t));e&&(e.element.close(),e.element.toggle.focus())}else this.closeCurrentlyOpened()}static onEnter(e){var t;const i=e.target,{element:s}=null!==(t=window.$hsDropdownCollection.find((e=>e.element.el===i.closest(\".dropdown\"))))&&void 0!==t?t:null;if(s&&i.classList.contains(\"dropdown-toggle\"))e.preventDefault(),s.open();else if(s&&\"menuitemcheckbox\"===i.getAttribute(\"role\"))s.selectCheckbox(i),s.close();else{if(!s||\"menuitemradio\"!==i.getAttribute(\"role\"))return!1;s.selectRadio(i),s.close()}}static onArrow(e=!0){const t=window.$hsDropdownCollection.find((e=>e.element.el.classList.contains(\"open\")));if(t){const i=t.element.menu;if(!i)return!1;const s=e?Array.from(i.querySelectorAll('a:not([hidden]), :scope button:not([hidden]), [role=\"button\"]:not([hidden]), [role^=\"menuitem\"]:not([hidden])')).reverse():Array.from(i.querySelectorAll('a:not([hidden]), :scope button:not([hidden]), [role=\"button\"]:not([hidden]), [role^=\"menuitem\"]:not([hidden], .dropdown-item, form)')),n=Array.from(s).filter((e=>{const t=e;return null===t.closest(\"[hidden]\")&&null!==t.offsetParent})).filter((e=>!e.classList.contains(\"disabled\"))),o=i.querySelector('a:focus, button:focus, [role=\"button\"]:focus, [role^=\"menuitem\"]:focus, .dropdown-item:focus, button:focus');let l=n.findIndex((e=>e===o));l+1e.element.el.classList.contains(\"open\")));if(t){const i=t.element.menu;if(!i)return!1;const s=(e?Array.from(i.querySelectorAll('a, button, [role=\"button\"], [role^=\"menuitem\"]')):Array.from(i.querySelectorAll('a, button, [role=\"button\"], [role^=\"menuitem\"]')).reverse()).filter((e=>!e.classList.contains(\"disabled\")));s.length&&s[0].focus()}}static onFirstLetter(e){const t=window.$hsDropdownCollection.find((e=>e.element.el.classList.contains(\"open\")));if(t){const i=t.element.menu;if(!i)return!1;const s=Array.from(i.querySelectorAll('a, [role=\"button\"], [role^=\"menuitem\"]')),n=()=>s.findIndex(((t,i)=>t.innerText.toLowerCase().charAt(0)===e.toLowerCase()&&this.history.existsInHistory(i)));let o=n();-1===o&&(this.history.clearHistory(),o=n()),-1!==o&&(s[o].focus(),this.history.addHistory(o))}}static closeCurrentlyOpened(e=null,t=!0){const i=e&&e.closest(\".dropdown\")&&e.closest(\".dropdown\").parentElement.closest(\".dropdown\")?e.closest(\".dropdown\").parentElement.closest(\".dropdown\"):null;let s=i?window.$hsDropdownCollection.filter((e=>e.element.el.classList.contains(\"open\")&&e.element.menu.closest(\".dropdown\").parentElement.closest(\".dropdown\")===i)):window.$hsDropdownCollection.filter((e=>e.element.el.classList.contains(\"open\")));e&&e.closest(\".dropdown\")&&\"inside\"===(0,n.getClassPropertyAlt)(e.closest(\".dropdown\"),\"--auto-close\")&&(s=s.filter((t=>t.element.el!==e.closest(\".dropdown\")))),e&&e.closest(\".dropdown\")&&\"outside\"===(0,n.getClassPropertyAlt)(e.closest(\".dropdown\"),\"--auto-close\")&&(s=s.filter((t=>t.element.el==e.closest(\".dropdown\"))),s.forEach((e=>e.element.close(t)))),s&&s.forEach((e=>{if(\"false\"===e.element.closeMode||\"outside\"===e.element.closeMode)return!1;e.element.close(t)})),s&&s.forEach((e=>{if(\"contextmenu\"!==(0,n.getClassPropertyAlt)(e.element.el,\"--trigger\"))return!1;document.body.style.overflow=\"\",document.body.style.paddingRight=\"\"}))}static on(e,t,i){const s=a.findInCollection(t);s&&(s.element.events[e]=i)}}window.addEventListener(\"load\",(()=>{a.autoInit()})),window.addEventListener(\"resize\",(()=>{window.$hsDropdownCollection||(window.$hsDropdownCollection=[]),window.$hsDropdownCollection.forEach((e=>e.element.resizeHandler()))})),\"undefined\"!=typeof window&&(window.HSDropdown=a),t.default=a},763:function(e,t,i){\n/*\n * HSCollapse\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287)),l=s(i(753));class r extends o.default{constructor(e,t,i){super(e,t,i),this.contentId=this.el.dataset.collapse,this.content=document.querySelector(this.contentId),this.animationInProcess=!1,this.content&&this.init()}elementClick(){this.content.classList.contains(\"open\")?this.hide():this.show()}init(){var e;this.createCollection(window.$hsCollapseCollection,this),this.onElementClickListener=()=>this.elementClick(),(null===(e=null==this?void 0:this.el)||void 0===e?void 0:e.ariaExpanded)&&(this.el.classList.contains(\"open\")?this.el.ariaExpanded=\"true\":this.el.ariaExpanded=\"false\"),this.el.addEventListener(\"click\",this.onElementClickListener)}hideAllMegaMenuItems(){this.content.querySelectorAll(\".mega-menu-content.block\").forEach((e=>{e.classList.remove(\"block\"),e.classList.add(\"hidden\")}))}closeDropdowns(){if(!this.content)return;this.content.querySelectorAll(\".dropdown\").forEach((e=>{try{const t=l.default.getInstance(e,!0);if(!(null==t?void 0:t.element))return;e instanceof HTMLElement&&e.classList.contains(\"open\")&&t.element.close(!1)}catch(e){console.warn(\"Error closing dropdown:\",e)}}))}show(){var e;if(this.animationInProcess||this.el.classList.contains(\"open\"))return!1;this.animationInProcess=!0,this.el.classList.add(\"open\"),(null===(e=null==this?void 0:this.el)||void 0===e?void 0:e.ariaExpanded)&&(this.el.ariaExpanded=\"true\"),this.content.classList.add(\"open\"),this.content.classList.remove(\"hidden\"),this.content.style.height=\"0\",setTimeout((()=>{this.content.style.height=`${this.content.scrollHeight}px`,this.fireEvent(\"beforeOpen\",this.el),(0,n.dispatch)(\"beforeOpen.collapse\",this.el,this.el)})),(0,n.afterTransition)(this.content,(()=>{this.content.style.height=\"\",this.fireEvent(\"open\",this.el),(0,n.dispatch)(\"open.collapse\",this.el,this.el),this.animationInProcess=!1}))}hide(){var e;if(this.animationInProcess||!this.el.classList.contains(\"open\"))return!1;this.animationInProcess=!0,this.el.classList.remove(\"open\"),(null===(e=null==this?void 0:this.el)||void 0===e?void 0:e.ariaExpanded)&&(this.el.ariaExpanded=\"false\"),this.content.style.height=`${this.content.scrollHeight}px`,setTimeout((()=>{this.content.style.height=\"0\"})),this.content.classList.remove(\"open\"),(0,n.afterTransition)(this.content,(()=>{this.content.classList.add(\"hidden\"),this.content.style.height=\"\",this.fireEvent(\"hide\",this.el),(0,n.dispatch)(\"hide.collapse\",this.el,this.el),this.animationInProcess=!1})),this.content.querySelectorAll(\".mega-menu-content.block\").length&&this.hideAllMegaMenuItems(),this.closeDropdowns()}destroy(){this.el.removeEventListener(\"click\",this.onElementClickListener),this.content=null,this.animationInProcess=!1,window.$hsCollapseCollection=window.$hsCollapseCollection.filter((({element:e})=>e.el!==this.el))}static findInCollection(e){return window.$hsCollapseCollection.find((t=>e instanceof r?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static getInstance(e,t=!1){const i=window.$hsCollapseCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsCollapseCollection||(window.$hsCollapseCollection=[]),window.$hsCollapseCollection&&(window.$hsCollapseCollection=window.$hsCollapseCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\".collapse-toggle:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsCollapseCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new r(e)}))}static show(e){const t=r.findInCollection(e);t&&t.element.content.classList.contains(\"hidden\")&&t.element.show()}static hide(e){const t=r.findInCollection(e);t&&!t.element.content.classList.contains(\"hidden\")&&t.element.hide()}static on(e,t,i){const s=r.findInCollection(t);s&&(s.element.events[e]=i)}}window.addEventListener(\"load\",(()=>{r.autoInit()})),\"undefined\"!=typeof window&&(window.HSCollapse=r),t.default=r},782:function(e,t,i){\n/*\n * HSTreeView\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t,i){super(e,t,i),this.items=[];const s=e.getAttribute(\"data-tree-view\"),n=s?JSON.parse(s):{},o=Object.assign(Object.assign({},n),t);this.controlBy=(null==o?void 0:o.controlBy)||\"button\",this.autoSelectChildren=(null==o?void 0:o.autoSelectChildren)||!1,this.isIndeterminate=(null==o?void 0:o.isIndeterminate)||!0,this.onElementClickListener=[],this.onControlChangeListener=[],this.init()}elementClick(e,t,i){if(e.stopPropagation(),t.classList.contains(\"disabled\"))return!1;e.metaKey||e.shiftKey||this.unselectItem(i),this.selectItem(t,i),this.fireEvent(\"click\",{el:t,data:i}),(0,n.dispatch)(\"click.treeView\",this.el,{el:t,data:i})}controlChange(e,t){this.autoSelectChildren?(this.selectItem(e,t),t.isDir&&this.selectChildren(e,t),this.toggleParent(e)):this.selectItem(e,t)}init(){this.createCollection(window.$hsTreeViewCollection,this),l.group+=1,this.initItems()}initItems(){this.el.querySelectorAll(\"[data-tree-view-item]\").forEach(((e,t)=>{var i,s;const n=JSON.parse(e.getAttribute(\"data-tree-view-item\"));e.id||(e.id=`tree-view-item-${l.group}-${t}`);const o=Object.assign(Object.assign({},n),{id:null!==(i=n.id)&&void 0!==i?i:e.id,path:this.getPath(e),isSelected:null!==(s=n.isSelected)&&void 0!==s&&s});this.items.push(o),\"checkbox\"===this.controlBy?this.controlByCheckbox(e,o):this.controlByButton(e,o)}))}controlByButton(e,t){this.onElementClickListener.push({el:e,fn:i=>this.elementClick(i,e,t)}),e.addEventListener(\"click\",this.onElementClickListener.find((t=>t.el===e)).fn)}controlByCheckbox(e,t){const i=e.querySelector(`input[value=\"${t.value}\"]`);i&&(this.onControlChangeListener.push({el:i,fn:()=>this.controlChange(e,t)}),i.addEventListener(\"change\",this.onControlChangeListener.find((e=>e.el===i)).fn))}getItem(e){return this.items.find((t=>t.id===e))}getPath(e){var t;const i=[];let s=e.closest(\"[data-tree-view-item]\");for(;s;){const e=JSON.parse(s.getAttribute(\"data-tree-view-item\"));i.push(e.value),s=null===(t=s.parentElement)||void 0===t?void 0:t.closest(\"[data-tree-view-item]\")}return i.reverse().join(\"/\")}unselectItem(e=null){let t=this.getSelectedItems();e&&(t=t.filter((t=>t.id!==e.id))),t.length&&t.forEach((e=>{document.querySelector(`#${e.id}`).classList.remove(\"selected\"),this.changeItemProp(e.id,\"isSelected\",!1)}))}selectItem(e,t){t.isSelected?(e.classList.remove(\"selected\"),this.changeItemProp(t.id,\"isSelected\",!1)):(e.classList.add(\"selected\"),this.changeItemProp(t.id,\"isSelected\",!0))}selectChildren(e,t){const i=e.querySelectorAll(\"[data-tree-view-item]\");Array.from(i).filter((e=>!e.classList.contains(\"disabled\"))).forEach((e=>{const i=e.id?this.getItem(e.id):null;if(!i)return!1;t.isSelected?(e.classList.add(\"selected\"),this.changeItemProp(i.id,\"isSelected\",!0)):(e.classList.remove(\"selected\"),this.changeItemProp(i.id,\"isSelected\",!1));const s=this.getItem(e.id),n=e.querySelector(`input[value=\"${s.value}\"]`);this.isIndeterminate&&(n.indeterminate=!1),s.isSelected?n.checked=!0:n.checked=!1}))}toggleParent(e){var t,i;let s=null===(t=e.parentElement)||void 0===t?void 0:t.closest(\"[data-tree-view-item]\");for(;s;){const e=s.querySelectorAll(\"[data-tree-view-item]:not(.disabled)\"),t=JSON.parse(s.getAttribute(\"data-tree-view-item\")),n=s.querySelector(`input[value=\"${t.value}\"]`);let o=!1,l=0;e.forEach((e=>{const t=this.getItem(e.id);t.isSelected&&(l+=1),t.isSelected||(o=!0)})),o?(s.classList.remove(\"selected\"),this.changeItemProp(s.id,\"isSelected\",!1),n.checked=!1):(s.classList.add(\"selected\"),this.changeItemProp(s.id,\"isSelected\",!0),n.checked=!0),this.isIndeterminate&&(l>0&&l{const t=document.querySelector(`#${e.id}`);return e.path!==this.getPath(t)&&(e.path=this.getPath(t)),e}))}getSelectedItems(){return this.items.filter((e=>e.isSelected))}changeItemProp(e,t,i){this.items.map((s=>(s.id===e&&(s[t]=i),s)))}destroy(){this.onElementClickListener.forEach((({el:e,fn:t})=>{e.removeEventListener(\"click\",t)})),this.onControlChangeListener.length&&this.onElementClickListener.forEach((({el:e,fn:t})=>{e.removeEventListener(\"change\",t)})),this.unselectItem(),this.items=[],window.$hsTreeViewCollection=window.$hsTreeViewCollection.filter((({element:e})=>e.el!==this.el)),l.group-=1}static findInCollection(e){return window.$hsTreeViewCollection.find((t=>e instanceof l?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static getInstance(e,t){const i=window.$hsTreeViewCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsTreeViewCollection||(window.$hsTreeViewCollection=[]),window.$hsTreeViewCollection&&(window.$hsTreeViewCollection=window.$hsTreeViewCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-tree-view]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsTreeViewCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}static on(e,t,i){const s=l.findInCollection(t);s&&(s.element.events[e]=i)}}l.group=0,window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSTreeView=l),t.default=l},792:function(e,t,i){\n/*\n * HSDataTable\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t,i){var s,n,o,l,r,a,c,d,h,u,p,m,g,f,v,w,y,b,C,S,L,I;super(e,t,i),this.el=\"string\"==typeof e?document.querySelector(e):e;const E=[];Array.from(this.el.querySelectorAll(\"thead th, thead td\")).forEach(((e,t)=>{e.classList.contains(\"--exclude-from-ordering\")&&E.push({targets:t,orderable:!1})}));const T=this.el.getAttribute(\"data-datatable\"),x=T?JSON.parse(T):{};this.concatOptions=Object.assign(Object.assign({searching:!0,lengthChange:!1,order:[],columnDefs:[...E]},x),t),this.table=this.el.querySelector(\"table\"),this.searches=null!==(s=Array.from(this.el.querySelectorAll(\"[data-datatable-search]\")))&&void 0!==s?s:null,this.pageEntitiesList=null!==(n=Array.from(this.el.querySelectorAll(\"[data-datatable-page-entities]\")))&&void 0!==n?n:null,this.pagingList=null!==(o=Array.from(this.el.querySelectorAll(\"[data-datatable-paging]\")))&&void 0!==o?o:null,this.pagingPagesList=null!==(l=Array.from(this.el.querySelectorAll(\"[data-datatable-paging-pages]\")))&&void 0!==l?l:null,this.pagingPrevList=null!==(r=Array.from(this.el.querySelectorAll(\"[data-datatable-paging-prev]\")))&&void 0!==r?r:null,this.pagingNextList=null!==(a=Array.from(this.el.querySelectorAll(\"[data-datatable-paging-next]\")))&&void 0!==a?a:null,this.infoList=null!==(c=Array.from(this.el.querySelectorAll(\"[data-datatable-info]\")))&&void 0!==c?c:null,(null===(d=this.concatOptions)||void 0===d?void 0:d.rowSelectingOptions)&&(this.rowSelectingAll=null!==(g=(null===(u=null===(h=this.concatOptions)||void 0===h?void 0:h.rowSelectingOptions)||void 0===u?void 0:u.selectAllSelector)?document.querySelector(null===(m=null===(p=this.concatOptions)||void 0===p?void 0:p.rowSelectingOptions)||void 0===m?void 0:m.selectAllSelector):document.querySelector(\"[data-datatable-row-selecting-all]\"))&&void 0!==g?g:null),(null===(f=this.concatOptions)||void 0===f?void 0:f.rowSelectingOptions)&&(this.rowSelectingIndividual=null!==(b=null!==(y=null===(w=null===(v=this.concatOptions)||void 0===v?void 0:v.rowSelectingOptions)||void 0===w?void 0:w.individualSelector)&&void 0!==y?y:\"[data-datatable-row-selecting-individual]\")&&void 0!==b?b:null),this.pageEntitiesList.length&&(this.concatOptions.pageLength=parseInt(this.pageEntitiesList[0].value)),this.maxPagesToShow=3,this.isRowSelecting=!!(null===(C=this.concatOptions)||void 0===C?void 0:C.rowSelectingOptions),this.pageBtnClasses=null!==(I=null===(L=null===(S=this.concatOptions)||void 0===S?void 0:S.pagingOptions)||void 0===L?void 0:L.pageBtnClasses)&&void 0!==I?I:null,this.onSearchInputListener=[],this.onPageEntitiesChangeListener=[],this.onSinglePagingClickListener=[],this.onPagingPrevClickListener=[],this.onPagingNextClickListener=[],this.init()}init(){this.createCollection(window.$hsDataTableCollection,this),this.initTable(),this.searches.length&&this.initSearch(),this.pageEntitiesList.length&&this.initPageEntities(),this.pagingList.length&&this.initPaging(),this.pagingPagesList.length&&this.buildPagingPages(),this.pagingPrevList.length&&this.initPagingPrev(),this.pagingNextList.length&&this.initPagingNext(),this.infoList.length&&this.initInfo(),this.isRowSelecting&&this.initRowSelecting()}initTable(){this.dataTable=new DataTable(this.table,this.concatOptions),this.isRowSelecting&&this.triggerChangeEventToRow(),this.dataTable.on(\"draw\",(()=>{this.isRowSelecting&&this.updateSelectAllCheckbox(),this.isRowSelecting&&this.triggerChangeEventToRow(),this.updateInfo(),this.pagingPagesList.forEach((e=>this.updatePaging(e)))}))}searchInput(e){this.onSearchInput(e.target.value)}pageEntitiesChange(e){this.onEntitiesChange(parseInt(e.target.value),e.target)}pagingPrevClick(){this.onPrevClick()}pagingNextClick(){this.onNextClick()}rowSelectingAllChange(){this.onSelectAllChange()}singlePagingClick(e){this.onPageClick(e)}initSearch(){this.searches.forEach((e=>{this.onSearchInputListener.push({el:e,fn:(0,n.debounce)((e=>this.searchInput(e)))}),e.addEventListener(\"input\",this.onSearchInputListener.find((t=>t.el===e)).fn)}))}onSearchInput(e){this.dataTable.search(e).draw()}initPageEntities(){this.pageEntitiesList.forEach((e=>{this.onPageEntitiesChangeListener.push({el:e,fn:e=>this.pageEntitiesChange(e)}),e.addEventListener(\"change\",this.onPageEntitiesChangeListener.find((t=>t.el===e)).fn)}))}onEntitiesChange(e,t){const i=this.pageEntitiesList.filter((e=>e!==t));i.length&&i.forEach((t=>{if(window.HSSelect){const i=window.HSSelect.getInstance(t,!0);i&&i.element.setValue(`${e}`)}else t.value=`${e}`})),this.dataTable.page.len(e).draw()}initInfo(){this.infoList.forEach((e=>{this.initInfoFrom(e),this.initInfoTo(e),this.initInfoLength(e)}))}initInfoFrom(e){var t;const i=null!==(t=e.querySelector(\"[data-datatable-info-from]\"))&&void 0!==t?t:null,{start:s}=this.dataTable.page.info();i&&(i.innerText=`${s+1}`)}initInfoTo(e){var t;const i=null!==(t=e.querySelector(\"[data-datatable-info-to]\"))&&void 0!==t?t:null,{end:s}=this.dataTable.page.info();i&&(i.innerText=`${s}`)}initInfoLength(e){var t;const i=null!==(t=e.querySelector(\"[data-datatable-info-length]\"))&&void 0!==t?t:null,{recordsTotal:s}=this.dataTable.page.info();i&&(i.innerText=`${s}`)}updateInfo(){this.initInfo()}initPaging(){this.pagingList.forEach((e=>this.hidePagingIfSinglePage(e)))}hidePagingIfSinglePage(e){const{pages:t}=this.dataTable.page.info();t<2?(e.classList.add(\"hidden\"),e.style.display=\"none\"):(e.classList.remove(\"hidden\"),e.style.display=\"\")}initPagingPrev(){this.pagingPrevList.forEach((e=>{this.onPagingPrevClickListener.push({el:e,fn:()=>this.pagingPrevClick()}),e.addEventListener(\"click\",this.onPagingPrevClickListener.find((t=>t.el===e)).fn)}))}onPrevClick(){this.dataTable.page(\"previous\").draw(\"page\")}disablePagingArrow(e,t){t?(e.classList.add(\"disabled\"),e.setAttribute(\"disabled\",\"disabled\")):(e.classList.remove(\"disabled\"),e.removeAttribute(\"disabled\"))}initPagingNext(){this.pagingNextList.forEach((e=>{this.onPagingNextClickListener.push({el:e,fn:()=>this.pagingNextClick()}),e.addEventListener(\"click\",this.onPagingNextClickListener.find((t=>t.el===e)).fn)}))}onNextClick(){this.dataTable.page(\"next\").draw(\"page\")}buildPagingPages(){this.pagingPagesList.forEach((e=>this.updatePaging(e)))}updatePaging(e){const{page:t,pages:i,length:s}=this.dataTable.page.info(),o=this.dataTable.rows({search:\"applied\"}).count(),l=Math.ceil(o/s),r=t+1;let a=Math.max(1,r-Math.floor(this.maxPagesToShow/2)),c=Math.min(l,a+(this.maxPagesToShow-1));c-a+11&&(this.buildPagingPage(1,e),a>2&&e.appendChild((0,n.htmlToElement)('...')));for(let t=a;t<=c;t++)this.buildPagingPage(t,e);c...')),this.buildPagingPage(l,e)),this.pagingPrevList.forEach((e=>this.disablePagingArrow(e,0===t))),this.pagingNextList.forEach((e=>this.disablePagingArrow(e,t===i-1))),this.pagingList.forEach((e=>this.hidePagingIfSinglePage(e)))}buildPagingPage(e,t){const{page:i}=this.dataTable.page.info(),s=(0,n.htmlToElement)('');s.innerText=`${e}`,s.setAttribute(\"data-page\",`${e}`),this.pageBtnClasses&&(0,n.classToClassList)(this.pageBtnClasses,s),i===e-1&&s.classList.add(\"active\"),this.onSinglePagingClickListener.push({el:s,fn:()=>this.singlePagingClick(e)}),s.addEventListener(\"click\",this.onSinglePagingClickListener.find((e=>e.el===s)).fn),t.append(s)}onPageClick(e){this.dataTable.page(e-1).draw(\"page\")}initRowSelecting(){this.onRowSelectingAllChangeListener=()=>this.rowSelectingAllChange(),this.rowSelectingAll.addEventListener(\"change\",this.onRowSelectingAllChangeListener)}triggerChangeEventToRow(){this.table.querySelectorAll(`tbody ${this.rowSelectingIndividual}`).forEach((e=>{e.addEventListener(\"change\",(()=>{this.updateSelectAllCheckbox()}))}))}onSelectAllChange(){let e=this.rowSelectingAll.checked;Array.from(this.dataTable.rows({page:\"current\",search:\"applied\"}).nodes()).forEach((t=>{const i=t.querySelector(this.rowSelectingIndividual);i&&(i.checked=e)})),this.updateSelectAllCheckbox()}updateSelectAllCheckbox(){if(!this.dataTable.rows({search:\"applied\"}).count())return this.rowSelectingAll.checked=!1,!1;let e=!0;Array.from(this.dataTable.rows({page:\"current\",search:\"applied\"}).nodes()).forEach((t=>{const i=t.querySelector(this.rowSelectingIndividual);if(i&&!i.checked)return e=!1,!1})),this.rowSelectingAll.checked=e}destroy(){this.searches&&this.onSearchInputListener.forEach((({el:e,fn:t})=>e.removeEventListener(\"click\",t))),this.pageEntitiesList&&this.onPageEntitiesChangeListener.forEach((({el:e,fn:t})=>e.removeEventListener(\"change\",t))),this.pagingPagesList.length&&(this.onSinglePagingClickListener.forEach((({el:e,fn:t})=>e.removeEventListener(\"click\",t))),this.pagingPagesList.forEach((e=>e.innerHTML=\"\"))),this.pagingPrevList.length&&this.onPagingPrevClickListener.forEach((({el:e,fn:t})=>e.removeEventListener(\"click\",t))),this.pagingNextList.length&&this.onPagingNextClickListener.forEach((({el:e,fn:t})=>e.removeEventListener(\"click\",t))),this.rowSelectingAll&&this.rowSelectingAll.removeEventListener(\"change\",this.onRowSelectingAllChangeListener),this.dataTable.destroy(),this.rowSelectingAll=null,this.rowSelectingIndividual=null,window.$hsDataTableCollection=window.$hsDataTableCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsDataTableCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsDataTableCollection||(window.$hsDataTableCollection=[]),window.$hsDataTableCollection&&(window.$hsDataTableCollection=window.$hsDataTableCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-datatable]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsDataTableCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{document.querySelectorAll(\"[data-datatable]:not(.--prevent-on-load-init)\").length&&(\"undefined\"==typeof jQuery&&console.error(\"HSDataTable: jQuery is not available, please add it to the page.\"),\"undefined\"==typeof DataTable&&console.error(\"HSDataTable: DataTable is not available, please add it to the page.\")),\"undefined\"!=typeof DataTable&&\"undefined\"!=typeof jQuery&&l.autoInit()})),\"undefined\"!=typeof window&&(window.HSDataTable=l),t.default=l},800:function(e,t,i){\n/*\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};let n,o,l;Object.defineProperty(t,\"__esModule\",{value:!0}),t.HSRangeSlider=t.HSFileUpload=t.HSDataTable=t.HSStaticMethods=t.HSTreeView=t.HSTooltip=t.HSTogglePassword=t.HSToggleCount=t.HSTabs=t.HSStrongPassword=t.HSStepper=t.HSSelect=t.HSScrollspy=t.HSRemoveElement=t.HSPinInput=t.HSOverlay=t.HSInputNumber=t.HSDropdown=t.HSComboBox=t.HSCollapse=t.HSCarousel=t.HSAccordion=t.HSCopyMarkup=void 0;var r=i(12);Object.defineProperty(t,\"HSCopyMarkup\",{enumerable:!0,get:function(){return s(r).default}});var a=i(306);Object.defineProperty(t,\"HSAccordion\",{enumerable:!0,get:function(){return s(a).default}});var c=i(302);Object.defineProperty(t,\"HSCarousel\",{enumerable:!0,get:function(){return s(c).default}});var d=i(763);Object.defineProperty(t,\"HSCollapse\",{enumerable:!0,get:function(){return s(d).default}});var h=i(75);Object.defineProperty(t,\"HSComboBox\",{enumerable:!0,get:function(){return s(h).default}});var u=i(753);Object.defineProperty(t,\"HSDropdown\",{enumerable:!0,get:function(){return s(u).default}});var p=i(86);Object.defineProperty(t,\"HSInputNumber\",{enumerable:!0,get:function(){return s(p).default}});var m=i(164);Object.defineProperty(t,\"HSOverlay\",{enumerable:!0,get:function(){return s(m).default}});var g=i(594);Object.defineProperty(t,\"HSPinInput\",{enumerable:!0,get:function(){return s(g).default}});var f=i(113);Object.defineProperty(t,\"HSRemoveElement\",{enumerable:!0,get:function(){return s(f).default}});var v=i(881);Object.defineProperty(t,\"HSScrollspy\",{enumerable:!0,get:function(){return s(v).default}});var w=i(956);Object.defineProperty(t,\"HSSelect\",{enumerable:!0,get:function(){return s(w).default}});var y=i(213);Object.defineProperty(t,\"HSStepper\",{enumerable:!0,get:function(){return s(y).default}});var b=i(207);Object.defineProperty(t,\"HSStrongPassword\",{enumerable:!0,get:function(){return s(b).default}});var C=i(944);Object.defineProperty(t,\"HSTabs\",{enumerable:!0,get:function(){return s(C).default}});var S=i(126);Object.defineProperty(t,\"HSToggleCount\",{enumerable:!0,get:function(){return s(S).default}});var L=i(234);Object.defineProperty(t,\"HSTogglePassword\",{enumerable:!0,get:function(){return s(L).default}});var I=i(487);Object.defineProperty(t,\"HSTooltip\",{enumerable:!0,get:function(){return s(I).default}});var E=i(782);Object.defineProperty(t,\"HSTreeView\",{enumerable:!0,get:function(){return s(E).default}});var T=i(319);Object.defineProperty(t,\"HSStaticMethods\",{enumerable:!0,get:function(){return s(T).default}}),\"undefined\"!=typeof DataTable&&\"undefined\"!=typeof jQuery?t.HSDataTable=n=i(792).default:t.HSDataTable=n=null,\"undefined\"!=typeof _&&\"undefined\"!=typeof Dropzone?t.HSFileUpload=o=i(192).default:t.HSFileUpload=o=null,\"undefined\"!=typeof noUiSlider?t.HSRangeSlider=l=i(977).default:t.HSRangeSlider=l=null},806:function(e,t){\n/*\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nObject.defineProperty(t,\"__esModule\",{value:!0}),t.menuSearchHistory=t.classToClassList=t.htmlToElement=t.afterTransition=t.dispatch=t.debounce=t.isScrollable=t.isParentOrElementHidden=t.isJson=t.isIpadOS=t.isIOS=t.isDirectChild=t.isFormElement=t.isFocused=t.isEnoughSpace=t.getHighestZIndex=t.getZIndex=t.getClassPropertyAlt=t.getClassProperty=t.stringToBoolean=void 0;t.stringToBoolean=e=>\"true\"===e;t.getClassProperty=(e,t,i=\"\")=>(window.getComputedStyle(e).getPropertyValue(t)||i).replace(\" \",\"\");t.getClassPropertyAlt=(e,t,i=\"\")=>{let s=\"\";return e.classList.forEach((e=>{e.includes(t)&&(s=e)})),s.match(/:(.*)]/)?s.match(/:(.*)]/)[1]:i};const i=e=>window.getComputedStyle(e).getPropertyValue(\"z-index\");t.getZIndex=i;t.getHighestZIndex=e=>{let t=Number.NEGATIVE_INFINITY;return e.forEach((e=>{let s=i(e);\"auto\"!==s&&(s=parseInt(s,10),s>t&&(t=s))})),t};t.isDirectChild=(e,t)=>{const i=e.children;for(let e=0;e{const o=t.getBoundingClientRect(),l=n?n.getBoundingClientRect():null,r=window.innerHeight,a=l?o.top-l.top:o.top,c=(n?l.bottom:r)-o.bottom,d=e.clientHeight+s;return\"bottom\"===i?c>=d:\"top\"===i?a>=d:a>=d||c>=d};t.isFocused=e=>document.activeElement===e;t.isFormElement=e=>e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement;t.isIOS=()=>!!/iPad|iPhone|iPod/.test(navigator.platform)||navigator.maxTouchPoints&&navigator.maxTouchPoints>2&&/MacIntel/.test(navigator.platform);t.isIpadOS=()=>navigator.maxTouchPoints&&navigator.maxTouchPoints>2&&/MacIntel/.test(navigator.platform);t.isJson=e=>{if(\"string\"!=typeof e)return!1;const t=e.trim()[0],i=e.trim().slice(-1);if(\"{\"===t&&\"}\"===i||\"[\"===t&&\"]\"===i)try{return JSON.parse(e),!0}catch(e){return!1}return!1};const s=e=>{if(!e)return!1;return\"none\"===window.getComputedStyle(e).display||s(e.parentElement)};t.isParentOrElementHidden=s;t.isScrollable=e=>{const t=window.getComputedStyle(e),i=t.overflowY,s=t.overflowX,n=(\"scroll\"===i||\"auto\"===i)&&e.scrollHeight>e.clientHeight,o=(\"scroll\"===s||\"auto\"===s)&&e.scrollWidth>e.clientWidth;return n||o};t.debounce=(e,t=200)=>{let i;return(...s)=>{clearTimeout(i),i=setTimeout((()=>{e.apply(this,s)}),t)}};t.dispatch=(e,t,i=null)=>{const s=new CustomEvent(e,{detail:{payload:i},bubbles:!0,cancelable:!0,composed:!1});t.dispatchEvent(s)};t.afterTransition=(e,t)=>{const i=()=>{t(),e.removeEventListener(\"transitionend\",i,!0)},s=window.getComputedStyle(e),n=s.getPropertyValue(\"transition-duration\");\"none\"!==s.getPropertyValue(\"transition-property\")&&parseFloat(n)>0?e.addEventListener(\"transitionend\",i,!0):t()};t.htmlToElement=e=>{const t=document.createElement(\"template\");return e=e.trim(),t.innerHTML=e,t.content.firstChild};t.classToClassList=(e,t,i=\" \",s=\"add\")=>{e.split(i).forEach((e=>\"add\"===s?t.classList.add(e):t.classList.remove(e)))};const n={historyIndex:-1,addHistory(e){this.historyIndex=e},existsInHistory(e){return e>this.historyIndex},clearHistory(){this.historyIndex=-1}};t.menuSearchHistory=n},881:function(e,t,i){\n/*\n * HSScrollspy\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287));class l extends o.default{constructor(e,t={}){super(e,t),this.isScrollingDown=!1,this.lastScrollTop=0;const i=e.getAttribute(\"data-scrollspy-options\"),s=i?JSON.parse(i):{},n=Object.assign(Object.assign({},s),t);this.ignoreScrollUp=void 0!==n.ignoreScrollUp&&n.ignoreScrollUp,this.links=this.el.querySelectorAll(\"[href]\"),this.sections=[],this.scrollableId=this.el.getAttribute(\"data-scrollspy-scrollable-parent\"),this.scrollable=this.scrollableId?document.querySelector(this.scrollableId):document,this.onLinkClickListener=[],this.init()}scrollableScroll(e){const t=this.scrollable instanceof HTMLElement?this.scrollable.scrollTop:window.scrollY;this.isScrollingDown=t>this.lastScrollTop,this.lastScrollTop=t<=0?0:t,Array.from(this.sections).forEach((t=>{if(!t.getAttribute(\"id\"))return!1;this.update(e,t)}))}init(){this.createCollection(window.$hsScrollspyCollection,this),this.links.forEach((e=>{this.sections.push(this.scrollable.querySelector(e.getAttribute(\"href\")))})),this.onScrollableScrollListener=e=>this.scrollableScroll(e),this.scrollable.addEventListener(\"scroll\",this.onScrollableScrollListener),this.links.forEach((e=>{this.onLinkClickListener.push({el:e,fn:t=>this.linkClick(t,e)}),e.addEventListener(\"click\",this.onLinkClickListener.find((t=>t.el===e)).fn)}))}determineScrollDirection(e){const t=this.el.querySelector(\"a.active\");if(!t)return!0;const i=Array.from(this.links).indexOf(t),s=Array.from(this.links).indexOf(e);return-1===s||s>i}linkClick(e,t){e.preventDefault();const i=t.getAttribute(\"href\");if(!i||\"javascript:;\"===i)return;(i?document.querySelector(i):null)&&(this.isScrollingDown=this.determineScrollDirection(t),this.scrollTo(t))}update(e,t){const i=parseInt((0,n.getClassProperty)(this.el,\"--scrollspy-offset\",\"0\")),s=parseInt((0,n.getClassProperty)(t,\"--scrollspy-offset\"))||i,o=e.target===document?0:parseInt(String(e.target.getBoundingClientRect().top)),l=parseInt(String(t.getBoundingClientRect().top))-s-o,r=t.offsetHeight;if(this.ignoreScrollUp||this.isScrollingDown?l<=0&&l+r>0:l<=0&&le.classList.remove(\"active\")));const e=this.el.querySelector(`[href=\"#${t.getAttribute(\"id\")}\"]`);if(e){e.classList.add(\"active\");const t=e.closest(\"[data-scrollspy-group]\");if(t){const e=t.querySelector(\"[href]\");e&&e.classList.add(\"active\")}}this.fireEvent(\"afterScroll\",e),(0,n.dispatch)(\"afterScroll.scrollspy\",e,this.el)}}scrollTo(e){const t=e.getAttribute(\"href\"),i=document.querySelector(t),s=parseInt((0,n.getClassProperty)(this.el,\"--scrollspy-offset\",\"0\")),o=parseInt((0,n.getClassProperty)(i,\"--scrollspy-offset\"))||s,l=this.scrollable===document?0:this.scrollable.offsetTop,r=i.offsetTop-o-l,a=this.scrollable===document?window:this.scrollable,c=()=>{window.history.replaceState(null,null,e.getAttribute(\"href\")),\"scrollTo\"in a&&a.scrollTo({top:r,left:0,behavior:\"smooth\"})},d=this.fireEvent(\"beforeScroll\",this.el);(0,n.dispatch)(\"beforeScroll.scrollspy\",this.el,this.el),d instanceof Promise?d.then((()=>c())):c()}destroy(){this.el.querySelector(\"[href].active\").classList.remove(\"active\"),this.scrollable.removeEventListener(\"scroll\",this.onScrollableScrollListener),this.onLinkClickListener.length&&this.onLinkClickListener.forEach((({el:e,fn:t})=>{e.removeEventListener(\"click\",t)})),window.$hsScrollspyCollection=window.$hsScrollspyCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t=!1){const i=window.$hsScrollspyCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsScrollspyCollection||(window.$hsScrollspyCollection=[]),window.$hsScrollspyCollection&&(window.$hsScrollspyCollection=window.$hsScrollspyCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-scrollspy]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsScrollspyCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new l(e)}))}}window.addEventListener(\"load\",(()=>{l.autoInit()})),\"undefined\"!=typeof window&&(window.HSScrollspy=l),t.default=l},917:(e,t)=>{Object.defineProperty(t,\"__esModule\",{value:!0}),t.BREAKPOINTS=t.COMBO_BOX_ACCESSIBILITY_KEY_SET=t.SELECT_ACCESSIBILITY_KEY_SET=t.TABS_ACCESSIBILITY_KEY_SET=t.OVERLAY_ACCESSIBILITY_KEY_SET=t.DROPDOWN_ACCESSIBILITY_KEY_SET=t.POSITIONS=void 0,t.POSITIONS={auto:\"auto\",\"auto-start\":\"auto-start\",\"auto-end\":\"auto-end\",top:\"top\",\"top-start\":\"top-start\",\"top-end\":\"top-end\",bottom:\"bottom\",\"bottom-start\":\"bottom-start\",\"bottom-end\":\"bottom-end\",right:\"right\",\"right-start\":\"right-start\",\"right-end\":\"right-end\",left:\"left\",\"left-start\":\"left-start\",\"left-end\":\"left-end\"},t.DROPDOWN_ACCESSIBILITY_KEY_SET=[\"Escape\",\"ArrowUp\",\"ArrowDown\",\"ArrowRight\",\"ArrowLeft\",\"Home\",\"End\",\"Enter\"],t.OVERLAY_ACCESSIBILITY_KEY_SET=[\"Escape\",\"Tab\"],t.TABS_ACCESSIBILITY_KEY_SET=[\"ArrowUp\",\"ArrowLeft\",\"ArrowDown\",\"ArrowRight\",\"Home\",\"End\"],t.SELECT_ACCESSIBILITY_KEY_SET=[\"ArrowUp\",\"ArrowLeft\",\"ArrowDown\",\"ArrowRight\",\"Home\",\"End\",\"Escape\",\"Enter\",\"Space\",\"Tab\"],t.COMBO_BOX_ACCESSIBILITY_KEY_SET=[\"ArrowUp\",\"ArrowLeft\",\"ArrowDown\",\"ArrowRight\",\"Home\",\"End\",\"Escape\",\"Enter\"],t.BREAKPOINTS={xs:0,sm:640,md:768,lg:1024,xl:1280,\"2xl\":1536}},944:function(e,t,i){\n/*\n * HSTabs\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=i(806),o=s(i(287)),l=i(917);class r extends o.default{constructor(e,t,i){var s,n;super(e,t,i);const o=e.getAttribute(\"data-tabs\"),r=o?JSON.parse(o):{},a=Object.assign(Object.assign({},r),t);this.eventType=null!==(s=a.eventType)&&void 0!==s?s:\"click\",this.preventNavigationResolution=\"number\"==typeof a.preventNavigationResolution?a.preventNavigationResolution:l.BREAKPOINTS[a.preventNavigationResolution]||null,this.toggles=this.el.querySelectorAll(\"[data-tab]\"),this.extraToggleId=this.el.getAttribute(\"data-tab-select\"),this.extraToggle=this.extraToggleId?document.querySelector(this.extraToggleId):null,this.current=Array.from(this.toggles).find((e=>e.classList.contains(\"active\"))),this.currentContentId=(null===(n=this.current)||void 0===n?void 0:n.getAttribute(\"data-tab\"))||null,this.currentContent=this.currentContentId?document.querySelector(this.currentContentId):null,this.prev=null,this.prevContentId=null,this.prevContent=null,this.onToggleHandler=[],this.init()}toggle(e){this.open(e)}extraToggleChange(e){this.change(e)}init(){this.createCollection(window.$hsTabsCollection,this),this.toggles.forEach((e=>{const t=t=>{\"click\"===this.eventType&&this.preventNavigationResolution&&document.body.clientWidth<=+this.preventNavigationResolution&&t.preventDefault(),this.toggle(e)},i=e=>{this.preventNavigationResolution&&document.body.clientWidth<=+this.preventNavigationResolution&&e.preventDefault()};this.onToggleHandler.push({el:e,fn:t,preventClickFn:i}),\"click\"===this.eventType?e.addEventListener(\"click\",t):(e.addEventListener(\"mouseenter\",t),e.addEventListener(\"click\",i))})),this.extraToggle&&(this.onExtraToggleChangeListener=e=>this.extraToggleChange(e),this.extraToggle.addEventListener(\"change\",this.onExtraToggleChangeListener))}open(e){var t,i,s,o,l;this.prev=this.current,this.prevContentId=this.currentContentId,this.prevContent=this.currentContent,this.current=e,this.currentContentId=e.getAttribute(\"data-tab\"),this.currentContent=this.currentContentId?document.querySelector(this.currentContentId):null,(null===(t=null==this?void 0:this.prev)||void 0===t?void 0:t.ariaSelected)&&(this.prev.ariaSelected=\"false\"),null===(i=this.prev)||void 0===i||i.classList.remove(\"active\"),null===(s=this.prevContent)||void 0===s||s.classList.add(\"hidden\"),(null===(o=null==this?void 0:this.current)||void 0===o?void 0:o.ariaSelected)&&(this.current.ariaSelected=\"true\"),this.current.classList.add(\"active\"),null===(l=this.currentContent)||void 0===l||l.classList.remove(\"hidden\"),this.fireEvent(\"change\",{el:e,prev:this.prevContentId,current:this.currentContentId,tabsId:this.el.id}),(0,n.dispatch)(\"change.tab\",e,{el:e,prev:this.prevContentId,current:this.currentContentId,tabsId:this.el.id})}change(e){const t=document.querySelector(`[data-tab=\"${e.target.value}\"]`);t&&(\"hover\"===this.eventType?t.dispatchEvent(new Event(\"mouseenter\")):t.click())}destroy(){this.toggles.forEach((e=>{var t;const i=null===(t=this.onToggleHandler)||void 0===t?void 0:t.find((({el:t})=>t===e));i&&(\"click\"===this.eventType?e.removeEventListener(\"click\",i.fn):(e.removeEventListener(\"mouseenter\",i.fn),e.removeEventListener(\"click\",i.preventClickFn)))})),this.onToggleHandler=[],this.extraToggle&&this.extraToggle.removeEventListener(\"change\",this.onExtraToggleChangeListener),window.$hsTabsCollection=window.$hsTabsCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t){const i=window.$hsTabsCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsTabsCollection||(window.$hsTabsCollection=[],document.addEventListener(\"keydown\",(e=>r.accessibility(e)))),window.$hsTabsCollection&&(window.$hsTabsCollection=window.$hsTabsCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll('[role=\"tablist\"]:not(select):not(.--prevent-on-load-init)').forEach((e=>{window.$hsTabsCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new r(e)}))}static open(e){const t=window.$hsTabsCollection.find((t=>Array.from(t.element.toggles).includes(\"string\"==typeof e?document.querySelector(e):e))),i=t?Array.from(t.element.toggles).find((t=>t===(\"string\"==typeof e?document.querySelector(e):e))):null;i&&!i.classList.contains(\"active\")&&t.element.open(i)}static accessibility(e){var t;const i=document.querySelector(\"[data-tab]:focus\");if(i&&l.TABS_ACCESSIBILITY_KEY_SET.includes(e.code)&&!e.metaKey){const s=null===(t=i.closest('[role=\"tablist\"]'))||void 0===t?void 0:t.getAttribute(\"data-tabs-vertical\");switch(e.preventDefault(),e.code){case\"true\"===s?\"ArrowUp\":\"ArrowLeft\":this.onArrow();break;case\"true\"===s?\"ArrowDown\":\"ArrowRight\":this.onArrow(!1);break;case\"Home\":this.onStartEnd();break;case\"End\":this.onStartEnd(!1)}}}static onArrow(e=!0){var t;const i=null===(t=document.querySelector(\"[data-tab]:focus\"))||void 0===t?void 0:t.closest('[role=\"tablist\"]');if(!i)return;const s=window.$hsTabsCollection.find((e=>e.element.el===i));if(s){const t=e?Array.from(s.element.toggles).reverse():Array.from(s.element.toggles),i=t.find((e=>document.activeElement===e));let n=t.findIndex((e=>e===i));n=n+1e.element.el===i));if(s){const t=e?Array.from(s.element.toggles):Array.from(s.element.toggles).reverse();t.length&&(t[0].focus(),t[0].click())}}static on(e,t,i){const s=window.$hsTabsCollection.find((e=>Array.from(e.element.toggles).includes(\"string\"==typeof t?document.querySelector(t):t)));s&&(s.element.events[e]=i)}}window.addEventListener(\"load\",(()=>{r.autoInit()})),\"undefined\"!=typeof window&&(window.HSTabs=r),t.default=r},949:(e,t,i)=>{i.r(t),i.d(t,{arrow:()=>Ce,autoPlacement:()=>fe,autoUpdate:()=>pe,computePosition:()=>Ie,detectOverflow:()=>me,flip:()=>we,getOverflowAncestors:()=>Z,hide:()=>be,inline:()=>Se,limitShift:()=>Le,offset:()=>ge,platform:()=>he,shift:()=>ve,size:()=>ye});const s=[\"top\",\"right\",\"bottom\",\"left\"],n=[\"start\",\"end\"],o=s.reduce(((e,t)=>e.concat(t,t+\"-\"+n[0],t+\"-\"+n[1])),[]),l=Math.min,r=Math.max,a=Math.round,c=Math.floor,d=e=>({x:e,y:e}),h={left:\"right\",right:\"left\",bottom:\"top\",top:\"bottom\"},u={start:\"end\",end:\"start\"};function p(e,t,i){return r(e,l(t,i))}function m(e,t){return\"function\"==typeof e?e(t):e}function g(e){return e.split(\"-\")[0]}function f(e){return e.split(\"-\")[1]}function v(e){return\"x\"===e?\"y\":\"x\"}function w(e){return\"y\"===e?\"height\":\"width\"}function y(e){return[\"top\",\"bottom\"].includes(g(e))?\"y\":\"x\"}function b(e){return v(y(e))}function C(e,t,i){void 0===i&&(i=!1);const s=f(e),n=b(e),o=w(n);let l=\"x\"===n?s===(i?\"end\":\"start\")?\"right\":\"left\":\"start\"===s?\"bottom\":\"top\";return t.reference[o]>t.floating[o]&&(l=L(l)),[l,L(l)]}function S(e){return e.replace(/start|end/g,(e=>u[e]))}function L(e){return e.replace(/left|right|bottom|top/g,(e=>h[e]))}function I(e){return\"number\"!=typeof e?function(e){return{top:0,right:0,bottom:0,left:0,...e}}(e):{top:e,right:e,bottom:e,left:e}}function E(e){const{x:t,y:i,width:s,height:n}=e;return{width:s,height:n,top:i,left:t,right:t+s,bottom:i+n,x:t,y:i}}function T(e,t,i){let{reference:s,floating:n}=e;const o=y(t),l=b(t),r=w(l),a=g(t),c=\"y\"===o,d=s.x+s.width/2-n.width/2,h=s.y+s.height/2-n.height/2,u=s[r]/2-n[r]/2;let p;switch(a){case\"top\":p={x:d,y:s.y-n.height};break;case\"bottom\":p={x:d,y:s.y+s.height};break;case\"right\":p={x:s.x+s.width,y:h};break;case\"left\":p={x:s.x-n.width,y:h};break;default:p={x:s.x,y:s.y}}switch(f(t)){case\"start\":p[l]-=u*(i&&c?-1:1);break;case\"end\":p[l]+=u*(i&&c?-1:1)}return p}async function x(e,t){var i;void 0===t&&(t={});const{x:s,y:n,platform:o,rects:l,elements:r,strategy:a}=e,{boundary:c=\"clippingAncestors\",rootBoundary:d=\"viewport\",elementContext:h=\"floating\",altBoundary:u=!1,padding:p=0}=m(t,e),g=I(p),f=r[u?\"floating\"===h?\"reference\":\"floating\":h],v=E(await o.getClippingRect({element:null==(i=await(null==o.isElement?void 0:o.isElement(f)))||i?f:f.contextElement||await(null==o.getDocumentElement?void 0:o.getDocumentElement(r.floating)),boundary:c,rootBoundary:d,strategy:a})),w=\"floating\"===h?{x:s,y:n,width:l.floating.width,height:l.floating.height}:l.reference,y=await(null==o.getOffsetParent?void 0:o.getOffsetParent(r.floating)),b=await(null==o.isElement?void 0:o.isElement(y))&&await(null==o.getScale?void 0:o.getScale(y))||{x:1,y:1},C=E(o.convertOffsetParentRelativeRectToViewportRelativeRect?await o.convertOffsetParentRelativeRectToViewportRelativeRect({elements:r,rect:w,offsetParent:y,strategy:a}):w);return{top:(v.top-C.top+g.top)/b.y,bottom:(C.bottom-v.bottom+g.bottom)/b.y,left:(v.left-C.left+g.left)/b.x,right:(C.right-v.right+g.right)/b.x}}function k(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function A(e){return s.some((t=>e[t]>=0))}function O(e){const t=l(...e.map((e=>e.left))),i=l(...e.map((e=>e.top)));return{x:t,y:i,width:r(...e.map((e=>e.right)))-t,height:r(...e.map((e=>e.bottom)))-i}}function P(){return\"undefined\"!=typeof window}function $(e){return M(e)?(e.nodeName||\"\").toLowerCase():\"#document\"}function B(e){var t;return(null==e||null==(t=e.ownerDocument)?void 0:t.defaultView)||window}function D(e){var t;return null==(t=(M(e)?e.ownerDocument:e.document)||window.document)?void 0:t.documentElement}function M(e){return!!P()&&(e instanceof Node||e instanceof B(e).Node)}function q(e){return!!P()&&(e instanceof Element||e instanceof B(e).Element)}function N(e){return!!P()&&(e instanceof HTMLElement||e instanceof B(e).HTMLElement)}function H(e){return!(!P()||\"undefined\"==typeof ShadowRoot)&&(e instanceof ShadowRoot||e instanceof B(e).ShadowRoot)}function F(e){const{overflow:t,overflowX:i,overflowY:s,display:n}=U(e);return/auto|scroll|overlay|hidden|clip/.test(t+s+i)&&![\"inline\",\"contents\"].includes(n)}function R(e){return[\"table\",\"td\",\"th\"].includes($(e))}function _(e){return[\":popover-open\",\":modal\"].some((t=>{try{return e.matches(t)}catch(e){return!1}}))}function V(e){const t=j(),i=q(e)?U(e):e;return[\"transform\",\"translate\",\"scale\",\"rotate\",\"perspective\"].some((e=>!!i[e]&&\"none\"!==i[e]))||!!i.containerType&&\"normal\"!==i.containerType||!t&&!!i.backdropFilter&&\"none\"!==i.backdropFilter||!t&&!!i.filter&&\"none\"!==i.filter||[\"transform\",\"translate\",\"scale\",\"rotate\",\"perspective\",\"filter\"].some((e=>(i.willChange||\"\").includes(e)))||[\"paint\",\"layout\",\"strict\",\"content\"].some((e=>(i.contain||\"\").includes(e)))}function j(){return!(\"undefined\"==typeof CSS||!CSS.supports)&&CSS.supports(\"-webkit-backdrop-filter\",\"none\")}function W(e){return[\"html\",\"body\",\"#document\"].includes($(e))}function U(e){return B(e).getComputedStyle(e)}function z(e){return q(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function Q(e){if(\"html\"===$(e))return e;const t=e.assignedSlot||e.parentNode||H(e)&&e.host||D(e);return H(t)?t.host:t}function J(e){const t=Q(e);return W(t)?e.ownerDocument?e.ownerDocument.body:e.body:N(t)&&F(t)?t:J(t)}function Z(e,t,i){var s;void 0===t&&(t=[]),void 0===i&&(i=!0);const n=J(e),o=n===(null==(s=e.ownerDocument)?void 0:s.body),l=B(n);if(o){const e=K(l);return t.concat(l,l.visualViewport||[],F(n)?n:[],e&&i?Z(e):[])}return t.concat(n,Z(n,[],i))}function K(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function X(e){const t=U(e);let i=parseFloat(t.width)||0,s=parseFloat(t.height)||0;const n=N(e),o=n?e.offsetWidth:i,l=n?e.offsetHeight:s,r=a(i)!==o||a(s)!==l;return r&&(i=o,s=l),{width:i,height:s,$:r}}function Y(e){return q(e)?e:e.contextElement}function G(e){const t=Y(e);if(!N(t))return d(1);const i=t.getBoundingClientRect(),{width:s,height:n,$:o}=X(t);let l=(o?a(i.width):i.width)/s,r=(o?a(i.height):i.height)/n;return l&&Number.isFinite(l)||(l=1),r&&Number.isFinite(r)||(r=1),{x:l,y:r}}const ee=d(0);function te(e){const t=B(e);return j()&&t.visualViewport?{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}:ee}function ie(e,t,i,s){void 0===t&&(t=!1),void 0===i&&(i=!1);const n=e.getBoundingClientRect(),o=Y(e);let l=d(1);t&&(s?q(s)&&(l=G(s)):l=G(e));const r=function(e,t,i){return void 0===t&&(t=!1),!(!i||t&&i!==B(e))&&t}(o,i,s)?te(o):d(0);let a=(n.left+r.x)/l.x,c=(n.top+r.y)/l.y,h=n.width/l.x,u=n.height/l.y;if(o){const e=B(o),t=s&&q(s)?B(s):s;let i=e,n=K(i);for(;n&&s&&t!==i;){const e=G(n),t=n.getBoundingClientRect(),s=U(n),o=t.left+(n.clientLeft+parseFloat(s.paddingLeft))*e.x,l=t.top+(n.clientTop+parseFloat(s.paddingTop))*e.y;a*=e.x,c*=e.y,h*=e.x,u*=e.y,a+=o,c+=l,i=B(n),n=K(i)}}return E({width:h,height:u,x:a,y:c})}function se(e,t){const i=z(e).scrollLeft;return t?t.left+i:ie(D(e)).left+i}function ne(e,t,i){void 0===i&&(i=!1);const s=e.getBoundingClientRect();return{x:s.left+t.scrollLeft-(i?0:se(e,s)),y:s.top+t.scrollTop}}function oe(e,t,i){let s;if(\"viewport\"===t)s=function(e,t){const i=B(e),s=D(e),n=i.visualViewport;let o=s.clientWidth,l=s.clientHeight,r=0,a=0;if(n){o=n.width,l=n.height;const e=j();(!e||e&&\"fixed\"===t)&&(r=n.offsetLeft,a=n.offsetTop)}return{width:o,height:l,x:r,y:a}}(e,i);else if(\"document\"===t)s=function(e){const t=D(e),i=z(e),s=e.ownerDocument.body,n=r(t.scrollWidth,t.clientWidth,s.scrollWidth,s.clientWidth),o=r(t.scrollHeight,t.clientHeight,s.scrollHeight,s.clientHeight);let l=-i.scrollLeft+se(e);const a=-i.scrollTop;return\"rtl\"===U(s).direction&&(l+=r(t.clientWidth,s.clientWidth)-n),{width:n,height:o,x:l,y:a}}(D(e));else if(q(t))s=function(e,t){const i=ie(e,!0,\"fixed\"===t),s=i.top+e.clientTop,n=i.left+e.clientLeft,o=N(e)?G(e):d(1);return{width:e.clientWidth*o.x,height:e.clientHeight*o.y,x:n*o.x,y:s*o.y}}(t,i);else{const i=te(e);s={x:t.x-i.x,y:t.y-i.y,width:t.width,height:t.height}}return E(s)}function le(e,t){const i=Q(e);return!(i===t||!q(i)||W(i))&&(\"fixed\"===U(i).position||le(i,t))}function re(e,t,i){const s=N(t),n=D(t),o=\"fixed\"===i,l=ie(e,!0,o,t);let r={scrollLeft:0,scrollTop:0};const a=d(0);if(s||!s&&!o)if((\"body\"!==$(t)||F(n))&&(r=z(t)),s){const e=ie(t,!0,o,t);a.x=e.x+t.clientLeft,a.y=e.y+t.clientTop}else n&&(a.x=se(n));const c=!n||s||o?d(0):ne(n,r);return{x:l.left+r.scrollLeft-a.x-c.x,y:l.top+r.scrollTop-a.y-c.y,width:l.width,height:l.height}}function ae(e){return\"static\"===U(e).position}function ce(e,t){if(!N(e)||\"fixed\"===U(e).position)return null;if(t)return t(e);let i=e.offsetParent;return D(e)===i&&(i=i.ownerDocument.body),i}function de(e,t){const i=B(e);if(_(e))return i;if(!N(e)){let t=Q(e);for(;t&&!W(t);){if(q(t)&&!ae(t))return t;t=Q(t)}return i}let s=ce(e,t);for(;s&&R(s)&&ae(s);)s=ce(s,t);return s&&W(s)&&ae(s)&&!V(s)?i:s||function(e){let t=Q(e);for(;N(t)&&!W(t);){if(V(t))return t;if(_(t))return null;t=Q(t)}return null}(e)||i}const he={convertOffsetParentRelativeRectToViewportRelativeRect:function(e){let{elements:t,rect:i,offsetParent:s,strategy:n}=e;const o=\"fixed\"===n,l=D(s),r=!!t&&_(t.floating);if(s===l||r&&o)return i;let a={scrollLeft:0,scrollTop:0},c=d(1);const h=d(0),u=N(s);if((u||!u&&!o)&&((\"body\"!==$(s)||F(l))&&(a=z(s)),N(s))){const e=ie(s);c=G(s),h.x=e.x+s.clientLeft,h.y=e.y+s.clientTop}const p=!l||u||o?d(0):ne(l,a,!0);return{width:i.width*c.x,height:i.height*c.y,x:i.x*c.x-a.scrollLeft*c.x+h.x+p.x,y:i.y*c.y-a.scrollTop*c.y+h.y+p.y}},getDocumentElement:D,getClippingRect:function(e){let{element:t,boundary:i,rootBoundary:s,strategy:n}=e;const o=[...\"clippingAncestors\"===i?_(t)?[]:function(e,t){const i=t.get(e);if(i)return i;let s=Z(e,[],!1).filter((e=>q(e)&&\"body\"!==$(e))),n=null;const o=\"fixed\"===U(e).position;let l=o?Q(e):e;for(;q(l)&&!W(l);){const t=U(l),i=V(l);i||\"fixed\"!==t.position||(n=null),(o?!i&&!n:!i&&\"static\"===t.position&&n&&[\"absolute\",\"fixed\"].includes(n.position)||F(l)&&!i&&le(e,l))?s=s.filter((e=>e!==l)):n=t,l=Q(l)}return t.set(e,s),s}(t,this._c):[].concat(i),s],a=o[0],c=o.reduce(((e,i)=>{const s=oe(t,i,n);return e.top=r(s.top,e.top),e.right=l(s.right,e.right),e.bottom=l(s.bottom,e.bottom),e.left=r(s.left,e.left),e}),oe(t,a,n));return{width:c.right-c.left,height:c.bottom-c.top,x:c.left,y:c.top}},getOffsetParent:de,getElementRects:async function(e){const t=this.getOffsetParent||de,i=this.getDimensions,s=await i(e.floating);return{reference:re(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:s.width,height:s.height}}},getClientRects:function(e){return Array.from(e.getClientRects())},getDimensions:function(e){const{width:t,height:i}=X(e);return{width:t,height:i}},getScale:G,isElement:q,isRTL:function(e){return\"rtl\"===U(e).direction}};function ue(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}function pe(e,t,i,s){void 0===s&&(s={});const{ancestorScroll:n=!0,ancestorResize:o=!0,elementResize:a=\"function\"==typeof ResizeObserver,layoutShift:d=\"function\"==typeof IntersectionObserver,animationFrame:h=!1}=s,u=Y(e),p=n||o?[...u?Z(u):[],...Z(t)]:[];p.forEach((e=>{n&&e.addEventListener(\"scroll\",i,{passive:!0}),o&&e.addEventListener(\"resize\",i)}));const m=u&&d?function(e,t){let i,s=null;const n=D(e);function o(){var e;clearTimeout(i),null==(e=s)||e.disconnect(),s=null}return function a(d,h){void 0===d&&(d=!1),void 0===h&&(h=1),o();const u=e.getBoundingClientRect(),{left:p,top:m,width:g,height:f}=u;if(d||t(),!g||!f)return;const v={rootMargin:-c(m)+\"px \"+-c(n.clientWidth-(p+g))+\"px \"+-c(n.clientHeight-(m+f))+\"px \"+-c(p)+\"px\",threshold:r(0,l(1,h))||1};let w=!0;function y(t){const s=t[0].intersectionRatio;if(s!==h){if(!w)return a();s?a(!1,s):i=setTimeout((()=>{a(!1,1e-7)}),1e3)}1!==s||ue(u,e.getBoundingClientRect())||a(),w=!1}try{s=new IntersectionObserver(y,{...v,root:n.ownerDocument})}catch(e){s=new IntersectionObserver(y,v)}s.observe(e)}(!0),o}(u,i):null;let g,f=-1,v=null;a&&(v=new ResizeObserver((e=>{let[s]=e;s&&s.target===u&&v&&(v.unobserve(t),cancelAnimationFrame(f),f=requestAnimationFrame((()=>{var e;null==(e=v)||e.observe(t)}))),i()})),u&&!h&&v.observe(u),v.observe(t));let w=h?ie(e):null;return h&&function t(){const s=ie(e);w&&!ue(w,s)&&i();w=s,g=requestAnimationFrame(t)}(),i(),()=>{var e;p.forEach((e=>{n&&e.removeEventListener(\"scroll\",i),o&&e.removeEventListener(\"resize\",i)})),null==m||m(),null==(e=v)||e.disconnect(),v=null,h&&cancelAnimationFrame(g)}}const me=x,ge=function(e){return void 0===e&&(e=0),{name:\"offset\",options:e,async fn(t){var i,s;const{x:n,y:o,placement:l,middlewareData:r}=t,a=await async function(e,t){const{placement:i,platform:s,elements:n}=e,o=await(null==s.isRTL?void 0:s.isRTL(n.floating)),l=g(i),r=f(i),a=\"y\"===y(i),c=[\"left\",\"top\"].includes(l)?-1:1,d=o&&a?-1:1,h=m(t,e);let{mainAxis:u,crossAxis:p,alignmentAxis:v}=\"number\"==typeof h?{mainAxis:h,crossAxis:0,alignmentAxis:null}:{mainAxis:h.mainAxis||0,crossAxis:h.crossAxis||0,alignmentAxis:h.alignmentAxis};return r&&\"number\"==typeof v&&(p=\"end\"===r?-1*v:v),a?{x:p*d,y:u*c}:{x:u*c,y:p*d}}(t,e);return l===(null==(i=r.offset)?void 0:i.placement)&&null!=(s=r.arrow)&&s.alignmentOffset?{}:{x:n+a.x,y:o+a.y,data:{...a,placement:l}}}}},fe=function(e){return void 0===e&&(e={}),{name:\"autoPlacement\",options:e,async fn(t){var i,s,n;const{rects:l,middlewareData:r,placement:a,platform:c,elements:d}=t,{crossAxis:h=!1,alignment:u,allowedPlacements:p=o,autoAlignment:v=!0,...w}=m(e,t),y=void 0!==u||p===o?function(e,t,i){return(e?[...i.filter((t=>f(t)===e)),...i.filter((t=>f(t)!==e))]:i.filter((e=>g(e)===e))).filter((i=>!e||f(i)===e||!!t&&S(i)!==i))}(u||null,v,p):p,b=await x(t,w),L=(null==(i=r.autoPlacement)?void 0:i.index)||0,I=y[L];if(null==I)return{};const E=C(I,l,await(null==c.isRTL?void 0:c.isRTL(d.floating)));if(a!==I)return{reset:{placement:y[0]}};const T=[b[g(I)],b[E[0]],b[E[1]]],k=[...(null==(s=r.autoPlacement)?void 0:s.overflows)||[],{placement:I,overflows:T}],A=y[L+1];if(A)return{data:{index:L+1,overflows:k},reset:{placement:A}};const O=k.map((e=>{const t=f(e.placement);return[e.placement,t&&h?e.overflows.slice(0,2).reduce(((e,t)=>e+t),0):e.overflows[0],e.overflows]})).sort(((e,t)=>e[1]-t[1])),P=(null==(n=O.filter((e=>e[2].slice(0,f(e[0])?2:3).every((e=>e<=0))))[0])?void 0:n[0])||O[0][0];return P!==a?{data:{index:L+1,overflows:k},reset:{placement:P}}:{}}}},ve=function(e){return void 0===e&&(e={}),{name:\"shift\",options:e,async fn(t){const{x:i,y:s,placement:n}=t,{mainAxis:o=!0,crossAxis:l=!1,limiter:r={fn:e=>{let{x:t,y:i}=e;return{x:t,y:i}}},...a}=m(e,t),c={x:i,y:s},d=await x(t,a),h=y(g(n)),u=v(h);let f=c[u],w=c[h];if(o){const e=\"y\"===u?\"bottom\":\"right\";f=p(f+d[\"y\"===u?\"top\":\"left\"],f,f-d[e])}if(l){const e=\"y\"===h?\"bottom\":\"right\";w=p(w+d[\"y\"===h?\"top\":\"left\"],w,w-d[e])}const b=r.fn({...t,[u]:f,[h]:w});return{...b,data:{x:b.x-i,y:b.y-s,enabled:{[u]:o,[h]:l}}}}}},we=function(e){return void 0===e&&(e={}),{name:\"flip\",options:e,async fn(t){var i,s;const{placement:n,middlewareData:o,rects:l,initialPlacement:r,platform:a,elements:c}=t,{mainAxis:d=!0,crossAxis:h=!0,fallbackPlacements:u,fallbackStrategy:p=\"bestFit\",fallbackAxisSideDirection:v=\"none\",flipAlignment:w=!0,...b}=m(e,t);if(null!=(i=o.arrow)&&i.alignmentOffset)return{};const I=g(n),E=y(r),T=g(r)===r,k=await(null==a.isRTL?void 0:a.isRTL(c.floating)),A=u||(T||!w?[L(r)]:function(e){const t=L(e);return[S(e),t,S(t)]}(r)),O=\"none\"!==v;!u&&O&&A.push(...function(e,t,i,s){const n=f(e);let o=function(e,t,i){const s=[\"left\",\"right\"],n=[\"right\",\"left\"],o=[\"top\",\"bottom\"],l=[\"bottom\",\"top\"];switch(e){case\"top\":case\"bottom\":return i?t?n:s:t?s:n;case\"left\":case\"right\":return t?o:l;default:return[]}}(g(e),\"start\"===i,s);return n&&(o=o.map((e=>e+\"-\"+n)),t&&(o=o.concat(o.map(S)))),o}(r,w,v,k));const P=[r,...A],$=await x(t,b),B=[];let D=(null==(s=o.flip)?void 0:s.overflows)||[];if(d&&B.push($[I]),h){const e=C(n,l,k);B.push($[e[0]],$[e[1]])}if(D=[...D,{placement:n,overflows:B}],!B.every((e=>e<=0))){var M,q;const e=((null==(M=o.flip)?void 0:M.index)||0)+1,t=P[e];if(t)return{data:{index:e,overflows:D},reset:{placement:t}};let i=null==(q=D.filter((e=>e.overflows[0]<=0)).sort(((e,t)=>e.overflows[1]-t.overflows[1]))[0])?void 0:q.placement;if(!i)switch(p){case\"bestFit\":{var N;const e=null==(N=D.filter((e=>{if(O){const t=y(e.placement);return t===E||\"y\"===t}return!0})).map((e=>[e.placement,e.overflows.filter((e=>e>0)).reduce(((e,t)=>e+t),0)])).sort(((e,t)=>e[1]-t[1]))[0])?void 0:N[0];e&&(i=e);break}case\"initialPlacement\":i=r}if(n!==i)return{reset:{placement:i}}}return{}}}},ye=function(e){return void 0===e&&(e={}),{name:\"size\",options:e,async fn(t){var i,s;const{placement:n,rects:o,platform:a,elements:c}=t,{apply:d=()=>{},...h}=m(e,t),u=await x(t,h),p=g(n),v=f(n),w=\"y\"===y(n),{width:b,height:C}=o.floating;let S,L;\"top\"===p||\"bottom\"===p?(S=p,L=v===(await(null==a.isRTL?void 0:a.isRTL(c.floating))?\"start\":\"end\")?\"left\":\"right\"):(L=p,S=\"end\"===v?\"top\":\"bottom\");const I=C-u.top-u.bottom,E=b-u.left-u.right,T=l(C-u[S],I),k=l(b-u[L],E),A=!t.middlewareData.shift;let O=T,P=k;if(null!=(i=t.middlewareData.shift)&&i.enabled.x&&(P=E),null!=(s=t.middlewareData.shift)&&s.enabled.y&&(O=I),A&&!v){const e=r(u.left,0),t=r(u.right,0),i=r(u.top,0),s=r(u.bottom,0);w?P=b-2*(0!==e||0!==t?e+t:r(u.left,u.right)):O=C-2*(0!==i||0!==s?i+s:r(u.top,u.bottom))}await d({...t,availableWidth:P,availableHeight:O});const $=await a.getDimensions(c.floating);return b!==$.width||C!==$.height?{reset:{rects:!0}}:{}}}},be=function(e){return void 0===e&&(e={}),{name:\"hide\",options:e,async fn(t){const{rects:i}=t,{strategy:s=\"referenceHidden\",...n}=m(e,t);switch(s){case\"referenceHidden\":{const e=k(await x(t,{...n,elementContext:\"reference\"}),i.reference);return{data:{referenceHiddenOffsets:e,referenceHidden:A(e)}}}case\"escaped\":{const e=k(await x(t,{...n,altBoundary:!0}),i.floating);return{data:{escapedOffsets:e,escaped:A(e)}}}default:return{}}}}},Ce=e=>({name:\"arrow\",options:e,async fn(t){const{x:i,y:s,placement:n,rects:o,platform:r,elements:a,middlewareData:c}=t,{element:d,padding:h=0}=m(e,t)||{};if(null==d)return{};const u=I(h),g={x:i,y:s},v=b(n),y=w(v),C=await r.getDimensions(d),S=\"y\"===v,L=S?\"top\":\"left\",E=S?\"bottom\":\"right\",T=S?\"clientHeight\":\"clientWidth\",x=o.reference[y]+o.reference[v]-g[v]-o.floating[y],k=g[v]-o.reference[v],A=await(null==r.getOffsetParent?void 0:r.getOffsetParent(d));let O=A?A[T]:0;O&&await(null==r.isElement?void 0:r.isElement(A))||(O=a.floating[T]||o.floating[y]);const P=x/2-k/2,$=O/2-C[y]/2-1,B=l(u[L],$),D=l(u[E],$),M=B,q=O-C[y]-D,N=O/2-C[y]/2+P,H=p(M,N,q),F=!c.arrow&&null!=f(n)&&N!==H&&o.reference[y]/2-(Ne.y-t.y)),i=[];let s=null;for(let e=0;es.height/2?i.push([n]):i[i.length-1].push(n),s=n}return i.map((e=>E(O(e))))}(u),f=E(O(u)),v=I(c);const w=await o.getElementRects({reference:{getBoundingClientRect:function(){if(2===p.length&&p[0].left>p[1].right&&null!=d&&null!=h)return p.find((e=>d>e.left-v.left&&de.top-v.top&&h=2){if(\"y\"===y(i)){const e=p[0],t=p[p.length-1],s=\"top\"===g(i),n=e.top,o=t.bottom,l=s?e.left:t.left,r=s?e.right:t.right;return{top:n,bottom:o,left:l,right:r,width:r-l,height:o-n,x:l,y:n}}const e=\"left\"===g(i),t=r(...p.map((e=>e.right))),s=l(...p.map((e=>e.left))),n=p.filter((i=>e?i.left===s:i.right===t)),o=n[0].top,a=n[n.length-1].bottom;return{top:o,bottom:a,left:s,right:t,width:t-s,height:a-o,x:s,y:o}}return f}},floating:s.floating,strategy:a});return n.reference.x!==w.reference.x||n.reference.y!==w.reference.y||n.reference.width!==w.reference.width||n.reference.height!==w.reference.height?{reset:{rects:w}}:{}}}},Le=function(e){return void 0===e&&(e={}),{options:e,fn(t){const{x:i,y:s,placement:n,rects:o,middlewareData:l}=t,{offset:r=0,mainAxis:a=!0,crossAxis:c=!0}=m(e,t),d={x:i,y:s},h=y(n),u=v(h);let p=d[u],f=d[h];const w=m(r,t),b=\"number\"==typeof w?{mainAxis:w,crossAxis:0}:{mainAxis:0,crossAxis:0,...w};if(a){const e=\"y\"===u?\"height\":\"width\",t=o.reference[u]-o.floating[e]+b.mainAxis,i=o.reference[u]+o.reference[e]-b.mainAxis;pi&&(p=i)}if(c){var C,S;const e=\"y\"===u?\"width\":\"height\",t=[\"top\",\"left\"].includes(g(n)),i=o.reference[h]-o.floating[e]+(t&&(null==(C=l.offset)?void 0:C[h])||0)+(t?0:b.crossAxis),s=o.reference[h]+o.reference[e]+(t?0:(null==(S=l.offset)?void 0:S[h])||0)-(t?b.crossAxis:0);fs&&(f=s)}return{[u]:p,[h]:f}}}},Ie=(e,t,i)=>{const s=new Map,n={platform:he,...i},o={...n.platform,_c:s};return(async(e,t,i)=>{const{placement:s=\"bottom\",strategy:n=\"absolute\",middleware:o=[],platform:l}=i,r=o.filter(Boolean),a=await(null==l.isRTL?void 0:l.isRTL(t));let c=await l.getElementRects({reference:e,floating:t,strategy:n}),{x:d,y:h}=T(c,s,a),u=s,p={},m=0;for(let i=0;i\",this.searchNoResultText=(null==a?void 0:a.searchNoResultText)||\"No results found\",this.searchNoResultClasses=(null==a?void 0:a.searchNoResultClasses)||\"block advance-select-option\",this.optionAllowEmptyOption=void 0!==(null==a?void 0:a.optionAllowEmptyOption)&&(null==a?void 0:a.optionAllowEmptyOption),this.optionTemplate=(null==a?void 0:a.optionTemplate)||null,this.optionTag=(null==a?void 0:a.optionTag)||null,this.optionClasses=(null==a?void 0:a.optionClasses)||null,this.extraMarkup=(null==a?void 0:a.extraMarkup)||null,this.descriptionClasses=(null==a?void 0:a.descriptionClasses)||null,this.iconClasses=(null==a?void 0:a.iconClasses)||null,this.isAddTagOnEnter=null===(o=null==a?void 0:a.isAddTagOnEnter)||void 0===o||o,this.animationInProcess=!1,this.selectOptions=[],this.remoteOptions=[],this.tagsInputHelper=null,this.init()}wrapperClick(e){e.target.closest(\"[data-select-dropdown]\")||e.target.closest(\"[data-tag-value]\")||this.tagsInput.focus()}toggleClick(){if(this.isDisabled)return!1;this.toggleFn()}tagsInputFocus(){this.isOpened||this.open()}tagsInputInput(){this.calculateInputWidth()}tagsInputInputSecond(e){this.searchOptions(e.target.value)}tagsInputKeydown(e){if(\"Enter\"===e.key&&this.isAddTagOnEnter){const t=e.target.value;if(this.selectOptions.find((e=>e.val===t)))return!1;this.addSelectOption(t,t),this.buildOption(t,t),this.dropdown.querySelector(`[data-value=\"${t}\"]`).click(),this.resetTagsInputField()}}searchInput(e){const t=e.target.value;this.apiUrl?this.remoteSearch(t):this.searchOptions(t)}setValue(e){if(this.value=e,this.clearSelections(),Array.isArray(e))if(\"tags\"===this.mode){this.unselectMultipleItems(),this.selectMultipleItems(),this.selectedItems=[];this.wrapper.querySelectorAll(\"[data-tag-value]\").forEach((e=>e.remove())),this.setTagsItems(),this.reassignTagsInputPlaceholder(this.value.length?\"\":this.placeholder)}else this.toggleTextWrapper.innerHTML=this.value.length?this.stringFromValue():this.placeholder,this.unselectMultipleItems(),this.selectMultipleItems();else this.setToggleTitle(),this.toggle.querySelector(\"[data-icon]\")&&this.setToggleIcon(),this.toggle.querySelector(\"[data-title]\")&&this.setToggleTitle(),this.selectSingleItem()}init(){this.createCollection(window.$hsSelectCollection,this),this.build()}build(){if(this.el.style.display=\"none\",this.el.children&&Array.from(this.el.children).filter((e=>this.optionAllowEmptyOption||!this.optionAllowEmptyOption&&e.value&&\"\"!==e.value)).forEach((e=>{const t=e.getAttribute(\"data-select-option\");this.selectOptions=[...this.selectOptions,{title:e.textContent,val:e.value,disabled:e.disabled,options:\"undefined\"!==t?JSON.parse(t):null}]})),this.isMultiple){const e=Array.from(this.el.children).filter((e=>e.selected));if(e){const t=[];e.forEach((e=>{t.push(e.value)})),this.value=t}}this.buildWrapper(),\"tags\"===this.mode?this.buildTags():this.buildToggle(),this.buildDropdown(),this.extraMarkup&&this.buildExtraMarkup()}buildWrapper(){this.wrapper=document.createElement(\"div\"),this.wrapper.classList.add(\"advance-select\",\"relative\"),\"tags\"===this.mode&&(this.onWrapperClickListener=e=>this.wrapperClick(e),this.wrapper.addEventListener(\"click\",this.onWrapperClickListener)),this.wrapperClasses&&(0,o.classToClassList)(this.wrapperClasses,this.wrapper),this.el.before(this.wrapper),this.wrapper.append(this.el)}buildExtraMarkup(){const e=e=>{const t=(0,o.htmlToElement)(e);return this.wrapper.append(t),t},t=e=>{e.classList.contains(\"--prevent-click\")||e.addEventListener(\"click\",(e=>{e.stopPropagation(),this.toggleFn()}))};if(Array.isArray(this.extraMarkup))this.extraMarkup.forEach((i=>{const s=e(i);t(s)}));else{const i=e(this.extraMarkup);t(i)}}buildToggle(){var e,t;let i,s;this.toggleTextWrapper=document.createElement(\"span\"),this.toggleTextWrapper.classList.add(\"truncate\"),this.toggle=(0,o.htmlToElement)(this.toggleTag||\"
\"),i=this.toggle.querySelector(\"[data-icon]\"),s=this.toggle.querySelector(\"[data-title]\"),!this.isMultiple&&i&&this.setToggleIcon(),!this.isMultiple&&s&&this.setToggleTitle(),this.isMultiple?this.toggleTextWrapper.innerHTML=this.value.length?this.stringFromValue():this.placeholder:this.toggleTextWrapper.innerHTML=(null===(e=this.getItemByValue(this.value))||void 0===e?void 0:e.title)||this.placeholder,s||this.toggle.append(this.toggleTextWrapper),this.toggleClasses&&(0,o.classToClassList)(this.toggleClasses,this.toggle),this.isDisabled&&this.toggle.classList.add(\"disabled\"),this.wrapper&&this.wrapper.append(this.toggle),(null===(t=this.toggle)||void 0===t?void 0:t.ariaExpanded)&&(this.isOpened?this.toggle.ariaExpanded=\"true\":this.toggle.ariaExpanded=\"false\"),this.onToggleClickListener=()=>this.toggleClick(),this.toggle.addEventListener(\"click\",this.onToggleClickListener)}setToggleIcon(){var e;const t=this.getItemByValue(this.value),i=this.toggle.querySelector(\"[data-icon]\");if(i){i.innerHTML=\"\";const s=(0,o.htmlToElement)(this.apiUrl&&this.apiIconTag?this.apiIconTag||\"\":(null===(e=null==t?void 0:t.options)||void 0===e?void 0:e.icon)||\"\");this.value&&this.apiUrl&&this.apiIconTag&&t[this.apiFieldsMap.icon]&&(s.src=t[this.apiFieldsMap.icon]||\"\"),i.append(s),s?i.classList.remove(\"hidden\"):i.classList.add(\"hidden\")}}setToggleTitle(){var e,t;const i=this.toggle.querySelector(\"[data-title]\");i?(i.innerHTML=(null===(e=this.getItemByValue(this.value))||void 0===e?void 0:e.title)||this.placeholder,i.classList.add(\"truncate\"),this.toggle.append(i)):this.toggle.innerText=(null===(t=this.getItemByValue(this.value))||void 0===t?void 0:t.title)||this.placeholder}buildTags(){this.isDisabled&&this.wrapper.classList.add(\"disabled\"),this.buildTagsInput(),this.setTagsItems()}reassignTagsInputPlaceholder(e){this.tagsInput.placeholder=e,this.tagsInputHelper.innerHTML=e,this.calculateInputWidth()}buildTagsItem(e){var t,i,s,n;const l=this.getItemByValue(e);let r,a,c,d;const h=document.createElement(\"div\");if(h.setAttribute(\"data-tag-value\",e),this.tagsItemClasses&&(0,o.classToClassList)(this.tagsItemClasses,h),this.tagsItemTemplate&&(r=(0,o.htmlToElement)(this.tagsItemTemplate),h.append(r)),(null===(t=null==l?void 0:l.options)||void 0===t?void 0:t.icon)||this.apiIconTag){const e=(0,o.htmlToElement)(this.apiUrl&&this.apiIconTag?this.apiIconTag:null===(i=null==l?void 0:l.options)||void 0===i?void 0:i.icon);this.apiUrl&&this.apiIconTag&&l[this.apiFieldsMap.icon]&&(e.src=l[this.apiFieldsMap.icon]||\"\"),d=r?r.querySelector(\"[data-icon]\"):document.createElement(\"span\"),d.append(e),r||h.append(d)}!r||!r.querySelector(\"[data-icon]\")||(null===(s=null==l?void 0:l.options)||void 0===s?void 0:s.icon)||this.apiUrl||this.apiIconTag||l[null===(n=this.apiFieldsMap)||void 0===n?void 0:n.icon]||r.querySelector(\"[data-icon]\").classList.add(\"hidden\"),a=r?r.querySelector(\"[data-title]\"):document.createElement(\"span\"),a.textContent=l.title||\"\",r||h.append(a),r?c=r.querySelector(\"[data-remove]\"):(c=document.createElement(\"span\"),c.textContent=\"X\",h.append(c)),c.addEventListener(\"click\",(()=>{this.value=this.value.filter((t=>t!==e)),this.selectedItems=this.selectedItems.filter((t=>t!==e)),this.value.length||this.reassignTagsInputPlaceholder(this.placeholder),this.unselectMultipleItems(),this.selectMultipleItems(),h.remove(),this.triggerChangeEventForNativeSelect()})),this.wrapper.append(h)}getItemByValue(e){return this.apiUrl?this.remoteOptions.find((t=>`${t[this.apiFieldsMap.val]}`===e||t[this.apiFieldsMap.title]===e)):this.selectOptions.find((t=>t.val===e))}setTagsItems(){this.value&&this.value.forEach((e=>{this.selectedItems.includes(e)||this.buildTagsItem(e),this.selectedItems=this.selectedItems.includes(e)?this.selectedItems:[...this.selectedItems,e]})),this.isOpened&&this.floatingUIInstance&&this.floatingUIInstance.update()}buildTagsInput(){this.tagsInput=document.createElement(\"input\"),this.tagsInputId&&(this.tagsInput.id=this.tagsInputId),this.tagsInputClasses&&(0,o.classToClassList)(this.tagsInputClasses,this.tagsInput),this.onTagsInputFocusListener=()=>this.tagsInputFocus(),this.onTagsInputInputListener=()=>this.tagsInputInput(),this.onTagsInputInputSecondListener=(0,o.debounce)((e=>this.tagsInputInputSecond(e))),this.onTagsInputKeydownListener=e=>this.tagsInputKeydown(e),this.tagsInput.addEventListener(\"focus\",this.onTagsInputFocusListener),this.tagsInput.addEventListener(\"input\",this.onTagsInputInputListener),this.tagsInput.addEventListener(\"input\",this.onTagsInputInputSecondListener),this.tagsInput.addEventListener(\"keydown\",this.onTagsInputKeydownListener),this.wrapper.append(this.tagsInput),setTimeout((()=>{this.adjustInputWidth(),this.reassignTagsInputPlaceholder(this.value.length?\"\":this.placeholder)}))}buildDropdown(){this.dropdown=(0,o.htmlToElement)(this.dropdownTag||\"
\"),this.dropdown.setAttribute(\"data-select-dropdown\",\"\"),\"parent\"===this.dropdownScope&&(this.dropdown.classList.add(\"absolute\"),this.dropdownVerticalFixedPlacement||this.dropdown.classList.add(\"top-full\")),this.dropdown.role=\"listbox\",this.dropdown.tabIndex=-1,this.dropdown.ariaOrientation=\"vertical\",this.isOpened||this.dropdown.classList.add(\"hidden\"),this.dropdownClasses&&(0,o.classToClassList)(this.dropdownClasses,this.dropdown),this.wrapper&&this.wrapper.append(this.dropdown),this.dropdown&&this.hasSearch&&this.buildSearch(),this.selectOptions&&this.selectOptions.forEach(((e,t)=>this.buildOption(e.title,e.val,e.disabled,e.selected,e.options,`${t}`))),this.apiUrl&&this.optionsFromRemoteData(),\"window\"===this.dropdownScope&&this.buildFloatingUI()}buildFloatingUI(){document.body.appendChild(this.dropdown);const e=\"tags\"===this.mode?this.wrapper:this.toggle,t={placement:a.POSITIONS[this.dropdownPlacement]||\"bottom\",strategy:\"fixed\",middleware:[(0,l.offset)(0)]},i=()=>{(0,l.computePosition)(e,this.dropdown,t).then((({x:e,y:t,placement:i})=>{Object.assign(this.dropdown.style,{position:\"fixed\",left:`${e}px`,top:`${t}px`}),this.dropdown.setAttribute(\"data-placement\",i)}))};i();const s=(0,l.autoUpdate)(e,this.dropdown,i);this.floatingUIInstance={update:i,destroy:s}}updateDropdownWidth(){const e=\"tags\"===this.mode?this.wrapper:this.toggle;this.dropdown.style.width=`${e.clientWidth}px`}buildSearch(){let e;this.searchWrapper=(0,o.htmlToElement)(this.searchWrapperTemplate||\"
\"),this.searchWrapperClasses&&(0,o.classToClassList)(this.searchWrapperClasses,this.searchWrapper),e=this.searchWrapper.querySelector(\"[data-input]\");const t=(0,o.htmlToElement)(this.searchTemplate||'');this.search=\"INPUT\"===t.tagName?t:t.querySelector(\":scope input\"),this.search.placeholder=this.searchPlaceholder,this.searchClasses&&(0,o.classToClassList)(this.searchClasses,this.search),this.searchId&&(this.search.id=this.searchId),this.onSearchInputListener=(0,o.debounce)((e=>this.searchInput(e))),this.search.addEventListener(\"input\",this.onSearchInputListener),e?e.append(t):this.searchWrapper.append(t),this.dropdown.append(this.searchWrapper)}buildOption(e,t,i=!1,s=!1,n,l=\"1\",r){var a;let c=null,d=null,h=null,u=null;const p=(0,o.htmlToElement)(this.optionTag||\"
\");if(p.setAttribute(\"data-value\",t),p.setAttribute(\"data-title-value\",e),p.setAttribute(\"tabIndex\",l),p.classList.add(\"cursor-pointer\"),p.setAttribute(\"data-id\",r||`${this.optionId}`),r||this.optionId++,i&&p.classList.add(\"disabled\"),s&&(this.isMultiple?this.value=[...this.value,t]:this.value=t),this.optionTemplate&&(c=(0,o.htmlToElement)(this.optionTemplate),p.append(c)),c?(d=c.querySelector(\"[data-title]\"),d.textContent=e||\"\"):p.textContent=e||\"\",n){if(n.icon){const t=(0,o.htmlToElement)(null!==(a=this.apiIconTag)&&void 0!==a?a:n.icon);if(t.classList.add(\"max-w-full\"),this.apiUrl&&(t.setAttribute(\"alt\",e),t.setAttribute(\"src\",n.icon)),c)h=c.querySelector(\"[data-icon]\"),h.append(t);else{const e=(0,o.htmlToElement)(\"
\");this.iconClasses&&(0,o.classToClassList)(this.iconClasses,e),e.append(t),p.append(e)}}if(n.description)if(c)u=c.querySelector(\"[data-description]\"),u&&u.append(n.description);else{const e=(0,o.htmlToElement)(\"
\");e.textContent=n.description,this.descriptionClasses&&(0,o.classToClassList)(this.descriptionClasses,e),p.append(e)}}c&&c.querySelector(\"[data-icon]\")&&!n&&!(null==n?void 0:n.icon)&&c.querySelector(\"[data-icon]\").classList.add(\"hidden\"),this.value&&(this.isMultiple?this.value.includes(t):this.value===t)&&p.classList.add(\"selected\"),i||p.addEventListener(\"click\",(()=>this.onSelectOption(t))),this.optionClasses&&(0,o.classToClassList)(this.optionClasses,p),this.dropdown&&this.dropdown.append(p),s&&this.setNewValue()}buildOptionFromRemoteData(e,t,i=!1,s=!1,n=\"1\",o,l){n?this.buildOption(e,t,i,s,l,n,o):alert(\"ID parameter is required for generating remote options! Please check your API endpoint have it.\")}buildOptionsFromRemoteData(e){e.forEach(((e,t)=>{let i=null,s=\"\",n=\"\";const o={id:\"\",val:\"\",title:\"\",icon:null,description:null,rest:{}};Object.keys(e).forEach((t=>{var l;e[this.apiFieldsMap.id]&&(i=e[this.apiFieldsMap.id]),(e[this.apiFieldsMap.val]||e[this.apiFieldsMap.title])&&(n=e[this.apiFieldsMap.val]||e[this.apiFieldsMap.title]),e[this.apiFieldsMap.title]&&(s=e[this.apiFieldsMap.title]),e[this.apiFieldsMap.icon]&&(o.icon=e[this.apiFieldsMap.icon]),e[null===(l=this.apiFieldsMap)||void 0===l?void 0:l.description]&&(o.description=e[this.apiFieldsMap.description]),o.rest[t]=e[t]})),this.buildOriginalOption(s,`${n}`,i,!1,!1,o),this.buildOptionFromRemoteData(s,`${n}`,!1,!1,`${t}`,i,o)})),this.sortElements(this.el,\"option\"),this.sortElements(this.dropdown,\"[data-value]\")}optionsFromRemoteData(){return s(this,arguments,void 0,(function*(e=\"\"){const t=yield this.apiRequest(e);this.remoteOptions=t,t.length?this.buildOptionsFromRemoteData(this.remoteOptions):console.log(\"There is no data were responded!\")}))}apiRequest(){return s(this,arguments,void 0,(function*(e=\"\"){try{let t=this.apiUrl;const i=this.apiSearchQueryKey?`${this.apiSearchQueryKey}=${e.toLowerCase()}`:null,s=`${this.apiQuery}`,n=this.apiOptions||{};i&&(t+=`?${i}`),this.apiQuery&&(t+=`${i?\"&\":\"?\"}${s}`);const o=yield fetch(t,n),l=yield o.json();return this.apiDataPart?l[this.apiDataPart]:l}catch(e){console.error(e)}}))}sortElements(e,t){const i=Array.from(e.querySelectorAll(t));i.sort(((e,t)=>{const i=e.classList.contains(\"selected\")||e.hasAttribute(\"selected\"),s=t.classList.contains(\"selected\")||t.hasAttribute(\"selected\");return i&&!s?-1:!i&&s?1:0})),i.forEach((t=>e.appendChild(t)))}remoteSearch(e){return s(this,void 0,void 0,(function*(){if(e.length<=this.minSearchLength){const e=yield this.apiRequest(\"\");return this.remoteOptions=e,Array.from(this.dropdown.querySelectorAll(\"[data-value]\")).forEach((e=>e.remove())),Array.from(this.el.querySelectorAll(\"option[value]\")).forEach((e=>{e.remove()})),e.length?this.buildOptionsFromRemoteData(e):console.log(\"No data responded!\"),!1}const t=yield this.apiRequest(e);this.remoteOptions=t;let i=t.map((e=>`${e.id}`)),s=null;const n=this.dropdown.querySelectorAll(\"[data-value]\");this.el.querySelectorAll(\"[data-select-option]\").forEach((e=>{var t;const s=e.getAttribute(\"data-id\");i.includes(s)||(null===(t=this.value)||void 0===t?void 0:t.includes(e.value))||this.destroyOriginalOption(e.value)})),n.forEach((e=>{var t;const s=e.getAttribute(\"data-id\");i.includes(s)||(null===(t=this.value)||void 0===t?void 0:t.includes(e.getAttribute(\"data-value\")))?i=i.filter((e=>e!==s)):this.destroyOption(e.getAttribute(\"data-value\"))})),s=t.filter((e=>i.includes(`${e.id}`))),s.length?this.buildOptionsFromRemoteData(s):console.log(\"There is no data were responded!\")}))}destroyOption(e){const t=this.dropdown.querySelector(`[data-value=\"${e}\"]`);if(!t)return!1;t.remove()}buildOriginalOption(e,t,i,s,n,l){const r=(0,o.htmlToElement)(\"\");r.setAttribute(\"value\",t),s&&r.setAttribute(\"disabled\",\"disabled\"),n&&r.setAttribute(\"selected\",\"selected\"),i&&r.setAttribute(\"data-id\",i),r.setAttribute(\"data-select-option\",JSON.stringify(l)),r.innerText=e,this.el.append(r)}destroyOriginalOption(e){const t=this.el.querySelector(`[value=\"${e}\"]`);if(!t)return!1;t.remove()}buildTagsInputHelper(){this.tagsInputHelper=document.createElement(\"span\"),this.tagsInputHelper.style.fontSize=window.getComputedStyle(this.tagsInput).fontSize,this.tagsInputHelper.style.fontFamily=window.getComputedStyle(this.tagsInput).fontFamily,this.tagsInputHelper.style.fontWeight=window.getComputedStyle(this.tagsInput).fontWeight,this.tagsInputHelper.style.letterSpacing=window.getComputedStyle(this.tagsInput).letterSpacing,this.tagsInputHelper.style.visibility=\"hidden\",this.tagsInputHelper.style.whiteSpace=\"pre\",this.tagsInputHelper.style.position=\"absolute\",this.wrapper.appendChild(this.tagsInputHelper)}calculateInputWidth(){this.tagsInputHelper.textContent=this.tagsInput.value||this.tagsInput.placeholder;const e=parseInt(window.getComputedStyle(this.tagsInput).paddingLeft)+parseInt(window.getComputedStyle(this.tagsInput).paddingRight),t=parseInt(window.getComputedStyle(this.tagsInput).borderLeftWidth)+parseInt(window.getComputedStyle(this.tagsInput).borderRightWidth),i=this.tagsInputHelper.offsetWidth+e+t,s=this.wrapper.offsetWidth-(parseInt(window.getComputedStyle(this.wrapper).paddingLeft)+parseInt(window.getComputedStyle(this.wrapper).paddingRight));this.tagsInput.style.width=`${Math.min(i,s)+2}px`}adjustInputWidth(){this.buildTagsInputHelper(),this.calculateInputWidth()}onSelectOption(e){if(this.clearSelections(),this.isMultiple?(this.value=this.value.includes(e)?Array.from(this.value).filter((t=>t!==e)):[...Array.from(this.value),e],this.selectMultipleItems(),this.setNewValue()):(this.value=e,this.selectSingleItem(),this.setNewValue()),this.fireEvent(\"change\",this.value),\"tags\"===this.mode){const e=this.selectedItems.filter((e=>!this.value.includes(e)));e.length&&e.forEach((e=>{this.selectedItems=this.selectedItems.filter((t=>t!==e)),this.wrapper.querySelector(`[data-tag-value=\"${e}\"]`).remove()})),this.resetTagsInputField()}this.isMultiple||(this.toggle.querySelector(\"[data-icon]\")&&this.setToggleIcon(),this.toggle.querySelector(\"[data-title]\")&&this.setToggleTitle(),this.close(!0)),this.value.length||\"tags\"!==this.mode||this.reassignTagsInputPlaceholder(this.placeholder),this.isOpened&&\"tags\"===this.mode&&this.tagsInput&&this.tagsInput.focus(),this.triggerChangeEventForNativeSelect()}triggerChangeEventForNativeSelect(){const e=new Event(\"change\",{bubbles:!0});this.el.dispatchEvent(e),(0,o.dispatch)(\"change.advance.select\",this.el,this.value)}addSelectOption(e,t,i,s,n){this.selectOptions=[...this.selectOptions,{title:e,val:t,disabled:i,selected:s,options:n}]}removeSelectOption(e,t=!1){if(!!!this.selectOptions.some((t=>t.val===e)))return!1;this.selectOptions=this.selectOptions.filter((t=>t.val!==e)),this.value=t?this.value.filter((t=>t!==e)):e}resetTagsInputField(){this.tagsInput.value=\"\",this.reassignTagsInputPlaceholder(\"\"),this.searchOptions(\"\")}clearSelections(){Array.from(this.dropdown.children).forEach((e=>{e.classList.contains(\"selected\")&&e.classList.remove(\"selected\")})),Array.from(this.el.children).forEach((e=>{e.selected&&(e.selected=!1)}))}setNewValue(){var e;\"tags\"===this.mode?this.setTagsItems():(null===(e=this.value)||void 0===e?void 0:e.length)?this.toggleTextWrapper.innerHTML=this.stringFromValue():this.toggleTextWrapper.innerHTML=this.placeholder}stringFromValueBasic(e){var t;const i=[];let s=\"\";if(e.forEach((e=>{this.isMultiple?this.value.includes(e.val)&&i.push(e.title):this.value===e.val&&i.push(e.title)})),void 0!==this.toggleCountText&&null!==this.toggleCountText&&i.length>=this.toggleCountTextMinItems)if(\"nItemsAndCount\"===this.toggleCountTextMode){const e=i.slice(0,this.toggleCountTextMinItems-1),n=[e.join(this.toggleSeparators.items)],o=\"\"+(i.length-e.length);if((null===(t=null==this?void 0:this.toggleSeparators)||void 0===t?void 0:t.betweenItemsAndCounter)&&n.push(this.toggleSeparators.betweenItemsAndCounter),this.toggleCountText)switch(this.toggleCountTextPlacement){case\"postfix-no-space\":n.push(`${o}${this.toggleCountText}`);break;case\"prefix-no-space\":n.push(`${this.toggleCountText}${o}`);break;case\"prefix\":n.push(`${this.toggleCountText} ${o}`);break;default:n.push(`${o} ${this.toggleCountText}`)}s=n.join(\" \")}else s=`${i.length} ${this.toggleCountText}`;else s=i.join(this.toggleSeparators.items);return s}stringFromValueRemoteData(){const e=this.dropdown.querySelectorAll(\"[data-title-value]\"),t=[];let i=\"\";if(e.forEach((e=>{const i=e.getAttribute(\"data-value\"),s=e.getAttribute(\"data-title-value\");this.isMultiple?this.value.includes(i)&&t.push(s):this.value===i&&t.push(s)})),this.toggleCountText&&\"\"!==this.toggleCountText&&t.length>=this.toggleCountTextMinItems)if(\"nItemsAndCount\"===this.toggleCountTextMode){const e=t.slice(0,this.toggleCountTextMinItems-1);i=`${e.join(this.toggleSeparators.items)} ${this.toggleSeparators.betweenItemsAndCounter} ${t.length-e.length} ${this.toggleCountText}`}else i=`${t.length} ${this.toggleCountText}`;else i=t.join(this.toggleSeparators.items);return i}stringFromValue(){return this.apiUrl?this.stringFromValueRemoteData():this.stringFromValueBasic(this.selectOptions)}selectSingleItem(){Array.from(this.el.children).find((e=>this.value===e.value)).selected=!0;const e=Array.from(this.dropdown.children).find((e=>this.value===e.getAttribute(\"data-value\")));e&&e.classList.add(\"selected\")}selectMultipleItems(){Array.from(this.dropdown.children).filter((e=>this.value.includes(e.getAttribute(\"data-value\")))).forEach((e=>e.classList.add(\"selected\"))),Array.from(this.el.children).filter((e=>this.value.includes(e.value))).forEach((e=>e.selected=!0))}unselectMultipleItems(){Array.from(this.dropdown.children).forEach((e=>e.classList.remove(\"selected\"))),Array.from(this.el.children).forEach((e=>e.selected=!1))}searchOptions(e){if(e.length<=this.minSearchLength){this.searchNoResult&&(this.searchNoResult.remove(),this.searchNoResult=null);return this.dropdown.querySelectorAll(\"[data-value]\").forEach((e=>{e.classList.remove(\"hidden\")})),!1}this.searchNoResult&&(this.searchNoResult.remove(),this.searchNoResult=null),this.searchNoResult=(0,o.htmlToElement)(this.searchNoResultTemplate),this.searchNoResult.innerText=this.searchNoResultText,(0,o.classToClassList)(this.searchNoResultClasses,this.searchNoResult);const t=this.dropdown.querySelectorAll(\"[data-value]\");let i,s=!1;this.searchLimit&&(i=0),t.forEach((t=>{const n=t.getAttribute(\"data-title-value\").toLocaleLowerCase();let o;if(this.isSearchDirectMatch)o=!n.includes(e.toLowerCase())||this.searchLimit&&i>=this.searchLimit;else{const t=e?e.split(\"\").map((e=>/\\w/.test(e)?`${e}[\\\\W_]*`:\"\\\\W*\")).join(\"\"):\"\";o=!new RegExp(t,\"i\").test(n.trim())||this.searchLimit&&i>=this.searchLimit}o?t.classList.add(\"hidden\"):(t.classList.remove(\"hidden\"),s=!0,this.searchLimit&&i++)})),s||this.dropdown.append(this.searchNoResult)}eraseToggleIcon(){const e=this.toggle.querySelector(\"[data-icon]\");e&&(e.innerHTML=null,e.classList.add(\"hidden\"))}eraseToggleTitle(){const e=this.toggle.querySelector(\"[data-title]\");e?e.innerHTML=this.placeholder:this.toggleTextWrapper.innerHTML=this.placeholder}toggleFn(){this.isOpened?this.close():this.open()}destroy(){this.wrapper&&this.wrapper.removeEventListener(\"click\",this.onWrapperClickListener),this.toggle&&this.toggle.removeEventListener(\"click\",this.onToggleClickListener),this.tagsInput&&(this.tagsInput.removeEventListener(\"focus\",this.onTagsInputFocusListener),this.tagsInput.removeEventListener(\"input\",this.onTagsInputInputListener),this.tagsInput.removeEventListener(\"input\",this.onTagsInputInputSecondListener),this.tagsInput.removeEventListener(\"keydown\",this.onTagsInputKeydownListener)),this.search&&this.search.removeEventListener(\"input\",this.onSearchInputListener);const e=this.el.parentElement.parentElement;this.el.classList.add(\"hidden\"),this.el.style.display=\"\",e.prepend(this.el),e.querySelector(\".advance-select\").remove(),this.wrapper=null,window.$hsSelectCollection=window.$hsSelectCollection.filter((({element:e})=>e.el!==this.el))}open(){var e;const t=(null===(e=null===window||void 0===window?void 0:window.$hsSelectCollection)||void 0===e?void 0:e.find((e=>e.element.isOpened)))||null;if(t&&t.element.close(),this.animationInProcess)return!1;this.animationInProcess=!0,\"window\"===this.dropdownScope&&this.dropdown.classList.add(\"invisible\"),this.dropdown.classList.remove(\"hidden\"),this.recalculateDirection(),setTimeout((()=>{var e;(null===(e=null==this?void 0:this.toggle)||void 0===e?void 0:e.ariaExpanded)&&(this.toggle.ariaExpanded=\"true\"),this.wrapper.classList.add(\"active\"),this.dropdown.classList.add(\"opened\"),this.dropdown.classList.contains(\"w-full\")&&\"window\"===this.dropdownScope&&this.updateDropdownWidth(),this.floatingUIInstance&&\"window\"===this.dropdownScope&&(this.floatingUIInstance.update(),this.dropdown.classList.remove(\"invisible\")),this.hasSearch&&!this.preventSearchFocus&&this.search.focus(),this.animationInProcess=!1})),this.isOpened=!0}close(e=!1){var t,i,s,n;if(this.animationInProcess)return!1;this.animationInProcess=!0,(null===(t=null==this?void 0:this.toggle)||void 0===t?void 0:t.ariaExpanded)&&(this.toggle.ariaExpanded=\"false\"),this.wrapper.classList.remove(\"active\"),this.dropdown.classList.remove(\"opened\",\"bottom-full\",\"top-full\"),(null===(i=this.dropdownDirectionClasses)||void 0===i?void 0:i.bottom)&&this.dropdown.classList.remove(this.dropdownDirectionClasses.bottom),(null===(s=this.dropdownDirectionClasses)||void 0===s?void 0:s.top)&&this.dropdown.classList.remove(this.dropdownDirectionClasses.top),this.dropdown.style.marginTop=\"\",this.dropdown.style.marginBottom=\"\",(0,o.afterTransition)(this.dropdown,(()=>{this.dropdown.classList.add(\"hidden\"),this.hasSearch&&(this.search.value=\"\",this.search.dispatchEvent(new Event(\"input\",{bubbles:!0})),this.search.blur()),e&&this.toggle.focus(),this.animationInProcess=!1})),null===(n=this.dropdown.querySelector(\".select-option-highlighted\"))||void 0===n||n.classList.remove(\"select-option-highlighted\"),this.isOpened=!1}addOption(e){let t=`${this.selectOptions.length}`;const i=e=>{const{title:i,val:s,disabled:n,selected:o,options:l}=e;!!this.selectOptions.some((e=>e.val===s))||(this.addSelectOption(i,s,n,o,l),this.buildOption(i,s,n,o,l,t),this.buildOriginalOption(i,s,null,n,o,l),o&&!this.isMultiple&&this.onSelectOption(s))};Array.isArray(e)?e.forEach((e=>{i(e)})):i(e)}removeOption(e){const t=(e,t=!1)=>{!!this.selectOptions.some((t=>t.val===e))&&(this.removeSelectOption(e,t),this.destroyOption(e),this.destroyOriginalOption(e),this.value===e&&(this.value=null,this.eraseToggleTitle(),this.eraseToggleIcon()))};Array.isArray(e)?e.forEach((e=>{t(e,this.isMultiple)})):t(e,this.isMultiple),this.setNewValue()}recalculateDirection(){var e,t,i,s;if((null==this?void 0:this.dropdownVerticalFixedPlacement)&&(this.dropdown.classList.contains(\"bottom-full\")||this.dropdown.classList.contains(\"top-full\")))return!1;\"top\"===(null==this?void 0:this.dropdownVerticalFixedPlacement)?(this.dropdown.classList.add(\"bottom-full\"),this.dropdown.style.marginBottom=`${this.dropdownSpace}px`):\"bottom\"===(null==this?void 0:this.dropdownVerticalFixedPlacement)?(this.dropdown.classList.add(\"top-full\"),this.dropdown.style.marginTop=`${this.dropdownSpace}px`):(0,o.isEnoughSpace)(this.dropdown,this.toggle||this.tagsInput,\"bottom\",this.dropdownSpace,this.viewport)?(this.dropdown.classList.remove(\"bottom-full\"),(null===(e=this.dropdownDirectionClasses)||void 0===e?void 0:e.bottom)&&this.dropdown.classList.remove(this.dropdownDirectionClasses.bottom),this.dropdown.style.marginBottom=\"\",this.dropdown.classList.add(\"top-full\"),(null===(t=this.dropdownDirectionClasses)||void 0===t?void 0:t.top)&&this.dropdown.classList.add(this.dropdownDirectionClasses.top),this.dropdown.style.marginTop=`${this.dropdownSpace}px`):(this.dropdown.classList.remove(\"top-full\"),(null===(i=this.dropdownDirectionClasses)||void 0===i?void 0:i.top)&&this.dropdown.classList.remove(this.dropdownDirectionClasses.top),this.dropdown.style.marginTop=\"\",this.dropdown.classList.add(\"bottom-full\"),(null===(s=this.dropdownDirectionClasses)||void 0===s?void 0:s.bottom)&&this.dropdown.classList.add(this.dropdownDirectionClasses.bottom),this.dropdown.style.marginBottom=`${this.dropdownSpace}px`)}static findInCollection(e){return window.$hsSelectCollection.find((t=>e instanceof c?t.element.el===e.el:\"string\"==typeof e?t.element.el===document.querySelector(e):t.element.el===e))||null}static getInstance(e,t){const i=window.$hsSelectCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element:null}static autoInit(){window.$hsSelectCollection||(window.$hsSelectCollection=[],window.addEventListener(\"click\",(e=>{const t=e.target;c.closeCurrentlyOpened(t)})),document.addEventListener(\"keydown\",(e=>c.accessibility(e)))),window.$hsSelectCollection&&(window.$hsSelectCollection=window.$hsSelectCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-select]:not(.--prevent-on-load-init)\").forEach((e=>{if(!window.$hsSelectCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))){const t=e.getAttribute(\"data-select\"),i=t?JSON.parse(t):{};new c(e,i)}}))}static open(e){const t=c.findInCollection(e);t&&!t.element.isOpened&&t.element.open()}static close(e){const t=c.findInCollection(e);t&&t.element.isOpened&&t.element.close()}static closeCurrentlyOpened(e=null){if(!e.closest(\".advance-select.active\")&&!e.closest(\"[data-select-dropdown].opened\")){const e=window.$hsSelectCollection.filter((e=>e.element.isOpened))||null;e&&e.forEach((e=>{e.element.close()}))}}static accessibility(e){const t=window.$hsSelectCollection.find((e=>e.element.isOpened));if(t&&a.SELECT_ACCESSIBILITY_KEY_SET.includes(e.code)&&!e.metaKey)switch(e.code){case\"Escape\":e.preventDefault(),this.onEscape();break;case\"ArrowUp\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrow();break;case\"ArrowDown\":e.preventDefault(),e.stopImmediatePropagation(),this.onArrow(!1);break;case\"Tab\":e.preventDefault(),e.stopImmediatePropagation(),this.onTab(e.shiftKey);break;case\"Home\":e.preventDefault(),e.stopImmediatePropagation(),this.onStartEnd();break;case\"End\":e.preventDefault(),e.stopImmediatePropagation(),this.onStartEnd(!1);break;case\"Enter\":e.preventDefault(),this.onEnter(e);break;case\"Space\":if((0,o.isFocused)(t.element.search))break;e.preventDefault(),this.onEnter(e)}}static onEscape(){const e=window.$hsSelectCollection.find((e=>e.element.isOpened));e&&e.element.close()}static onArrow(e=!0){const t=window.$hsSelectCollection.find((e=>e.element.isOpened));if(t){const i=t.element.dropdown;if(!i)return!1;const s=(e?Array.from(i.querySelectorAll(\":scope > *:not(.hidden)\")).reverse():Array.from(i.querySelectorAll(\":scope > *:not(.hidden)\"))).filter((e=>!e.classList.contains(\"disabled\"))),n=i.querySelector(\".select-option-highlighted\")||i.querySelector(\".selected\");n||s[0].classList.add(\"select-option-highlighted\");let o=s.findIndex((e=>e===n));o+1e.element.isOpened));if(t){const i=t.element.dropdown;if(!i)return!1;const s=(e?Array.from(i.querySelectorAll(\":scope > *:not(.hidden)\")).reverse():Array.from(i.querySelectorAll(\":scope > *:not(.hidden)\"))).filter((e=>!e.classList.contains(\"disabled\"))),n=i.querySelector(\".select-option-highlighted\")||i.querySelector(\".selected\");n||s[0].classList.add(\"select-option-highlighted\");let o=s.findIndex((e=>e===n));if(!(o+1e.element.isOpened));if(t){const i=t.element.dropdown;if(!i)return!1;const s=(e?Array.from(i.querySelectorAll(\":scope > *:not(.hidden)\")):Array.from(i.querySelectorAll(\":scope > *:not(.hidden)\")).reverse()).filter((e=>!e.classList.contains(\"disabled\"))),n=i.querySelector(\".select-option-highlighted\");s.length&&(s[0].focus(),n&&n.classList.remove(\"select-option-highlighted\"),s[0].classList.add(\"select-option-highlighted\"))}}static onEnter(e){const t=e.target.previousSibling;if(window.$hsSelectCollection.find((e=>e.element.el===t))){const e=window.$hsSelectCollection.find((e=>e.element.isOpened)),i=window.$hsSelectCollection.find((e=>e.element.el===t));e.element.close(),e!==i&&i.element.open()}else{const t=window.$hsSelectCollection.find((e=>e.element.isOpened));t&&t.element.onSelectOption(e.target.dataset.value||\"\")}}}window.addEventListener(\"load\",(()=>{c.autoInit()})),document.addEventListener(\"scroll\",(()=>{if(!window.$hsSelectCollection)return!1;const e=window.$hsSelectCollection.find((e=>e.element.isOpened));e&&e.element.recalculateDirection()})),\"undefined\"!=typeof window&&(window.HSSelect=c),t.default=c},977:function(e,t,i){\n/*\n * HSRangeSlider\n * @version: 3.0.0\n * @author: Preline Labs Ltd.\n * @license: Licensed under MIT and Preline UI Fair Use License (https://preline.co/docs/license.html)\n * Copyright 2024 Preline Labs Ltd.\n */\nvar s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,\"__esModule\",{value:!0});const n=s(i(287));class o extends n.default{constructor(e,t,i){super(e,t,i);const s=e.getAttribute(\"data-range-slider\"),n=s?JSON.parse(s):{};this.concatOptions=Object.assign(Object.assign(Object.assign({},n),t),{cssClasses:Object.assign(Object.assign({},noUiSlider.cssClasses),this.processClasses(n.cssClasses))}),this.init()}get formattedValue(){const e=this.el.noUiSlider.get();if(Array.isArray(e)&&this.format){const t=[];return e.forEach((e=>{t.push(this.format.to(e))})),t}return this.format?this.format.to(e):e}processClasses(e){const t={};return Object.keys(e).forEach((i=>{i&&(t[i]=`${noUiSlider.cssClasses[i]} ${e[i]}`)})),t}init(){var e,t,i,s,n,o,l,r,a,c,d,h,u;this.createCollection(window.$hsRangeSliderCollection,this),(\"object\"==typeof(null===(e=this.concatOptions)||void 0===e?void 0:e.formatter)?\"thousandsSeparatorAndDecimalPoints\"===(null===(i=null===(t=this.concatOptions)||void 0===t?void 0:t.formatter)||void 0===i?void 0:i.type):\"thousandsSeparatorAndDecimalPoints\"===(null===(s=this.concatOptions)||void 0===s?void 0:s.formatter))?this.thousandsSeparatorAndDecimalPointsFormatter():(\"object\"==typeof(null===(n=this.concatOptions)||void 0===n?void 0:n.formatter)?\"integer\"===(null===(l=null===(o=this.concatOptions)||void 0===o?void 0:o.formatter)||void 0===l?void 0:l.type):\"integer\"===(null===(r=this.concatOptions)||void 0===r?void 0:r.formatter))?this.integerFormatter():\"object\"==typeof(null===(a=this.concatOptions)||void 0===a?void 0:a.formatter)&&((null===(d=null===(c=this.concatOptions)||void 0===c?void 0:c.formatter)||void 0===d?void 0:d.prefix)||(null===(u=null===(h=this.concatOptions)||void 0===h?void 0:h.formatter)||void 0===u?void 0:u.postfix))&&this.prefixOrPostfixFormatter(),noUiSlider.create(this.el,this.concatOptions),this.concatOptions.disabled&&this.setDisabled()}formatValue(e){var t,i,s,n,o,l,r,a,c;let d=\"\";return\"object\"==typeof(null===(t=this.concatOptions)||void 0===t?void 0:t.formatter)?((null===(s=null===(i=this.concatOptions)||void 0===i?void 0:i.formatter)||void 0===s?void 0:s.prefix)&&(d+=null===(o=null===(n=this.concatOptions)||void 0===n?void 0:n.formatter)||void 0===o?void 0:o.prefix),d+=e,(null===(r=null===(l=this.concatOptions)||void 0===l?void 0:l.formatter)||void 0===r?void 0:r.postfix)&&(d+=null===(c=null===(a=this.concatOptions)||void 0===a?void 0:a.formatter)||void 0===c?void 0:c.postfix)):d+=e,d}integerFormatter(){var e;this.format={to:e=>this.formatValue(Math.round(e)),from:e=>Math.round(+e)},(null===(e=this.concatOptions)||void 0===e?void 0:e.tooltips)&&(this.concatOptions.tooltips=this.format)}prefixOrPostfixFormatter(){var e;this.format={to:e=>this.formatValue(e),from:e=>+e},(null===(e=this.concatOptions)||void 0===e?void 0:e.tooltips)&&(this.concatOptions.tooltips=this.format)}thousandsSeparatorAndDecimalPointsFormatter(){var e;this.format={to:e=>this.formatValue(new Intl.NumberFormat(\"en-US\",{minimumFractionDigits:2,maximumFractionDigits:2}).format(e)),from:e=>parseFloat(e.replace(/,/g,\"\"))},(null===(e=this.concatOptions)||void 0===e?void 0:e.tooltips)&&(this.concatOptions.tooltips=this.format)}setDisabled(){this.el.setAttribute(\"disabled\",\"disabled\"),this.el.classList.add(\"disabled\")}destroy(){this.el.noUiSlider.destroy(),this.format=null,window.$hsRangeSliderCollection=window.$hsRangeSliderCollection.filter((({element:e})=>e.el!==this.el))}static getInstance(e,t=!1){const i=window.$hsRangeSliderCollection.find((t=>t.element.el===(\"string\"==typeof e?document.querySelector(e):e)));return i?t?i:i.element.el:null}static autoInit(){window.$hsRangeSliderCollection||(window.$hsRangeSliderCollection=[]),window.$hsRangeSliderCollection&&(window.$hsRangeSliderCollection=window.$hsRangeSliderCollection.filter((({element:e})=>document.contains(e.el)))),document.querySelectorAll(\"[data-range-slider]:not(.--prevent-on-load-init)\").forEach((e=>{window.$hsRangeSliderCollection.find((t=>{var i;return(null===(i=null==t?void 0:t.element)||void 0===i?void 0:i.el)===e}))||new o(e)}))}}window.addEventListener(\"load\",(()=>{o.autoInit()})),\"undefined\"!=typeof window&&(window.HSRangeSlider=o),t.default=o}},t={};function i(s){var n=t[s];if(void 0!==n)return n.exports;var o=t[s]={exports:{}};return e[s].call(o.exports,o,o.exports,i),o.exports}return i.d=(e,t)=>{for(var s in t)i.o(t,s)&&!i.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),i.r=e=>{\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},i(800)})()));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUssT0FBTyw4QkFBOEIsb25DQUFvbkMsZUFBZSxzQkFBc0IsU0FBUyxxZ0JBQXFnQixtQkFBbUIsTUFBTSxhQUFhLDZEQUE2RCwwR0FBMEcsMkJBQTJCLE1BQU0sYUFBYSxxQ0FBcUMsMEdBQTBHLDhDQUE4QyxNQUFNLGFBQWEsc0RBQXNELGdEQUFnRCxvREFBb0QsMEdBQTBHLGNBQWMsOEVBQThFLFVBQVUsd0hBQXdILFVBQVUsb0JBQW9CLDJCQUEyQixtSEFBbUgsK0JBQStCLGtCQUFrQixrTEFBa0wsVUFBVSx5SEFBeUgsMENBQTBDLE1BQU0sd0VBQXdFLGFBQWEsSUFBSSxxQ0FBcUMsYUFBYSxxRUFBcUUsTUFBTSxjQUFjLFdBQVcsK0JBQStCLFlBQVksWUFBWSxvREFBb0QsbUJBQW1CLCtEQUErRCx1QkFBdUIsRUFBRSw4REFBOEQsNEZBQTRGLGVBQWUsd0NBQXdDLFNBQVMsRUFBRSxRQUFRIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2ZseW9udWkvZmx5b251aS5qcz81YzY1Il0sInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbihlLHQpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlKW1vZHVsZS5leHBvcnRzPXQoKTtlbHNlIGlmKFwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZClkZWZpbmUoW10sdCk7ZWxzZXt2YXIgaT10KCk7Zm9yKHZhciBzIGluIGkpKFwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHM6ZSlbc109aVtzXX19KHNlbGYsKCgpPT4oKCk9PntcInVzZSBzdHJpY3RcIjt2YXIgZT17MTI6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTQ29weU1hcmt1cFxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCl7c3VwZXIoZSx0KSx0aGlzLmNvdW50PTA7Y29uc3QgaT1lLmdldEF0dHJpYnV0ZShcImRhdGEtY29weS1tYXJrdXBcIikscz1pP0pTT04ucGFyc2UoaSk6e30sbj1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30scyksdCk7dGhpcy50YXJnZXRTZWxlY3Rvcj0obnVsbD09bj92b2lkIDA6bi50YXJnZXRTZWxlY3Rvcil8fG51bGwsdGhpcy53cmFwcGVyU2VsZWN0b3I9KG51bGw9PW4/dm9pZCAwOm4ud3JhcHBlclNlbGVjdG9yKXx8bnVsbCx0aGlzLmxpbWl0PShudWxsPT1uP3ZvaWQgMDpuLmxpbWl0KXx8bnVsbCx0aGlzLml0ZW1zPVtdLHRoaXMudGFyZ2V0U2VsZWN0b3ImJnRoaXMuaW5pdCgpfWVsZW1lbnRDbGljaygpe3RoaXMuY29weSgpfWRlbGV0ZUl0ZW1CdXR0b25DbGljayhlKXt0aGlzLmRlbGV0ZShlKX1pbml0KCl7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNDb3B5TWFya3VwQ29sbGVjdGlvbix0aGlzKSx0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXI9KCk9PnRoaXMuZWxlbWVudENsaWNrKCksdGhpcy5zZXRUYXJnZXQoKSx0aGlzLnNldFdyYXBwZXIoKSx0aGlzLmFkZFByZWRlZmluZWRJdGVtcygpLHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyKX1jb3B5KCl7aWYodGhpcy5saW1pdCYmdGhpcy5pdGVtcy5sZW5ndGg+PXRoaXMubGltaXQpcmV0dXJuITE7dGhpcy5lbC5oYXNBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSYmdGhpcy5lbC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLFwiXCIpO2NvbnN0IGU9dGhpcy50YXJnZXQuY2xvbmVOb2RlKCEwKSx0PWAke3RoaXMudGFyZ2V0LmlkfS0ke3RoaXMuY291bnQrK31gO2Uuc2V0QXR0cmlidXRlKFwiaWRcIix0KSx0aGlzLmFkZFRvSXRlbXMoZSksdGhpcy5saW1pdCYmdGhpcy5pdGVtcy5sZW5ndGg+PXRoaXMubGltaXQmJnRoaXMuZWwuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpLHRoaXMuZmlyZUV2ZW50KFwiY29weVwiLGUpLCgwLG4uZGlzcGF0Y2gpKFwiY29weS5jb3B5TWFya3VwXCIsZSxlKX1hZGRQcmVkZWZpbmVkSXRlbXMoKXtBcnJheS5mcm9tKHRoaXMud3JhcHBlci5jaGlsZHJlbikuZmlsdGVyKChlPT4hZS5jbGFzc0xpc3QuY29udGFpbnMoXCJbLS1pZ25vcmUtZm9yLWNvdW50XVwiKSkpLmZvckVhY2goKGU9Pnt0aGlzLmFkZFRvSXRlbXMoZSl9KSksdGhpcy5saW1pdCYmdGhpcy5pdGVtcy5sZW5ndGg+PXRoaXMubGltaXQmJnRoaXMuZWwuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpfXNldFRhcmdldCgpe2NvbnN0IGU9XCJzdHJpbmdcIj09dHlwZW9mIHRoaXMudGFyZ2V0U2VsZWN0b3I/ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLnRhcmdldFNlbGVjdG9yKS5jbG9uZU5vZGUoITApOnRoaXMudGFyZ2V0U2VsZWN0b3IuY2xvbmVOb2RlKCEwKTt0aGlzLnRhcmdldD1lfXNldFdyYXBwZXIoKXt0aGlzLndyYXBwZXI9XCJzdHJpbmdcIj09dHlwZW9mIHRoaXMud3JhcHBlclNlbGVjdG9yP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy53cmFwcGVyU2VsZWN0b3IpOnRoaXMud3JhcHBlclNlbGVjdG9yfWFkZFRvSXRlbXMoZSl7Y29uc3QgdD1lLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1jb3B5LW1hcmt1cC1kZWxldGUtaXRlbV1cIik7dGhpcy53cmFwcGVyP3RoaXMud3JhcHBlci5hcHBlbmQoZSk6dGhpcy5lbC5iZWZvcmUoZSksdCYmKHRoaXMub25EZWxldGVJdGVtQnV0dG9uQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5kZWxldGVJdGVtQnV0dG9uQ2xpY2soZSksdC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uRGVsZXRlSXRlbUJ1dHRvbkNsaWNrTGlzdGVuZXIpKSx0aGlzLml0ZW1zLnB1c2goZSl9ZGVsZXRlKGUpe2lmKGUpe2NvbnN0IHQ9dGhpcy5pdGVtcy5pbmRleE9mKGUpOy0xIT09dCYmdGhpcy5pdGVtcy5zcGxpY2UodCwxKSxlLnJlbW92ZSgpLHRoaXMuZmlyZUV2ZW50KFwiZGVsZXRlXCIsZSksKDAsbi5kaXNwYXRjaCkoXCJkZWxldGUuY29weU1hcmt1cFwiLGUsZSksdGhpcy5saW1pdCYmdGhpcy5pdGVtcy5sZW5ndGg8dGhpcy5saW1pdCYmdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKX19ZGVzdHJveSgpe2NvbnN0IGU9dGhpcy53cmFwcGVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1jb3B5LW1hcmt1cC1kZWxldGUtaXRlbV1cIik7dGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXIpLGUubGVuZ3RoJiZlLmZvckVhY2goKGU9PmUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkRlbGV0ZUl0ZW1CdXR0b25DbGlja0xpc3RlbmVyKSkpLHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIiksdGhpcy50YXJnZXQ9bnVsbCx0aGlzLndyYXBwZXI9bnVsbCx0aGlzLml0ZW1zPW51bGwsd2luZG93LiRoc0NvcHlNYXJrdXBDb2xsZWN0aW9uPXdpbmRvdy4kaHNDb3B5TWFya3VwQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzQ29weU1hcmt1cENvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50Om51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0NvcHlNYXJrdXBDb2xsZWN0aW9ufHwod2luZG93LiRoc0NvcHlNYXJrdXBDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzQ29weU1hcmt1cENvbGxlY3Rpb24mJih3aW5kb3cuJGhzQ29weU1hcmt1cENvbGxlY3Rpb249d2luZG93LiRoc0NvcHlNYXJrdXBDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWNvcHktbWFya3VwXTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmZvckVhY2goKGU9PntpZighd2luZG93LiRoc0NvcHlNYXJrdXBDb2xsZWN0aW9uLmZpbmQoKHQ9Pnt2YXIgaTtyZXR1cm4obnVsbD09PShpPW51bGw9PXQ/dm9pZCAwOnQuZWxlbWVudCl8fHZvaWQgMD09PWk/dm9pZCAwOmkuZWwpPT09ZX0pKSl7Y29uc3QgdD1lLmdldEF0dHJpYnV0ZShcImRhdGEtY29weS1tYXJrdXBcIiksaT10P0pTT04ucGFyc2UodCk6e307bmV3IGwoZSxpKX19KSl9fXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCgoKT0+e2wuYXV0b0luaXQoKX0pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYod2luZG93LkhTQ29weU1hcmt1cD1sKSx0LmRlZmF1bHQ9bH0sNzU6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTQ29tYm9Cb3hcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2F3YWl0ZXJ8fGZ1bmN0aW9uKGUsdCxpLHMpe3JldHVybiBuZXcoaXx8KGk9UHJvbWlzZSkpKChmdW5jdGlvbihuLG8pe2Z1bmN0aW9uIGwoZSl7dHJ5e2Eocy5uZXh0KGUpKX1jYXRjaChlKXtvKGUpfX1mdW5jdGlvbiByKGUpe3RyeXthKHMudGhyb3coZSkpfWNhdGNoKGUpe28oZSl9fWZ1bmN0aW9uIGEoZSl7dmFyIHQ7ZS5kb25lP24oZS52YWx1ZSk6KHQ9ZS52YWx1ZSx0IGluc3RhbmNlb2YgaT90Om5ldyBpKChmdW5jdGlvbihlKXtlKHQpfSkpKS50aGVuKGwscil9YSgocz1zLmFwcGx5KGUsdHx8W10pKS5uZXh0KCkpfSkpfSxuPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IG89aSg4MDYpLGw9bihpKDI4NykpLHI9aSg5MTcpO2NsYXNzIGEgZXh0ZW5kcyBsLmRlZmF1bHR7Y29uc3RydWN0b3IoZSx0LGkpe3ZhciBzLG4sbyxsLHIsYSxjLGQsaCx1LHAsbSxnLGYsdix3LHksYixDLFMsTCxJLEUsVCx4LGssQSxPO3N1cGVyKGUsdCxpKSx0aGlzLmlzU2VhcmNoTGVuZ3RoRXhjZWVkZWQ9ITE7Y29uc3QgUD1lLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94XCIpLCQ9UD9KU09OLnBhcnNlKFApOnt9LEI9T2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCQpLHQpO3RoaXMuZ2FwPTYsdGhpcy52aWV3cG9ydD1udWxsIT09KHM9XCJzdHJpbmdcIj09dHlwZW9mKG51bGw9PUI/dm9pZCAwOkIudmlld3BvcnQpP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobnVsbD09Qj92b2lkIDA6Qi52aWV3cG9ydCk6bnVsbD09Qj92b2lkIDA6Qi52aWV3cG9ydCkmJnZvaWQgMCE9PXM/czpudWxsLHRoaXMucHJldmVudFZpc2liaWxpdHk9bnVsbCE9PShuPW51bGw9PUI/dm9pZCAwOkIucHJldmVudFZpc2liaWxpdHkpJiZ2b2lkIDAhPT1uJiZuLHRoaXMubWluU2VhcmNoTGVuZ3RoPW51bGwhPT0obz1udWxsPT1CP3ZvaWQgMDpCLm1pblNlYXJjaExlbmd0aCkmJnZvaWQgMCE9PW8/bzowLHRoaXMuYXBpVXJsPW51bGwhPT0obD1udWxsPT1CP3ZvaWQgMDpCLmFwaVVybCkmJnZvaWQgMCE9PWw/bDpudWxsLHRoaXMuYXBpRGF0YVBhcnQ9bnVsbCE9PShyPW51bGw9PUI/dm9pZCAwOkIuYXBpRGF0YVBhcnQpJiZ2b2lkIDAhPT1yP3I6bnVsbCx0aGlzLmFwaVF1ZXJ5PW51bGwhPT0oYT1udWxsPT1CP3ZvaWQgMDpCLmFwaVF1ZXJ5KSYmdm9pZCAwIT09YT9hOm51bGwsdGhpcy5hcGlTZWFyY2hRdWVyeT1udWxsIT09KGM9bnVsbD09Qj92b2lkIDA6Qi5hcGlTZWFyY2hRdWVyeSkmJnZvaWQgMCE9PWM/YzpudWxsLHRoaXMuYXBpU2VhcmNoUGF0aD1udWxsIT09KGQ9bnVsbD09Qj92b2lkIDA6Qi5hcGlTZWFyY2hQYXRoKSYmdm9pZCAwIT09ZD9kOm51bGwsdGhpcy5hcGlTZWFyY2hEZWZhdWx0UGF0aD1udWxsIT09KGg9bnVsbD09Qj92b2lkIDA6Qi5hcGlTZWFyY2hEZWZhdWx0UGF0aCkmJnZvaWQgMCE9PWg/aDpudWxsLHRoaXMuYXBpSGVhZGVycz1udWxsIT09KHU9bnVsbD09Qj92b2lkIDA6Qi5hcGlIZWFkZXJzKSYmdm9pZCAwIT09dT91Ont9LHRoaXMuYXBpR3JvdXBGaWVsZD1udWxsIT09KHA9bnVsbD09Qj92b2lkIDA6Qi5hcGlHcm91cEZpZWxkKSYmdm9pZCAwIT09cD9wOm51bGwsdGhpcy5vdXRwdXRJdGVtVGVtcGxhdGU9bnVsbCE9PShtPW51bGw9PUI/dm9pZCAwOkIub3V0cHV0SXRlbVRlbXBsYXRlKSYmdm9pZCAwIT09bT9tOic8ZGl2IGNsYXNzPVwiZHJvcGRvd24taXRlbSBjb21iby1ib3gtc2VsZWN0ZWQ6ZHJvcGRvd24tYWN0aXZlXCIgZGF0YS1jb21iby1ib3gtb3V0cHV0LWl0ZW0+XFxuXFx0XFx0XFx0XFx0PGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlciB3LWZ1bGxcIj5cXG5cXHRcXHRcXHRcXHRcXHQ8c3BhbiBkYXRhLWNvbWJvLWJveC1zZWFyY2gtdGV4dD48L3NwYW4+XFxuXFx0XFx0XFx0XFx0XFx0PHNwYW4gY2xhc3M9XCJoaWRkZW4gY29tYm8tYm94LXNlbGVjdGVkOmJsb2NrXCI+XFxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cInNocmluay0wIHNpemUtNCB0ZXh0LXByaW1hcnlcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIyNFwiIGhlaWdodD1cIjI0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPjxwYXRoIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgc3Ryb2tlLXdpZHRoPVwiMlwiIGQ9XCJtNSAxMmw1IDVMMjAgN1wiLz48L3N2Zz5cXG5cXHRcXHRcXHRcXHRcXHQ8L3NwYW4+XFxuXFx0XFx0XFx0XFx0PC9kaXY+XFxuXFx0XFx0XFx0PC9kaXY+Jyx0aGlzLm91dHB1dEVtcHR5VGVtcGxhdGU9bnVsbCE9PShnPW51bGw9PUI/dm9pZCAwOkIub3V0cHV0RW1wdHlUZW1wbGF0ZSkmJnZvaWQgMCE9PWc/ZzonPGRpdiBjbGFzcz1cImRyb3Bkb3duLWl0ZW1cIj5Ob3RoaW5nIGZvdW5kLi4uPC9kaXY+Jyx0aGlzLm91dHB1dExvYWRlclRlbXBsYXRlPW51bGwhPT0oZj1udWxsPT1CP3ZvaWQgMDpCLm91dHB1dExvYWRlclRlbXBsYXRlKSYmdm9pZCAwIT09Zj9mOic8c3BhbiBjbGFzcz1cImxvYWRpbmcgbG9hZGluZy1zcGlubmVyIHRleHQtcHJpbWFyeVwiPjwvc3Bhbj4nLHRoaXMuZ3JvdXBpbmdUeXBlPW51bGwhPT0odj1udWxsPT1CP3ZvaWQgMDpCLmdyb3VwaW5nVHlwZSkmJnZvaWQgMCE9PXY/djpudWxsLHRoaXMuZ3JvdXBpbmdUaXRsZVRlbXBsYXRlPW51bGwhPT0odz1udWxsPT1CP3ZvaWQgMDpCLmdyb3VwaW5nVGl0bGVUZW1wbGF0ZSkmJnZvaWQgMCE9PXc/dzpcImRlZmF1bHRcIj09PXRoaXMuZ3JvdXBpbmdUeXBlPyc8ZGl2IGNsYXNzPVwiYmxvY2sgbWItMSB0ZXh0LXhzIGZvbnQtc2VtaWJvbGQgdXBwZXJjYXNlIHRleHQtcHJpbWFyeVwiPjwvZGl2Pic6JzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zb2Z0IGJ0bi1wcmltYXJ5XCI+PC9idXR0b24+Jyx0aGlzLnRhYnNXcmFwcGVyVGVtcGxhdGU9bnVsbCE9PSh5PW51bGw9PUI/dm9pZCAwOkIudGFic1dyYXBwZXJUZW1wbGF0ZSkmJnZvaWQgMCE9PXk/eTonPGRpdiBjbGFzcz1cIm92ZXJmbG93LXgtYXV0byBwLTRcIj48L2Rpdj4nLHRoaXMucHJldmVudFNlbGVjdGlvbj1udWxsIT09KGI9bnVsbD09Qj92b2lkIDA6Qi5wcmV2ZW50U2VsZWN0aW9uKSYmdm9pZCAwIT09YiYmYix0aGlzLnByZXZlbnRBdXRvUG9zaXRpb249bnVsbCE9PShDPW51bGw9PUI/dm9pZCAwOkIucHJldmVudEF1dG9Qb3NpdGlvbikmJnZvaWQgMCE9PUMmJkMsdGhpcy5pc09wZW5PbkZvY3VzPW51bGwhPT0oUz1udWxsPT1CP3ZvaWQgMDpCLmlzT3Blbk9uRm9jdXMpJiZ2b2lkIDAhPT1TJiZTLHRoaXMuaW5wdXQ9bnVsbCE9PShMPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC1pbnB1dF1cIikpJiZ2b2lkIDAhPT1MP0w6bnVsbCx0aGlzLm91dHB1dD1udWxsIT09KEk9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtY29tYm8tYm94LW91dHB1dF1cIikpJiZ2b2lkIDAhPT1JP0k6bnVsbCx0aGlzLml0ZW1zV3JhcHBlcj1udWxsIT09KEU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtY29tYm8tYm94LW91dHB1dC1pdGVtcy13cmFwcGVyXVwiKSkmJnZvaWQgMCE9PUU/RTpudWxsLHRoaXMuaXRlbXM9bnVsbCE9PShUPUFycmF5LmZyb20odGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtY29tYm8tYm94LW91dHB1dC1pdGVtXVwiKSkpJiZ2b2lkIDAhPT1UP1Q6W10sdGhpcy50YWJzPVtdLHRoaXMudG9nZ2xlPW51bGwhPT0oeD10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1jb21iby1ib3gtdG9nZ2xlXVwiKSkmJnZvaWQgMCE9PXg/eDpudWxsLHRoaXMudG9nZ2xlQ2xvc2U9bnVsbCE9PShrPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC1jbG9zZV1cIikpJiZ2b2lkIDAhPT1rP2s6bnVsbCx0aGlzLnRvZ2dsZU9wZW49bnVsbCE9PShBPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC1vcGVuXVwiKSkmJnZvaWQgMCE9PUE/QTpudWxsLHRoaXMub3V0cHV0UGxhY2Vob2xkZXI9bnVsbCx0aGlzLnNlbGVjdGVkPXRoaXMudmFsdWU9bnVsbCE9PShPPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC1pbnB1dF1cIikudmFsdWUpJiZ2b2lkIDAhPT1PP086XCJcIix0aGlzLmN1cnJlbnREYXRhPW51bGwsdGhpcy5pc09wZW5lZD0hMSx0aGlzLmlzQ3VycmVudD0hMSx0aGlzLmFuaW1hdGlvbkluUHJvY2Vzcz0hMSx0aGlzLnNlbGVjdGVkR3JvdXA9XCJhbGxcIix0aGlzLmluaXQoKX1pbnB1dEZvY3VzKCl7dGhpcy5pc09wZW5lZHx8KHRoaXMuc2V0UmVzdWx0QW5kUmVuZGVyKCksdGhpcy5vcGVuKCkpfWlucHV0SW5wdXQoZSl7Y29uc3QgdD1lLnRhcmdldC52YWx1ZS50cmltKCk7dC5sZW5ndGg8PXRoaXMubWluU2VhcmNoTGVuZ3RoP3RoaXMuc2V0UmVzdWx0QW5kUmVuZGVyKFwiXCIpOnRoaXMuc2V0UmVzdWx0QW5kUmVuZGVyKHQpLFwiXCIhPT10aGlzLmlucHV0LnZhbHVlP3RoaXMuZWwuY2xhc3NMaXN0LmFkZChcImhhcy12YWx1ZVwiKTp0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJoYXMtdmFsdWVcIiksdGhpcy5pc09wZW5lZHx8dGhpcy5vcGVuKCl9dG9nZ2xlQ2xpY2soKXt0aGlzLmlzT3BlbmVkP3RoaXMuY2xvc2UoKTp0aGlzLm9wZW4odGhpcy50b2dnbGUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtdG9nZ2xlXCIpKX10b2dnbGVDbG9zZUNsaWNrKCl7dGhpcy5jbG9zZSgpfXRvZ2dsZU9wZW5DbGljaygpe3RoaXMub3BlbigpfWluaXQoKXt0aGlzLmNyZWF0ZUNvbGxlY3Rpb24od2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbix0aGlzKSx0aGlzLmJ1aWxkKCl9YnVpbGQoKXt0aGlzLmJ1aWxkSW5wdXQoKSx0aGlzLmdyb3VwaW5nVHlwZSYmdGhpcy5zZXRHcm91cHMoKSx0aGlzLmJ1aWxkSXRlbXMoKSx0aGlzLnByZXZlbnRWaXNpYmlsaXR5JiYodGhpcy5wcmV2ZW50QXV0b1Bvc2l0aW9ufHx0aGlzLnJlY2FsY3VsYXRlRGlyZWN0aW9uKCkpLHRoaXMudG9nZ2xlJiZ0aGlzLmJ1aWxkVG9nZ2xlKCksdGhpcy50b2dnbGVDbG9zZSYmdGhpcy5idWlsZFRvZ2dsZUNsb3NlKCksdGhpcy50b2dnbGVPcGVuJiZ0aGlzLmJ1aWxkVG9nZ2xlT3BlbigpfWdldE5lc3RlZFByb3BlcnR5KGUsdCl7cmV0dXJuIHQuc3BsaXQoXCIuXCIpLnJlZHVjZSgoKGUsdCk9PmUmJmVbdF0pLGUpfXNldFZhbHVlKGUsdD1udWxsKXt0aGlzLnNlbGVjdGVkPWUsdGhpcy52YWx1ZT1lLHRoaXMuaW5wdXQudmFsdWU9ZSx0JiYodGhpcy5jdXJyZW50RGF0YT10KSx0aGlzLmZpcmVFdmVudChcInNlbGVjdFwiLHRoaXMuY3VycmVudERhdGEpLCgwLG8uZGlzcGF0Y2gpKFwic2VsZWN0LmNvbWJvYm94XCIsdGhpcy5lbCx0aGlzLmN1cnJlbnREYXRhKX1zZXRWYWx1ZUFuZE9wZW4oZSl7dGhpcy52YWx1ZT1lLHRoaXMuaXRlbXMubGVuZ3RoJiZ0aGlzLnNldEl0ZW1zVmlzaWJpbGl0eSgpfXNldFZhbHVlQW5kQ2xlYXIoZSx0PW51bGwpe2U/dGhpcy5zZXRWYWx1ZShlLHQpOnRoaXMuc2V0VmFsdWUodGhpcy5zZWxlY3RlZCx0KSx0aGlzLm91dHB1dFBsYWNlaG9sZGVyJiZ0aGlzLmRlc3Ryb3lPdXRwdXRQbGFjZWhvbGRlcigpfXNldFNlbGVjdGVkQnlWYWx1ZShlKXt0aGlzLml0ZW1zLmZvckVhY2goKHQ9Pnt0aGlzLmlzVGV4dEV4aXN0cyh0LGUpP3QuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpOnQuY2xhc3NMaXN0LnJlbW92ZShcInNlbGVjdGVkXCIpfSkpfXNldFJlc3VsdEFuZFJlbmRlcihlPVwiXCIpe2xldCB0PXRoaXMucHJldmVudFZpc2liaWxpdHk/dGhpcy5pbnB1dC52YWx1ZTplO3RoaXMuc2V0UmVzdWx0cyh0KSwodGhpcy5hcGlTZWFyY2hRdWVyeXx8dGhpcy5hcGlTZWFyY2hQYXRofHx0aGlzLmFwaVNlYXJjaERlZmF1bHRQYXRoKSYmdGhpcy5pdGVtc0Zyb21Kc29uKCksdGhpcy5pc1NlYXJjaExlbmd0aEV4Y2VlZGVkPVwiXCI9PT10fXNldFJlc3VsdHMoZSl7dGhpcy52YWx1ZT1lLHRoaXMucmVzdWx0SXRlbXMoKSx0aGlzLmhhc1Zpc2libGVJdGVtcygpP3RoaXMuZGVzdHJveU91dHB1dFBsYWNlaG9sZGVyKCk6dGhpcy5idWlsZE91dHB1dFBsYWNlaG9sZGVyKCl9c2V0R3JvdXBzKCl7Y29uc3QgZT1bXTt0aGlzLml0ZW1zLmZvckVhY2goKHQ9Pntjb25zdHtncm91cDppfT1KU09OLnBhcnNlKHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtb3V0cHV0LWl0ZW1cIikpO2Uuc29tZSgoZT0+KG51bGw9PWU/dm9pZCAwOmUubmFtZSk9PT1pLm5hbWUpKXx8ZS5wdXNoKGkpfSkpLHRoaXMuZ3JvdXBzPWV9c2V0QXBpR3JvdXBzKGUpe2NvbnN0IHQ9W107ZS5mb3JFYWNoKChlPT57Y29uc3QgaT1lW3RoaXMuYXBpR3JvdXBGaWVsZF07dC5zb21lKChlPT5lLm5hbWU9PT1pKSl8fHQucHVzaCh7bmFtZTppLHRpdGxlOml9KX0pKSx0aGlzLmdyb3Vwcz10fXNldEl0ZW1zVmlzaWJpbGl0eSgpe1widGFic1wiPT09dGhpcy5ncm91cGluZ1R5cGUmJlwiYWxsXCIhPT10aGlzLnNlbGVjdGVkR3JvdXAmJnRoaXMuaXRlbXMuZm9yRWFjaCgoZT0+e2Uuc3R5bGUuZGlzcGxheT1cIm5vbmVcIn0pKTtjb25zdCBlPVwidGFic1wiPT09dGhpcy5ncm91cGluZ1R5cGU/XCJhbGxcIj09PXRoaXMuc2VsZWN0ZWRHcm91cD90aGlzLml0ZW1zOnRoaXMuaXRlbXMuZmlsdGVyKChlPT57Y29uc3R7Z3JvdXA6dH09SlNPTi5wYXJzZShlLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LW91dHB1dC1pdGVtXCIpKTtyZXR1cm4gdC5uYW1lPT09dGhpcy5zZWxlY3RlZEdyb3VwfSkpOnRoaXMuaXRlbXM7XCJ0YWJzXCI9PT10aGlzLmdyb3VwaW5nVHlwZSYmXCJhbGxcIiE9PXRoaXMuc2VsZWN0ZWRHcm91cCYmZS5mb3JFYWNoKChlPT57ZS5zdHlsZS5kaXNwbGF5PVwiYmxvY2tcIn0pKSxlLmZvckVhY2goKGU9Pnt0aGlzLmlzVGV4dEV4aXN0c0FueShlLHRoaXMudmFsdWUpP2Uuc3R5bGUuZGlzcGxheT1cImJsb2NrXCI6ZS5zdHlsZS5kaXNwbGF5PVwibm9uZVwifSkpLFwiZGVmYXVsdFwiPT09dGhpcy5ncm91cGluZ1R5cGUmJnRoaXMub3V0cHV0LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1jb21iby1ib3gtZ3JvdXAtdGl0bGVdXCIpLmZvckVhY2goKGU9Pntjb25zdCB0PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtZ3JvdXAtdGl0bGVcIik7dGhpcy5pdGVtcy5maWx0ZXIoKGU9Pntjb25zdHtncm91cDppfT1KU09OLnBhcnNlKGUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtb3V0cHV0LWl0ZW1cIikpO3JldHVybiBpLm5hbWU9PT10JiZcImJsb2NrXCI9PT1lLnN0eWxlLmRpc3BsYXl9KSkubGVuZ3RoP2Uuc3R5bGUuZGlzcGxheT1cImJsb2NrXCI6ZS5zdHlsZS5kaXNwbGF5PVwibm9uZVwifSkpfWlzVGV4dEV4aXN0cyhlLHQpe2NvbnN0IGk9dC5tYXAoKGU9PmUudG9Mb3dlckNhc2UoKSkpO3JldHVybiBBcnJheS5mcm9tKGUucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWNvbWJvLWJveC1zZWFyY2gtdGV4dF1cIikpLnNvbWUoKGU9PmkuaW5jbHVkZXMoZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbWJvLWJveC1zZWFyY2gtdGV4dFwiKS50b0xvd2VyQ2FzZSgpKSkpfWlzVGV4dEV4aXN0c0FueShlLHQpe3JldHVybiBBcnJheS5mcm9tKGUucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWNvbWJvLWJveC1zZWFyY2gtdGV4dF1cIikpLnNvbWUoKGU9PmUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtc2VhcmNoLXRleHRcIikudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0LnRvTG93ZXJDYXNlKCkpKSl9aGFzVmlzaWJsZUl0ZW1zKCl7cmV0dXJuISF0aGlzLml0ZW1zLmxlbmd0aCYmdGhpcy5pdGVtcy5zb21lKChlPT5cImJsb2NrXCI9PT1lLnN0eWxlLmRpc3BsYXkpKX12YWx1ZXNCeVNlbGVjdG9yKGUpe3JldHVybiBBcnJheS5mcm9tKGUucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWNvbWJvLWJveC1zZWFyY2gtdGV4dF1cIikpLnJlZHVjZSgoKGUsdCk9PlsuLi5lLHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtc2VhcmNoLXRleHRcIildKSxbXSl9c29ydEl0ZW1zKCl7cmV0dXJuIHRoaXMuaXRlbXMuc29ydCgoKGUsdCk9Pntjb25zdCBpPWUucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC12YWx1ZV1cIikuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtc2VhcmNoLXRleHRcIikscz10LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1jb21iby1ib3gtdmFsdWVdXCIpLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LXNlYXJjaC10ZXh0XCIpO3JldHVybiBpPHM/LTE6aT5zPzE6MH0pKX1idWlsZElucHV0KCl7dGhpcy5pc09wZW5PbkZvY3VzJiYodGhpcy5vbklucHV0Rm9jdXNMaXN0ZW5lcj0oKT0+dGhpcy5pbnB1dEZvY3VzKCksdGhpcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIix0aGlzLm9uSW5wdXRGb2N1c0xpc3RlbmVyKSksdGhpcy5vbklucHV0SW5wdXRMaXN0ZW5lcj0oMCxvLmRlYm91bmNlKSgoZT0+dGhpcy5pbnB1dElucHV0KGUpKSksdGhpcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uSW5wdXRJbnB1dExpc3RlbmVyKX1idWlsZEl0ZW1zKCl7cmV0dXJuIHModGhpcyx2b2lkIDAsdm9pZCAwLChmdW5jdGlvbiooKXt0aGlzLm91dHB1dC5yb2xlPVwibGlzdGJveFwiLHRoaXMub3V0cHV0LnRhYkluZGV4PS0xLHRoaXMub3V0cHV0LmFyaWFPcmllbnRhdGlvbj1cInZlcnRpY2FsXCIsdGhpcy5hcGlVcmw/eWllbGQgdGhpcy5pdGVtc0Zyb21Kc29uKCk6KHRoaXMuaXRlbXNXcmFwcGVyP3RoaXMuaXRlbXNXcmFwcGVyLmlubmVySFRNTD1cIlwiOnRoaXMub3V0cHV0LmlubmVySFRNTD1cIlwiLHRoaXMuaXRlbXNGcm9tSHRtbCgpKSwobnVsbD09dGhpcz92b2lkIDA6dGhpcy5pdGVtcy5sZW5ndGgpJiZ0aGlzLml0ZW1zWzBdLmNsYXNzTGlzdC5jb250YWlucyhcInNlbGVjdGVkXCIpJiYodGhpcy5jdXJyZW50RGF0YT1KU09OLnBhcnNlKHRoaXMuaXRlbXNbMF0uZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtaXRlbS1zdG9yZWQtZGF0YVwiKSkpfSkpfWJ1aWxkT3V0cHV0TG9hZGVyKCl7aWYodGhpcy5vdXRwdXRMb2FkZXIpcmV0dXJuITE7dGhpcy5vdXRwdXRMb2FkZXI9KDAsby5odG1sVG9FbGVtZW50KSh0aGlzLm91dHB1dExvYWRlclRlbXBsYXRlKSx0aGlzLml0ZW1zLmxlbmd0aHx8dGhpcy5vdXRwdXRQbGFjZWhvbGRlcj8odGhpcy5vdXRwdXRMb2FkZXIuc3R5bGUucG9zaXRpb249XCJhYnNvbHV0ZVwiLHRoaXMub3V0cHV0TG9hZGVyLnN0eWxlLnRvcD1cIjBcIix0aGlzLm91dHB1dExvYWRlci5zdHlsZS5ib3R0b209XCIwXCIsdGhpcy5vdXRwdXRMb2FkZXIuc3R5bGUubGVmdD1cIjBcIix0aGlzLm91dHB1dExvYWRlci5zdHlsZS5yaWdodD1cIjBcIix0aGlzLm91dHB1dExvYWRlci5zdHlsZS56SW5kZXg9XCIyXCIpOih0aGlzLm91dHB1dExvYWRlci5zdHlsZS5wb3NpdGlvbj1cIlwiLHRoaXMub3V0cHV0TG9hZGVyLnN0eWxlLnRvcD1cIlwiLHRoaXMub3V0cHV0TG9hZGVyLnN0eWxlLmJvdHRvbT1cIlwiLHRoaXMub3V0cHV0TG9hZGVyLnN0eWxlLmxlZnQ9XCJcIix0aGlzLm91dHB1dExvYWRlci5zdHlsZS5yaWdodD1cIlwiLHRoaXMub3V0cHV0TG9hZGVyLnN0eWxlLnpJbmRleD1cIlwiLHRoaXMub3V0cHV0TG9hZGVyLnN0eWxlLmhlaWdodD1cIjMwcHhcIiksdGhpcy5vdXRwdXQuYXBwZW5kKHRoaXMub3V0cHV0TG9hZGVyKX1idWlsZFRvZ2dsZSgpe3ZhciBlLHQsaSxzO3RoaXMuaXNPcGVuZWQ/KChudWxsPT09KGU9bnVsbD09dGhpcz92b2lkIDA6dGhpcy50b2dnbGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmFyaWFFeHBhbmRlZCkmJih0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJ0cnVlXCIpLChudWxsPT09KHQ9bnVsbD09dGhpcz92b2lkIDA6dGhpcy5pbnB1dCl8fHZvaWQgMD09PXQ/dm9pZCAwOnQuYXJpYUV4cGFuZGVkKSYmKHRoaXMuaW5wdXQuYXJpYUV4cGFuZGVkPVwidHJ1ZVwiKSk6KChudWxsPT09KGk9bnVsbD09dGhpcz92b2lkIDA6dGhpcy50b2dnbGUpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmFyaWFFeHBhbmRlZCkmJih0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJmYWxzZVwiKSwobnVsbD09PShzPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMuaW5wdXQpfHx2b2lkIDA9PT1zP3ZvaWQgMDpzLmFyaWFFeHBhbmRlZCkmJih0aGlzLmlucHV0LmFyaWFFeHBhbmRlZD1cImZhbHNlXCIpKSx0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy50b2dnbGVDbGljaygpLHRoaXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyKX1idWlsZFRvZ2dsZUNsb3NlKCl7dGhpcy5vblRvZ2dsZUNsb3NlQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy50b2dnbGVDbG9zZUNsaWNrKCksdGhpcy50b2dnbGVDbG9zZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlQ2xvc2VDbGlja0xpc3RlbmVyKX1idWlsZFRvZ2dsZU9wZW4oKXt0aGlzLm9uVG9nZ2xlT3BlbkNsaWNrTGlzdGVuZXI9KCk9PnRoaXMudG9nZ2xlT3BlbkNsaWNrKCksdGhpcy50b2dnbGVPcGVuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVPcGVuQ2xpY2tMaXN0ZW5lcil9YnVpbGRPdXRwdXRQbGFjZWhvbGRlcigpe3RoaXMub3V0cHV0UGxhY2Vob2xkZXJ8fCh0aGlzLm91dHB1dFBsYWNlaG9sZGVyPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy5vdXRwdXRFbXB0eVRlbXBsYXRlKSksdGhpcy5hcHBlbmRJdGVtc1RvV3JhcHBlcih0aGlzLm91dHB1dFBsYWNlaG9sZGVyKX1kZXN0cm95T3V0cHV0TG9hZGVyKCl7dGhpcy5vdXRwdXRMb2FkZXImJnRoaXMub3V0cHV0TG9hZGVyLnJlbW92ZSgpLHRoaXMub3V0cHV0TG9hZGVyPW51bGx9aXRlbVJlbmRlcihlKXt2YXIgdDtjb25zdCBpPWUucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC12YWx1ZV1cIikuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtc2VhcmNoLXRleHRcIikscz1udWxsIT09KHQ9SlNPTi5wYXJzZShlLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LWl0ZW0tc3RvcmVkLWRhdGFcIikpKSYmdm9pZCAwIT09dD90Om51bGw7dGhpcy5pdGVtc1dyYXBwZXI/dGhpcy5pdGVtc1dyYXBwZXIuYXBwZW5kKGUpOnRoaXMub3V0cHV0LmFwcGVuZChlKSx0aGlzLnByZXZlbnRTZWxlY3Rpb258fGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsKCgpPT57dGhpcy5jbG9zZShpLHMpLHRoaXMuc2V0U2VsZWN0ZWRCeVZhbHVlKHRoaXMudmFsdWVzQnlTZWxlY3RvcihlKSl9KSl9cGxhaW5SZW5kZXIoZSl7ZS5mb3JFYWNoKChlPT57dGhpcy5pdGVtUmVuZGVyKGUpfSkpfWpzb25JdGVtc1JlbmRlcihlKXtlLmZvckVhY2goKChlLHQpPT57Y29uc3QgaT0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMub3V0cHV0SXRlbVRlbXBsYXRlKTtpLnNldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LWl0ZW0tc3RvcmVkLWRhdGFcIixKU09OLnN0cmluZ2lmeShlKSksaS5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtY29tYm8tYm94LW91dHB1dC1pdGVtLWZpZWxkXVwiKS5mb3JFYWNoKCh0PT57Y29uc3QgaT10aGlzLmdldE5lc3RlZFByb3BlcnR5KGUsdC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbWJvLWJveC1vdXRwdXQtaXRlbS1maWVsZFwiKSkscz10Lmhhc0F0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LW91dHB1dC1pdGVtLWhpZGUtaWYtZW1wdHlcIik7dC50ZXh0Q29udGVudD1udWxsIT1pP2k6XCJcIiwhaSYmcyYmKHQuc3R5bGUuZGlzcGxheT1cIm5vbmVcIil9KSksaS5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtY29tYm8tYm94LXNlYXJjaC10ZXh0XVwiKS5mb3JFYWNoKCh0PT57Y29uc3QgaT10aGlzLmdldE5lc3RlZFByb3BlcnR5KGUsdC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbWJvLWJveC1vdXRwdXQtaXRlbS1maWVsZFwiKSk7dC5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbWJvLWJveC1zZWFyY2gtdGV4dFwiLG51bGwhPWk/aTpcIlwiKX0pKSxpLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1jb21iby1ib3gtb3V0cHV0LWl0ZW0tYXR0cl1cIikuZm9yRWFjaCgodD0+e0pTT04ucGFyc2UodC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbWJvLWJveC1vdXRwdXQtaXRlbS1hdHRyXCIpKS5mb3JFYWNoKChpPT57dC5zZXRBdHRyaWJ1dGUoaS5hdHRyLGVbaS52YWx1ZUZyb21dKX0pKX0pKSxpLnNldEF0dHJpYnV0ZShcInRhYkluZGV4XCIsYCR7dH1gKSxcInRhYnNcIiE9PXRoaXMuZ3JvdXBpbmdUeXBlJiZcImRlZmF1bHRcIiE9PXRoaXMuZ3JvdXBpbmdUeXBlfHxpLnNldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LW91dHB1dC1pdGVtXCIsYHtcImdyb3VwXCI6IHtcIm5hbWVcIjogXCIke2VbdGhpcy5hcGlHcm91cEZpZWxkXX1cIiwgXCJ0aXRsZVwiOiBcIiR7ZVt0aGlzLmFwaUdyb3VwRmllbGRdfVwifX1gKSx0aGlzLml0ZW1zPVsuLi50aGlzLml0ZW1zLGldLHRoaXMucHJldmVudFNlbGVjdGlvbnx8aS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwoKCk9Pnt0aGlzLmNsb3NlKGkucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC12YWx1ZV1cIikuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtc2VhcmNoLXRleHRcIiksSlNPTi5wYXJzZShpLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LWl0ZW0tc3RvcmVkLWRhdGFcIikpKSx0aGlzLnNldFNlbGVjdGVkQnlWYWx1ZSh0aGlzLnZhbHVlc0J5U2VsZWN0b3IoaSkpfSkpLHRoaXMuYXBwZW5kSXRlbXNUb1dyYXBwZXIoaSl9KSl9Z3JvdXBEZWZhdWx0UmVuZGVyKCl7dGhpcy5ncm91cHMuZm9yRWFjaCgoZT0+e2NvbnN0IHQ9KDAsby5odG1sVG9FbGVtZW50KSh0aGlzLmdyb3VwaW5nVGl0bGVUZW1wbGF0ZSk7dC5zZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbWJvLWJveC1ncm91cC10aXRsZVwiLGUubmFtZSksdC5jbGFzc0xpc3QuYWRkKFwiLS1leGNsdWRlLWFjY2Vzc2liaWxpdHlcIiksdC5pbm5lclRleHQ9ZS50aXRsZSx0aGlzLml0ZW1zV3JhcHBlcj90aGlzLml0ZW1zV3JhcHBlci5hcHBlbmQodCk6dGhpcy5vdXRwdXQuYXBwZW5kKHQpO2NvbnN0IGk9dGhpcy5zb3J0SXRlbXMoKS5maWx0ZXIoKHQ9Pntjb25zdHtncm91cDppfT1KU09OLnBhcnNlKHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtb3V0cHV0LWl0ZW1cIikpO3JldHVybiBpLm5hbWU9PT1lLm5hbWV9KSk7dGhpcy5wbGFpblJlbmRlcihpKX0pKX1ncm91cFRhYnNSZW5kZXIoKXtjb25zdCBlPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy50YWJzV3JhcHBlclRlbXBsYXRlKSx0PSgwLG8uaHRtbFRvRWxlbWVudCkoJzxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtbm93cmFwIGdhcC14LTJcIj48L2Rpdj4nKTtlLmFwcGVuZCh0KSx0aGlzLm91dHB1dC5pbnNlcnRCZWZvcmUoZSx0aGlzLm91dHB1dC5maXJzdENoaWxkKTtjb25zdCBpPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy5ncm91cGluZ1RpdGxlVGVtcGxhdGUpO2kuc2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtZ3JvdXAtdGl0bGVcIixcImFsbFwiKSxpLmNsYXNzTGlzdC5hZGQoXCItLWV4Y2x1ZGUtYWNjZXNzaWJpbGl0eVwiLFwiYWN0aXZlXCIpLGkuaW5uZXJUZXh0PVwiQWxsXCIsdGhpcy50YWJzPVsuLi50aGlzLnRhYnMsaV0sdC5hcHBlbmQoaSksaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwoKCk9Pnt0aGlzLnNlbGVjdGVkR3JvdXA9XCJhbGxcIjtjb25zdCBlPXRoaXMudGFicy5maW5kKChlPT5lLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LWdyb3VwLXRpdGxlXCIpPT09dGhpcy5zZWxlY3RlZEdyb3VwKSk7dGhpcy50YWJzLmZvckVhY2goKGU9PmUuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKSkpLGUuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKSx0aGlzLnNldEl0ZW1zVmlzaWJpbGl0eSgpfSkpLHRoaXMuZ3JvdXBzLmZvckVhY2goKGU9Pntjb25zdCBpPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy5ncm91cGluZ1RpdGxlVGVtcGxhdGUpO2kuc2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtZ3JvdXAtdGl0bGVcIixlLm5hbWUpLGkuY2xhc3NMaXN0LmFkZChcIi0tZXhjbHVkZS1hY2Nlc3NpYmlsaXR5XCIpLGkuaW5uZXJUZXh0PWUudGl0bGUsdGhpcy50YWJzPVsuLi50aGlzLnRhYnMsaV0sdC5hcHBlbmQoaSksaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwoKCk9Pnt0aGlzLnNlbGVjdGVkR3JvdXA9ZS5uYW1lO2NvbnN0IHQ9dGhpcy50YWJzLmZpbmQoKGU9PmUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtZ3JvdXAtdGl0bGVcIik9PT10aGlzLnNlbGVjdGVkR3JvdXApKTt0aGlzLnRhYnMuZm9yRWFjaCgoZT0+ZS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpKSksdC5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLHRoaXMuc2V0SXRlbXNWaXNpYmlsaXR5KCl9KSl9KSl9aXRlbXNGcm9tSHRtbCgpe2lmKFwiZGVmYXVsdFwiPT09dGhpcy5ncm91cGluZ1R5cGUpdGhpcy5ncm91cERlZmF1bHRSZW5kZXIoKTtlbHNlIGlmKFwidGFic1wiPT09dGhpcy5ncm91cGluZ1R5cGUpe2NvbnN0IGU9dGhpcy5zb3J0SXRlbXMoKTt0aGlzLmdyb3VwVGFic1JlbmRlcigpLHRoaXMucGxhaW5SZW5kZXIoZSl9ZWxzZXtjb25zdCBlPXRoaXMuc29ydEl0ZW1zKCk7dGhpcy5wbGFpblJlbmRlcihlKX10aGlzLnNldFJlc3VsdHModGhpcy5pbnB1dC52YWx1ZSl9aXRlbXNGcm9tSnNvbigpe3JldHVybiBzKHRoaXMsdm9pZCAwLHZvaWQgMCwoZnVuY3Rpb24qKCl7aWYodGhpcy5pc1NlYXJjaExlbmd0aEV4Y2VlZGVkKXJldHVybiExO3RoaXMuYnVpbGRPdXRwdXRMb2FkZXIoKTt0cnl7Y29uc3QgZT1gJHt0aGlzLmFwaVF1ZXJ5fWA7bGV0IHQsaSxzPXRoaXMuYXBpVXJsOyF0aGlzLmFwaVNlYXJjaFF1ZXJ5JiZ0aGlzLmFwaVNlYXJjaFBhdGg/KGk9dGhpcy5hcGlTZWFyY2hEZWZhdWx0UGF0aCYmXCJcIj09PXRoaXMudmFsdWU/YC8ke3RoaXMuYXBpU2VhcmNoRGVmYXVsdFBhdGh9YDpgLyR7dGhpcy5hcGlTZWFyY2hQYXRofS8ke3RoaXMudmFsdWUudG9Mb3dlckNhc2UoKX1gLCh0aGlzLmFwaVNlYXJjaFBhdGh8fHRoaXMuYXBpU2VhcmNoRGVmYXVsdFBhdGgpJiYocys9aSkpOih0PWAke3RoaXMuYXBpU2VhcmNoUXVlcnl9PSR7dGhpcy52YWx1ZS50b0xvd2VyQ2FzZSgpfWAsdGhpcy5hcGlRdWVyeSYmdGhpcy5hcGlTZWFyY2hRdWVyeT9zKz1gPyR7dH0mJHtlfWA6dGhpcy5hcGlRdWVyeT9zKz1gPyR7ZX1gOnRoaXMuYXBpU2VhcmNoUXVlcnkmJihzKz1gPyR7dH1gKSk7Y29uc3Qgbj15aWVsZCBmZXRjaChzLHRoaXMuYXBpSGVhZGVycyk7bGV0IGw9eWllbGQgbi5qc29uKCk7dGhpcy5hcGlEYXRhUGFydCYmKGw9bFt0aGlzLmFwaURhdGFQYXJ0XSksKHRoaXMuYXBpU2VhcmNoUXVlcnl8fHRoaXMuYXBpU2VhcmNoUGF0aCkmJih0aGlzLml0ZW1zPVtdKSx0aGlzLml0ZW1zV3JhcHBlcj90aGlzLml0ZW1zV3JhcHBlci5pbm5lckhUTUw9XCJcIjp0aGlzLm91dHB1dC5pbm5lckhUTUw9XCJcIixcInRhYnNcIj09PXRoaXMuZ3JvdXBpbmdUeXBlPyh0aGlzLnNldEFwaUdyb3VwcyhsKSx0aGlzLmdyb3VwVGFic1JlbmRlcigpLHRoaXMuanNvbkl0ZW1zUmVuZGVyKGwpKTpcImRlZmF1bHRcIj09PXRoaXMuZ3JvdXBpbmdUeXBlPyh0aGlzLnNldEFwaUdyb3VwcyhsKSx0aGlzLmdyb3Vwcy5mb3JFYWNoKChlPT57Y29uc3QgdD0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMuZ3JvdXBpbmdUaXRsZVRlbXBsYXRlKTt0LnNldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LWdyb3VwLXRpdGxlXCIsZS5uYW1lKSx0LmNsYXNzTGlzdC5hZGQoXCItLWV4Y2x1ZGUtYWNjZXNzaWJpbGl0eVwiKSx0LmlubmVyVGV4dD1lLnRpdGxlO2NvbnN0IGk9bC5maWx0ZXIoKHQ9PnRbdGhpcy5hcGlHcm91cEZpZWxkXT09PWUubmFtZSkpO3RoaXMuaXRlbXNXcmFwcGVyP3RoaXMuaXRlbXNXcmFwcGVyLmFwcGVuZCh0KTp0aGlzLm91dHB1dC5hcHBlbmQodCksdGhpcy5qc29uSXRlbXNSZW5kZXIoaSl9KSkpOnRoaXMuanNvbkl0ZW1zUmVuZGVyKGwpLHRoaXMuc2V0UmVzdWx0cyh0aGlzLmlucHV0LnZhbHVlLmxlbmd0aDw9dGhpcy5taW5TZWFyY2hMZW5ndGg/XCJcIjp0aGlzLmlucHV0LnZhbHVlKX1jYXRjaChlKXtjb25zb2xlLmVycm9yKGUpLHRoaXMuYnVpbGRPdXRwdXRQbGFjZWhvbGRlcigpfXRoaXMuZGVzdHJveU91dHB1dExvYWRlcigpfSkpfWFwcGVuZEl0ZW1zVG9XcmFwcGVyKGUpe3RoaXMuaXRlbXNXcmFwcGVyP3RoaXMuaXRlbXNXcmFwcGVyLmFwcGVuZChlKTp0aGlzLm91dHB1dC5hcHBlbmQoZSl9cmVzdWx0SXRlbXMoKXtpZighdGhpcy5pdGVtcy5sZW5ndGgpcmV0dXJuITE7dGhpcy5zZXRJdGVtc1Zpc2liaWxpdHkoKSx0aGlzLnNldFNlbGVjdGVkQnlWYWx1ZShbdGhpcy5zZWxlY3RlZF0pfWRlc3Ryb3lPdXRwdXRQbGFjZWhvbGRlcigpe3RoaXMub3V0cHV0UGxhY2Vob2xkZXImJnRoaXMub3V0cHV0UGxhY2Vob2xkZXIucmVtb3ZlKCksdGhpcy5vdXRwdXRQbGFjZWhvbGRlcj1udWxsfWdldEN1cnJlbnREYXRhKCl7cmV0dXJuIHRoaXMuY3VycmVudERhdGF9c2V0Q3VycmVudCgpe3dpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24ubGVuZ3RoJiYod2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbi5tYXAoKGU9PmUuZWxlbWVudC5pc0N1cnJlbnQ9ITEpKSx0aGlzLmlzQ3VycmVudD0hMCl9b3BlbihlKXtyZXR1cm4hdGhpcy5hbmltYXRpb25JblByb2Nlc3MmJih2b2lkIDAhPT1lJiZ0aGlzLnNldFZhbHVlQW5kT3BlbihlKSwhdGhpcy5wcmV2ZW50VmlzaWJpbGl0eSYmKHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSEwLHRoaXMub3V0cHV0LnN0eWxlLmRpc3BsYXk9XCJibG9ja1wiLHRoaXMucHJldmVudEF1dG9Qb3NpdGlvbnx8dGhpcy5yZWNhbGN1bGF0ZURpcmVjdGlvbigpLHNldFRpbWVvdXQoKCgpPT57dmFyIGUsdDsobnVsbD09PShlPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMuaW5wdXQpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmFyaWFFeHBhbmRlZCkmJih0aGlzLmlucHV0LmFyaWFFeHBhbmRlZD1cInRydWVcIiksKG51bGw9PT0odD1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLnRvZ2dsZSl8fHZvaWQgMD09PXQ/dm9pZCAwOnQuYXJpYUV4cGFuZGVkKSYmKHRoaXMudG9nZ2xlLmFyaWFFeHBhbmRlZD1cInRydWVcIiksdGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExfSkpLHZvaWQodGhpcy5pc09wZW5lZD0hMCkpKX1jbG9zZShlLHQ9bnVsbCl7dmFyIGkscztyZXR1cm4hdGhpcy5hbmltYXRpb25JblByb2Nlc3MmJih0aGlzLnByZXZlbnRWaXNpYmlsaXR5Pyh0aGlzLnNldFZhbHVlQW5kQ2xlYXIoZSx0KSxcIlwiIT09dGhpcy5pbnB1dC52YWx1ZT90aGlzLmVsLmNsYXNzTGlzdC5hZGQoXCJoYXMtdmFsdWVcIik6dGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiaGFzLXZhbHVlXCIpLCExKToodGhpcy5hbmltYXRpb25JblByb2Nlc3M9ITAsKG51bGw9PT0oaT1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLmlucHV0KXx8dm9pZCAwPT09aT92b2lkIDA6aS5hcmlhRXhwYW5kZWQpJiYodGhpcy5pbnB1dC5hcmlhRXhwYW5kZWQ9XCJmYWxzZVwiKSwobnVsbD09PShzPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMudG9nZ2xlKXx8dm9pZCAwPT09cz92b2lkIDA6cy5hcmlhRXhwYW5kZWQpJiYodGhpcy50b2dnbGUuYXJpYUV4cGFuZGVkPVwiZmFsc2VcIiksdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpLHRoaXMucHJldmVudEF1dG9Qb3NpdGlvbnx8KHRoaXMub3V0cHV0LmNsYXNzTGlzdC5yZW1vdmUoXCJib3R0b20tZnVsbFwiLFwidG9wLWZ1bGxcIiksdGhpcy5vdXRwdXQuc3R5bGUubWFyZ2luVG9wPVwiXCIsdGhpcy5vdXRwdXQuc3R5bGUubWFyZ2luQm90dG9tPVwiXCIpLCgwLG8uYWZ0ZXJUcmFuc2l0aW9uKSh0aGlzLm91dHB1dCwoKCk9Pnt0aGlzLm91dHB1dC5zdHlsZS5kaXNwbGF5PVwibm9uZVwiLHRoaXMuc2V0VmFsdWVBbmRDbGVhcihlLHR8fG51bGwpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExfSkpLFwiXCIhPT10aGlzLmlucHV0LnZhbHVlP3RoaXMuZWwuY2xhc3NMaXN0LmFkZChcImhhcy12YWx1ZVwiKTp0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJoYXMtdmFsdWVcIiksdm9pZCh0aGlzLmlzT3BlbmVkPSExKSkpfXJlY2FsY3VsYXRlRGlyZWN0aW9uKCl7KDAsby5pc0Vub3VnaFNwYWNlKSh0aGlzLm91dHB1dCx0aGlzLmlucHV0LFwiYm90dG9tXCIsdGhpcy5nYXAsdGhpcy52aWV3cG9ydCk/KHRoaXMub3V0cHV0LmNsYXNzTGlzdC5yZW1vdmUoXCJib3R0b20tZnVsbFwiKSx0aGlzLm91dHB1dC5zdHlsZS5tYXJnaW5Cb3R0b209XCJcIix0aGlzLm91dHB1dC5jbGFzc0xpc3QuYWRkKFwidG9wLWZ1bGxcIiksdGhpcy5vdXRwdXQuc3R5bGUubWFyZ2luVG9wPWAke3RoaXMuZ2FwfXB4YCk6KHRoaXMub3V0cHV0LmNsYXNzTGlzdC5yZW1vdmUoXCJ0b3AtZnVsbFwiKSx0aGlzLm91dHB1dC5zdHlsZS5tYXJnaW5Ub3A9XCJcIix0aGlzLm91dHB1dC5jbGFzc0xpc3QuYWRkKFwiYm90dG9tLWZ1bGxcIiksdGhpcy5vdXRwdXQuc3R5bGUubWFyZ2luQm90dG9tPWAke3RoaXMuZ2FwfXB4YCl9ZGVzdHJveSgpe3RoaXMuaW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsdGhpcy5vbklucHV0Rm9jdXNMaXN0ZW5lciksdGhpcy5pbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uSW5wdXRJbnB1dExpc3RlbmVyKSx0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lciksdGhpcy50b2dnbGVDbG9zZSYmdGhpcy50b2dnbGVDbG9zZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlQ2xvc2VDbGlja0xpc3RlbmVyKSx0aGlzLnRvZ2dsZU9wZW4mJnRoaXMudG9nZ2xlT3Blbi5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlT3BlbkNsaWNrTGlzdGVuZXIpLHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcImhhcy12YWx1ZVwiLFwiYWN0aXZlXCIpLHRoaXMuaXRlbXMubGVuZ3RoJiZ0aGlzLml0ZW1zLmZvckVhY2goKGU9PntlLmNsYXNzTGlzdC5yZW1vdmUoXCJzZWxlY3RlZFwiKSxlLnN0eWxlLmRpc3BsYXk9XCJcIn0pKSx0aGlzLm91dHB1dC5yZW1vdmVBdHRyaWJ1dGUoXCJyb2xlXCIpLHRoaXMub3V0cHV0LnJlbW92ZUF0dHJpYnV0ZShcInRhYmluZGV4XCIpLHRoaXMub3V0cHV0LnJlbW92ZUF0dHJpYnV0ZShcImFyaWEtb3JpZW50YXRpb25cIiksdGhpcy5vdXRwdXRMb2FkZXImJih0aGlzLm91dHB1dExvYWRlci5yZW1vdmUoKSx0aGlzLm91dHB1dExvYWRlcj1udWxsKSx0aGlzLm91dHB1dFBsYWNlaG9sZGVyJiYodGhpcy5vdXRwdXRQbGFjZWhvbGRlci5yZW1vdmUoKSx0aGlzLm91dHB1dFBsYWNlaG9sZGVyPW51bGwpLHRoaXMuYXBpVXJsJiYodGhpcy5vdXRwdXQuaW5uZXJIVE1MPVwiXCIpLHRoaXMuaXRlbXM9W10sd2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbj13aW5kb3cuJGhzQ29tYm9Cb3hDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZS5lbCE9PXRoaXMuZWwpKX1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0KXtjb25zdCBpPXdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50Om51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbnx8KHdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb249W10sd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLChlPT57Y29uc3QgdD1lLnRhcmdldDthLmNsb3NlQ3VycmVudGx5T3BlbmVkKHQpfSkpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsKGU9PmEuYWNjZXNzaWJpbGl0eShlKSkpKSx3aW5kb3cuJGhzQ29tYm9Cb3hDb2xsZWN0aW9uJiYod2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbj13aW5kb3cuJGhzQ29tYm9Cb3hDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWNvbWJvLWJveF06bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57aWYoIXdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpKXtjb25zdCB0PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3hcIiksaT10P0pTT04ucGFyc2UodCk6e307bmV3IGEoZSxpKX19KSl9c3RhdGljIGNsb3NlKGUpe2NvbnN0IHQ9d2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbi5maW5kKCh0PT50LmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKSkpO3QmJnQuZWxlbWVudC5pc09wZW5lZCYmdC5lbGVtZW50LmNsb3NlKCl9c3RhdGljIGNsb3NlQ3VycmVudGx5T3BlbmVkKGU9bnVsbCl7aWYoIWUuY2xvc2VzdChcIltkYXRhLWNvbWJvLWJveF0uYWN0aXZlXCIpKXtjb25zdCBlPXdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24uZmlsdGVyKChlPT5lLmVsZW1lbnQuaXNPcGVuZWQpKXx8bnVsbDtlJiZlLmZvckVhY2goKGU9PntlLmVsZW1lbnQuY2xvc2UoKX0pKX19c3RhdGljIGdldFByZXBhcmVkSXRlbXMoZT0hMSx0KXtpZighdClyZXR1cm4gbnVsbDtyZXR1cm4oZT9BcnJheS5mcm9tKHQucXVlcnlTZWxlY3RvckFsbChcIjpzY29wZSA+ICo6bm90KC4tLWV4Y2x1ZGUtYWNjZXNzaWJpbGl0eSlcIikpLmZpbHRlcigoZT0+XCJub25lXCIhPT1lLnN0eWxlLmRpc3BsYXkpKS5yZXZlcnNlKCk6QXJyYXkuZnJvbSh0LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6c2NvcGUgPiAqOm5vdCguLS1leGNsdWRlLWFjY2Vzc2liaWxpdHkpXCIpKS5maWx0ZXIoKGU9Plwibm9uZVwiIT09ZS5zdHlsZS5kaXNwbGF5KSkpLmZpbHRlcigoZT0+IWUuY2xhc3NMaXN0LmNvbnRhaW5zKFwiZGlzYWJsZWRcIikpKX1zdGF0aWMgc2V0SGlnaGxpZ2h0ZWQoZSx0LGkpe3QuZm9jdXMoKSxpLnZhbHVlPXQucXVlcnlTZWxlY3RvcihcIltkYXRhLWNvbWJvLWJveC12YWx1ZV1cIikuZ2V0QXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtc2VhcmNoLXRleHRcIiksZSYmZS5jbGFzc0xpc3QucmVtb3ZlKFwiY29tYm8tYm94LW91dHB1dC1pdGVtLWhpZ2hsaWdodGVkXCIpLHQuY2xhc3NMaXN0LmFkZChcImNvbWJvLWJveC1vdXRwdXQtaXRlbS1oaWdobGlnaHRlZFwiKX1zdGF0aWMgYWNjZXNzaWJpbGl0eShlKXtpZih3aW5kb3cuJGhzQ29tYm9Cb3hDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5wcmV2ZW50VmlzaWJpbGl0eT9lLmVsZW1lbnQuaXNDdXJyZW50OmUuZWxlbWVudC5pc09wZW5lZCkpJiZyLkNPTUJPX0JPWF9BQ0NFU1NJQklMSVRZX0tFWV9TRVQuaW5jbHVkZXMoZS5jb2RlKSYmIWUubWV0YUtleSlzd2l0Y2goZS5jb2RlKXtjYXNlXCJFc2NhcGVcIjplLnByZXZlbnREZWZhdWx0KCksdGhpcy5vbkVzY2FwZSgpO2JyZWFrO2Nhc2VcIkFycm93VXBcIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uQXJyb3coKTticmVhaztjYXNlXCJBcnJvd0Rvd25cIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uQXJyb3coITEpO2JyZWFrO2Nhc2VcIkhvbWVcIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uU3RhcnRFbmQoKTticmVhaztjYXNlXCJFbmRcIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uU3RhcnRFbmQoITEpO2JyZWFrO2Nhc2VcIkVudGVyXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMub25FbnRlcihlKX19c3RhdGljIG9uRXNjYXBlKCl7Y29uc3QgZT13aW5kb3cuJGhzQ29tYm9Cb3hDb2xsZWN0aW9uLmZpbmQoKGU9PiFlLmVsZW1lbnQucHJldmVudFZpc2liaWxpdHkmJmUuZWxlbWVudC5pc09wZW5lZCkpO2UmJihlLmVsZW1lbnQuY2xvc2UoKSxlLmVsZW1lbnQuaW5wdXQuYmx1cigpKX1zdGF0aWMgb25BcnJvdyhlPSEwKXt2YXIgdDtjb25zdCBpPXdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LnByZXZlbnRWaXNpYmlsaXR5P2UuZWxlbWVudC5pc0N1cnJlbnQ6ZS5lbGVtZW50LmlzT3BlbmVkKSk7aWYoaSl7Y29uc3Qgcz1udWxsIT09KHQ9aS5lbGVtZW50Lml0ZW1zV3JhcHBlcikmJnZvaWQgMCE9PXQ/dDppLmVsZW1lbnQub3V0cHV0O2lmKCFzKXJldHVybiExO2NvbnN0IG49YS5nZXRQcmVwYXJlZEl0ZW1zKGUscyksbz1zLnF1ZXJ5U2VsZWN0b3IoXCIuY29tYm8tYm94LW91dHB1dC1pdGVtLWhpZ2hsaWdodGVkXCIpO2xldCBsPW51bGw7b3x8blswXS5jbGFzc0xpc3QuYWRkKFwiY29tYm8tYm94LW91dHB1dC1pdGVtLWhpZ2hsaWdodGVkXCIpO2xldCByPW4uZmluZEluZGV4KChlPT5lPT09bykpO3IrMTxuLmxlbmd0aCYmcisrLGw9bltyXSxhLnNldEhpZ2hsaWdodGVkKG8sbCxpLmVsZW1lbnQuaW5wdXQpfX1zdGF0aWMgb25TdGFydEVuZChlPSEwKXt2YXIgdDtjb25zdCBpPXdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LnByZXZlbnRWaXNpYmlsaXR5P2UuZWxlbWVudC5pc0N1cnJlbnQ6ZS5lbGVtZW50LmlzT3BlbmVkKSk7aWYoaSl7Y29uc3Qgcz1udWxsIT09KHQ9aS5lbGVtZW50Lml0ZW1zV3JhcHBlcikmJnZvaWQgMCE9PXQ/dDppLmVsZW1lbnQub3V0cHV0O2lmKCFzKXJldHVybiExO2NvbnN0IG49YS5nZXRQcmVwYXJlZEl0ZW1zKGUscyksbz1zLnF1ZXJ5U2VsZWN0b3IoXCIuY29tYm8tYm94LW91dHB1dC1pdGVtLWhpZ2hsaWdodGVkXCIpO24ubGVuZ3RoJiZhLnNldEhpZ2hsaWdodGVkKG8sblswXSxpLmVsZW1lbnQuaW5wdXQpfX1zdGF0aWMgb25FbnRlcihlKXt2YXIgdDtjb25zdCBpPWUudGFyZ2V0LHM9d2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbi5maW5kKCh0PT4hKDAsby5pc1BhcmVudE9yRWxlbWVudEhpZGRlbikodC5lbGVtZW50LmVsKSYmZS50YXJnZXQuY2xvc2VzdChcIltkYXRhLWNvbWJvLWJveF1cIik9PT10LmVsZW1lbnQuZWwpKSxuPXMuZWxlbWVudC5lbC5xdWVyeVNlbGVjdG9yKFwiLmNvbWJvLWJveC1vdXRwdXQtaXRlbS1oaWdobGlnaHRlZCBhXCIpO2kuaGFzQXR0cmlidXRlKFwiZGF0YS1jb21iby1ib3gtaW5wdXRcIik/KHMuZWxlbWVudC5jbG9zZSgpLGkuYmx1cigpKToocy5lbGVtZW50LnByZXZlbnRTZWxlY3Rpb258fHMuZWxlbWVudC5zZXRTZWxlY3RlZEJ5VmFsdWUocy5lbGVtZW50LnZhbHVlc0J5U2VsZWN0b3IoZS50YXJnZXQpKSxzLmVsZW1lbnQucHJldmVudFNlbGVjdGlvbiYmbiYmd2luZG93LmxvY2F0aW9uLmFzc2lnbihuLmdldEF0dHJpYnV0ZShcImhyZWZcIikpLHMuZWxlbWVudC5jbG9zZShzLmVsZW1lbnQucHJldmVudFNlbGVjdGlvbj9udWxsOmUudGFyZ2V0LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1jb21iby1ib3gtdmFsdWVdXCIpLmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LXNlYXJjaC10ZXh0XCIpLG51bGwhPT0odD1KU09OLnBhcnNlKGUudGFyZ2V0LmdldEF0dHJpYnV0ZShcImRhdGEtY29tYm8tYm94LWl0ZW0tc3RvcmVkLWRhdGFcIikpKSYmdm9pZCAwIT09dD90Om51bGwpKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57YS5hdXRvSW5pdCgpfSkpLGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwoKCk9PntpZighd2luZG93LiRoc0NvbWJvQm94Q29sbGVjdGlvbilyZXR1cm4hMTtjb25zdCBlPXdpbmRvdy4kaHNDb21ib0JveENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSk7ZSYmIWUuZWxlbWVudC5wcmV2ZW50QXV0b1Bvc2l0aW9uJiZlLmVsZW1lbnQucmVjYWxjdWxhdGVEaXJlY3Rpb24oKX0pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYod2luZG93LkhTQ29tYm9Cb3g9YSksdC5kZWZhdWx0PWF9LDg2OmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU0lucHV0TnVtYmVyXG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbnZhciBzPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IG49aSg4MDYpLG89cyhpKDI4NykpO2NsYXNzIGwgZXh0ZW5kcyBvLmRlZmF1bHR7Y29uc3RydWN0b3IoZSx0KXtzdXBlcihlLHQpLHRoaXMuaW5wdXQ9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtaW5wdXQtbnVtYmVyLWlucHV0XVwiKXx8bnVsbCx0aGlzLmluY3JlbWVudD10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pbnB1dC1udW1iZXItaW5jcmVtZW50XVwiKXx8bnVsbCx0aGlzLmRlY3JlbWVudD10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pbnB1dC1udW1iZXItZGVjcmVtZW50XVwiKXx8bnVsbCx0aGlzLmlucHV0JiZ0aGlzLmNoZWNrSXNOdW1iZXJBbmRDb252ZXJ0KCk7Y29uc3QgaT10aGlzLmVsLmRhdGFzZXQuaW5wdXROdW1iZXIscz1pP0pTT04ucGFyc2UoaSk6e3N0ZXA6MX0sbj1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30scyksdCk7dGhpcy5taW5JbnB1dFZhbHVlPVwibWluXCJpbiBuP24ubWluOjAsdGhpcy5tYXhJbnB1dFZhbHVlPVwibWF4XCJpbiBuP24ubWF4Om51bGwsdGhpcy5zdGVwPVwic3RlcFwiaW4gbiYmbi5zdGVwPjA/bi5zdGVwOjEsdGhpcy5pbml0KCl9aW5wdXRJbnB1dCgpe3RoaXMuY2hhbmdlVmFsdWUoKX1pbmNyZW1lbnRDbGljaygpe3RoaXMuY2hhbmdlVmFsdWUoXCJpbmNyZW1lbnRcIil9ZGVjcmVtZW50Q2xpY2soKXt0aGlzLmNoYW5nZVZhbHVlKFwiZGVjcmVtZW50XCIpfWluaXQoKXt0aGlzLmNyZWF0ZUNvbGxlY3Rpb24od2luZG93LiRoc0lucHV0TnVtYmVyQ29sbGVjdGlvbix0aGlzKSx0aGlzLmlucHV0JiZ0aGlzLmluY3JlbWVudCYmdGhpcy5idWlsZCgpfWNoZWNrSXNOdW1iZXJBbmRDb252ZXJ0KCl7Y29uc3QgZT10aGlzLmlucHV0LnZhbHVlLnRyaW0oKSx0PXRoaXMuY2xlYW5BbmRFeHRyYWN0TnVtYmVyKGUpO251bGwhPT10Pyh0aGlzLmlucHV0VmFsdWU9dCx0aGlzLmlucHV0LnZhbHVlPXQudG9TdHJpbmcoKSk6KHRoaXMuaW5wdXRWYWx1ZT0wLHRoaXMuaW5wdXQudmFsdWU9XCIwXCIpfWNsZWFuQW5kRXh0cmFjdE51bWJlcihlKXtjb25zdCB0PVtdO2xldCBpPSExO2Uuc3BsaXQoXCJcIikuZm9yRWFjaCgoZT0+e2U+PVwiMFwiJiZlPD1cIjlcIj90LnB1c2goZSk6XCIuXCIhPT1lfHxpfHwodC5wdXNoKGUpLGk9ITApfSkpO2NvbnN0IHM9dC5qb2luKFwiXCIpLG49cGFyc2VGbG9hdChzKTtyZXR1cm4gaXNOYU4obik/bnVsbDpufWJ1aWxkKCl7dGhpcy5pbnB1dCYmdGhpcy5idWlsZElucHV0KCksdGhpcy5pbmNyZW1lbnQmJnRoaXMuYnVpbGRJbmNyZW1lbnQoKSx0aGlzLmRlY3JlbWVudCYmdGhpcy5idWlsZERlY3JlbWVudCgpLHRoaXMuaW5wdXRWYWx1ZTw9dGhpcy5taW5JbnB1dFZhbHVlJiYodGhpcy5pbnB1dFZhbHVlPXRoaXMubWluSW5wdXRWYWx1ZSx0aGlzLmlucHV0LnZhbHVlPWAke3RoaXMubWluSW5wdXRWYWx1ZX1gKSx0aGlzLmlucHV0VmFsdWU8PXRoaXMubWluSW5wdXRWYWx1ZSYmdGhpcy5jaGFuZ2VWYWx1ZSgpLHRoaXMuaW5wdXQuaGFzQXR0cmlidXRlKFwiZGlzYWJsZWRcIikmJnRoaXMuZGlzYWJsZUJ1dHRvbnMoKX1idWlsZElucHV0KCl7dGhpcy5vbklucHV0SW5wdXRMaXN0ZW5lcj0oKT0+dGhpcy5pbnB1dElucHV0KCksdGhpcy5pbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uSW5wdXRJbnB1dExpc3RlbmVyKX1idWlsZEluY3JlbWVudCgpe3RoaXMub25JbmNyZW1lbnRDbGlja0xpc3RlbmVyPSgpPT50aGlzLmluY3JlbWVudENsaWNrKCksdGhpcy5pbmNyZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkluY3JlbWVudENsaWNrTGlzdGVuZXIpfWJ1aWxkRGVjcmVtZW50KCl7dGhpcy5vbkRlY3JlbWVudENsaWNrTGlzdGVuZXI9KCk9PnRoaXMuZGVjcmVtZW50Q2xpY2soKSx0aGlzLmRlY3JlbWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uRGVjcmVtZW50Q2xpY2tMaXN0ZW5lcil9Y2hhbmdlVmFsdWUoZT1cIm5vbmVcIil7dmFyIHQsaTtjb25zdCBzPXtpbnB1dFZhbHVlOnRoaXMuaW5wdXRWYWx1ZX0sbz1udWxsIT09KHQ9dGhpcy5taW5JbnB1dFZhbHVlKSYmdm9pZCAwIT09dD90Ok51bWJlci5NSU5fU0FGRV9JTlRFR0VSLGw9bnVsbCE9PShpPXRoaXMubWF4SW5wdXRWYWx1ZSkmJnZvaWQgMCE9PWk/aTpOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtzd2l0Y2godGhpcy5pbnB1dFZhbHVlPWlzTmFOKHRoaXMuaW5wdXRWYWx1ZSk/MDp0aGlzLmlucHV0VmFsdWUsZSl7Y2FzZVwiaW5jcmVtZW50XCI6Y29uc3QgZT10aGlzLmlucHV0VmFsdWUrdGhpcy5zdGVwO3RoaXMuaW5wdXRWYWx1ZT1lPj1vJiZlPD1sP2U6bCx0aGlzLmlucHV0LnZhbHVlPXRoaXMuaW5wdXRWYWx1ZS50b1N0cmluZygpO2JyZWFrO2Nhc2VcImRlY3JlbWVudFwiOmNvbnN0IHQ9dGhpcy5pbnB1dFZhbHVlLXRoaXMuc3RlcDt0aGlzLmlucHV0VmFsdWU9dD49byYmdDw9bD90Om8sdGhpcy5pbnB1dC52YWx1ZT10aGlzLmlucHV0VmFsdWUudG9TdHJpbmcoKTticmVhaztkZWZhdWx0OmNvbnN0IGk9aXNOYU4ocGFyc2VJbnQodGhpcy5pbnB1dC52YWx1ZSkpPzA6cGFyc2VJbnQodGhpcy5pbnB1dC52YWx1ZSk7dGhpcy5pbnB1dFZhbHVlPWk+PWw/bDppPD1vP286aSx0aGlzLmlucHV0VmFsdWU8PW8mJih0aGlzLmlucHV0LnZhbHVlPXRoaXMuaW5wdXRWYWx1ZS50b1N0cmluZygpKX1zLmlucHV0VmFsdWU9dGhpcy5pbnB1dFZhbHVlLHRoaXMuaW5wdXRWYWx1ZT09PW8/KHRoaXMuZWwuY2xhc3NMaXN0LmFkZChcImRpc2FibGVkXCIpLHRoaXMuZGVjcmVtZW50JiZ0aGlzLmRpc2FibGVCdXR0b25zKFwiZGVjcmVtZW50XCIpKToodGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiZGlzYWJsZWRcIiksdGhpcy5kZWNyZW1lbnQmJnRoaXMuZW5hYmxlQnV0dG9ucyhcImRlY3JlbWVudFwiKSksdGhpcy5pbnB1dFZhbHVlPT09bD8odGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwiZGlzYWJsZWRcIiksdGhpcy5pbmNyZW1lbnQmJnRoaXMuZGlzYWJsZUJ1dHRvbnMoXCJpbmNyZW1lbnRcIikpOih0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJkaXNhYmxlZFwiKSx0aGlzLmluY3JlbWVudCYmdGhpcy5lbmFibGVCdXR0b25zKFwiaW5jcmVtZW50XCIpKSx0aGlzLmZpcmVFdmVudChcImNoYW5nZVwiLHMpLCgwLG4uZGlzcGF0Y2gpKFwiY2hhbmdlLmlucHV0TnVtYmVyXCIsdGhpcy5lbCxzKX1kaXNhYmxlQnV0dG9ucyhlPVwiYWxsXCIpe1wiYWxsXCI9PT1lPyhcIkJVVFRPTlwiIT09dGhpcy5pbmNyZW1lbnQudGFnTmFtZSYmXCJJTlBVVFwiIT09dGhpcy5pbmNyZW1lbnQudGFnTmFtZXx8dGhpcy5pbmNyZW1lbnQuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpLFwiQlVUVE9OXCIhPT10aGlzLmRlY3JlbWVudC50YWdOYW1lJiZcIklOUFVUXCIhPT10aGlzLmRlY3JlbWVudC50YWdOYW1lfHx0aGlzLmRlY3JlbWVudC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLFwiZGlzYWJsZWRcIikpOlwiaW5jcmVtZW50XCI9PT1lP1wiQlVUVE9OXCIhPT10aGlzLmluY3JlbWVudC50YWdOYW1lJiZcIklOUFVUXCIhPT10aGlzLmluY3JlbWVudC50YWdOYW1lfHx0aGlzLmluY3JlbWVudC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLFwiZGlzYWJsZWRcIik6XCJkZWNyZW1lbnRcIj09PWUmJihcIkJVVFRPTlwiIT09dGhpcy5kZWNyZW1lbnQudGFnTmFtZSYmXCJJTlBVVFwiIT09dGhpcy5kZWNyZW1lbnQudGFnTmFtZXx8dGhpcy5kZWNyZW1lbnQuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpKX1lbmFibGVCdXR0b25zKGU9XCJhbGxcIil7XCJhbGxcIj09PWU/KFwiQlVUVE9OXCIhPT10aGlzLmluY3JlbWVudC50YWdOYW1lJiZcIklOUFVUXCIhPT10aGlzLmluY3JlbWVudC50YWdOYW1lfHx0aGlzLmluY3JlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSxcIkJVVFRPTlwiIT09dGhpcy5kZWNyZW1lbnQudGFnTmFtZSYmXCJJTlBVVFwiIT09dGhpcy5kZWNyZW1lbnQudGFnTmFtZXx8dGhpcy5kZWNyZW1lbnQucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIikpOlwiaW5jcmVtZW50XCI9PT1lP1wiQlVUVE9OXCIhPT10aGlzLmluY3JlbWVudC50YWdOYW1lJiZcIklOUFVUXCIhPT10aGlzLmluY3JlbWVudC50YWdOYW1lfHx0aGlzLmluY3JlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKTpcImRlY3JlbWVudFwiPT09ZSYmKFwiQlVUVE9OXCIhPT10aGlzLmRlY3JlbWVudC50YWdOYW1lJiZcIklOUFVUXCIhPT10aGlzLmRlY3JlbWVudC50YWdOYW1lfHx0aGlzLmRlY3JlbWVudC5yZW1vdmVBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSl9ZGVzdHJveSgpe3RoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpLHRoaXMuaW5jcmVtZW50LnJlbW92ZUF0dHJpYnV0ZShcImRpc2FibGVkXCIpLHRoaXMuZGVjcmVtZW50LnJlbW92ZUF0dHJpYnV0ZShcImRpc2FibGVkXCIpLHRoaXMuaW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vbklucHV0SW5wdXRMaXN0ZW5lciksdGhpcy5pbmNyZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkluY3JlbWVudENsaWNrTGlzdGVuZXIpLHRoaXMuZGVjcmVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25EZWNyZW1lbnRDbGlja0xpc3RlbmVyKSx3aW5kb3cuJGhzSW5wdXROdW1iZXJDb2xsZWN0aW9uPXdpbmRvdy4kaHNJbnB1dE51bWJlckNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5lLmVsIT09dGhpcy5lbCkpfXN0YXRpYyBnZXRJbnN0YW5jZShlLHQpe2NvbnN0IGk9d2luZG93LiRoc0lucHV0TnVtYmVyQ29sbGVjdGlvbi5maW5kKCh0PT50LmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKSkpO3JldHVybiBpP3Q/aTppLmVsZW1lbnQ6bnVsbH1zdGF0aWMgYXV0b0luaXQoKXt3aW5kb3cuJGhzSW5wdXROdW1iZXJDb2xsZWN0aW9ufHwod2luZG93LiRoc0lucHV0TnVtYmVyQ29sbGVjdGlvbj1bXSksd2luZG93LiRoc0lucHV0TnVtYmVyQ29sbGVjdGlvbiYmKHdpbmRvdy4kaHNJbnB1dE51bWJlckNvbGxlY3Rpb249d2luZG93LiRoc0lucHV0TnVtYmVyQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmRvY3VtZW50LmNvbnRhaW5zKGUuZWwpKSkpLGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1pbnB1dC1udW1iZXJdOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNJbnB1dE51bWJlckNvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgbChlKX0pKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57bC5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNJbnB1dE51bWJlcj1sKSx0LmRlZmF1bHQ9bH0sMTEzOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU1JlbW92ZUVsZW1lbnRcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1pKDgwNiksbz1zKGkoMjg3KSk7Y2xhc3MgbCBleHRlbmRzIG8uZGVmYXVsdHtjb25zdHJ1Y3RvcihlLHQpe3N1cGVyKGUsdCk7Y29uc3QgaT1lLmdldEF0dHJpYnV0ZShcImRhdGEtcmVtb3ZlLWVsZW1lbnQtb3B0aW9uc1wiKSxzPWk/SlNPTi5wYXJzZShpKTp7fSxuPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KTt0aGlzLnJlbW92ZVRhcmdldElkPXRoaXMuZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1yZW1vdmUtZWxlbWVudFwiKSx0aGlzLnJlbW92ZVRhcmdldD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMucmVtb3ZlVGFyZ2V0SWQpLHRoaXMucmVtb3ZlVGFyZ2V0QW5pbWF0aW9uQ2xhc3M9KG51bGw9PW4/dm9pZCAwOm4ucmVtb3ZlVGFyZ2V0QW5pbWF0aW9uQ2xhc3MpfHxcInJlbW92aW5nXCIsdGhpcy5yZW1vdmVUYXJnZXQmJnRoaXMuaW5pdCgpfWVsZW1lbnRDbGljaygpe3RoaXMucmVtb3ZlKCl9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzUmVtb3ZlRWxlbWVudENvbGxlY3Rpb24sdGhpcyksdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyPSgpPT50aGlzLmVsZW1lbnRDbGljaygpLHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyKX1yZW1vdmUoKXtpZighdGhpcy5yZW1vdmVUYXJnZXQpcmV0dXJuITE7dGhpcy5yZW1vdmVUYXJnZXQuY2xhc3NMaXN0LmFkZCh0aGlzLnJlbW92ZVRhcmdldEFuaW1hdGlvbkNsYXNzKSwoMCxuLmFmdGVyVHJhbnNpdGlvbikodGhpcy5yZW1vdmVUYXJnZXQsKCgpPT5zZXRUaW1lb3V0KCgoKT0+dGhpcy5yZW1vdmVUYXJnZXQucmVtb3ZlKCkpKSkpfWRlc3Ryb3koKXt0aGlzLnJlbW92ZVRhcmdldC5jbGFzc0xpc3QucmVtb3ZlKHRoaXMucmVtb3ZlVGFyZ2V0QW5pbWF0aW9uQ2xhc3MpLHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyKSx3aW5kb3cuJGhzUmVtb3ZlRWxlbWVudENvbGxlY3Rpb249d2luZG93LiRoc1JlbW92ZUVsZW1lbnRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZS5lbCE9PXRoaXMuZWwpKX1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0KXtjb25zdCBpPXdpbmRvdy4kaHNSZW1vdmVFbGVtZW50Q29sbGVjdGlvbi5maW5kKCh0PT50LmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKXx8dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50LmVsOm51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc1JlbW92ZUVsZW1lbnRDb2xsZWN0aW9ufHwod2luZG93LiRoc1JlbW92ZUVsZW1lbnRDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzUmVtb3ZlRWxlbWVudENvbGxlY3Rpb24mJih3aW5kb3cuJGhzUmVtb3ZlRWxlbWVudENvbGxlY3Rpb249d2luZG93LiRoc1JlbW92ZUVsZW1lbnRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXJlbW92ZS1lbGVtZW50XTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmZvckVhY2goKGU9Pnt3aW5kb3cuJGhzUmVtb3ZlRWxlbWVudENvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgbChlKX0pKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57bC5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNSZW1vdmVFbGVtZW50PWwpLHQuZGVmYXVsdD1sfSwxMjY6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTVG9nZ2xlQ291bnRcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1zKGkoMjg3KSk7Y2xhc3MgbyBleHRlbmRzIG4uZGVmYXVsdHtjb25zdHJ1Y3RvcihlLHQpe3N1cGVyKGUsdCk7Y29uc3QgaT1lLmdldEF0dHJpYnV0ZShcImRhdGEtdG9nZ2xlLWNvdW50XCIpLHM9aT9KU09OLnBhcnNlKGkpOnt9LG49T2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LHMpLHQpO3RoaXMudGFyZ2V0PShudWxsPT1uP3ZvaWQgMDpuLnRhcmdldCk/XCJzdHJpbmdcIj09dHlwZW9mKG51bGw9PW4/dm9pZCAwOm4udGFyZ2V0KT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKG4udGFyZ2V0KTpuLnRhcmdldDpudWxsLHRoaXMubWluPShudWxsPT1uP3ZvaWQgMDpuLm1pbil8fDAsdGhpcy5tYXg9KG51bGw9PW4/dm9pZCAwOm4ubWF4KXx8MCx0aGlzLmR1cmF0aW9uPShudWxsPT1uP3ZvaWQgMDpuLmR1cmF0aW9uKXx8NzAwLHRoaXMuaXNDaGVja2VkPXRoaXMudGFyZ2V0LmNoZWNrZWR8fCExLHRoaXMudGFyZ2V0JiZ0aGlzLmluaXQoKX10b2dnbGVDaGFuZ2UoKXt0aGlzLmlzQ2hlY2tlZD0hdGhpcy5pc0NoZWNrZWQsdGhpcy50b2dnbGUoKX1pbml0KCl7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNUb2dnbGVDb3VudENvbGxlY3Rpb24sdGhpcyksdGhpcy5pc0NoZWNrZWQmJih0aGlzLmVsLmlubmVyVGV4dD1TdHJpbmcodGhpcy5tYXgpKSx0aGlzLm9uVG9nZ2xlQ2hhbmdlTGlzdGVuZXI9KCk9PnRoaXMudG9nZ2xlQ2hhbmdlKCksdGhpcy50YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLHRoaXMub25Ub2dnbGVDaGFuZ2VMaXN0ZW5lcil9dG9nZ2xlKCl7dGhpcy5pc0NoZWNrZWQ/dGhpcy5jb3VudFVwKCk6dGhpcy5jb3VudERvd24oKX1hbmltYXRlKGUsdCl7bGV0IGk9MDtjb25zdCBzPW49PntpfHwoaT1uKTtjb25zdCBvPU1hdGgubWluKChuLWkpL3RoaXMuZHVyYXRpb24sMSk7dGhpcy5lbC5pbm5lclRleHQ9U3RyaW5nKE1hdGguZmxvb3IobyoodC1lKStlKSksbzwxJiZ3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHMpfTt3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHMpfWNvdW50VXAoKXt0aGlzLmFuaW1hdGUodGhpcy5taW4sdGhpcy5tYXgpfWNvdW50RG93bigpe3RoaXMuYW5pbWF0ZSh0aGlzLm1heCx0aGlzLm1pbil9ZGVzdHJveSgpe3RoaXMudGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIix0aGlzLm9uVG9nZ2xlQ2hhbmdlTGlzdGVuZXIpLHdpbmRvdy4kaHNUb2dnbGVDb3VudENvbGxlY3Rpb249d2luZG93LiRoc1RvZ2dsZUNvdW50Q29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzVG9nZ2xlQ291bnRDb2xsZWN0aW9uLmZpbmQoKHQ9PnQuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSk7cmV0dXJuIGk/dD9pOmkuZWxlbWVudDpudWxsfXN0YXRpYyBhdXRvSW5pdCgpe3dpbmRvdy4kaHNUb2dnbGVDb3VudENvbGxlY3Rpb258fCh3aW5kb3cuJGhzVG9nZ2xlQ291bnRDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzVG9nZ2xlQ291bnRDb2xsZWN0aW9uJiYod2luZG93LiRoc1RvZ2dsZUNvdW50Q29sbGVjdGlvbj13aW5kb3cuJGhzVG9nZ2xlQ291bnRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXRvZ2dsZS1jb3VudF06bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57d2luZG93LiRoc1RvZ2dsZUNvdW50Q29sbGVjdGlvbi5maW5kKCh0PT57dmFyIGk7cmV0dXJuKG51bGw9PT0oaT1udWxsPT10P3ZvaWQgMDp0LmVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmVsKT09PWV9KSl8fG5ldyBvKGUpfSkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PntvLmF1dG9Jbml0KCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1RvZ2dsZUNvdW50PW8pLHQuZGVmYXVsdD1vfSwxNjQ6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTT3ZlcmxheVxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPWkoOTE3KSxsPXMoaSgyODcpKTtjbGFzcyByIGV4dGVuZHMgbC5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCxpKXt2YXIgcyxsLHIsYSxjLGQ7c3VwZXIoZSx0LGkpLHRoaXMuaW5pdGlhbFpJbmRleD0wLHRoaXMudG9nZ2xlQnV0dG9ucz1BcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLW92ZXJsYXk9XCIjJHt0aGlzLmVsLmlkfVwiXWApKTtjb25zdCBoPXRoaXMuY29sbGVjdFRvZ2dsZVBhcmFtZXRlcnModGhpcy50b2dnbGVCdXR0b25zKSx1PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1vdmVybGF5LW9wdGlvbnNcIikscD11P0pTT04ucGFyc2UodSk6e30sbT1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxwKSxoKSx0KTt0aGlzLmhpZGRlbkNsYXNzPShudWxsPT1tP3ZvaWQgMDptLmhpZGRlbkNsYXNzKXx8XCJoaWRkZW5cIix0aGlzLmVtdWxhdGVTY3JvbGxiYXJTcGFjZT0obnVsbD09bT92b2lkIDA6bS5lbXVsYXRlU2Nyb2xsYmFyU3BhY2UpfHwhMSx0aGlzLmlzQ2xvc2VQcmV2PW51bGw9PT0ocz1udWxsPT1tP3ZvaWQgMDptLmlzQ2xvc2VQcmV2KXx8dm9pZCAwPT09c3x8cyx0aGlzLmJhY2tkcm9wQ2xhc3Nlcz1udWxsIT09KGw9bnVsbD09bT92b2lkIDA6bS5iYWNrZHJvcENsYXNzZXMpJiZ2b2lkIDAhPT1sP2w6XCJvdmVybGF5LWJhY2tkcm9wIHRyYW5zaXRpb24gZHVyYXRpb24tMzAwIGZpeGVkIGluc2V0LTAgYmctYmFzZS0zMDAvNjAgb3ZlcmZsb3cteS1hdXRvXCIsdGhpcy5iYWNrZHJvcFBhcmVudD1cInN0cmluZ1wiPT10eXBlb2YgbS5iYWNrZHJvcFBhcmVudD9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKG0uYmFja2Ryb3BQYXJlbnQpOmRvY3VtZW50LmJvZHksdGhpcy5iYWNrZHJvcEV4dHJhQ2xhc3Nlcz1udWxsIT09KHI9bnVsbD09bT92b2lkIDA6bS5iYWNrZHJvcEV4dHJhQ2xhc3NlcykmJnZvaWQgMCE9PXI/cjpcIlwiLHRoaXMubW92ZU92ZXJsYXlUb0JvZHk9KG51bGw9PW0/dm9pZCAwOm0ubW92ZU92ZXJsYXlUb0JvZHkpfHxudWxsLHRoaXMub3Blbk5leHRPdmVybGF5PSExLHRoaXMuYXV0b0hpZGU9bnVsbCx0aGlzLmluaXRDb250YWluZXI9KG51bGw9PT0oYT10aGlzLmVsKXx8dm9pZCAwPT09YT92b2lkIDA6YS5wYXJlbnRFbGVtZW50KXx8bnVsbCx0aGlzLmlzQ2xvc2VXaGVuQ2xpY2tJbnNpZGU9KDAsbi5zdHJpbmdUb0Jvb2xlYW4pKCgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tY2xvc2Utd2hlbi1jbGljay1pbnNpZGVcIixcImZhbHNlXCIpfHxcImZhbHNlXCIpLHRoaXMuaXNUYWJBY2Nlc3NpYmlsaXR5TGltaXRlZD0oMCxuLnN0cmluZ1RvQm9vbGVhbikoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS10YWItYWNjZXNzaWJpbGl0eS1saW1pdGVkXCIsXCJ0cnVlXCIpfHxcInRydWVcIiksdGhpcy5pc0xheW91dEFmZmVjdD0oMCxuLnN0cmluZ1RvQm9vbGVhbikoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS1pcy1sYXlvdXQtYWZmZWN0XCIsXCJmYWxzZVwiKXx8XCJmYWxzZVwiKSx0aGlzLmhhc0F1dG9mb2N1cz0oMCxuLnN0cmluZ1RvQm9vbGVhbikoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS1oYXMtYXV0b2ZvY3VzXCIsXCJ0cnVlXCIpfHxcInRydWVcIiksdGhpcy5oYXNEeW5hbWljWkluZGV4PSgwLG4uc3RyaW5nVG9Cb29sZWFuKSgoMCxuLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLWhhcy1keW5hbWljLXotaW5kZXhcIixcImZhbHNlXCIpfHxcImZhbHNlXCIpLHRoaXMuaGFzQWJpbGl0eVRvQ2xvc2VPbkJhY2tkcm9wQ2xpY2s9KDAsbi5zdHJpbmdUb0Jvb2xlYW4pKHRoaXMuZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1vdmVybGF5LWtleWJvYXJkXCIpfHxcInRydWVcIik7Y29uc3QgZz0oMCxuLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLWF1dG8tY2xvc2VcIiksZj0oMCxuLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLWF1dG8tY2xvc2UtZXF1YWxpdHktdHlwZVwiKSx2PSgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tb3BlbmVkXCIpO3RoaXMuYXV0b0Nsb3NlPSFpc05hTigrZykmJmlzRmluaXRlKCtnKT8rZzpvLkJSRUFLUE9JTlRTW2ddfHxudWxsLHRoaXMuYXV0b0Nsb3NlRXF1YWxpdHlUeXBlPW51bGwhPT0oYz1mKSYmdm9pZCAwIT09Yz9jOm51bGwsdGhpcy5vcGVuZWRCcmVha3BvaW50PSghaXNOYU4oK3YpJiZpc0Zpbml0ZSgrdik/K3Y6by5CUkVBS1BPSU5UU1t2XSl8fG51bGwsdGhpcy5hbmltYXRpb25UYXJnZXQ9KG51bGw9PT0oZD1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLmVsKXx8dm9pZCAwPT09ZD92b2lkIDA6ZC5xdWVyeVNlbGVjdG9yKFwiLm92ZXJsYXktYW5pbWF0aW9uLXRhcmdldFwiKSl8fHRoaXMuZWwsdGhpcy5pbml0aWFsWkluZGV4PXBhcnNlSW50KGdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuekluZGV4LDEwKSx0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXI9W10sdGhpcy5pbml0KCl9ZWxlbWVudENsaWNrKCl7Y29uc3QgZT0oKT0+e2NvbnN0IGU9e2VsOnRoaXMuZWwsaXNPcGVuZWQ6ISF0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIil9O3RoaXMuZmlyZUV2ZW50KFwidG9nZ2xlQ2xpY2tlZFwiLGUpLCgwLG4uZGlzcGF0Y2gpKFwidG9nZ2xlQ2xpY2tlZC5vdmVybGF5XCIsdGhpcy5lbCxlKX07dGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJvcGVuZWRcIik/dGhpcy5jbG9zZSghMSxlKTp0aGlzLm9wZW4oZSl9b3ZlcmxheUNsaWNrKGUpe2UudGFyZ2V0LmlkJiZgIyR7ZS50YXJnZXQuaWR9YD09PXRoaXMuZWwuaWQmJnRoaXMuaXNDbG9zZVdoZW5DbGlja0luc2lkZSYmdGhpcy5oYXNBYmlsaXR5VG9DbG9zZU9uQmFja2Ryb3BDbGljayYmdGhpcy5jbG9zZSgpfWJhY2tkcm9wQ2xpY2soKXt0aGlzLmNsb3NlKCl9aW5pdCgpe2lmKHRoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24sdGhpcyksdGhpcy5pc0xheW91dEFmZmVjdCYmdGhpcy5vcGVuZWRCcmVha3BvaW50KXtjb25zdCBlPXIuZ2V0SW5zdGFuY2UodGhpcy5lbCwhMCk7ci5zZXRPcGVuZWQodGhpcy5vcGVuZWRCcmVha3BvaW50LGUpfXRoaXMub25PdmVybGF5Q2xpY2tMaXN0ZW5lcj1lPT50aGlzLm92ZXJsYXlDbGljayhlKSx0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25PdmVybGF5Q2xpY2tMaXN0ZW5lciksdGhpcy50b2dnbGVCdXR0b25zLmxlbmd0aCYmdGhpcy5idWlsZFRvZ2dsZUJ1dHRvbnMoKX1nZXRFbGVtZW50c0J5WkluZGV4KCl7cmV0dXJuIHdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5maWx0ZXIoKGU9PmUuZWxlbWVudC5pbml0aWFsWkluZGV4PT09dGhpcy5pbml0aWFsWkluZGV4KSl9YnVpbGRUb2dnbGVCdXR0b25zKCl7dGhpcy50b2dnbGVCdXR0b25zLmZvckVhY2goKGU9Pnt0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5lZFwiKT9lLmFyaWFFeHBhbmRlZD1cInRydWVcIjplLmFyaWFFeHBhbmRlZD1cImZhbHNlXCIsdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyLnB1c2goe2VsOmUsZm46KCk9PnRoaXMuZWxlbWVudENsaWNrKCl9KSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25FbGVtZW50Q2xpY2tMaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKX0pKX1oaWRlQXV0bygpe2NvbnN0IGU9cGFyc2VJbnQoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS1hdXRvLWhpZGVcIixcIjBcIikpO2UmJih0aGlzLmF1dG9IaWRlPXNldFRpbWVvdXQoKCgpPT57dGhpcy5jbG9zZSgpfSksZSkpfWNoZWNrVGltZXIoKXt0aGlzLmF1dG9IaWRlJiYoY2xlYXJUaW1lb3V0KHRoaXMuYXV0b0hpZGUpLHRoaXMuYXV0b0hpZGU9bnVsbCl9YnVpbGRCYWNrZHJvcCgpe2NvbnN0IGU9dGhpcy5lbC5jbGFzc0xpc3QudmFsdWUuc3BsaXQoXCIgXCIpLHQ9cGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZ2V0UHJvcGVydHlWYWx1ZShcInotaW5kZXhcIikpLGk9dGhpcy5lbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW92ZXJsYXktYmFja2Ryb3AtY29udGFpbmVyXCIpfHwhMTt0aGlzLmJhY2tkcm9wPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7bGV0IHM9YCR7dGhpcy5iYWNrZHJvcENsYXNzZXN9ICR7dGhpcy5iYWNrZHJvcEV4dHJhQ2xhc3Nlc31gO2NvbnN0IG89XCJzdGF0aWNcIiE9PSgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tb3ZlcmxheS1iYWNrZHJvcFwiLFwidHJ1ZVwiKSxsPVwiZmFsc2VcIj09PSgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tb3ZlcmxheS1iYWNrZHJvcFwiLFwidHJ1ZVwiKTt0aGlzLmJhY2tkcm9wLmlkPWAke3RoaXMuZWwuaWR9LWJhY2tkcm9wYCxcInN0eWxlXCJpbiB0aGlzLmJhY2tkcm9wJiYodGhpcy5iYWNrZHJvcC5zdHlsZS56SW5kZXg9XCJcIisodC0xKSk7Zm9yKGNvbnN0IHQgb2YgZSkodC5zdGFydHNXaXRoKFwib3ZlcmxheS1iYWNrZHJvcC1vcGVuOlwiKXx8dC5pbmNsdWRlcyhcIjpvdmVybGF5LWJhY2tkcm9wLW9wZW46XCIpKSYmKHMrPWAgJHt0fWApO2x8fChpJiYodGhpcy5iYWNrZHJvcD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGkpLmNsb25lTm9kZSghMCksdGhpcy5iYWNrZHJvcC5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpLHM9YCR7dGhpcy5iYWNrZHJvcC5jbGFzc0xpc3QudG9TdHJpbmcoKX1gLHRoaXMuYmFja2Ryb3AuY2xhc3NMaXN0LnZhbHVlPVwiXCIpLG8mJih0aGlzLm9uQmFja2Ryb3BDbGlja0xpc3RlbmVyPSgpPT50aGlzLmJhY2tkcm9wQ2xpY2soKSx0aGlzLmJhY2tkcm9wLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25CYWNrZHJvcENsaWNrTGlzdGVuZXIsITApKSx0aGlzLmJhY2tkcm9wLnNldEF0dHJpYnV0ZShcImRhdGEtb3ZlcmxheS1iYWNrZHJvcC10ZW1wbGF0ZVwiLFwiXCIpLHRoaXMuYmFja2Ryb3BQYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5iYWNrZHJvcCksc2V0VGltZW91dCgoKCk9Pnt0aGlzLmJhY2tkcm9wLmNsYXNzTGlzdC52YWx1ZT1zfSkpKX1kZXN0cm95QmFja2Ryb3AoKXtjb25zdCBlPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCMke3RoaXMuZWwuaWR9LWJhY2tkcm9wYCk7ZSYmKHRoaXMub3Blbk5leHRPdmVybGF5JiYoZS5zdHlsZS50cmFuc2l0aW9uRHVyYXRpb249MS44KnBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUoZSkudHJhbnNpdGlvbkR1cmF0aW9uLnJlcGxhY2UoL1teXFxkLi1dL2csXCJcIikpK1wic1wiKSxlLmNsYXNzTGlzdC5hZGQoXCJvcGFjaXR5LTBcIiksKDAsbi5hZnRlclRyYW5zaXRpb24pKGUsKCgpPT57ZS5yZW1vdmUoKX0pKSl9Zm9jdXNFbGVtZW50KCl7Y29uc3QgZT10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbYXV0b2ZvY3VzXVwiKTtpZighZSlyZXR1cm4hMTtlLmZvY3VzKCl9Z2V0U2Nyb2xsYmFyU2l6ZSgpe2xldCBlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7ZS5zdHlsZS5vdmVyZmxvdz1cInNjcm9sbFwiLGUuc3R5bGUud2lkdGg9XCIxMDBweFwiLGUuc3R5bGUuaGVpZ2h0PVwiMTAwcHhcIixkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGUpO2xldCB0PWUub2Zmc2V0V2lkdGgtZS5jbGllbnRXaWR0aDtyZXR1cm4gZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChlKSx0fWNvbGxlY3RUb2dnbGVQYXJhbWV0ZXJzKGUpe2xldCB0PXt9O3JldHVybiBlLmZvckVhY2goKGU9Pntjb25zdCBpPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1vdmVybGF5LW9wdGlvbnNcIikscz1pP0pTT04ucGFyc2UoaSk6e307dD1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sdCkscyl9KSksdH1vcGVuKGU9bnVsbCl7dGhpcy5oYXNEeW5hbWljWkluZGV4JiYoci5jdXJyZW50WkluZGV4PHRoaXMuaW5pdGlhbFpJbmRleCYmKHIuY3VycmVudFpJbmRleD10aGlzLmluaXRpYWxaSW5kZXgpLHIuY3VycmVudFpJbmRleCsrLHRoaXMuZWwuc3R5bGUuekluZGV4PWAke3IuY3VycmVudFpJbmRleH1gKTtjb25zdCB0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIub3ZlcmxheS5vcGVuXCIpLGk9d2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uLmZpbmQoKGU9PkFycmF5LmZyb20odCkuaW5jbHVkZXMoZS5lbGVtZW50LmVsKSYmIWUuZWxlbWVudC5pc0xheW91dEFmZmVjdCkpLHM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgW2RhdGEtb3ZlcmxheT1cIiMke3RoaXMuZWwuaWR9XCJdYCksbz1cInRydWVcIiE9PSgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tYm9keS1zY3JvbGxcIixcImZhbHNlXCIpO2lmKHRoaXMuaXNDbG9zZVByZXYmJmkpcmV0dXJuIHRoaXMub3Blbk5leHRPdmVybGF5PSEwLGkuZWxlbWVudC5jbG9zZSgpLnRoZW4oKCgpPT57dGhpcy5vcGVuKCksdGhpcy5vcGVuTmV4dE92ZXJsYXk9ITF9KSk7byYmKGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3c9XCJoaWRkZW5cIix0aGlzLmVtdWxhdGVTY3JvbGxiYXJTcGFjZSYmKGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0PWAke3RoaXMuZ2V0U2Nyb2xsYmFyU2l6ZSgpfXB4YCkpLHRoaXMuYnVpbGRCYWNrZHJvcCgpLHRoaXMuY2hlY2tUaW1lcigpLHRoaXMuaGlkZUF1dG8oKSxzLmZvckVhY2goKGU9PntlLmFyaWFFeHBhbmRlZCYmKGUuYXJpYUV4cGFuZGVkPVwidHJ1ZVwiKX0pKSx0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5oaWRkZW5DbGFzcyksdGhpcy5lbC5zZXRBdHRyaWJ1dGUoXCJhcmlhLW92ZXJsYXlcIixcInRydWVcIiksdGhpcy5lbC5zZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiLFwiLTFcIiksc2V0VGltZW91dCgoKCk9PntpZih0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5lZFwiKSlyZXR1cm4hMTt0aGlzLmVsLmNsYXNzTGlzdC5hZGQoXCJvcGVuXCIsXCJvcGVuZWRcIiksdGhpcy5pc0xheW91dEFmZmVjdCYmZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwib3ZlcmxheS1ib2R5LW9wZW5cIiksdGhpcy5maXJlRXZlbnQoXCJvcGVuXCIsdGhpcy5lbCksKDAsbi5kaXNwYXRjaCkoXCJvcGVuLm92ZXJsYXlcIix0aGlzLmVsLHRoaXMuZWwpLHRoaXMuaGFzQXV0b2ZvY3VzJiZ0aGlzLmZvY3VzRWxlbWVudCgpLFwiZnVuY3Rpb25cIj09dHlwZW9mIGUmJmUoKSxyLm9wZW5lZEl0ZW1zUXR5Kyt9KSw1MCl9Y2xvc2UoZT0hMSx0PW51bGwpe3Iub3BlbmVkSXRlbXNRdHk9ci5vcGVuZWRJdGVtc1F0eTw9MD8wOnIub3BlbmVkSXRlbXNRdHktMSwwPT09ci5vcGVuZWRJdGVtc1F0eSYmdGhpcy5pc0xheW91dEFmZmVjdCYmZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKFwib3ZlcmxheS1ib2R5LW9wZW5cIik7Y29uc3QgaT1lPT57aWYodGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJvcGVuXCIpKXJldHVybiExO2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYFtkYXRhLW92ZXJsYXk9XCIjJHt0aGlzLmVsLmlkfVwiXWApLmZvckVhY2goKGU9PntlLmFyaWFFeHBhbmRlZCYmKGUuYXJpYUV4cGFuZGVkPVwiZmFsc2VcIil9KSksdGhpcy5lbC5jbGFzc0xpc3QuYWRkKHRoaXMuaGlkZGVuQ2xhc3MpLHRoaXMuaGFzRHluYW1pY1pJbmRleCYmKHRoaXMuZWwuc3R5bGUuekluZGV4PVwiXCIpLHRoaXMuZGVzdHJveUJhY2tkcm9wKCksdGhpcy5maXJlRXZlbnQoXCJjbG9zZVwiLHRoaXMuZWwpLCgwLG4uZGlzcGF0Y2gpKFwiY2xvc2Uub3ZlcmxheVwiLHRoaXMuZWwsdGhpcy5lbCksZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi5vdmVybGF5Lm9wZW5lZFwiKXx8KGRvY3VtZW50LmJvZHkuc3R5bGUub3ZlcmZsb3c9XCJcIix0aGlzLmVtdWxhdGVTY3JvbGxiYXJTcGFjZSYmKGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0PVwiXCIpKSxlKHRoaXMuZWwpLFwiZnVuY3Rpb25cIj09dHlwZW9mIHQmJnQoKSwwPT09ci5vcGVuZWRJdGVtc1F0eSYmKGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJsYXktYm9keS1vcGVuXCIpLHRoaXMuaGFzRHluYW1pY1pJbmRleCYmKHIuY3VycmVudFpJbmRleD0wKSl9O3JldHVybiBuZXcgUHJvbWlzZSgodD0+e3RoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcIm9wZW5cIixcIm9wZW5lZFwiKSx0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShcImFyaWEtb3ZlcmxheVwiKSx0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZShcInRhYmluZGV4XCIpLGU/aSh0KTooMCxuLmFmdGVyVHJhbnNpdGlvbikodGhpcy5hbmltYXRpb25UYXJnZXQsKCgpPT5pKHQpKSl9KSl9ZGVzdHJveSgpe3RoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcIm9wZW5cIixcIm9wZW5lZFwiLHRoaXMuaGlkZGVuQ2xhc3MpLHRoaXMuaXNMYXlvdXRBZmZlY3QmJmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShcIm92ZXJsYXktYm9keS1vcGVuXCIpLHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbk92ZXJsYXlDbGlja0xpc3RlbmVyKSx0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXIubGVuZ3RoJiYodGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyLmZvckVhY2goKCh7ZWw6ZSxmbjp0fSk9PntlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHQpfSkpLHRoaXMub25FbGVtZW50Q2xpY2tMaXN0ZW5lcj1udWxsKSx0aGlzLmJhY2tkcm9wJiZ0aGlzLmJhY2tkcm9wLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25CYWNrZHJvcENsaWNrTGlzdGVuZXIpLHRoaXMuYmFja2Ryb3AmJih0aGlzLmJhY2tkcm9wLnJlbW92ZSgpLHRoaXMuYmFja2Ryb3A9bnVsbCksd2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uPXdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGZpbmRJbkNvbGxlY3Rpb24oZSl7cmV0dXJuIHdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5maW5kKCh0PT5lIGluc3RhbmNlb2Ygcj90LmVsZW1lbnQuZWw9PT1lLmVsOlwic3RyaW5nXCI9PXR5cGVvZiBlP3QuZWxlbWVudC5lbD09PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6dC5lbGVtZW50LmVsPT09ZSkpfHxudWxsfXN0YXRpYyBnZXRJbnN0YW5jZShlLHQpe2NvbnN0IGk9XCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplLHM9KG51bGw9PWk/dm9pZCAwOmkuZ2V0QXR0cmlidXRlKFwiZGF0YS1vdmVybGF5XCIpKT9pLmdldEF0dHJpYnV0ZShcImRhdGEtb3ZlcmxheVwiKTplLG49d2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2Ygcz9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKHMpOnMpfHxlLmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIHM/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzKTpzKSkpO3JldHVybiBuP3Q/bjpuLmVsZW1lbnQuZWw6bnVsbH1zdGF0aWMgYXV0b0luaXQoKXt3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb258fCh3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb249W10sZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwoZT0+ci5hY2Nlc3NpYmlsaXR5KGUpKSkpLHdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbiYmKHdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbj13aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLm92ZXJsYXk6bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57d2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uLmZpbmQoKHQ9Pnt2YXIgaTtyZXR1cm4obnVsbD09PShpPW51bGw9PXQ/dm9pZCAwOnQuZWxlbWVudCl8fHZvaWQgMD09PWk/dm9pZCAwOmkuZWwpPT09ZX0pKXx8bmV3IHIoZSl9KSl9c3RhdGljIG9wZW4oZSl7Y29uc3QgdD1yLmZpbmRJbkNvbGxlY3Rpb24oZSk7dCYmdC5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyh0LmVsZW1lbnQuaGlkZGVuQ2xhc3MpJiZ0LmVsZW1lbnQub3BlbigpfXN0YXRpYyBjbG9zZShlKXtjb25zdCB0PXIuZmluZEluQ29sbGVjdGlvbihlKTt0JiYhdC5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyh0LmVsZW1lbnQuaGlkZGVuQ2xhc3MpJiZ0LmVsZW1lbnQuY2xvc2UoKX1zdGF0aWMgc2V0T3BlbmVkKGUsdCl7ZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aD49ZT8oZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKFwib3ZlcmxheS1ib2R5LW9wZW5cIiksdC5lbGVtZW50Lm9wZW4oKSk6dC5lbGVtZW50LmNsb3NlKCEwKX1zdGF0aWMgYWNjZXNzaWJpbGl0eShlKXt2YXIgdCxpO2NvbnN0IHM9ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5vdmVybGF5Lm9wZW5cIiksbz0oMCxuLmdldEhpZ2hlc3RaSW5kZXgpKEFycmF5LmZyb20ocykpLGw9d2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uLmZpbHRlcigoZT0+ZS5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpKS5maW5kKChlPT53aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlLmVsZW1lbnQuZWwpLmdldFByb3BlcnR5VmFsdWUoXCJ6LWluZGV4XCIpPT09YCR7b31gKSkscj1udWxsPT09KGk9bnVsbD09PSh0PW51bGw9PWw/dm9pZCAwOmwuZWxlbWVudCl8fHZvaWQgMD09PXQ/dm9pZCAwOnQuZWwpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLnF1ZXJ5U2VsZWN0b3JBbGwoJ2J1dHRvbiwgW2hyZWZdLCBpbnB1dCwgc2VsZWN0LCB0ZXh0YXJlYSwgW3RhYmluZGV4XTpub3QoW3RhYmluZGV4PVwiLTFcIl0pJyksYT1bXTsobnVsbD09cj92b2lkIDA6ci5sZW5ndGgpJiZyLmZvckVhY2goKGU9PnsoMCxuLmlzUGFyZW50T3JFbGVtZW50SGlkZGVuKShlKXx8YS5wdXNoKGUpfSkpO2NvbnN0IGM9bCYmIWUubWV0YUtleTtpZihjJiYhbC5lbGVtZW50LmlzVGFiQWNjZXNzaWJpbGl0eUxpbWl0ZWQmJlwiVGFiXCI9PT1lLmNvZGUpcmV0dXJuITE7YyYmYS5sZW5ndGgmJlwiVGFiXCI9PT1lLmNvZGUmJihlLnByZXZlbnREZWZhdWx0KCksdGhpcy5vblRhYihsKSksYyYmXCJFc2NhcGVcIj09PWUuY29kZSYmKGUucHJldmVudERlZmF1bHQoKSx0aGlzLm9uRXNjYXBlKGwpKX1zdGF0aWMgb25Fc2NhcGUoZSl7ZSYmZS5lbGVtZW50Lmhhc0FiaWxpdHlUb0Nsb3NlT25CYWNrZHJvcENsaWNrJiZlLmVsZW1lbnQuY2xvc2UoKX1zdGF0aWMgb25UYWIoZSl7Y29uc3QgdD1lLmVsZW1lbnQuZWwsaT1BcnJheS5mcm9tKHQucXVlcnlTZWxlY3RvckFsbCgnYnV0dG9uLCBbaHJlZl0sIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhLCBbdGFiaW5kZXhdOm5vdChbdGFiaW5kZXg9XCItMVwiXSknKSk7aWYoMD09PWkubGVuZ3RoKXJldHVybiExO2NvbnN0IHM9dC5xdWVyeVNlbGVjdG9yKFwiOmZvY3VzXCIpO2lmKHMpe2xldCBlPSExO2Zvcihjb25zdCB0IG9mIGkpe2lmKGUpcmV0dXJuIHZvaWQgdC5mb2N1cygpO3Q9PT1zJiYoZT0hMCl9aVswXS5mb2N1cygpfWVsc2UgaVswXS5mb2N1cygpfXN0YXRpYyBvbihlLHQsaSl7Y29uc3Qgcz1yLmZpbmRJbkNvbGxlY3Rpb24odCk7cyYmKHMuZWxlbWVudC5ldmVudHNbZV09aSl9fXIub3BlbmVkSXRlbXNRdHk9MCxyLmN1cnJlbnRaSW5kZXg9MDtjb25zdCBhPSgpPT57aWYoIXdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5sZW5ndGh8fCF3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50Lm1vdmVPdmVybGF5VG9Cb2R5KSkpcmV0dXJuITE7d2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uLmZpbHRlcigoZT0+ZS5lbGVtZW50Lm1vdmVPdmVybGF5VG9Cb2R5KSkuZm9yRWFjaCgoZT0+e2NvbnN0IHQ9ZS5lbGVtZW50Lm1vdmVPdmVybGF5VG9Cb2R5LGk9ZS5lbGVtZW50LmluaXRDb250YWluZXIscz1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKSxvPWUuZWxlbWVudC5lbDtpZighaSYmbylyZXR1cm4hMTtkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoPD10JiYhKDAsbi5pc0RpcmVjdENoaWxkKShzLG8pP3MuYXBwZW5kQ2hpbGQobyk6ZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aD50JiYhaS5jb250YWlucyhvKSYmaS5hcHBlbmRDaGlsZChvKX0pKX07d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57ci5hdXRvSW5pdCgpLGEoKX0pKSx3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLCgoKT0+eygoKT0+e2lmKCF3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24ubGVuZ3RofHwhd2luZG93LiRoc092ZXJsYXlDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5hdXRvQ2xvc2UpKSlyZXR1cm4hMTt3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24uZmlsdGVyKChlPT5lLmVsZW1lbnQuYXV0b0Nsb3NlKSkuZm9yRWFjaCgoZT0+e2NvbnN0e2F1dG9DbG9zZUVxdWFsaXR5VHlwZTp0LGF1dG9DbG9zZTppfT1lLmVsZW1lbnQ7KFwibGVzcy10aGFuXCI9PT10P2RvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg8PWk6ZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aD49aSk/ZS5lbGVtZW50LmNsb3NlKCEwKTplLmVsZW1lbnQuaXNMYXlvdXRBZmZlY3QmJmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChcIm92ZXJsYXktYm9keS1vcGVuXCIpfSkpfSkoKSxhKCksKCgpPT57aWYoIXdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5sZW5ndGh8fCF3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmF1dG9DbG9zZSkpKXJldHVybiExO3dpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5maWx0ZXIoKGU9PmUuZWxlbWVudC5hdXRvQ2xvc2UpKS5mb3JFYWNoKChlPT57Y29uc3R7YXV0b0Nsb3NlRXF1YWxpdHlUeXBlOnQsYXV0b0Nsb3NlOml9PWUuZWxlbWVudDsoXCJsZXNzLXRoYW5cIj09PXQ/ZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDw9aTpkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoPj1pKSYmZS5lbGVtZW50LmNsb3NlKCEwKX0pKX0pKCksKCgpPT57aWYoIXdpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5sZW5ndGh8fCF3aW5kb3cuJGhzT3ZlcmxheUNvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5lZFwiKSkpKXJldHVybiExO3dpbmRvdy4kaHNPdmVybGF5Q29sbGVjdGlvbi5maWx0ZXIoKGU9PmUuZWxlbWVudC5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJvcGVuZWRcIikpKS5mb3JFYWNoKChlPT57Y29uc3QgdD1wYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlLmVsZW1lbnQuZWwpLmdldFByb3BlcnR5VmFsdWUoXCJ6LWluZGV4XCIpKSxpPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCMke2UuZWxlbWVudC5lbC5pZH0tYmFja2Ryb3BgKTtyZXR1cm4hIWkmJih0IT09cGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUoaSkuZ2V0UHJvcGVydHlWYWx1ZShcInotaW5kZXhcIikpKzEmJihcInN0eWxlXCJpbiBpJiYoaS5zdHlsZS56SW5kZXg9XCJcIisodC0xKSksdm9pZCBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoXCJvdmVybGF5LWJvZHktb3BlblwiKSkpfSkpfSkoKX0pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYod2luZG93LkhTT3ZlcmxheT1yKSx0LmRlZmF1bHQ9cn0sMTkyOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU0ZpbGVVcGxvYWRcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1pKDgwNiksbz1zKGkoMjg3KSk7XCJ1bmRlZmluZWRcIiE9dHlwZW9mIERyb3B6b25lJiYoRHJvcHpvbmUuYXV0b0Rpc2NvdmVyPSExKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCxpKXt2YXIgcztzdXBlcihlLHQsaSksdGhpcy5leHRlbnNpb25zPXt9LHRoaXMuZWw9XCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplO2NvbnN0IG49dGhpcy5lbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWZpbGUtdXBsb2FkXCIpLG89bj9KU09OLnBhcnNlKG4pOnt9O3RoaXMucHJldmlld1RlbXBsYXRlPShudWxsPT09KHM9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZmlsZS11cGxvYWQtcHJldmlld11cIikpfHx2b2lkIDA9PT1zP3ZvaWQgMDpzLmlubmVySFRNTCl8fCc8ZGl2IGNsYXNzPVwicm91bmRlZC1ib3ggc2hhZG93LWxnIHNoYWRvdy1iYXNlLTMwMC8yMCBiZy1iYXNlLTEwMCBwLTNcIj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XCJtYi0xIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiPlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLXgtM1wiPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1iYXNlLWNvbnRlbnQvODAgYm9yZGVyLWJhc2UtY29udGVudC8yMCBmbGV4IHNpemUtOCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1sZyBib3JkZXIgcC0wLjVcIiBkYXRhLWZpbGUtdXBsb2FkLWZpbGUtaWNvbj1cIlwiID5cXG4gICAgICAgICAgICAgIDxpbWcgY2xhc3M9XCJyb3VuZGVkLW1kIGhpZGRlblwiIGRhdGEtZHotdGh1bWJuYWlsPVwiXCIgLz5cXG4gICAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgICAgPGRpdj5cXG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1iYXNlLWNvbnRlbnQgdGV4dC1zbSBmb250LW1lZGl1bVwiPlxcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlubGluZS1ibG9jayB0cnVuY2F0ZSBhbGlnbi1ib3R0b21cIiBkYXRhLWZpbGUtdXBsb2FkLWZpbGUtbmFtZT1cIlwiPjwvc3Bhbj4uPHNwYW4gZGF0YS1maWxlLXVwbG9hZC1maWxlLWV4dD1cIlwiPjwvc3Bhbj5cXG4gICAgICAgICAgICAgIDwvcD5cXG4gICAgICAgICAgICAgIDxwIGNsYXNzPVwidGV4dC1iYXNlLWNvbnRlbnQvNTAgdGV4dC14c1wiIGRhdGEtZmlsZS11cGxvYWQtZmlsZS1zaXplPVwiXCI+PC9wPlxcbiAgICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGdhcC14LTJcIj5cXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLWNpcmNsZSBidG4tdGV4dFwiIGRhdGEtZmlsZS11cGxvYWQtcmVtb3ZlPVwiXCI+XFxuICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiBjbGFzcz1cInNpemUtNCBzaHJpbmstMFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj4gPHBhdGggZmlsbD1cIm5vbmVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiBzdHJva2Utd2lkdGg9XCIyXCIgZD1cIk0xOCA2TDYgMThNNiA2bDEyIDEyXCIgLz4gPC9zdmc+XFxuICAgICAgICAgICAgPC9idXR0b24+XFxuICAgICAgICAgIDwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLXgtMyB3aGl0ZXNwYWNlLW5vd3JhcFwiPlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MgaC0yXCIgcm9sZT1cInByb2dyZXNzYmFyXCIgYXJpYS12YWx1ZW5vdz1cIjBcIiBhcmlhLXZhbHVlbWluPVwiMFwiIGFyaWEtdmFsdWVtYXg9XCIxMDBcIiBkYXRhLWZpbGUtdXBsb2FkLXByb2dyZXNzLWJhcj1cIlwiID5cXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyIHByb2dyZXNzLXByaW1hcnkgZmlsZS11cGxvYWQtY29tcGxldGU6cHJvZ3Jlc3Mtc3VjY2VzcyB0cmFuc2l0aW9uLWFsbCBkdXJhdGlvbi01MDBcIiBzdHlsZT1cIndpZHRoOiAwXCIgZGF0YS1maWxlLXVwbG9hZC1wcm9ncmVzcy1iYXItcGFuZT1cIlwiID48L2Rpdj5cXG4gICAgICAgICAgPC9kaXY+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1iYXNlLWNvbnRlbnQgbWItMC41IHRleHQtc21cIj5cXG4gICAgICAgICAgICA8c3BhbiBkYXRhLWZpbGUtdXBsb2FkLXByb2dyZXNzLWJhci12YWx1ZT1cIlwiPjA8L3NwYW4+JVxcbiAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgICA8L2Rpdj4nLHRoaXMuZXh0ZW5zaW9ucz1fLm1lcmdlKHtkZWZhdWx0OntpY29uOic8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCI+PHBhdGggZD1cIk0xNSAySDZhMiAyIDAgMCAwLTIgMnYxNmEyIDIgMCAwIDAgMiAyaDEyYTIgMiAwIDAgMCAyLTJWN1pcIi8+PHBhdGggZD1cIk0xNCAydjRhMiAyIDAgMCAwIDIgMmg0XCIvPjwvc3ZnPicsY2xhc3M6XCJzaHJpbmstMCBzaXplLTVcIn0seGxzOntpY29uOic8c3ZnIHdpZHRoPVwiMjRcIiBoZWlnaHQ9XCIyNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj48cGF0aCBkPVwiTTE1LjAyNDMgMS40Mzk5Nkg3LjA4ODA1QzYuODI1MDEgMS40Mzk5NiA2LjU3Mjc3IDEuNTQ0NDUgNi4zODY3NyAxLjczMDQzQzYuMjAwNzcgMS45MTY0MiA2LjA5NjMxIDIuMTY4NjggNi4wOTYzMSAyLjQzMTcxVjYuNjQ3OTZMMTUuMDI0MyAxMS44NTZMMTkuNDg4MyAxMy43Mzk4TDIzLjk1MjMgMTEuODU2VjYuNjQ3OTZMMTUuMDI0MyAxLjQzOTk2WlwiIGZpbGw9XCIjMjFBMzY2XCI+PC9wYXRoPjxwYXRoIGQ9XCJNNi4wOTYzMSA2LjY0Nzk2SDE1LjAyNDNWMTEuODU2SDYuMDk2MzFWNi42NDc5NlpcIiBmaWxsPVwiIzEwN0M0MVwiPjwvcGF0aD48cGF0aCBkPVwiTTIyLjk2MDUgMS40Mzk5NkgxNS4wMjQzVjYuNjQ3OTZIMjMuOTUyM1YyLjQzMTcxQzIzLjk1MjMgMi4xNjg2OCAyMy44NDc4IDEuOTE2NDIgMjMuNjYxOCAxLjczMDQzQzIzLjQ3NTggMS41NDQ0NSAyMy4yMjM1IDEuNDM5OTYgMjIuOTYwNSAxLjQzOTk2WlwiIGZpbGw9XCIjMzNDNDgxXCI+PC9wYXRoPjxwYXRoIGQ9XCJNMTUuMDI0MyAxMS44NTZINi4wOTYzMVYyMS4yODAyQzYuMDk2MzEgMjEuNTQzMyA2LjIwMDc3IDIxLjc5NTUgNi4zODY3NyAyMS45ODE1QzYuNTcyNzcgMjIuMTY3NSA2LjgyNTAxIDIyLjI3MiA3LjA4ODA1IDIyLjI3MkgyMi45NjA2QzIzLjIyMzYgMjIuMjcyIDIzLjQ3NTkgMjIuMTY3NSAyMy42NjE4IDIxLjk4MTVDMjMuODQ3OCAyMS43OTU1IDIzLjk1MjMgMjEuNTQzMyAyMy45NTIzIDIxLjI4MDJWMTcuMDY0TDE1LjAyNDMgMTEuODU2WlwiIGZpbGw9XCIjMTg1QzM3XCI+PC9wYXRoPjxwYXRoIGQ9XCJNMTUuMDI0MyAxMS44NTZIMjMuOTUyM1YxNy4wNjRIMTUuMDI0M1YxMS44NTZaXCIgZmlsbD1cIiMxMDdDNDFcIj48L3BhdGg+PHBhdGggb3BhY2l0eT1cIjAuMVwiIGQ9XCJNMTIuNTQ0NiA1LjE1OTk2SDYuMDk2MzFWMTkuMjk2SDEyLjU0NDZDMTIuODA3MyAxOS4yOTUyIDEzLjA1OTEgMTkuMTkwNCAxMy4yNDUgMTkuMDA0NkMxMy40MzA4IDE4LjgxODggMTMuNTM1NSAxOC41NjcgMTMuNTM2MyAxOC4zMDQyVjYuMTUxN0MxMy41MzU1IDUuODg4OTIgMTMuNDMwOCA1LjYzNzEyIDEzLjI0NSA1LjQ1MTNDMTMuMDU5MSA1LjI2NTQ4IDEyLjgwNzMgNS4xNjA3NCAxMi41NDQ2IDUuMTU5OTZaXCIgZmlsbD1cImJsYWNrXCI+PC9wYXRoPjxwYXRoIG9wYWNpdHk9XCIwLjJcIiBkPVwiTTExLjgwMDYgNS45MDM5Nkg2LjA5NjMxVjIwLjA0SDExLjgwMDZDMTIuMDYzMyAyMC4wMzkyIDEyLjMxNTEgMTkuOTM0NCAxMi41MDEgMTkuNzQ4NkMxMi42ODY4IDE5LjU2MjggMTIuNzkxNSAxOS4zMTEgMTIuNzkyMyAxOS4wNDgyVjYuODk1N0MxMi43OTE1IDYuNjMyOSAxMi42ODY4IDYuMzgxMTQgMTIuNTAxIDYuMTk1MzJDMTIuMzE1MSA2LjAwOTUgMTIuMDYzMyA1LjkwNDc1IDExLjgwMDYgNS45MDM5NlpcIiBmaWxsPVwiYmxhY2tcIj48L3BhdGg+PHBhdGggb3BhY2l0eT1cIjAuMlwiIGQ9XCJNMTEuODAwNiA1LjkwMzk2SDYuMDk2MzFWMTguNTUySDExLjgwMDZDMTIuMDYzMyAxOC41NTEyIDEyLjMxNTEgMTguNDQ2NCAxMi41MDEgMTguMjYwNkMxMi42ODY4IDE4LjA3NDggMTIuNzkxNSAxNy44MjMgMTIuNzkyMyAxNy41NjAyVjYuODk1N0MxMi43OTE1IDYuNjMyOSAxMi42ODY4IDYuMzgxMTQgMTIuNTAxIDYuMTk1MzJDMTIuMzE1MSA2LjAwOTUgMTIuMDYzMyA1LjkwNDc1IDExLjgwMDYgNS45MDM5NlpcIiBmaWxsPVwiYmxhY2tcIj48L3BhdGg+PHBhdGggb3BhY2l0eT1cIjAuMlwiIGQ9XCJNMTEuMDU2NiA1LjkwMzk2SDYuMDk2MzFWMTguNTUySDExLjA1NjZDMTEuMzE5MyAxOC41NTEyIDExLjU3MTEgMTguNDQ2NCAxMS43NTcgMTguMjYwNkMxMS45NDI4IDE4LjA3NDggMTIuMDQ3NSAxNy44MjMgMTIuMDQ4MyAxNy41NjAyVjYuODk1N0MxMi4wNDc1IDYuNjMyOSAxMS45NDI4IDYuMzgxMTQgMTEuNzU3IDYuMTk1MzJDMTEuNTcxMSA2LjAwOTUgMTEuMzE5MyA1LjkwNDc1IDExLjA1NjYgNS45MDM5NlpcIiBmaWxsPVwiYmxhY2tcIj48L3BhdGg+PHBhdGggZD1cIk0xLjEzNjA0IDUuOTAzOTZIMTEuMDU2NkMxMS4zMTk1IDUuOTAzOTYgMTEuNTcxOCA2LjAwODQyIDExLjc1NzggNi4xOTQ0MkMxMS45NDM4IDYuMzgwNDIgMTIuMDQ4MyA2LjYzMjY2IDEyLjA0ODMgNi44OTU3VjE2LjgxNjJDMTIuMDQ4MyAxNy4wNzkzIDExLjk0MzggMTcuMzMxNSAxMS43NTc4IDE3LjUxNzVDMTEuNTcxOCAxNy43MDM1IDExLjMxOTUgMTcuODA4IDExLjA1NjYgMTcuODA4SDEuMTM2MDRDMC44NzMwMTIgMTcuODA4IDAuNjIwNzU0IDE3LjcwMzUgMC40MzQ3NjUgMTcuNTE3NUMwLjI0ODc3NSAxNy4zMzE1IDAuMTQ0Mjg3IDE3LjA3OTMgMC4xNDQyODcgMTYuODE2MlY2Ljg5NTdDMC4xNDQyODcgNi42MzI2NiAwLjI0ODc3NSA2LjM4MDQyIDAuNDM0NzY1IDYuMTk0NDJDMC42MjA3NTQgNi4wMDg0MiAwLjg3MzAxMiA1LjkwMzk2IDEuMTM2MDQgNS45MDM5NlpcIiBmaWxsPVwiIzEwN0M0MVwiPjwvcGF0aD48cGF0aCBkPVwiTTIuNzcyODMgMTUuNTc2TDUuMTgwNDEgMTEuODQ1NUwyLjk3NTIgOC4xMzU5Nkg0Ljc0OTY0TDUuOTUzNDMgMTAuNTA3MUM2LjA2NDAxIDEwLjczMTggNi4xNDAxNSAxMC44OTk0IDYuMTgxODUgMTEuMDFINi4xOTc0NUM2LjI3NjgzIDEwLjgzMDUgNi4zNTk4NyAxMC42NTU5IDYuNDQ2NjkgMTAuNDg2M0w3LjczMzA5IDguMTM1OTZIOS4zNjE2N0w3LjA5OTkxIDExLjgyNDdMOS40MTg5NyAxNS41NzZINy42ODU0NUw2LjI5NDg5IDEyLjk3MkM2LjIyOTQzIDEyLjg2MSA2LjE3Mzg3IDEyLjc0NDUgNi4xMjg5OSAxMi42MjM4SDYuMTA4MTdDNi4wNjc2MSAxMi43NDE5IDYuMDEzNjcgMTIuODU1IDUuOTQ3NDggMTIuOTYwOEw0LjUxNjc2IDE1LjU3NkgyLjc3MjgzWlwiIGZpbGw9XCJ3aGl0ZVwiPjwvcGF0aD48L3N2Zz4nLGNsYXNzOlwic2hyaW5rLTAgc2l6ZS01XCJ9LGRvYzp7aWNvbjonPHN2ZyB3aWR0aD1cIjMyXCIgaGVpZ2h0PVwiMzJcIiB2aWV3Qm94PVwiMCAwIDMyIDMyXCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+PHBhdGggZD1cIk0zMC42MTQxIDEuOTE5OTRIOS40NTA3MUM5LjA5OTk5IDEuOTE5OTQgOC43NjM2NyAyLjA1OTI2IDguNTE1NjcgMi4zMDcyNUM4LjI2NzY3IDIuNTU1MjMgOC4xMjgzOSAyLjg5MTU4IDguMTI4MzkgMy4yNDIyOFY4Ljg2Mzk1TDIwLjAzMjQgMTIuMzM1OUwzMS45MzY0IDguODYzOTVWMy4yNDIyOEMzMS45MzY0IDIuODkxNTggMzEuNzk3IDIuNTU1MjMgMzEuNTQ5IDIuMzA3MjVDMzEuMzAxMSAyLjA1OTI2IDMwLjk2NDcgMS45MTk5NCAzMC42MTQxIDEuOTE5OTRaXCIgZmlsbD1cIiM0MUE1RUVcIj48L3BhdGg+PHBhdGggZD1cIk0zMS45MzY0IDguODYzOTVIOC4xMjgzOVYxNS44MDc5TDIwLjAzMjQgMTkuMjc5OUwzMS45MzY0IDE1LjgwNzlWOC44NjM5NVpcIiBmaWxsPVwiIzJCN0NEM1wiPjwvcGF0aD48cGF0aCBkPVwiTTMxLjkzNjQgMTUuODA3OUg4LjEyODM5VjIyLjc1MTlMMjAuMDMyNCAyNi4yMjM5TDMxLjkzNjQgMjIuNzUxOVYxNS44MDc5WlwiIGZpbGw9XCIjMTg1QUJEXCI+PC9wYXRoPjxwYXRoIGQ9XCJNMzEuOTM2NCAyMi43NTJIOC4xMjgzOVYyOC4zNzM2QzguMTI4MzkgMjguNzI0NCA4LjI2NzY3IDI5LjA2MDcgOC41MTU2NyAyOS4zMDg3QzguNzYzNjcgMjkuNTU2NyA5LjA5OTk5IDI5LjY5NiA5LjQ1MDcxIDI5LjY5NkgzMC42MTQxQzMwLjk2NDcgMjkuNjk2IDMxLjMwMTEgMjkuNTU2NyAzMS41NDkgMjkuMzA4N0MzMS43OTcgMjkuMDYwNyAzMS45MzY0IDI4LjcyNDQgMzEuOTM2NCAyOC4zNzM2VjIyLjc1MlpcIiBmaWxsPVwiIzEwM0Y5MVwiPjwvcGF0aD48cGF0aCBvcGFjaXR5PVwiMC4xXCIgZD1cIk0xNi43MjYxIDYuODc5OTRIOC4xMjgzOVYyNS43Mjc5SDE2LjcyNjFDMTcuMDc2NCAyNS43MjY5IDE3LjQxMjEgMjUuNTg3MiAxNy42NTk5IDI1LjMzOTVDMTcuOTA3NyAyNS4wOTE3IDE4LjA0NzMgMjQuNzU2IDE4LjA0ODQgMjQuNDA1NlY4LjIwMjI2QzE4LjA0NzMgNy44NTE5IDE3LjkwNzcgNy41MTYxNiAxNy42NTk5IDcuMjY4NEMxNy40MTIxIDcuMDIwNjQgMTcuMDc2NCA2Ljg4MDk5IDE2LjcyNjEgNi44Nzk5NFpcIiBjbGFzcz1cImZpbGwtYmxhY2tcIiBmaWxsPVwiY3VycmVudENvbG9yXCI+PC9wYXRoPjxwYXRoIG9wYWNpdHk9XCIwLjJcIiBkPVwiTTE1LjczNDEgNy44NzE5NEg4LjEyODM5VjI2LjcxOTlIMTUuNzM0MUMxNi4wODQ0IDI2LjcxODkgMTYuNDIwMSAyNi41NzkyIDE2LjY2NzkgMjYuMzMxNUMxNi45MTU3IDI2LjA4MzcgMTcuMDU1MyAyNS43NDggMTcuMDU2NCAyNS4zOTc2VjkuMTk0MjZDMTcuMDU1MyA4Ljg0Mzg2IDE2LjkxNTcgOC41MDgxOCAxNi42Njc5IDguMjYwNDJDMTYuNDIwMSA4LjAxMjY2IDE2LjA4NDQgNy44NzI5OSAxNS43MzQxIDcuODcxOTRaXCIgY2xhc3M9XCJmaWxsLWJsYWNrXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiPjwvcGF0aD48cGF0aCBvcGFjaXR5PVwiMC4yXCIgZD1cIk0xNS43MzQxIDcuODcxOTRIOC4xMjgzOVYyNC43MzU5SDE1LjczNDFDMTYuMDg0NCAyNC43MzQ5IDE2LjQyMDEgMjQuNTk1MiAxNi42Njc5IDI0LjM0NzVDMTYuOTE1NyAyNC4wOTk3IDE3LjA1NTMgMjMuNzY0IDE3LjA1NjQgMjMuNDEzNlY5LjE5NDI2QzE3LjA1NTMgOC44NDM4NiAxNi45MTU3IDguNTA4MTggMTYuNjY3OSA4LjI2MDQyQzE2LjQyMDEgOC4wMTI2NiAxNi4wODQ0IDcuODcyOTkgMTUuNzM0MSA3Ljg3MTk0WlwiIGNsYXNzPVwiZmlsbC1ibGFja1wiIGZpbGw9XCJjdXJyZW50Q29sb3JcIj48L3BhdGg+PHBhdGggb3BhY2l0eT1cIjAuMlwiIGQ9XCJNMTQuNzQyMSA3Ljg3MTk0SDguMTI4MzlWMjQuNzM1OUgxNC43NDIxQzE1LjA5MjQgMjQuNzM0OSAxNS40MjgxIDI0LjU5NTIgMTUuNjc1OSAyNC4zNDc1QzE1LjkyMzcgMjQuMDk5NyAxNi4wNjMzIDIzLjc2NCAxNi4wNjQ0IDIzLjQxMzZWOS4xOTQyNkMxNi4wNjMzIDguODQzODYgMTUuOTIzNyA4LjUwODE4IDE1LjY3NTkgOC4yNjA0MkMxNS40MjgxIDguMDEyNjYgMTUuMDkyNCA3Ljg3Mjk5IDE0Ljc0MjEgNy44NzE5NFpcIiBjbGFzcz1cImZpbGwtYmxhY2tcIiBmaWxsPVwiY3VycmVudENvbG9yXCI+PC9wYXRoPjxwYXRoIGQ9XCJNMS41MTQ3MiA3Ljg3MTk0SDE0Ljc0MjFDMTUuMDkyNyA3Ljg3MTk0IDE1LjQyOTEgOC4wMTEyMiAxNS42NzcxIDguMjU5MjJDMTUuOTI1IDguNTA3MjIgMTYuMDY0NCA4Ljg0MzU0IDE2LjA2NDQgOS4xOTQyNlYyMi40MjE2QzE2LjA2NDQgMjIuNzcyMyAxNS45MjUgMjMuMTA4NyAxNS42NzcxIDIzLjM1NjdDMTUuNDI5MSAyMy42MDQ3IDE1LjA5MjcgMjMuNzQzOSAxNC43NDIxIDIzLjc0MzlIMS41MTQ3MkMxLjE2NDAxIDIzLjc0MzkgMC44Mjc2NjkgMjMuNjA0NyAwLjU3OTY4NyAyMy4zNTY3QzAuMzMxNyAyMy4xMDg3IDAuMTkyMzgzIDIyLjc3MjMgMC4xOTIzODMgMjIuNDIxNlY5LjE5NDI2QzAuMTkyMzgzIDguODQzNTQgMC4zMzE3IDguNTA3MjIgMC41Nzk2ODcgOC4yNTkyMkMwLjgyNzY2OSA4LjAxMTIyIDEuMTY0MDEgNy44NzE5NCAxLjUxNDcyIDcuODcxOTRaXCIgZmlsbD1cIiMxODVBQkRcIj48L3BhdGg+PHBhdGggZD1cIk0xMi4wNDY4IDIwLjc2NzlIMTAuMjYxMkw4LjE3ODAxIDEzLjkyMzFMNS45OTU1OCAyMC43Njc5SDQuMjA5OThMMi4yMjU5OCAxMC44NDc5SDQuMDExNThMNS40MDAzOCAxNy43OTE5TDcuNDgzNTggMTEuMDQ2M0g4Ljk3MTYxTDEwLjk1NTYgMTcuNzkxOUwxMi4zNDQ0IDEwLjg0NzlIMTQuMDMwOEwxMi4wNDY4IDIwLjc2NzlaXCIgZmlsbD1cIndoaXRlXCI+PC9wYXRoPjwvc3ZnPicsY2xhc3M6XCJzaHJpbmstMCBzaXplLTVcIn0semlwOntpY29uOic8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCI+PHBhdGggZD1cIk0xNiAyMmgyYTIgMiAwIDAgMCAyLTJWN2wtNS01SDZhMiAyIDAgMCAwLTIgMnYxOFwiLz48cGF0aCBkPVwiTTE0IDJ2NGEyIDIgMCAwIDAgMiAyaDRcIi8+PGNpcmNsZSBjeD1cIjEwXCIgY3k9XCIyMFwiIHI9XCIyXCIvPjxwYXRoIGQ9XCJNMTAgN1Y2XCIvPjxwYXRoIGQ9XCJNMTAgMTJ2LTFcIi8+PHBhdGggZD1cIk0xMCAxOHYtMlwiLz48L3N2Zz4nLGNsYXNzOlwic2hyaW5rLTAgc2l6ZS01XCJ9fSxvLmV4dGVuc2lvbnMpLHRoaXMuc2luZ2xldG9uPW8uc2luZ2xldG9uLHRoaXMuY29uY2F0T3B0aW9ucz1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe2NsaWNrYWJsZTp0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC10cmlnZ2VyXVwiKSxwcmV2aWV3c0NvbnRhaW5lcjp0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC1wcmV2aWV3c11cIiksYWRkUmVtb3ZlTGlua3M6ITEscHJldmlld1RlbXBsYXRlOnRoaXMucHJldmlld1RlbXBsYXRlLGF1dG9IaWRlVHJpZ2dlcjohMX0sbyksdCksdGhpcy5vblJlbG9hZEJ1dHRvbkNsaWNrTGlzdGVuZXI9W10sdGhpcy5vblRlbXBGaWxlSW5wdXRDaGFuZ2VMaXN0ZW5lcj1bXSx0aGlzLmluaXQoKX10ZW1wRmlsZUlucHV0Q2hhbmdlKGUsdCl7dmFyIGk7Y29uc3Qgcz1udWxsPT09KGk9ZS50YXJnZXQuZmlsZXMpfHx2b2lkIDA9PT1pP3ZvaWQgMDppWzBdO2lmKHMpe2NvbnN0IGU9cztlLnN0YXR1cz1Ecm9wem9uZS5BRERFRCxlLmFjY2VwdGVkPSEwLGUucHJldmlld0VsZW1lbnQ9dC5wcmV2aWV3RWxlbWVudCxlLnByZXZpZXdUZW1wbGF0ZT10LnByZXZpZXdUZW1wbGF0ZSxlLnByZXZpZXdzQ29udGFpbmVyPXQucHJldmlld3NDb250YWluZXIsdGhpcy5kcm9wem9uZS5yZW1vdmVGaWxlKHQpLHRoaXMuZHJvcHpvbmUuYWRkRmlsZShlKX19cmVsb2FkQnV0dG9uQ2xpY2soZSx0KXtlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKTtjb25zdCBpPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtpLnR5cGU9XCJmaWxlXCIsdGhpcy5vblRlbXBGaWxlSW5wdXRDaGFuZ2VMaXN0ZW5lci5wdXNoKHtlbDppLGZuOmU9PnRoaXMudGVtcEZpbGVJbnB1dENoYW5nZShlLHQpfSksaS5jbGljaygpLGkuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLHRoaXMub25UZW1wRmlsZUlucHV0Q2hhbmdlTGlzdGVuZXIuZmluZCgoZT0+ZS5lbD09PWkpKS5mbil9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzRmlsZVVwbG9hZENvbGxlY3Rpb24sdGhpcyksdGhpcy5pbml0RHJvcHpvbmUoKX1pbml0RHJvcHpvbmUoKXtjb25zdCBlPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLWZpbGUtdXBsb2FkLWNsZWFyXVwiKSx0PUFycmF5LmZyb20odGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtZmlsZS11cGxvYWQtcHNldWRvLXRyaWdnZXJdXCIpKTt0aGlzLmRyb3B6b25lPW5ldyBEcm9wem9uZSh0aGlzLmVsLHRoaXMuY29uY2F0T3B0aW9ucyksdGhpcy5kcm9wem9uZS5vbihcImFkZGVkZmlsZVwiLChlPT50aGlzLm9uQWRkRmlsZShlKSkpLHRoaXMuZHJvcHpvbmUub24oXCJyZW1vdmVkZmlsZVwiLCgoKT0+dGhpcy5vblJlbW92ZUZpbGUoKSkpLHRoaXMuZHJvcHpvbmUub24oXCJ1cGxvYWRwcm9ncmVzc1wiLCgoZSx0KT0+dGhpcy5vblVwbG9hZFByb2dyZXNzKGUsdCkpKSx0aGlzLmRyb3B6b25lLm9uKFwiY29tcGxldGVcIiwoZT0+dGhpcy5vbkNvbXBsZXRlKGUpKSksZSYmKGUub25jbGljaz0oKT0+e3RoaXMuZHJvcHpvbmUuZmlsZXMubGVuZ3RoJiZ0aGlzLmRyb3B6b25lLnJlbW92ZUFsbEZpbGVzKCEwKX0pLHQubGVuZ3RoJiZ0LmZvckVhY2goKGU9PntlLm9uY2xpY2s9KCk9Pnt2YXIgZSx0OyhudWxsPT09KGU9dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5jbGlja2FibGUpJiYobnVsbD09PSh0PXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PXQ/dm9pZCAwOnQuY2xpY2thYmxlKS5jbGljaygpfX0pKX1kZXN0cm95KCl7dGhpcy5vblRlbXBGaWxlSW5wdXRDaGFuZ2VMaXN0ZW5lci5mb3JFYWNoKChlPT57ZS5lbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsZS5mbil9KSksdGhpcy5vblRlbXBGaWxlSW5wdXRDaGFuZ2VMaXN0ZW5lcj1udWxsLHRoaXMub25SZWxvYWRCdXR0b25DbGlja0xpc3RlbmVyLmZvckVhY2goKGU9PntlLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLGUuZm4pfSkpLHRoaXMub25SZWxvYWRCdXR0b25DbGlja0xpc3RlbmVyPW51bGwsdGhpcy5kcm9wem9uZS5kZXN0cm95KCksd2luZG93LiRoc0ZpbGVVcGxvYWRDb2xsZWN0aW9uPXdpbmRvdy4kaHNGaWxlVXBsb2FkQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9b25BZGRGaWxlKGUpe2NvbnN0e3ByZXZpZXdFbGVtZW50OnR9PWUsaT1lLnByZXZpZXdFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC1yZWxvYWRdXCIpO2lmKCF0KXJldHVybiExO3RoaXMuc2luZ2xldG9uJiZ0aGlzLmRyb3B6b25lLmZpbGVzLmxlbmd0aD4xJiZ0aGlzLmRyb3B6b25lLnJlbW92ZUZpbGUodGhpcy5kcm9wem9uZS5maWxlc1swXSksaSYmKHRoaXMub25SZWxvYWRCdXR0b25DbGlja0xpc3RlbmVyLnB1c2goe2VsOmksZm46dD0+dGhpcy5yZWxvYWRCdXR0b25DbGljayh0LGUpfSksaS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uUmVsb2FkQnV0dG9uQ2xpY2tMaXN0ZW5lci5maW5kKChlPT5lLmVsPT09aSkpLmZuKSksdGhpcy5wcmV2aWV3QWNjZXB0ZWQoZSl9cHJldmlld0FjY2VwdGVkKGUpe2NvbnN0e3ByZXZpZXdFbGVtZW50OnR9PWUsaT10aGlzLnNwbGl0RmlsZU5hbWUoZS5uYW1lKSxzPXQucXVlcnlTZWxlY3RvcihcIltkYXRhLWZpbGUtdXBsb2FkLWZpbGUtbmFtZV1cIiksbj10LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC1maWxlLWV4dF1cIiksbz10LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC1maWxlLXNpemVdXCIpLGw9dC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZmlsZS11cGxvYWQtZmlsZS1pY29uXVwiKSxyPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLWZpbGUtdXBsb2FkLXRyaWdnZXJdXCIpLGE9dC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZHotdGh1bWJuYWlsXVwiKSxjPXQucXVlcnlTZWxlY3RvcihcIltkYXRhLWZpbGUtdXBsb2FkLXJlbW92ZV1cIik7cyYmKHMudGV4dENvbnRlbnQ9aS5uYW1lKSxuJiYobi50ZXh0Q29udGVudD1pLmV4dGVuc2lvbiksbyYmKG8udGV4dENvbnRlbnQ9dGhpcy5mb3JtYXRGaWxlU2l6ZShlLnNpemUpKSxhJiYoZS50eXBlLmluY2x1ZGVzKFwiaW1hZ2UvXCIpP2EuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKTp0aGlzLnNldEljb24oaS5leHRlbnNpb24sbCkpLHRoaXMuZHJvcHpvbmUuZmlsZXMubGVuZ3RoPjAmJnRoaXMuY29uY2F0T3B0aW9ucy5hdXRvSGlkZVRyaWdnZXImJihyLnN0eWxlLmRpc3BsYXk9XCJub25lXCIpLGMmJihjLm9uY2xpY2s9KCk9PnRoaXMuZHJvcHpvbmUucmVtb3ZlRmlsZShlKSl9b25SZW1vdmVGaWxlKCl7Y29uc3QgZT10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC10cmlnZ2VyXVwiKTswPT09dGhpcy5kcm9wem9uZS5maWxlcy5sZW5ndGgmJnRoaXMuY29uY2F0T3B0aW9ucy5hdXRvSGlkZVRyaWdnZXImJihlLnN0eWxlLmRpc3BsYXk9XCJcIil9b25VcGxvYWRQcm9ncmVzcyhlLHQpe2NvbnN0e3ByZXZpZXdFbGVtZW50Oml9PWU7aWYoIWkpcmV0dXJuITE7Y29uc3Qgcz1pLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1maWxlLXVwbG9hZC1wcm9ncmVzcy1iYXJdXCIpLG49aS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZmlsZS11cGxvYWQtcHJvZ3Jlc3MtYmFyLXBhbmVdXCIpLG89aS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZmlsZS11cGxvYWQtcHJvZ3Jlc3MtYmFyLXZhbHVlXVwiKSxsPU1hdGguZmxvb3IodCk7cyYmcy5zZXRBdHRyaWJ1dGUoXCJhcmlhLXZhbHVlbm93XCIsYCR7bH1gKSxuJiYobi5zdHlsZS53aWR0aD1gJHtsfSVgKSxvJiYoby5pbm5lclRleHQ9YCR7bH1gKX1vbkNvbXBsZXRlKGUpe2NvbnN0e3ByZXZpZXdFbGVtZW50OnR9PWU7aWYoIXQpcmV0dXJuITE7dC5jbGFzc0xpc3QuYWRkKFwiY29tcGxldGVcIil9c2V0SWNvbihlLHQpe2NvbnN0IGk9dGhpcy5jcmVhdGVJY29uKGUpO3QuYXBwZW5kKGkpfWNyZWF0ZUljb24oZSl7dmFyIHQsaTtjb25zdCBzPShudWxsPT09KHQ9dGhpcy5leHRlbnNpb25zW2VdKXx8dm9pZCAwPT09dD92b2lkIDA6dC5pY29uKT8oMCxuLmh0bWxUb0VsZW1lbnQpKHRoaXMuZXh0ZW5zaW9uc1tlXS5pY29uKTooMCxuLmh0bWxUb0VsZW1lbnQpKHRoaXMuZXh0ZW5zaW9ucy5kZWZhdWx0Lmljb24pO3JldHVybigwLG4uY2xhc3NUb0NsYXNzTGlzdCkoKG51bGw9PT0oaT10aGlzLmV4dGVuc2lvbnNbZV0pfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmNsYXNzKT90aGlzLmV4dGVuc2lvbnNbZV0uY2xhc3M6dGhpcy5leHRlbnNpb25zLmRlZmF1bHQuY2xhc3Mscyksc31mb3JtYXRGaWxlU2l6ZShlKXtyZXR1cm4gZTwxMDI0P2UudG9GaXhlZCgyKStcIiBCXCI6ZTwxMDQ4NTc2PyhlLzEwMjQpLnRvRml4ZWQoMikrXCIgS0JcIjplPDEwNzM3NDE4MjQ/KGUvMTA0ODU3NikudG9GaXhlZCgyKStcIiBNQlwiOmU8MTA5OTUxMTYyNzc3Nj8oZS8xMDczNzQxODI0KS50b0ZpeGVkKDIpK1wiIEdCXCI6KGUvMTA5OTUxMTYyNzc3NikudG9GaXhlZCgyKStcIiBUQlwifXNwbGl0RmlsZU5hbWUoZSl7bGV0IHQ9ZS5sYXN0SW5kZXhPZihcIi5cIik7cmV0dXJuLTE9PXQ/e25hbWU6ZSxleHRlbnNpb246XCJcIn06e25hbWU6ZS5zdWJzdHJpbmcoMCx0KSxleHRlbnNpb246ZS5zdWJzdHJpbmcodCsxKX19c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzRmlsZVVwbG9hZENvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50LmVsOm51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0ZpbGVVcGxvYWRDb2xsZWN0aW9ufHwod2luZG93LiRoc0ZpbGVVcGxvYWRDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzRmlsZVVwbG9hZENvbGxlY3Rpb24mJih3aW5kb3cuJGhzRmlsZVVwbG9hZENvbGxlY3Rpb249d2luZG93LiRoc0ZpbGVVcGxvYWRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWZpbGUtdXBsb2FkXTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmZvckVhY2goKGU9Pnt3aW5kb3cuJGhzRmlsZVVwbG9hZENvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgbChlKX0pKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWZpbGUtdXBsb2FkXTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmxlbmd0aCYmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBfJiZjb25zb2xlLmVycm9yKFwiSFNGaWxlVXBsb2FkOiBMb2Rhc2ggaXMgbm90IGF2YWlsYWJsZSwgcGxlYXNlIGFkZCBpdCB0byB0aGUgcGFnZS5cIiksXCJ1bmRlZmluZWRcIj09dHlwZW9mIERyb3B6b25lJiZjb25zb2xlLmVycm9yKFwiSFNGaWxlVXBsb2FkOiBEcm9wem9uZSBpcyBub3QgYXZhaWxhYmxlLCBwbGVhc2UgYWRkIGl0IHRvIHRoZSBwYWdlLlwiKSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIF8mJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBEcm9wem9uZSYmbC5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNGaWxlVXBsb2FkPWwpLHQuZGVmYXVsdD1sfSwyMDc6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTU3Ryb25nUGFzc3dvcmRcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1pKDgwNiksbz1zKGkoMjg3KSk7Y2xhc3MgbCBleHRlbmRzIG8uZGVmYXVsdHtjb25zdHJ1Y3RvcihlLHQpe3N1cGVyKGUsdCksdGhpcy5pc09wZW5lZD0hMSx0aGlzLnN0cmVuZ3RoPTAsdGhpcy5wYXNzZWRSdWxlcz1uZXcgU2V0O2NvbnN0IGk9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXN0cm9uZy1wYXNzd29yZFwiKSxzPWk/SlNPTi5wYXJzZShpKTp7fSxuPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KTt0aGlzLnRhcmdldD0obnVsbD09bj92b2lkIDA6bi50YXJnZXQpP1wic3RyaW5nXCI9PXR5cGVvZihudWxsPT1uP3ZvaWQgMDpuLnRhcmdldCk/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihuLnRhcmdldCk6bi50YXJnZXQ6bnVsbCx0aGlzLmhpbnRzPShudWxsPT1uP3ZvaWQgMDpuLmhpbnRzKT9cInN0cmluZ1wiPT10eXBlb2YobnVsbD09bj92b2lkIDA6bi5oaW50cyk/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihuLmhpbnRzKTpuLmhpbnRzOm51bGwsdGhpcy5zdHJpcENsYXNzZXM9KG51bGw9PW4/dm9pZCAwOm4uc3RyaXBDbGFzc2VzKXx8bnVsbCx0aGlzLm1pbkxlbmd0aD0obnVsbD09bj92b2lkIDA6bi5taW5MZW5ndGgpfHw2LHRoaXMubW9kZT0obnVsbD09bj92b2lkIDA6bi5tb2RlKXx8XCJkZWZhdWx0XCIsdGhpcy5wb3BvdmVyU3BhY2U9KG51bGw9PW4/dm9pZCAwOm4ucG9wb3ZlclNwYWNlKXx8MTAsdGhpcy5jaGVja3NFeGNsdWRlPShudWxsPT1uP3ZvaWQgMDpuLmNoZWNrc0V4Y2x1ZGUpfHxbXSx0aGlzLmF2YWlsYWJsZUNoZWNrcz1bXCJsb3dlcmNhc2VcIixcInVwcGVyY2FzZVwiLFwibnVtYmVyc1wiLFwic3BlY2lhbC1jaGFyYWN0ZXJzXCIsXCJtaW4tbGVuZ3RoXCJdLmZpbHRlcigoZT0+IXRoaXMuY2hlY2tzRXhjbHVkZS5pbmNsdWRlcyhlKSkpLHRoaXMuc3BlY2lhbENoYXJhY3RlcnNTZXQ9KG51bGw9PW4/dm9pZCAwOm4uc3BlY2lhbENoYXJhY3RlcnNTZXQpfHxcIiFcXFwiIyQlJicoKSorLC0uLzo7PD0+P0BbXFxcXFxcXFxcXFxcXV5fYHt8fX5cIix0aGlzLnRhcmdldCYmdGhpcy5pbml0KCl9dGFyZ2V0SW5wdXQoZSl7dGhpcy5zZXRTdHJlbmd0aChlLnRhcmdldC52YWx1ZSl9dGFyZ2V0Rm9jdXMoKXt0aGlzLmlzT3BlbmVkPSEwLHRoaXMuaGludHMuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKSx0aGlzLmhpbnRzLmNsYXNzTGlzdC5hZGQoXCJibG9ja1wiKSx0aGlzLnJlY2FsY3VsYXRlRGlyZWN0aW9uKCl9dGFyZ2V0Qmx1cigpe3RoaXMuaXNPcGVuZWQ9ITEsdGhpcy5oaW50cy5jbGFzc0xpc3QucmVtb3ZlKFwiYmxvY2tcIixcImJvdHRvbS1mdWxsXCIsXCJ0b3AtZnVsbFwiKSx0aGlzLmhpbnRzLmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIiksdGhpcy5oaW50cy5zdHlsZS5tYXJnaW5Ub3A9XCJcIix0aGlzLmhpbnRzLnN0eWxlLm1hcmdpbkJvdHRvbT1cIlwifXRhcmdldElucHV0U2Vjb25kKCl7dGhpcy5zZXRXZWFrbmVzc1RleHQoKX10YXJnZXRJbnB1dFRoaXJkKCl7dGhpcy5zZXRSdWxlc1RleHQoKX1pbml0KCl7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNTdHJvbmdQYXNzd29yZENvbGxlY3Rpb24sdGhpcyksdGhpcy5hdmFpbGFibGVDaGVja3MubGVuZ3RoJiZ0aGlzLmJ1aWxkKCl9YnVpbGQoKXt0aGlzLmJ1aWxkU3RyaXBzKCksdGhpcy5oaW50cyYmdGhpcy5idWlsZEhpbnRzKCksdGhpcy5zZXRTdHJlbmd0aCh0aGlzLnRhcmdldC52YWx1ZSksdGhpcy5vblRhcmdldElucHV0TGlzdGVuZXI9ZT0+dGhpcy50YXJnZXRJbnB1dChlKSx0aGlzLnRhcmdldC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uVGFyZ2V0SW5wdXRMaXN0ZW5lcil9YnVpbGRTdHJpcHMoKXtpZih0aGlzLmVsLmlubmVySFRNTD1cIlwiLHRoaXMuc3RyaXBDbGFzc2VzKWZvcihsZXQgZT0wO2U8dGhpcy5hdmFpbGFibGVDaGVja3MubGVuZ3RoO2UrKyl7Y29uc3QgZT0oMCxuLmh0bWxUb0VsZW1lbnQpKFwiPGRpdj48L2Rpdj5cIik7KDAsbi5jbGFzc1RvQ2xhc3NMaXN0KSh0aGlzLnN0cmlwQ2xhc3NlcyxlKSx0aGlzLmVsLmFwcGVuZChlKX19YnVpbGRIaW50cygpe3RoaXMud2Vha25lc3M9dGhpcy5oaW50cy5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtcHctc3RyZW5ndGgtaGludF1cIil8fG51bGwsdGhpcy5ydWxlcz1BcnJheS5mcm9tKHRoaXMuaGludHMucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXB3LXN0cmVuZ3RoLXJ1bGVdXCIpKXx8bnVsbCx0aGlzLnJ1bGVzLmZvckVhY2goKGU9Pnt2YXIgdDtjb25zdCBpPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1wdy1zdHJlbmd0aC1ydWxlXCIpOyhudWxsPT09KHQ9dGhpcy5jaGVja3NFeGNsdWRlKXx8dm9pZCAwPT09dD92b2lkIDA6dC5pbmNsdWRlcyhpKSkmJmUucmVtb3ZlKCl9KSksdGhpcy53ZWFrbmVzcyYmdGhpcy5idWlsZFdlYWtuZXNzKCksdGhpcy5ydWxlcyYmdGhpcy5idWlsZFJ1bGVzKCksXCJwb3BvdmVyXCI9PT10aGlzLm1vZGUmJih0aGlzLm9uVGFyZ2V0Rm9jdXNMaXN0ZW5lcj0oKT0+dGhpcy50YXJnZXRGb2N1cygpLHRoaXMub25UYXJnZXRCbHVyTGlzdGVuZXI9KCk9PnRoaXMudGFyZ2V0Qmx1cigpLHRoaXMudGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c1wiLHRoaXMub25UYXJnZXRGb2N1c0xpc3RlbmVyKSx0aGlzLnRhcmdldC5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLHRoaXMub25UYXJnZXRCbHVyTGlzdGVuZXIpKX1idWlsZFdlYWtuZXNzKCl7dGhpcy5jaGVja1N0cmVuZ3RoKHRoaXMudGFyZ2V0LnZhbHVlKSx0aGlzLnNldFdlYWtuZXNzVGV4dCgpLHRoaXMub25UYXJnZXRJbnB1dFNlY29uZExpc3RlbmVyPSgpPT5zZXRUaW1lb3V0KCgoKT0+dGhpcy50YXJnZXRJbnB1dFNlY29uZCgpKSksdGhpcy50YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vblRhcmdldElucHV0U2Vjb25kTGlzdGVuZXIpfWJ1aWxkUnVsZXMoKXt0aGlzLnNldFJ1bGVzVGV4dCgpLHRoaXMub25UYXJnZXRJbnB1dFRoaXJkTGlzdGVuZXI9KCk9PnNldFRpbWVvdXQoKCgpPT50aGlzLnRhcmdldElucHV0VGhpcmQoKSkpLHRoaXMudGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLHRoaXMub25UYXJnZXRJbnB1dFRoaXJkTGlzdGVuZXIpfXNldFdlYWtuZXNzVGV4dCgpe2NvbnN0IGU9dGhpcy53ZWFrbmVzcy5nZXRBdHRyaWJ1dGUoXCJkYXRhLXB3LXN0cmVuZ3RoLWhpbnRcIiksdD1KU09OLnBhcnNlKGUpO3RoaXMud2Vha25lc3MudGV4dENvbnRlbnQ9dFt0aGlzLnN0cmVuZ3RoXX1zZXRSdWxlc1RleHQoKXt0aGlzLnJ1bGVzLmZvckVhY2goKGU9Pntjb25zdCB0PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1wdy1zdHJlbmd0aC1ydWxlXCIpO3RoaXMuY2hlY2tJZlBhc3NlZChlLHRoaXMucGFzc2VkUnVsZXMuaGFzKHQpKX0pKX10b2dnbGVQb3BvdmVyKCl7Y29uc3QgZT10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCIucG9wb3ZlclwiKTtlJiZlLmNsYXNzTGlzdC50b2dnbGUoXCJzaG93XCIpfWNoZWNrU3RyZW5ndGgoZSl7Y29uc3QgdD1uZXcgU2V0LGk9e2xvd2VyY2FzZTovW2Etel0rLyx1cHBlcmNhc2U6L1tBLVpdKy8sbnVtYmVyczovWzAtOV0rLyxcInNwZWNpYWwtY2hhcmFjdGVyc1wiOm5ldyBSZWdFeHAoYFske3RoaXMuc3BlY2lhbENoYXJhY3RlcnNTZXR9XWApfTtsZXQgcz0wO3JldHVybiB0aGlzLmF2YWlsYWJsZUNoZWNrcy5pbmNsdWRlcyhcImxvd2VyY2FzZVwiKSYmZS5tYXRjaChpLmxvd2VyY2FzZSkmJihzKz0xLHQuYWRkKFwibG93ZXJjYXNlXCIpKSx0aGlzLmF2YWlsYWJsZUNoZWNrcy5pbmNsdWRlcyhcInVwcGVyY2FzZVwiKSYmZS5tYXRjaChpLnVwcGVyY2FzZSkmJihzKz0xLHQuYWRkKFwidXBwZXJjYXNlXCIpKSx0aGlzLmF2YWlsYWJsZUNoZWNrcy5pbmNsdWRlcyhcIm51bWJlcnNcIikmJmUubWF0Y2goaS5udW1iZXJzKSYmKHMrPTEsdC5hZGQoXCJudW1iZXJzXCIpKSx0aGlzLmF2YWlsYWJsZUNoZWNrcy5pbmNsdWRlcyhcInNwZWNpYWwtY2hhcmFjdGVyc1wiKSYmZS5tYXRjaChpW1wic3BlY2lhbC1jaGFyYWN0ZXJzXCJdKSYmKHMrPTEsdC5hZGQoXCJzcGVjaWFsLWNoYXJhY3RlcnNcIikpLHRoaXMuYXZhaWxhYmxlQ2hlY2tzLmluY2x1ZGVzKFwibWluLWxlbmd0aFwiKSYmZS5sZW5ndGg+PXRoaXMubWluTGVuZ3RoJiYocys9MSx0LmFkZChcIm1pbi1sZW5ndGhcIikpLGUubGVuZ3RofHwocz0wKSxzPT09dGhpcy5hdmFpbGFibGVDaGVja3MubGVuZ3RoP3RoaXMuZWwuY2xhc3NMaXN0LmFkZChcImFjY2VwdGVkXCIpOnRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcImFjY2VwdGVkXCIpLHRoaXMuc3RyZW5ndGg9cyx0aGlzLnBhc3NlZFJ1bGVzPXQse3N0cmVuZ3RoOnRoaXMuc3RyZW5ndGgscnVsZXM6dGhpcy5wYXNzZWRSdWxlc319Y2hlY2tJZlBhc3NlZChlLHQ9ITEpe2NvbnN0IGk9ZS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtY2hlY2tdXCIpLHM9ZS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtdW5jaGVja11cIik7dD8oZS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLGkuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKSxzLmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIikpOihlLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIiksaS5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpLHMuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKSl9c2V0U3RyZW5ndGgoZSl7Y29uc3R7c3RyZW5ndGg6dCxydWxlczppfT10aGlzLmNoZWNrU3RyZW5ndGgoZSkscz17c3RyZW5ndGg6dCxydWxlczppfTt0aGlzLmhpZGVTdHJpcHModCksdGhpcy5maXJlRXZlbnQoXCJjaGFuZ2VcIixzKSwoMCxuLmRpc3BhdGNoKShcImNoYW5nZS5zdHJvbmdQYXNzd29yZFwiLHRoaXMuZWwscyl9aGlkZVN0cmlwcyhlKXtBcnJheS5mcm9tKHRoaXMuZWwuY2hpbGRyZW4pLmZvckVhY2goKCh0LGkpPT57aTxlP3QuY2xhc3NMaXN0LmFkZChcInBhc3NlZFwiKTp0LmNsYXNzTGlzdC5yZW1vdmUoXCJwYXNzZWRcIil9KSl9cmVjYWxjdWxhdGVEaXJlY3Rpb24oKXsoMCxuLmlzRW5vdWdoU3BhY2UpKHRoaXMuaGludHMsdGhpcy50YXJnZXQsXCJib3R0b21cIix0aGlzLnBvcG92ZXJTcGFjZSk/KHRoaXMuaGludHMuY2xhc3NMaXN0LnJlbW92ZShcImJvdHRvbS1mdWxsXCIpLHRoaXMuaGludHMuY2xhc3NMaXN0LmFkZChcInRvcC1mdWxsXCIpLHRoaXMuaGludHMuc3R5bGUubWFyZ2luQm90dG9tPVwiXCIsdGhpcy5oaW50cy5zdHlsZS5tYXJnaW5Ub3A9YCR7dGhpcy5wb3BvdmVyU3BhY2V9cHhgKToodGhpcy5oaW50cy5jbGFzc0xpc3QucmVtb3ZlKFwidG9wLWZ1bGxcIiksdGhpcy5oaW50cy5jbGFzc0xpc3QuYWRkKFwiYm90dG9tLWZ1bGxcIiksdGhpcy5oaW50cy5zdHlsZS5tYXJnaW5Ub3A9XCJcIix0aGlzLmhpbnRzLnN0eWxlLm1hcmdpbkJvdHRvbT1gJHt0aGlzLnBvcG92ZXJTcGFjZX1weGApfWRlc3Ryb3koKXt0aGlzLnRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uVGFyZ2V0SW5wdXRMaXN0ZW5lciksdGhpcy50YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImZvY3VzXCIsdGhpcy5vblRhcmdldEZvY3VzTGlzdGVuZXIpLHRoaXMudGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJibHVyXCIsdGhpcy5vblRhcmdldEJsdXJMaXN0ZW5lciksdGhpcy50YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vblRhcmdldElucHV0U2Vjb25kTGlzdGVuZXIpLHRoaXMudGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLHRoaXMub25UYXJnZXRJbnB1dFRoaXJkTGlzdGVuZXIpLHdpbmRvdy4kaHNTdHJvbmdQYXNzd29yZENvbGxlY3Rpb249d2luZG93LiRoc1N0cm9uZ1Bhc3N3b3JkQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzU3Ryb25nUGFzc3dvcmRDb2xsZWN0aW9uLmZpbmQoKHQ9PnQuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSk7cmV0dXJuIGk/dD9pOmkuZWxlbWVudC5lbDpudWxsfXN0YXRpYyBhdXRvSW5pdCgpe3dpbmRvdy4kaHNTdHJvbmdQYXNzd29yZENvbGxlY3Rpb258fCh3aW5kb3cuJGhzU3Ryb25nUGFzc3dvcmRDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzU3Ryb25nUGFzc3dvcmRDb2xsZWN0aW9uJiYod2luZG93LiRoc1N0cm9uZ1Bhc3N3b3JkQ29sbGVjdGlvbj13aW5kb3cuJGhzU3Ryb25nUGFzc3dvcmRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXN0cm9uZy1wYXNzd29yZF06bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57aWYoIXdpbmRvdy4kaHNTdHJvbmdQYXNzd29yZENvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpKXtjb25zdCB0PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1zdHJvbmctcGFzc3dvcmRcIiksaT10P0pTT04ucGFyc2UodCk6e307bmV3IGwoZSxpKX19KSl9fXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCgoKT0+e2wuYXV0b0luaXQoKX0pKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsKCgpPT57aWYoIXdpbmRvdy4kaHNTdHJvbmdQYXNzd29yZENvbGxlY3Rpb24pcmV0dXJuITE7Y29uc3QgZT13aW5kb3cuJGhzU3Ryb25nUGFzc3dvcmRDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5pc09wZW5lZCkpO2UmJmUuZWxlbWVudC5yZWNhbGN1bGF0ZURpcmVjdGlvbigpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNTdHJvbmdQYXNzd29yZD1sKSx0LmRlZmF1bHQ9bH0sMjEzOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU1N0ZXBwZXJcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1pKDgwNiksbz1zKGkoMjg3KSk7Y2xhc3MgbCBleHRlbmRzIG8uZGVmYXVsdHtjb25zdHJ1Y3RvcihlLHQpe3N1cGVyKGUsdCk7Y29uc3QgaT1lLmdldEF0dHJpYnV0ZShcImRhdGEtc3RlcHBlclwiKSxzPWk/SlNPTi5wYXJzZShpKTp7fSxuPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KTt0aGlzLmN1cnJlbnRJbmRleD0obnVsbD09bj92b2lkIDA6bi5jdXJyZW50SW5kZXgpfHwxLHRoaXMubW9kZT0obnVsbD09bj92b2lkIDA6bi5tb2RlKXx8XCJsaW5lYXJcIix0aGlzLmlzQ29tcGxldGVkPXZvaWQgMCE9PShudWxsPT1uP3ZvaWQgMDpuLmlzQ29tcGxldGVkKSYmKG51bGw9PW4/dm9pZCAwOm4uaXNDb21wbGV0ZWQpLHRoaXMudG90YWxTdGVwcz0xLHRoaXMubmF2SXRlbXM9W10sdGhpcy5jb250ZW50SXRlbXM9W10sdGhpcy5vbk5hdkl0ZW1DbGlja0xpc3RlbmVyPVtdLHRoaXMuaW5pdCgpfW5hdkl0ZW1DbGljayhlKXt0aGlzLmhhbmRsZU5hdkl0ZW1DbGljayhlKX1iYWNrQ2xpY2soKXtpZih0aGlzLmhhbmRsZUJhY2tCdXR0b25DbGljaygpLFwibGluZWFyXCI9PT10aGlzLm1vZGUpe2NvbnN0IGU9dGhpcy5uYXZJdGVtcy5maW5kKCgoe2luZGV4OmV9KT0+ZT09PXRoaXMuY3VycmVudEluZGV4KSksdD10aGlzLmNvbnRlbnRJdGVtcy5maW5kKCgoe2luZGV4OmV9KT0+ZT09PXRoaXMuY3VycmVudEluZGV4KSk7aWYoIWV8fCF0KXJldHVybjtlLmlzQ29tcGxldGVkJiYoZS5pc0NvbXBsZXRlZD0hMSxlLmlzU2tpcD0hMSxlLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJpcy12YWxpZFwiLFwic2tpcHBlZFwiKSksdC5pc0NvbXBsZXRlZCYmKHQuaXNDb21wbGV0ZWQ9ITEsdC5pc1NraXA9ITEsdC5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiaXMtdmFsaWRcIixcInNraXBwZWRcIikpLFwibGluZWFyXCI9PT10aGlzLm1vZGUmJnRoaXMuY3VycmVudEluZGV4IT09dGhpcy50b3RhbFN0ZXBzJiYodGhpcy5uZXh0QnRuJiYodGhpcy5uZXh0QnRuLnN0eWxlLmRpc3BsYXk9XCJcIiksdGhpcy5jb21wbGV0ZVN0ZXBCdG4mJih0aGlzLmNvbXBsZXRlU3RlcEJ0bi5zdHlsZS5kaXNwbGF5PVwiXCIpKSx0aGlzLnNob3dTa2lwQnV0dG9uKCksdGhpcy5zaG93RmluaXNoQnV0dG9uKCksdGhpcy5zaG93Q29tcGxldGVTdGVwQnV0dG9uKCl9fW5leHRDbGljaygpe3ZhciBlO2lmKHRoaXMuZmlyZUV2ZW50KFwiYmVmb3JlTmV4dFwiLHRoaXMuY3VycmVudEluZGV4KSwoMCxuLmRpc3BhdGNoKShcImJlZm9yZU5leHQuc3RlcHBlclwiLHRoaXMuZWwsdGhpcy5jdXJyZW50SW5kZXgpLG51bGw9PT0oZT10aGlzLmdldE5hdkl0ZW0odGhpcy5jdXJyZW50SW5kZXgpKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5pc1Byb2Nlc3NlZClyZXR1cm4gdGhpcy5kaXNhYmxlQWxsKCksITE7dGhpcy5nb1RvTmV4dCgpfXNraXBDbGljaygpe3RoaXMuaGFuZGxlU2tpcEJ1dHRvbkNsaWNrKCksXCJsaW5lYXJcIj09PXRoaXMubW9kZSYmdGhpcy5jdXJyZW50SW5kZXg9PT10aGlzLnRvdGFsU3RlcHMmJih0aGlzLm5leHRCdG4mJih0aGlzLm5leHRCdG4uc3R5bGUuZGlzcGxheT1cIm5vbmVcIiksdGhpcy5jb21wbGV0ZVN0ZXBCdG4mJih0aGlzLmNvbXBsZXRlU3RlcEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwiKSx0aGlzLmZpbmlzaEJ0biYmKHRoaXMuZmluaXNoQnRuLnN0eWxlLmRpc3BsYXk9XCJcIikpfWNvbXBsZXRlU3RlcEJ0bkNsaWNrKCl7dGhpcy5oYW5kbGVDb21wbGV0ZVN0ZXBCdXR0b25DbGljaygpfWZpbmlzaEJ0bkNsaWNrKCl7dmFyIGU7aWYodGhpcy5maXJlRXZlbnQoXCJiZWZvcmVGaW5pc2hcIix0aGlzLmN1cnJlbnRJbmRleCksKDAsbi5kaXNwYXRjaCkoXCJiZWZvcmVGaW5pc2guc3RlcHBlclwiLHRoaXMuZWwsdGhpcy5jdXJyZW50SW5kZXgpLG51bGw9PT0oZT10aGlzLmdldE5hdkl0ZW0odGhpcy5jdXJyZW50SW5kZXgpKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5pc1Byb2Nlc3NlZClyZXR1cm4gdGhpcy5kaXNhYmxlQWxsKCksITE7dGhpcy5oYW5kbGVGaW5pc2hCdXR0b25DbGljaygpfXJlc2V0QnRuQ2xpY2soKXt0aGlzLmhhbmRsZVJlc2V0QnV0dG9uQ2xpY2soKX1pbml0KCl7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNTdGVwcGVyQ29sbGVjdGlvbix0aGlzKSx0aGlzLmJ1aWxkTmF2KCksdGhpcy5idWlsZENvbnRlbnQoKSx0aGlzLmJ1aWxkQnV0dG9ucygpLHRoaXMuc2V0VG90YWxTdGVwcygpfWdldFVuY29tcGxldGVkU3RlcHMoZT0hMSl7cmV0dXJuIHRoaXMubmF2SXRlbXMuZmlsdGVyKCgoe2lzQ29tcGxldGVkOnQsaXNTa2lwOml9KT0+ZT8hdHx8aTohdCYmIWkpKX1zZXRUb3RhbFN0ZXBzKCl7dGhpcy5uYXZJdGVtcy5mb3JFYWNoKChlPT57Y29uc3R7aW5kZXg6dH09ZTt0PnRoaXMudG90YWxTdGVwcyYmKHRoaXMudG90YWxTdGVwcz10KX0pKX1idWlsZE5hdigpe3RoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXN0ZXBwZXItbmF2LWl0ZW1dXCIpLmZvckVhY2goKGU9PnRoaXMuYWRkTmF2SXRlbShlKSkpLHRoaXMubmF2SXRlbXMuZm9yRWFjaCgoZT0+dGhpcy5idWlsZE5hdkl0ZW0oZSkpKX1idWlsZE5hdkl0ZW0oZSl7Y29uc3R7aW5kZXg6dCxpc0Rpc2FibGVkOmksZWw6c309ZTt0PT09dGhpcy5jdXJyZW50SW5kZXgmJnRoaXMuc2V0Q3VycmVudE5hdkl0ZW0oKSwoXCJsaW5lYXJcIiE9PXRoaXMubW9kZXx8aSkmJih0aGlzLm9uTmF2SXRlbUNsaWNrTGlzdGVuZXIucHVzaCh7ZWw6cyxmbjooKT0+dGhpcy5uYXZJdGVtQ2xpY2soZSl9KSxzLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25OYXZJdGVtQ2xpY2tMaXN0ZW5lci5maW5kKChlPT5lLmVsPT09cykpLmZuKSl9YWRkTmF2SXRlbShlKXtjb25zdHtpbmRleDp0LGlzRmluYWw6aT0hMSxpc0NvbXBsZXRlZDpzPSExLGlzU2tpcDpuPSExLGlzT3B0aW9uYWw6bz0hMSxpc0Rpc2FibGVkOmw9ITEsaXNQcm9jZXNzZWQ6cj0hMSxpc0ludmFsaWQ6YT0hMX09SlNPTi5wYXJzZShlLmdldEF0dHJpYnV0ZShcImRhdGEtc3RlcHBlci1uYXYtaXRlbVwiKSk7cyYmZS5jbGFzc0xpc3QuYWRkKFwiaXMtdmFsaWRcIiksbiYmZS5jbGFzc0xpc3QuYWRkKFwic2tpcHBlZFwiKSxsJiYoXCJCVVRUT05cIiE9PWUudGFnTmFtZSYmXCJJTlBVVFwiIT09ZS50YWdOYW1lfHxlLnNldEF0dHJpYnV0ZShcImRpc2FibGVkXCIsXCJkaXNhYmxlZFwiKSxlLmNsYXNzTGlzdC5hZGQoXCJkaXNhYmxlZFwiKSksYSYmZS5jbGFzc0xpc3QuYWRkKFwiaXMtaW52YWxpZFwiKSx0aGlzLm5hdkl0ZW1zLnB1c2goe2luZGV4OnQsaXNGaW5hbDppLGlzQ29tcGxldGVkOnMsaXNTa2lwOm4saXNPcHRpb25hbDpvLGlzRGlzYWJsZWQ6bCxpc1Byb2Nlc3NlZDpyLGlzSW52YWxpZDphLGVsOmV9KX1zZXRDdXJyZW50TmF2SXRlbSgpe3RoaXMubmF2SXRlbXMuZm9yRWFjaCgoZT0+e2NvbnN0e2luZGV4OnQsZWw6aX09ZTt0PT09dGhpcy5jdXJyZW50SW5kZXg/dGhpcy5zZXRDdXJyZW50TmF2SXRlbUFjdGlvbnMoaSk6dGhpcy51bnNldEN1cnJlbnROYXZJdGVtQWN0aW9ucyhpKX0pKX1zZXRDdXJyZW50TmF2SXRlbUFjdGlvbnMoZSl7ZS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLHRoaXMuZmlyZUV2ZW50KFwiYWN0aXZlXCIsdGhpcy5jdXJyZW50SW5kZXgpLCgwLG4uZGlzcGF0Y2gpKFwiYWN0aXZlLnN0ZXBwZXJcIix0aGlzLmVsLHRoaXMuY3VycmVudEluZGV4KX1nZXROYXZJdGVtKGU9dGhpcy5jdXJyZW50SW5kZXgpe3JldHVybiB0aGlzLm5hdkl0ZW1zLmZpbmQoKCh7aW5kZXg6dH0pPT50PT09ZSkpfXNldFByb2Nlc3NlZE5hdkl0ZW1BY3Rpb25zKGUpe2UuaXNQcm9jZXNzZWQ9ITAsZS5lbC5jbGFzc0xpc3QuYWRkKFwicHJvY2Vzc2VkXCIpfXNldEVycm9yTmF2SXRlbUFjdGlvbnMoZSl7ZS5pc0ludmFsaWQ9ITAsZS5lbC5jbGFzc0xpc3QuYWRkKFwiaXMtaW52YWxpZFwiKX11bnNldEN1cnJlbnROYXZJdGVtQWN0aW9ucyhlKXtlLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIil9aGFuZGxlTmF2SXRlbUNsaWNrKGUpe2NvbnN0e2luZGV4OnR9PWU7dGhpcy5jdXJyZW50SW5kZXg9dCx0aGlzLnNldEN1cnJlbnROYXZJdGVtKCksdGhpcy5zZXRDdXJyZW50Q29udGVudEl0ZW0oKSx0aGlzLmNoZWNrRm9yVGhlRmlyc3RTdGVwKCl9YnVpbGRDb250ZW50KCl7dGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtc3RlcHBlci1jb250ZW50LWl0ZW1dXCIpLmZvckVhY2goKGU9PnRoaXMuYWRkQ29udGVudEl0ZW0oZSkpKSx0aGlzLm5hdkl0ZW1zLmZvckVhY2goKGU9PnRoaXMuYnVpbGRDb250ZW50SXRlbShlKSkpfWJ1aWxkQ29udGVudEl0ZW0oZSl7Y29uc3R7aW5kZXg6dH09ZTt0PT09dGhpcy5jdXJyZW50SW5kZXgmJnRoaXMuc2V0Q3VycmVudENvbnRlbnRJdGVtKCl9YWRkQ29udGVudEl0ZW0oZSl7Y29uc3R7aW5kZXg6dCxpc0ZpbmFsOmk9ITEsaXNDb21wbGV0ZWQ6cz0hMSxpc1NraXA6bj0hMX09SlNPTi5wYXJzZShlLmdldEF0dHJpYnV0ZShcImRhdGEtc3RlcHBlci1jb250ZW50LWl0ZW1cIikpO3MmJmUuY2xhc3NMaXN0LmFkZChcImlzLXZhbGlkXCIpLG4mJmUuY2xhc3NMaXN0LmFkZChcInNraXBwZWRcIiksdGhpcy5jb250ZW50SXRlbXMucHVzaCh7aW5kZXg6dCxpc0ZpbmFsOmksaXNDb21wbGV0ZWQ6cyxpc1NraXA6bixlbDplfSl9c2V0Q3VycmVudENvbnRlbnRJdGVtKCl7aWYodGhpcy5pc0NvbXBsZXRlZCl7Y29uc3QgZT10aGlzLmNvbnRlbnRJdGVtcy5maW5kKCgoe2lzRmluYWw6ZX0pPT5lKSksdD10aGlzLmNvbnRlbnRJdGVtcy5maWx0ZXIoKCh7aXNGaW5hbDplfSk9PiFlKSk7cmV0dXJuIGUuZWwuc3R5bGUuZGlzcGxheT1cIlwiLHQuZm9yRWFjaCgoKHtlbDplfSk9PmUuc3R5bGUuZGlzcGxheT1cIm5vbmVcIikpLCExfXRoaXMuY29udGVudEl0ZW1zLmZvckVhY2goKGU9Pntjb25zdHtpbmRleDp0LGVsOml9PWU7dD09PXRoaXMuY3VycmVudEluZGV4P3RoaXMuc2V0Q3VycmVudENvbnRlbnRJdGVtQWN0aW9ucyhpKTp0aGlzLnVuc2V0Q3VycmVudENvbnRlbnRJdGVtQWN0aW9ucyhpKX0pKX1oaWRlQWxsQ29udGVudEl0ZW1zKCl7dGhpcy5jb250ZW50SXRlbXMuZm9yRWFjaCgoKHtlbDplfSk9PmUuc3R5bGUuZGlzcGxheT1cIm5vbmVcIikpfXNldEN1cnJlbnRDb250ZW50SXRlbUFjdGlvbnMoZSl7ZS5zdHlsZS5kaXNwbGF5PVwiXCJ9dW5zZXRDdXJyZW50Q29udGVudEl0ZW1BY3Rpb25zKGUpe2Uuc3R5bGUuZGlzcGxheT1cIm5vbmVcIn1kaXNhYmxlQWxsKCl7Y29uc3QgZT10aGlzLmdldE5hdkl0ZW0odGhpcy5jdXJyZW50SW5kZXgpO2UuaXNJbnZhbGlkPSExLGUuaXNDb21wbGV0ZWQ9ITEsZS5pc0Rpc2FibGVkPSExLGUuZWwuY2xhc3NMaXN0LnJlbW92ZShcImlzLWludmFsaWRcIixcImlzLXZhbGlkXCIpLHRoaXMuZGlzYWJsZUJ1dHRvbnMoKX1kaXNhYmxlTmF2SXRlbUFjdGlvbnMoZSl7ZS5pc0Rpc2FibGVkPSEwLGUuZWwuY2xhc3NMaXN0LmFkZChcImRpc2FibGVkXCIpfWVuYWJsZU5hdkl0ZW1BY3Rpb25zKGUpe2UuaXNEaXNhYmxlZD0hMSxlLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJkaXNhYmxlZFwiKX1idWlsZEJ1dHRvbnMoKXt0aGlzLmJhY2tCdG49dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtc3RlcHBlci1iYWNrLWJ0bl1cIiksdGhpcy5uZXh0QnRuPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIltkYXRhLXN0ZXBwZXItbmV4dC1idG5dXCIpLHRoaXMuc2tpcEJ0bj10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1zdGVwcGVyLXNraXAtYnRuXVwiKSx0aGlzLmNvbXBsZXRlU3RlcEJ0bj10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1zdGVwcGVyLWNvbXBsZXRlLXN0ZXAtYnRuXVwiKSx0aGlzLmZpbmlzaEJ0bj10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1zdGVwcGVyLWZpbmlzaC1idG5dXCIpLHRoaXMucmVzZXRCdG49dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtc3RlcHBlci1yZXNldC1idG5dXCIpLHRoaXMuYnVpbGRCYWNrQnV0dG9uKCksdGhpcy5idWlsZE5leHRCdXR0b24oKSx0aGlzLmJ1aWxkU2tpcEJ1dHRvbigpLHRoaXMuYnVpbGRDb21wbGV0ZVN0ZXBCdXR0b24oKSx0aGlzLmJ1aWxkRmluaXNoQnV0dG9uKCksdGhpcy5idWlsZFJlc2V0QnV0dG9uKCl9YnVpbGRCYWNrQnV0dG9uKCl7dGhpcy5iYWNrQnRuJiYodGhpcy5jaGVja0ZvclRoZUZpcnN0U3RlcCgpLHRoaXMub25CYWNrQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5iYWNrQ2xpY2soKSx0aGlzLmJhY2tCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkJhY2tDbGlja0xpc3RlbmVyKSl9aGFuZGxlQmFja0J1dHRvbkNsaWNrKCl7MSE9PXRoaXMuY3VycmVudEluZGV4JiYoXCJsaW5lYXJcIj09PXRoaXMubW9kZSYmdGhpcy5yZW1vdmVPcHRpb25hbENsYXNzZXMoKSx0aGlzLmN1cnJlbnRJbmRleC0tLFwibGluZWFyXCI9PT10aGlzLm1vZGUmJnRoaXMucmVtb3ZlT3B0aW9uYWxDbGFzc2VzKCksdGhpcy5zZXRDdXJyZW50TmF2SXRlbSgpLHRoaXMuc2V0Q3VycmVudENvbnRlbnRJdGVtKCksdGhpcy5jaGVja0ZvclRoZUZpcnN0U3RlcCgpLHRoaXMuY29tcGxldGVTdGVwQnRuJiZ0aGlzLmNoYW5nZVRleHRBbmREaXNhYmxlQ29tcGxldGVCdXR0b25JZlN0ZXBDb21wbGV0ZWQoKSx0aGlzLmZpcmVFdmVudChcImJhY2tcIix0aGlzLmN1cnJlbnRJbmRleCksKDAsbi5kaXNwYXRjaCkoXCJiYWNrLnN0ZXBwZXJcIix0aGlzLmVsLHRoaXMuY3VycmVudEluZGV4KSl9Y2hlY2tGb3JUaGVGaXJzdFN0ZXAoKXsxPT09dGhpcy5jdXJyZW50SW5kZXg/dGhpcy5zZXRUb0Rpc2FibGVkKHRoaXMuYmFja0J0bik6dGhpcy5zZXRUb05vbkRpc2FibGVkKHRoaXMuYmFja0J0bil9c2V0VG9EaXNhYmxlZChlKXtcIkJVVFRPTlwiIT09ZS50YWdOYW1lJiZcIklOUFVUXCIhPT1lLnRhZ05hbWV8fGUuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpLGUuY2xhc3NMaXN0LmFkZChcImRpc2FibGVkXCIpfXNldFRvTm9uRGlzYWJsZWQoZSl7XCJCVVRUT05cIiE9PWUudGFnTmFtZSYmXCJJTlBVVFwiIT09ZS50YWdOYW1lfHxlLnJlbW92ZUF0dHJpYnV0ZShcImRpc2FibGVkXCIpLGUuY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpfWJ1aWxkTmV4dEJ1dHRvbigpe3RoaXMubmV4dEJ0biYmKHRoaXMub25OZXh0Q2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5uZXh0Q2xpY2soKSx0aGlzLm5leHRCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbk5leHRDbGlja0xpc3RlbmVyKSl9dW5zZXRQcm9jZXNzZWROYXZJdGVtQWN0aW9ucyhlKXtlLmlzUHJvY2Vzc2VkPSExLGUuZWwuY2xhc3NMaXN0LnJlbW92ZShcInByb2Nlc3NlZFwiKX1oYW5kbGVOZXh0QnV0dG9uQ2xpY2soZT0hMCl7aWYoZSl0aGlzLmN1cnJlbnRJbmRleD09PXRoaXMudG90YWxTdGVwcz90aGlzLmN1cnJlbnRJbmRleD0xOnRoaXMuY3VycmVudEluZGV4Kys7ZWxzZXtjb25zdCBlPXRoaXMuZ2V0VW5jb21wbGV0ZWRTdGVwcygpO2lmKDE9PT1lLmxlbmd0aCl7Y29uc3R7aW5kZXg6dH09ZVswXTt0aGlzLmN1cnJlbnRJbmRleD10fWVsc2V7aWYodGhpcy5jdXJyZW50SW5kZXg9PT10aGlzLnRvdGFsU3RlcHMpcmV0dXJuO3RoaXMuY3VycmVudEluZGV4Kyt9fVwibGluZWFyXCI9PT10aGlzLm1vZGUmJnRoaXMucmVtb3ZlT3B0aW9uYWxDbGFzc2VzKCksdGhpcy5zZXRDdXJyZW50TmF2SXRlbSgpLHRoaXMuc2V0Q3VycmVudENvbnRlbnRJdGVtKCksdGhpcy5jaGVja0ZvclRoZUZpcnN0U3RlcCgpLHRoaXMuY29tcGxldGVTdGVwQnRuJiZ0aGlzLmNoYW5nZVRleHRBbmREaXNhYmxlQ29tcGxldGVCdXR0b25JZlN0ZXBDb21wbGV0ZWQoKSx0aGlzLnNob3dTa2lwQnV0dG9uKCksdGhpcy5zaG93RmluaXNoQnV0dG9uKCksdGhpcy5zaG93Q29tcGxldGVTdGVwQnV0dG9uKCksdGhpcy5maXJlRXZlbnQoXCJuZXh0XCIsdGhpcy5jdXJyZW50SW5kZXgpLCgwLG4uZGlzcGF0Y2gpKFwibmV4dC5zdGVwcGVyXCIsdGhpcy5lbCx0aGlzLmN1cnJlbnRJbmRleCl9cmVtb3ZlT3B0aW9uYWxDbGFzc2VzKCl7Y29uc3QgZT10aGlzLm5hdkl0ZW1zLmZpbmQoKCh7aW5kZXg6ZX0pPT5lPT09dGhpcy5jdXJyZW50SW5kZXgpKSx0PXRoaXMuY29udGVudEl0ZW1zLmZpbmQoKCh7aW5kZXg6ZX0pPT5lPT09dGhpcy5jdXJyZW50SW5kZXgpKTtlLmlzU2tpcD0hMSxlLmlzSW52YWxpZD0hMSxlLmlzRGlzYWJsZWQ9ITEsdC5pc1NraXA9ITEsZS5lbC5jbGFzc0xpc3QucmVtb3ZlKFwic2tpcHBlZFwiLFwiaXMtdmFsaWRcIixcImlzLWludmFsaWRcIiksdC5lbC5jbGFzc0xpc3QucmVtb3ZlKFwic2tpcHBlZFwiLFwiaXMtdmFsaWRcIixcImlzLWludmFsaWRcIil9YnVpbGRTa2lwQnV0dG9uKCl7dGhpcy5za2lwQnRuJiYodGhpcy5zaG93U2tpcEJ1dHRvbigpLHRoaXMub25Ta2lwQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5za2lwQ2xpY2soKSx0aGlzLnNraXBCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblNraXBDbGlja0xpc3RlbmVyKSl9c2V0U2tpcEl0ZW0oZSl7Y29uc3QgdD10aGlzLm5hdkl0ZW1zLmZpbmQoKCh7aW5kZXg6dH0pPT50PT09KGV8fHRoaXMuY3VycmVudEluZGV4KSkpLGk9dGhpcy5jb250ZW50SXRlbXMuZmluZCgoKHtpbmRleDp0fSk9PnQ9PT0oZXx8dGhpcy5jdXJyZW50SW5kZXgpKSk7dCYmaSYmKHRoaXMuc2V0U2tpcEl0ZW1BY3Rpb25zKHQpLHRoaXMuc2V0U2tpcEl0ZW1BY3Rpb25zKGkpKX1zZXRTa2lwSXRlbUFjdGlvbnMoZSl7ZS5pc1NraXA9ITAsZS5lbC5jbGFzc0xpc3QuYWRkKFwic2tpcHBlZFwiKX1zaG93U2tpcEJ1dHRvbigpe2lmKCF0aGlzLnNraXBCdG4pcmV0dXJuO2NvbnN0e2lzT3B0aW9uYWw6ZX09dGhpcy5uYXZJdGVtcy5maW5kKCgoe2luZGV4OmV9KT0+ZT09PXRoaXMuY3VycmVudEluZGV4KSk7dGhpcy5za2lwQnRuLnN0eWxlLmRpc3BsYXk9ZT9cIlwiOlwibm9uZVwifWhhbmRsZVNraXBCdXR0b25DbGljaygpe3RoaXMuc2V0U2tpcEl0ZW0oKSx0aGlzLmhhbmRsZU5leHRCdXR0b25DbGljaygpLHRoaXMuZmlyZUV2ZW50KFwic2tpcFwiLHRoaXMuY3VycmVudEluZGV4KSwoMCxuLmRpc3BhdGNoKShcInNraXAuc3RlcHBlclwiLHRoaXMuZWwsdGhpcy5jdXJyZW50SW5kZXgpfWJ1aWxkQ29tcGxldGVTdGVwQnV0dG9uKCl7dGhpcy5jb21wbGV0ZVN0ZXBCdG4mJih0aGlzLmNvbXBsZXRlU3RlcEJ0bkRlZmF1bHRUZXh0PXRoaXMuY29tcGxldGVTdGVwQnRuLmlubmVyVGV4dCx0aGlzLm9uQ29tcGxldGVTdGVwQnRuQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5jb21wbGV0ZVN0ZXBCdG5DbGljaygpLHRoaXMuY29tcGxldGVTdGVwQnRuLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Db21wbGV0ZVN0ZXBCdG5DbGlja0xpc3RlbmVyKSl9Y2hhbmdlVGV4dEFuZERpc2FibGVDb21wbGV0ZUJ1dHRvbklmU3RlcENvbXBsZXRlZCgpe2NvbnN0IGU9dGhpcy5uYXZJdGVtcy5maW5kKCgoe2luZGV4OmV9KT0+ZT09PXRoaXMuY3VycmVudEluZGV4KSkse2NvbXBsZXRlZFRleHQ6dH09SlNPTi5wYXJzZSh0aGlzLmNvbXBsZXRlU3RlcEJ0bi5nZXRBdHRyaWJ1dGUoXCJkYXRhLXN0ZXBwZXItY29tcGxldGUtc3RlcC1idG5cIikpO2UmJihlLmlzQ29tcGxldGVkPyh0aGlzLmNvbXBsZXRlU3RlcEJ0bi5pbm5lclRleHQ9dHx8dGhpcy5jb21wbGV0ZVN0ZXBCdG5EZWZhdWx0VGV4dCx0aGlzLmNvbXBsZXRlU3RlcEJ0bi5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLFwiZGlzYWJsZWRcIiksdGhpcy5jb21wbGV0ZVN0ZXBCdG4uY2xhc3NMaXN0LmFkZChcImRpc2FibGVkXCIpKToodGhpcy5jb21wbGV0ZVN0ZXBCdG4uaW5uZXJUZXh0PXRoaXMuY29tcGxldGVTdGVwQnRuRGVmYXVsdFRleHQsdGhpcy5jb21wbGV0ZVN0ZXBCdG4ucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIiksdGhpcy5jb21wbGV0ZVN0ZXBCdG4uY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpKSl9c2V0Q29tcGxldGVJdGVtKGUpe2NvbnN0IHQ9dGhpcy5uYXZJdGVtcy5maW5kKCgoe2luZGV4OnR9KT0+dD09PShlfHx0aGlzLmN1cnJlbnRJbmRleCkpKSxpPXRoaXMuY29udGVudEl0ZW1zLmZpbmQoKCh7aW5kZXg6dH0pPT50PT09KGV8fHRoaXMuY3VycmVudEluZGV4KSkpO3QmJmkmJih0aGlzLnNldENvbXBsZXRlSXRlbUFjdGlvbnModCksdGhpcy5zZXRDb21wbGV0ZUl0ZW1BY3Rpb25zKGkpKX1zZXRDb21wbGV0ZUl0ZW1BY3Rpb25zKGUpe2UuaXNDb21wbGV0ZWQ9ITAsZS5lbC5jbGFzc0xpc3QuYWRkKFwiaXMtdmFsaWRcIil9c2hvd0NvbXBsZXRlU3RlcEJ1dHRvbigpe2lmKCF0aGlzLmNvbXBsZXRlU3RlcEJ0bilyZXR1cm47MT09PXRoaXMuZ2V0VW5jb21wbGV0ZWRTdGVwcygpLmxlbmd0aD90aGlzLmNvbXBsZXRlU3RlcEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwiOnRoaXMuY29tcGxldGVTdGVwQnRuLnN0eWxlLmRpc3BsYXk9XCJcIn1oYW5kbGVDb21wbGV0ZVN0ZXBCdXR0b25DbGljaygpe3RoaXMuc2V0Q29tcGxldGVJdGVtKCksdGhpcy5maXJlRXZlbnQoXCJjb21wbGV0ZVwiLHRoaXMuY3VycmVudEluZGV4KSwoMCxuLmRpc3BhdGNoKShcImNvbXBsZXRlLnN0ZXBwZXJcIix0aGlzLmVsLHRoaXMuY3VycmVudEluZGV4KSx0aGlzLmhhbmRsZU5leHRCdXR0b25DbGljayghMSksdGhpcy5zaG93RmluaXNoQnV0dG9uKCksdGhpcy5zaG93Q29tcGxldGVTdGVwQnV0dG9uKCksdGhpcy5jaGVja0ZvclRoZUZpcnN0U3RlcCgpLHRoaXMuY29tcGxldGVTdGVwQnRuJiZ0aGlzLmNoYW5nZVRleHRBbmREaXNhYmxlQ29tcGxldGVCdXR0b25JZlN0ZXBDb21wbGV0ZWQoKSx0aGlzLnNob3dTa2lwQnV0dG9uKCl9YnVpbGRGaW5pc2hCdXR0b24oKXt0aGlzLmZpbmlzaEJ0biYmKHRoaXMuaXNDb21wbGV0ZWQmJnRoaXMuc2V0Q29tcGxldGVkKCksdGhpcy5vbkZpbmlzaEJ0bkNsaWNrTGlzdGVuZXI9KCk9PnRoaXMuZmluaXNoQnRuQ2xpY2soKSx0aGlzLmZpbmlzaEJ0bi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uRmluaXNoQnRuQ2xpY2tMaXN0ZW5lcikpfXNldENvbXBsZXRlZCgpe3RoaXMuZWwuY2xhc3NMaXN0LmFkZChcImNvbXBsZXRlZFwiKX11bnNldENvbXBsZXRlZCgpe3RoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcImNvbXBsZXRlZFwiKX1zaG93RmluaXNoQnV0dG9uKCl7aWYoIXRoaXMuZmluaXNoQnRuKXJldHVybjsxPT09dGhpcy5nZXRVbmNvbXBsZXRlZFN0ZXBzKCkubGVuZ3RoP3RoaXMuZmluaXNoQnRuLnN0eWxlLmRpc3BsYXk9XCJcIjp0aGlzLmZpbmlzaEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwifWhhbmRsZUZpbmlzaEJ1dHRvbkNsaWNrKCl7Y29uc3QgZT10aGlzLmdldFVuY29tcGxldGVkU3RlcHMoKSx0PXRoaXMuZ2V0VW5jb21wbGV0ZWRTdGVwcyghMCkse2VsOml9PXRoaXMuY29udGVudEl0ZW1zLmZpbmQoKCh7aXNGaW5hbDplfSk9PmUpKTtlLmxlbmd0aCYmZS5mb3JFYWNoKCgoe2luZGV4OmV9KT0+dGhpcy5zZXRDb21wbGV0ZUl0ZW0oZSkpKSx0aGlzLmN1cnJlbnRJbmRleD10aGlzLnRvdGFsU3RlcHMsdGhpcy5zZXRDdXJyZW50TmF2SXRlbSgpLHRoaXMuaGlkZUFsbENvbnRlbnRJdGVtcygpO2NvbnN0IHM9dGhpcy5uYXZJdGVtcy5maW5kKCgoe2luZGV4OmV9KT0+ZT09PXRoaXMuY3VycmVudEluZGV4KSk7KHM/cy5lbDpudWxsKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpLGkuc3R5bGUuZGlzcGxheT1cImJsb2NrXCIsdGhpcy5iYWNrQnRuJiYodGhpcy5iYWNrQnRuLnN0eWxlLmRpc3BsYXk9XCJub25lXCIpLHRoaXMubmV4dEJ0biYmKHRoaXMubmV4dEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwiKSx0aGlzLnNraXBCdG4mJih0aGlzLnNraXBCdG4uc3R5bGUuZGlzcGxheT1cIm5vbmVcIiksdGhpcy5jb21wbGV0ZVN0ZXBCdG4mJih0aGlzLmNvbXBsZXRlU3RlcEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwiKSx0aGlzLmZpbmlzaEJ0biYmKHRoaXMuZmluaXNoQnRuLnN0eWxlLmRpc3BsYXk9XCJub25lXCIpLHRoaXMucmVzZXRCdG4mJih0aGlzLnJlc2V0QnRuLnN0eWxlLmRpc3BsYXk9XCJcIiksdC5sZW5ndGg8PTEmJih0aGlzLmlzQ29tcGxldGVkPSEwLHRoaXMuc2V0Q29tcGxldGVkKCkpLHRoaXMuZmlyZUV2ZW50KFwiZmluaXNoXCIsdGhpcy5jdXJyZW50SW5kZXgpLCgwLG4uZGlzcGF0Y2gpKFwiZmluaXNoLnN0ZXBwZXJcIix0aGlzLmVsLHRoaXMuY3VycmVudEluZGV4KX1idWlsZFJlc2V0QnV0dG9uKCl7dGhpcy5yZXNldEJ0biYmKHRoaXMub25SZXNldEJ0bkNsaWNrTGlzdGVuZXI9KCk9PnRoaXMucmVzZXRCdG5DbGljaygpLHRoaXMucmVzZXRCdG4uYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblJlc2V0QnRuQ2xpY2tMaXN0ZW5lcikpfWhhbmRsZVJlc2V0QnV0dG9uQ2xpY2soKXt0aGlzLmJhY2tCdG4mJih0aGlzLmJhY2tCdG4uc3R5bGUuZGlzcGxheT1cIlwiKSx0aGlzLm5leHRCdG4mJih0aGlzLm5leHRCdG4uc3R5bGUuZGlzcGxheT1cIlwiKSx0aGlzLmNvbXBsZXRlU3RlcEJ0biYmKHRoaXMuY29tcGxldGVTdGVwQnRuLnN0eWxlLmRpc3BsYXk9XCJcIix0aGlzLmNvbXBsZXRlU3RlcEJ0bi5pbm5lclRleHQ9dGhpcy5jb21wbGV0ZVN0ZXBCdG5EZWZhdWx0VGV4dCx0aGlzLmNvbXBsZXRlU3RlcEJ0bi5yZW1vdmVBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSx0aGlzLmNvbXBsZXRlU3RlcEJ0bi5jbGFzc0xpc3QucmVtb3ZlKFwiZGlzYWJsZWRcIikpLHRoaXMucmVzZXRCdG4mJih0aGlzLnJlc2V0QnRuLnN0eWxlLmRpc3BsYXk9XCJub25lXCIpLHRoaXMubmF2SXRlbXMuZm9yRWFjaCgoZT0+e2NvbnN0e2VsOnR9PWU7ZS5pc1NraXA9ITEsZS5pc0NvbXBsZXRlZD0hMSx0aGlzLnVuc2V0Q3VycmVudE5hdkl0ZW1BY3Rpb25zKHQpLHQuY2xhc3NMaXN0LnJlbW92ZShcImlzLXZhbGlkXCIsXCJza2lwcGVkXCIpfSkpLHRoaXMuY29udGVudEl0ZW1zLmZvckVhY2goKGU9Pntjb25zdHtlbDp0fT1lO2UuaXNTa2lwPSExLGUuaXNDb21wbGV0ZWQ9ITEsdGhpcy51bnNldEN1cnJlbnRDb250ZW50SXRlbUFjdGlvbnModCksdC5jbGFzc0xpc3QucmVtb3ZlKFwiaXMtdmFsaWRcIixcInNraXBwZWRcIil9KSksdGhpcy5jdXJyZW50SW5kZXg9MSx0aGlzLnVuc2V0Q29tcGxldGVkKCksdGhpcy5pc0NvbXBsZXRlZD0hMSx0aGlzLnNob3dTa2lwQnV0dG9uKCksdGhpcy5zZXRDdXJyZW50TmF2SXRlbSgpLHRoaXMuc2V0Q3VycmVudENvbnRlbnRJdGVtKCksdGhpcy5zaG93RmluaXNoQnV0dG9uKCksdGhpcy5zaG93Q29tcGxldGVTdGVwQnV0dG9uKCksdGhpcy5jaGVja0ZvclRoZUZpcnN0U3RlcCgpLHRoaXMuZmlyZUV2ZW50KFwicmVzZXRcIix0aGlzLmN1cnJlbnRJbmRleCksKDAsbi5kaXNwYXRjaCkoXCJyZXNldC5zdGVwcGVyXCIsdGhpcy5lbCx0aGlzLmN1cnJlbnRJbmRleCl9c2V0UHJvY2Vzc2VkTmF2SXRlbShlKXtjb25zdCB0PXRoaXMuZ2V0TmF2SXRlbShlKTt0JiZ0aGlzLnNldFByb2Nlc3NlZE5hdkl0ZW1BY3Rpb25zKHQpfXVuc2V0UHJvY2Vzc2VkTmF2SXRlbShlKXtjb25zdCB0PXRoaXMuZ2V0TmF2SXRlbShlKTt0JiZ0aGlzLnVuc2V0UHJvY2Vzc2VkTmF2SXRlbUFjdGlvbnModCl9Z29Ub05leHQoKXtcImxpbmVhclwiPT09dGhpcy5tb2RlJiZ0aGlzLnNldENvbXBsZXRlSXRlbSgpLHRoaXMuaGFuZGxlTmV4dEJ1dHRvbkNsaWNrKFwibGluZWFyXCIhPT10aGlzLm1vZGUpLFwibGluZWFyXCI9PT10aGlzLm1vZGUmJnRoaXMuY3VycmVudEluZGV4PT09dGhpcy50b3RhbFN0ZXBzJiYodGhpcy5uZXh0QnRuJiYodGhpcy5uZXh0QnRuLnN0eWxlLmRpc3BsYXk9XCJub25lXCIpLHRoaXMuY29tcGxldGVTdGVwQnRuJiYodGhpcy5jb21wbGV0ZVN0ZXBCdG4uc3R5bGUuZGlzcGxheT1cIm5vbmVcIikpfWRpc2FibGVCdXR0b25zKCl7dGhpcy5iYWNrQnRuJiZ0aGlzLnNldFRvRGlzYWJsZWQodGhpcy5iYWNrQnRuKSx0aGlzLm5leHRCdG4mJnRoaXMuc2V0VG9EaXNhYmxlZCh0aGlzLm5leHRCdG4pfWVuYWJsZUJ1dHRvbnMoKXt0aGlzLmJhY2tCdG4mJnRoaXMuc2V0VG9Ob25EaXNhYmxlZCh0aGlzLmJhY2tCdG4pLHRoaXMubmV4dEJ0biYmdGhpcy5zZXRUb05vbkRpc2FibGVkKHRoaXMubmV4dEJ0bil9c2V0RXJyb3JOYXZJdGVtKGUpe2NvbnN0IHQ9dGhpcy5nZXROYXZJdGVtKGUpO3QmJnRoaXMuc2V0RXJyb3JOYXZJdGVtQWN0aW9ucyh0KX1kZXN0cm95KCl7dGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiY29tcGxldGVkXCIpLHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXN0ZXBwZXItbmF2LWl0ZW1dXCIpLmZvckVhY2goKGU9PntlLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIixcImlzLXZhbGlkXCIsXCJza2lwcGVkXCIsXCJkaXNhYmxlZFwiLFwiaXMtaW52YWxpZFwiKSxcIkJVVFRPTlwiIT09ZS50YWdOYW1lJiZcIklOUFVUXCIhPT1lLnRhZ05hbWV8fGUucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIil9KSksdGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtc3RlcHBlci1jb250ZW50LWl0ZW1dXCIpLmZvckVhY2goKGU9PntlLmNsYXNzTGlzdC5yZW1vdmUoXCJpcy12YWxpZFwiLFwic2tpcHBlZFwiKX0pKSx0aGlzLmJhY2tCdG4mJnRoaXMuYmFja0J0bi5jbGFzc0xpc3QucmVtb3ZlKFwiZGlzYWJsZWRcIiksdGhpcy5uZXh0QnRuJiZ0aGlzLm5leHRCdG4uY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpLHRoaXMuY29tcGxldGVTdGVwQnRuJiZ0aGlzLmNvbXBsZXRlU3RlcEJ0bi5jbGFzc0xpc3QucmVtb3ZlKFwiZGlzYWJsZWRcIiksdGhpcy5iYWNrQnRuJiYodGhpcy5iYWNrQnRuLnN0eWxlLmRpc3BsYXk9XCJcIiksdGhpcy5uZXh0QnRuJiYodGhpcy5uZXh0QnRuLnN0eWxlLmRpc3BsYXk9XCJcIiksdGhpcy5za2lwQnRuJiYodGhpcy5za2lwQnRuLnN0eWxlLmRpc3BsYXk9XCJcIiksdGhpcy5maW5pc2hCdG4mJih0aGlzLmZpbmlzaEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwiKSx0aGlzLnJlc2V0QnRuJiYodGhpcy5yZXNldEJ0bi5zdHlsZS5kaXNwbGF5PVwibm9uZVwiKSx0aGlzLm9uTmF2SXRlbUNsaWNrTGlzdGVuZXIubGVuZ3RoJiZ0aGlzLm9uTmF2SXRlbUNsaWNrTGlzdGVuZXIuZm9yRWFjaCgoKHtlbDplLGZuOnR9KT0+e2UucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdCl9KSksdGhpcy5iYWNrQnRuJiZ0aGlzLmJhY2tCdG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkJhY2tDbGlja0xpc3RlbmVyKSx0aGlzLm5leHRCdG4mJnRoaXMubmV4dEJ0bi5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uTmV4dENsaWNrTGlzdGVuZXIpLHRoaXMuc2tpcEJ0biYmdGhpcy5za2lwQnRuLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ta2lwQ2xpY2tMaXN0ZW5lciksdGhpcy5jb21wbGV0ZVN0ZXBCdG4mJnRoaXMuY29tcGxldGVTdGVwQnRuLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Db21wbGV0ZVN0ZXBCdG5DbGlja0xpc3RlbmVyKSx0aGlzLmZpbmlzaEJ0biYmdGhpcy5maW5pc2hCdG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkZpbmlzaEJ0bkNsaWNrTGlzdGVuZXIpLHRoaXMucmVzZXRCdG4mJnRoaXMucmVzZXRCdG4ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblJlc2V0QnRuQ2xpY2tMaXN0ZW5lciksd2luZG93LiRoc1N0ZXBwZXJDb2xsZWN0aW9uPXdpbmRvdy4kaHNTdGVwcGVyQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzU3RlcHBlckNvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50Om51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc1N0ZXBwZXJDb2xsZWN0aW9ufHwod2luZG93LiRoc1N0ZXBwZXJDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzU3RlcHBlckNvbGxlY3Rpb24mJih3aW5kb3cuJGhzU3RlcHBlckNvbGxlY3Rpb249d2luZG93LiRoc1N0ZXBwZXJDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXN0ZXBwZXJdOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNTdGVwcGVyQ29sbGVjdGlvbi5maW5kKCh0PT57dmFyIGk7cmV0dXJuKG51bGw9PT0oaT1udWxsPT10P3ZvaWQgMDp0LmVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmVsKT09PWV9KSl8fG5ldyBsKGUpfSkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PntsLmF1dG9Jbml0KCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1N0ZXBwZXI9bCksdC5kZWZhdWx0PWx9LDIzNDpmdW5jdGlvbihlLHQsaSl7XG4vKlxuICogSFNUb2dnbGVQYXNzd29yZFxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCl7c3VwZXIoZSx0KTtjb25zdCBpPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS10b2dnbGUtcGFzc3dvcmRcIikscz1pP0pTT04ucGFyc2UoaSk6e30sbz1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30scyksdCksbD1bXTtpZigobnVsbD09bz92b2lkIDA6by50YXJnZXQpJiZcInN0cmluZ1wiPT10eXBlb2YobnVsbD09bz92b2lkIDA6by50YXJnZXQpKXsobnVsbD09bz92b2lkIDA6by50YXJnZXQuc3BsaXQoXCIsXCIpKS5mb3JFYWNoKChlPT57bC5wdXNoKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSkpfSkpfWVsc2UobnVsbD09bz92b2lkIDA6by50YXJnZXQpJiZcIm9iamVjdFwiPT10eXBlb2YobnVsbD09bz92b2lkIDA6by50YXJnZXQpP28udGFyZ2V0LmZvckVhY2goKGU9PmwucHVzaChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpKSkpOm8udGFyZ2V0LmZvckVhY2goKGU9PmwucHVzaChlKSkpO3RoaXMudGFyZ2V0PWwsdGhpcy5pc1Nob3duPSEhdGhpcy5lbC5oYXNBdHRyaWJ1dGUoXCJ0eXBlXCIpJiZ0aGlzLmVsLmNoZWNrZWQsdGhpcy5ldmVudFR5cGU9KDAsbi5pc0Zvcm1FbGVtZW50KSh0aGlzLmVsKT9cImNoYW5nZVwiOlwiY2xpY2tcIix0aGlzLmlzTXVsdGlwbGU9dGhpcy50YXJnZXQubGVuZ3RoPjEmJiEhdGhpcy5lbC5jbG9zZXN0KFwiW2RhdGEtdG9nZ2xlLXBhc3N3b3JkLWdyb3VwXVwiKSx0aGlzLnRhcmdldCYmdGhpcy5pbml0KCl9ZWxlbWVudEFjdGlvbigpe3RoaXMuaXNTaG93bj90aGlzLmhpZGUoKTp0aGlzLnNob3coKSx0aGlzLmZpcmVFdmVudChcInRvZ2dsZVwiLHRoaXMudGFyZ2V0KSwoMCxuLmRpc3BhdGNoKShcInRvZ2dsZS50b2dnbGUtc2VsZWN0XCIsdGhpcy5lbCx0aGlzLnRhcmdldCl9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzVG9nZ2xlUGFzc3dvcmRDb2xsZWN0aW9uLHRoaXMpLHRoaXMuaXNTaG93bj90aGlzLnNob3coKTp0aGlzLmhpZGUoKSx0aGlzLm9uRWxlbWVudEFjdGlvbkxpc3RlbmVyPSgpPT50aGlzLmVsZW1lbnRBY3Rpb24oKSx0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIodGhpcy5ldmVudFR5cGUsdGhpcy5vbkVsZW1lbnRBY3Rpb25MaXN0ZW5lcil9Z2V0TXVsdGlwbGVUb2dnbGVzKCl7Y29uc3QgZT10aGlzLmVsLmNsb3Nlc3QoXCJbZGF0YS10b2dnbGUtcGFzc3dvcmQtZ3JvdXBdXCIpLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS10b2dnbGUtcGFzc3dvcmRdXCIpLHQ9W107cmV0dXJuIGUuZm9yRWFjaCgoZT0+e3QucHVzaChsLmdldEluc3RhbmNlKGUpKX0pKSx0fXNob3coKXtpZih0aGlzLmlzTXVsdGlwbGUpe3RoaXMuZ2V0TXVsdGlwbGVUb2dnbGVzKCkuZm9yRWFjaCgoZT0+ISFlJiYoZS5pc1Nob3duPSEwKSkpLHRoaXMuZWwuY2xvc2VzdChcIltkYXRhLXRvZ2dsZS1wYXNzd29yZC1ncm91cF1cIikuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKX1lbHNlIHRoaXMuaXNTaG93bj0hMCx0aGlzLmVsLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIik7dGhpcy50YXJnZXQuZm9yRWFjaCgoZT0+e2UudHlwZT1cInRleHRcIn0pKX1oaWRlKCl7aWYodGhpcy5pc011bHRpcGxlKXt0aGlzLmdldE11bHRpcGxlVG9nZ2xlcygpLmZvckVhY2goKGU9PiEhZSYmKGUuaXNTaG93bj0hMSkpKSx0aGlzLmVsLmNsb3Nlc3QoXCJbZGF0YS10b2dnbGUtcGFzc3dvcmQtZ3JvdXBdXCIpLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIil9ZWxzZSB0aGlzLmlzU2hvd249ITEsdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpO3RoaXMudGFyZ2V0LmZvckVhY2goKGU9PntlLnR5cGU9XCJwYXNzd29yZFwifSkpfWRlc3Ryb3koKXt0aGlzLmlzTXVsdGlwbGU/dGhpcy5lbC5jbG9zZXN0KFwiW2RhdGEtdG9nZ2xlLXBhc3N3b3JkLWdyb3VwXVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpOnRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKSx0aGlzLnRhcmdldC5mb3JFYWNoKChlPT57ZS50eXBlPVwicGFzc3dvcmRcIn0pKSx0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodGhpcy5ldmVudFR5cGUsdGhpcy5vbkVsZW1lbnRBY3Rpb25MaXN0ZW5lciksdGhpcy5pc1Nob3duPSExLHdpbmRvdy4kaHNUb2dnbGVQYXNzd29yZENvbGxlY3Rpb249d2luZG93LiRoc1RvZ2dsZVBhc3N3b3JkQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzVG9nZ2xlUGFzc3dvcmRDb2xsZWN0aW9uLmZpbmQoKHQ9PnQuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSk7cmV0dXJuIGk/dD9pOmkuZWxlbWVudDpudWxsfXN0YXRpYyBhdXRvSW5pdCgpe3dpbmRvdy4kaHNUb2dnbGVQYXNzd29yZENvbGxlY3Rpb258fCh3aW5kb3cuJGhzVG9nZ2xlUGFzc3dvcmRDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzVG9nZ2xlUGFzc3dvcmRDb2xsZWN0aW9uJiYod2luZG93LiRoc1RvZ2dsZVBhc3N3b3JkQ29sbGVjdGlvbj13aW5kb3cuJGhzVG9nZ2xlUGFzc3dvcmRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXRvZ2dsZS1wYXNzd29yZF06bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57d2luZG93LiRoc1RvZ2dsZVBhc3N3b3JkQ29sbGVjdGlvbi5maW5kKCh0PT57dmFyIGk7cmV0dXJuKG51bGw9PT0oaT1udWxsPT10P3ZvaWQgMDp0LmVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmVsKT09PWV9KSl8fG5ldyBsKGUpfSkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PntsLmF1dG9Jbml0KCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1RvZ2dsZVBhc3N3b3JkPWwpLHQuZGVmYXVsdD1sfSwyODc6KGUsdCk9PntPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTt0LmRlZmF1bHQ9Y2xhc3N7Y29uc3RydWN0b3IoZSx0LGkpe3RoaXMuZWw9ZSx0aGlzLm9wdGlvbnM9dCx0aGlzLmV2ZW50cz1pLHRoaXMuZWw9ZSx0aGlzLm9wdGlvbnM9dCx0aGlzLmV2ZW50cz17fX1jcmVhdGVDb2xsZWN0aW9uKGUsdCl7dmFyIGk7ZS5wdXNoKHtpZDoobnVsbD09PShpPW51bGw9PXQ/dm9pZCAwOnQuZWwpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmlkKXx8ZS5sZW5ndGgrMSxlbGVtZW50OnR9KX1maXJlRXZlbnQoZSx0PW51bGwpe2lmKHRoaXMuZXZlbnRzLmhhc093blByb3BlcnR5KGUpKXJldHVybiB0aGlzLmV2ZW50c1tlXSh0KX1vbihlLHQpe3RoaXMuZXZlbnRzW2VdPXR9fX0sMzAyOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU0Nhcm91c2VsXG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbnZhciBzPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IG49aSg4MDYpLG89cyhpKDI4NykpLGw9aSg5MTcpO2NsYXNzIHIgZXh0ZW5kcyBvLmRlZmF1bHR7Y29uc3RydWN0b3IoZSx0KXt2YXIgaSxzLG4sbyxsO3N1cGVyKGUsdCk7Y29uc3Qgcj1lLmdldEF0dHJpYnV0ZShcImRhdGEtY2Fyb3VzZWxcIiksYT1yP0pTT04ucGFyc2Uocik6e30sYz1PYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sYSksdCk7dGhpcy5jdXJyZW50SW5kZXg9Yy5jdXJyZW50SW5kZXh8fDAsdGhpcy5sb2FkaW5nQ2xhc3Nlcz1jLmxvYWRpbmdDbGFzc2VzP2Ake2MubG9hZGluZ0NsYXNzZXN9YC5zcGxpdChcIixcIik6bnVsbCx0aGlzLmRvdHNJdGVtQ2xhc3Nlcz1jLmRvdHNJdGVtQ2xhc3Nlcz9jLmRvdHNJdGVtQ2xhc3NlczpudWxsLHRoaXMuaXNBdXRvSGVpZ2h0PXZvaWQgMCE9PWMuaXNBdXRvSGVpZ2h0JiZjLmlzQXV0b0hlaWdodCx0aGlzLmlzQXV0b1BsYXk9dm9pZCAwIT09Yy5pc0F1dG9QbGF5JiZjLmlzQXV0b1BsYXksdGhpcy5pc0NlbnRlcmVkPXZvaWQgMCE9PWMuaXNDZW50ZXJlZCYmYy5pc0NlbnRlcmVkLHRoaXMuaXNEcmFnZ2FibGU9dm9pZCAwIT09Yy5pc0RyYWdnYWJsZSYmYy5pc0RyYWdnYWJsZSx0aGlzLmlzSW5maW5pdGVMb29wPXZvaWQgMCE9PWMuaXNJbmZpbml0ZUxvb3AmJmMuaXNJbmZpbml0ZUxvb3AsdGhpcy5pc1JUTD12b2lkIDAhPT1jLmlzUlRMJiZjLmlzUlRMLHRoaXMuaXNTbmFwPXZvaWQgMCE9PWMuaXNTbmFwJiZjLmlzU25hcCx0aGlzLmhhc1NuYXBTcGFjZXJzPXZvaWQgMD09PWMuaGFzU25hcFNwYWNlcnN8fGMuaGFzU25hcFNwYWNlcnMsdGhpcy5zcGVlZD1jLnNwZWVkfHw0ZTMsdGhpcy51cGRhdGVEZWxheT1jLnVwZGF0ZURlbGF5fHwwLHRoaXMuc2xpZGVzUXR5PWMuc2xpZGVzUXR5fHwxLHRoaXMubG9hZGluZ0NsYXNzZXNSZW1vdmU9KG51bGw9PT0oaT10aGlzLmxvYWRpbmdDbGFzc2VzKXx8dm9pZCAwPT09aT92b2lkIDA6aVswXSk/dGhpcy5sb2FkaW5nQ2xhc3Nlc1swXS5zcGxpdChcIiBcIik6XCJvcGFjaXR5LTBcIix0aGlzLmxvYWRpbmdDbGFzc2VzQWRkPShudWxsPT09KHM9dGhpcy5sb2FkaW5nQ2xhc3Nlcyl8fHZvaWQgMD09PXM/dm9pZCAwOnNbMV0pP3RoaXMubG9hZGluZ0NsYXNzZXNbMV0uc3BsaXQoXCIgXCIpOlwiXCIsdGhpcy5hZnRlckxvYWRpbmdDbGFzc2VzQWRkPShudWxsPT09KG49dGhpcy5sb2FkaW5nQ2xhc3Nlcyl8fHZvaWQgMD09PW4/dm9pZCAwOm5bMl0pP3RoaXMubG9hZGluZ0NsYXNzZXNbMl0uc3BsaXQoXCIgXCIpOlwiXCIsdGhpcy5jb250YWluZXI9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLmNhcm91c2VsXCIpfHxudWxsLHRoaXMuaW5uZXI9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLmNhcm91c2VsLWJvZHlcIil8fG51bGwsdGhpcy5zbGlkZXM9dGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNhcm91c2VsLXNsaWRlXCIpfHxbXSx0aGlzLnByZXY9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLmNhcm91c2VsLXByZXZcIil8fG51bGwsdGhpcy5uZXh0PXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIi5jYXJvdXNlbC1uZXh0XCIpfHxudWxsLHRoaXMuZG90cz10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCIuY2Fyb3VzZWwtcGFnaW5hdGlvblwiKXx8bnVsbCx0aGlzLmluZm89dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLmNhcm91c2VsLWluZm9cIil8fG51bGwsdGhpcy5pbmZvVG90YWw9KG51bGw9PT0obz1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLmluZm8pfHx2b2lkIDA9PT1vP3ZvaWQgMDpvLnF1ZXJ5U2VsZWN0b3IoXCIuY2Fyb3VzZWwtaW5mby10b3RhbFwiKSl8fG51bGwsdGhpcy5pbmZvQ3VycmVudD0obnVsbD09PShsPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMuaW5mbyl8fHZvaWQgMD09PWw/dm9pZCAwOmwucXVlcnlTZWxlY3RvcihcIi5jYXJvdXNlbC1pbmZvLWN1cnJlbnRcIikpfHxudWxsLHRoaXMuc2xpZGVyV2lkdGg9dGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCx0aGlzLmlzRHJhZ2dpbmc9ITEsdGhpcy5kcmFnU3RhcnRYPW51bGwsdGhpcy5pbml0aWFsVHJhbnNsYXRlWD1udWxsLHRoaXMudG91Y2hYPXtzdGFydDowLGVuZDowfSx0aGlzLnJlc2l6ZUNvbnRhaW5lcj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYm9keVwiKSx0aGlzLnJlc2l6ZUNvbnRhaW5lcldpZHRoPTAsdGhpcy5pbml0KCl9c2V0SXNTbmFwKCl7Y29uc3QgZT10aGlzLmNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSx0PWUubGVmdCtlLndpZHRoLzI7bGV0IGk9bnVsbCxzPW51bGwsbj0xLzA7QXJyYXkuZnJvbSh0aGlzLmlubmVyLmNoaWxkcmVuKS5mb3JFYWNoKChlPT57Y29uc3Qgcz1lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLG89dGhpcy5pbm5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxsPXMubGVmdCtzLndpZHRoLzItby5sZWZ0LHI9TWF0aC5hYnModC0oby5sZWZ0K2wpKTtyPG4mJihuPXIsaT1lKX0pKSxpJiYocz1BcnJheS5mcm9tKHRoaXMuc2xpZGVzKS5maW5kSW5kZXgoKGU9PmU9PT1pKSkpLHRoaXMuc2V0SW5kZXgocyksdGhpcy5kb3RzJiZ0aGlzLnNldEN1cnJlbnREb3QoKX1wcmV2Q2xpY2soKXt0aGlzLmdvVG9QcmV2KCksdGhpcy5pc0F1dG9QbGF5JiYodGhpcy5yZXNldFRpbWVyKCksdGhpcy5zZXRUaW1lcigpKX1uZXh0Q2xpY2soKXt0aGlzLmdvVG9OZXh0KCksdGhpcy5pc0F1dG9QbGF5JiYodGhpcy5yZXNldFRpbWVyKCksdGhpcy5zZXRUaW1lcigpKX1jb250YWluZXJTY3JvbGwoKXtjbGVhclRpbWVvdXQodGhpcy5pc1Njcm9sbGluZyksdGhpcy5pc1Njcm9sbGluZz1zZXRUaW1lb3V0KCgoKT0+e3RoaXMuc2V0SXNTbmFwKCl9KSwxMDApfWVsZW1lbnRUb3VjaFN0YXJ0KGUpe3RoaXMudG91Y2hYLnN0YXJ0PWUuY2hhbmdlZFRvdWNoZXNbMF0uc2NyZWVuWH1lbGVtZW50VG91Y2hFbmQoZSl7dGhpcy50b3VjaFguZW5kPWUuY2hhbmdlZFRvdWNoZXNbMF0uc2NyZWVuWCx0aGlzLmRldGVjdERpcmVjdGlvbigpfWlubmVyTW91c2VEb3duKGUpe3RoaXMuaGFuZGxlRHJhZ1N0YXJ0KGUpfWlubmVyVG91Y2hTdGFydChlKXt0aGlzLmhhbmRsZURyYWdTdGFydChlKX1kb2N1bWVudE1vdXNlTW92ZShlKXt0aGlzLmhhbmRsZURyYWdNb3ZlKGUpfWRvY3VtZW50VG91Y2hNb3ZlKGUpe3RoaXMuaGFuZGxlRHJhZ01vdmUoZSl9ZG9jdW1lbnRNb3VzZVVwKCl7dGhpcy5oYW5kbGVEcmFnRW5kKCl9ZG9jdW1lbnRUb3VjaEVuZCgpe3RoaXMuaGFuZGxlRHJhZ0VuZCgpfWRvdENsaWNrKGUpe3RoaXMuZ29UbyhlKSx0aGlzLmlzQXV0b1BsYXkmJih0aGlzLnJlc2V0VGltZXIoKSx0aGlzLnNldFRpbWVyKCkpfWluaXQoKXt0aGlzLmNyZWF0ZUNvbGxlY3Rpb24od2luZG93LiRoc0Nhcm91c2VsQ29sbGVjdGlvbix0aGlzKSx0aGlzLmlubmVyJiYodGhpcy5jYWxjdWxhdGVXaWR0aCgpLHRoaXMuaXNEcmFnZ2FibGUmJiF0aGlzLmlzU25hcCYmdGhpcy5pbml0RHJhZ0hhbmRsaW5nKCkpLHRoaXMucHJldiYmKHRoaXMub25QcmV2Q2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5wcmV2Q2xpY2soKSx0aGlzLnByZXYuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblByZXZDbGlja0xpc3RlbmVyKSksdGhpcy5uZXh0JiYodGhpcy5vbk5leHRDbGlja0xpc3RlbmVyPSgpPT50aGlzLm5leHRDbGljaygpLHRoaXMubmV4dC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uTmV4dENsaWNrTGlzdGVuZXIpKSx0aGlzLmRvdHMmJnRoaXMuaW5pdERvdHMoKSx0aGlzLmluZm8mJnRoaXMuYnVpbGRJbmZvKCksdGhpcy5zbGlkZXMubGVuZ3RoJiYodGhpcy5hZGRDdXJyZW50Q2xhc3MoKSx0aGlzLmlzSW5maW5pdGVMb29wfHx0aGlzLmFkZERpc2FibGVkQ2xhc3MoKSx0aGlzLmlzQXV0b1BsYXkmJnRoaXMuYXV0b1BsYXkoKSksc2V0VGltZW91dCgoKCk9Pnt0aGlzLmlzU25hcCYmdGhpcy5zZXRJc1NuYXAoKSx0aGlzLmxvYWRpbmdDbGFzc2VzUmVtb3ZlJiYoXCJzdHJpbmdcIj09dHlwZW9mIHRoaXMubG9hZGluZ0NsYXNzZXNSZW1vdmU/dGhpcy5pbm5lci5jbGFzc0xpc3QucmVtb3ZlKHRoaXMubG9hZGluZ0NsYXNzZXNSZW1vdmUpOnRoaXMuaW5uZXIuY2xhc3NMaXN0LnJlbW92ZSguLi50aGlzLmxvYWRpbmdDbGFzc2VzUmVtb3ZlKSksdGhpcy5sb2FkaW5nQ2xhc3Nlc0FkZCYmKFwic3RyaW5nXCI9PXR5cGVvZiB0aGlzLmxvYWRpbmdDbGFzc2VzQWRkP3RoaXMuaW5uZXIuY2xhc3NMaXN0LmFkZCh0aGlzLmxvYWRpbmdDbGFzc2VzQWRkKTp0aGlzLmlubmVyLmNsYXNzTGlzdC5hZGQoLi4udGhpcy5sb2FkaW5nQ2xhc3Nlc0FkZCkpLHRoaXMuaW5uZXImJnRoaXMuYWZ0ZXJMb2FkaW5nQ2xhc3Nlc0FkZCYmc2V0VGltZW91dCgoKCk9PntcInN0cmluZ1wiPT10eXBlb2YgdGhpcy5hZnRlckxvYWRpbmdDbGFzc2VzQWRkP3RoaXMuaW5uZXIuY2xhc3NMaXN0LmFkZCh0aGlzLmFmdGVyTG9hZGluZ0NsYXNzZXNBZGQpOnRoaXMuaW5uZXIuY2xhc3NMaXN0LmFkZCguLi50aGlzLmFmdGVyTG9hZGluZ0NsYXNzZXNBZGQpfSkpfSksNDAwKSx0aGlzLmlzU25hcCYmKHRoaXMub25Db250YWluZXJTY3JvbGxMaXN0ZW5lcj0oKT0+dGhpcy5jb250YWluZXJTY3JvbGwoKSx0aGlzLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsdGhpcy5vbkNvbnRhaW5lclNjcm9sbExpc3RlbmVyKSksdGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwiaW5pdFwiKSx0aGlzLmlzU25hcHx8KHRoaXMub25FbGVtZW50VG91Y2hTdGFydExpc3RlbmVyPWU9PnRoaXMuZWxlbWVudFRvdWNoU3RhcnQoZSksdGhpcy5vbkVsZW1lbnRUb3VjaEVuZExpc3RlbmVyPWU9PnRoaXMuZWxlbWVudFRvdWNoRW5kKGUpLHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIix0aGlzLm9uRWxlbWVudFRvdWNoU3RhcnRMaXN0ZW5lciksdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIix0aGlzLm9uRWxlbWVudFRvdWNoRW5kTGlzdGVuZXIpKSx0aGlzLm9ic2VydmVSZXNpemUoKX1pbml0RHJhZ0hhbmRsaW5nKCl7Y29uc3QgZT10aGlzLmlubmVyO3RoaXMub25Jbm5lck1vdXNlRG93bkxpc3RlbmVyPWU9PnRoaXMuaW5uZXJNb3VzZURvd24oZSksdGhpcy5vbklubmVyVG91Y2hTdGFydExpc3RlbmVyPWU9PnRoaXMuaW5uZXJUb3VjaFN0YXJ0KGUpLHRoaXMub25Eb2N1bWVudE1vdXNlTW92ZUxpc3RlbmVyPWU9PnRoaXMuZG9jdW1lbnRNb3VzZU1vdmUoZSksdGhpcy5vbkRvY3VtZW50VG91Y2hNb3ZlTGlzdGVuZXI9ZT0+dGhpcy5kb2N1bWVudFRvdWNoTW92ZShlKSx0aGlzLm9uRG9jdW1lbnRNb3VzZVVwTGlzdGVuZXI9KCk9PnRoaXMuZG9jdW1lbnRNb3VzZVVwKCksdGhpcy5vbkRvY3VtZW50VG91Y2hFbmRMaXN0ZW5lcj0oKT0+dGhpcy5kb2N1bWVudFRvdWNoRW5kKCksZSYmKGUuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZG93blwiLHRoaXMub25Jbm5lck1vdXNlRG93bkxpc3RlbmVyKSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsdGhpcy5vbklubmVyVG91Y2hTdGFydExpc3RlbmVyLHtwYXNzaXZlOiEwfSksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLHRoaXMub25Eb2N1bWVudE1vdXNlTW92ZUxpc3RlbmVyKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsdGhpcy5vbkRvY3VtZW50VG91Y2hNb3ZlTGlzdGVuZXIse3Bhc3NpdmU6ITF9KSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLHRoaXMub25Eb2N1bWVudE1vdXNlVXBMaXN0ZW5lciksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsdGhpcy5vbkRvY3VtZW50VG91Y2hFbmRMaXN0ZW5lcikpfWdldFRyYW5zbGF0ZVhWYWx1ZSgpe3ZhciBlO2NvbnN0IHQ9d2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5pbm5lcikudHJhbnNmb3JtO2lmKFwibm9uZVwiIT09dCl7Y29uc3QgaT1udWxsPT09KGU9dC5tYXRjaCgvbWF0cml4LipcXCgoLispXFwpLykpfHx2b2lkIDA9PT1lP3ZvaWQgMDplWzFdLnNwbGl0KFwiLCBcIik7aWYoaSl7bGV0IGU9cGFyc2VGbG9hdCg2PT09aS5sZW5ndGg/aVs0XTppWzEyXSk7cmV0dXJuIHRoaXMuaXNSVEwmJihlPS1lKSxpc05hTihlKXx8MD09PWU/MDotZX19cmV0dXJuIDB9cmVtb3ZlQ2xpY2tFdmVudFdoaWxlRHJhZ2dpbmcoZSl7ZS5wcmV2ZW50RGVmYXVsdCgpfWhhbmRsZURyYWdTdGFydChlKXtlLnByZXZlbnREZWZhdWx0KCksdGhpcy5pc0RyYWdnaW5nPSEwLHRoaXMuZHJhZ1N0YXJ0WD10aGlzLmdldEV2ZW50WChlKSx0aGlzLmluaXRpYWxUcmFuc2xhdGVYPXRoaXMuaXNSVEw/dGhpcy5nZXRUcmFuc2xhdGVYVmFsdWUoKTotdGhpcy5nZXRUcmFuc2xhdGVYVmFsdWUoKSx0aGlzLmlubmVyLmNsYXNzTGlzdC5hZGQoXCJkcmFnZ2luZ1wiKX1oYW5kbGVEcmFnTW92ZShlKXtpZighdGhpcy5pc0RyYWdnaW5nKXJldHVybjt0aGlzLmlubmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCJhOm5vdCgucHJldmVudGVkLWNsaWNrKVwiKS5mb3JFYWNoKChlPT57ZS5jbGFzc0xpc3QuYWRkKFwicHJldmVudGVkLWNsaWNrXCIpLGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5yZW1vdmVDbGlja0V2ZW50V2hpbGVEcmFnZ2luZyl9KSk7bGV0IHQ9dGhpcy5nZXRFdmVudFgoZSktdGhpcy5kcmFnU3RhcnRYO3RoaXMuaXNSVEwmJih0PS10KTtjb25zdCBpPXRoaXMuaW5pdGlhbFRyYW5zbGF0ZVgrdDt0aGlzLnNldFRyYW5zbGF0ZSgoKCk9PntsZXQgZT10aGlzLnNsaWRlcldpZHRoKnRoaXMuc2xpZGVzLmxlbmd0aC90aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKS10aGlzLnNsaWRlcldpZHRoO2NvbnN0IHQ9dGhpcy5zbGlkZXJXaWR0aCxzPSh0LXQvdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCkpLzIsbj10aGlzLmlzQ2VudGVyZWQ/czowO3RoaXMuaXNDZW50ZXJlZCYmKGUrPXMpO2NvbnN0IG89LWU7cmV0dXJuIHRoaXMuaXNSVEw/aTxuP246aT5lP286LWk6aT5uP246aTwtZT9vOml9KSgpKX1oYW5kbGVEcmFnRW5kKCl7aWYoIXRoaXMuaXNEcmFnZ2luZylyZXR1cm47dGhpcy5pc0RyYWdnaW5nPSExO2NvbnN0IGU9dGhpcy5zbGlkZXJXaWR0aC90aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKSx0PXRoaXMuZ2V0VHJhbnNsYXRlWFZhbHVlKCk7bGV0IGk9TWF0aC5yb3VuZCh0L2UpO3RoaXMuaXNSVEwmJihpPU1hdGgucm91bmQodC9lKSksdGhpcy5pbm5lci5jbGFzc0xpc3QucmVtb3ZlKFwiZHJhZ2dpbmdcIiksc2V0VGltZW91dCgoKCk9Pnt0aGlzLmNhbGN1bGF0ZVRyYW5zZm9ybShpKSx0aGlzLmRvdHMmJnRoaXMuc2V0Q3VycmVudERvdCgpLHRoaXMuZHJhZ1N0YXJ0WD1udWxsLHRoaXMuaW5pdGlhbFRyYW5zbGF0ZVg9bnVsbCx0aGlzLmlubmVyLnF1ZXJ5U2VsZWN0b3JBbGwoXCJhLnByZXZlbnRlZC1jbGlja1wiKS5mb3JFYWNoKChlPT57ZS5jbGFzc0xpc3QucmVtb3ZlKFwicHJldmVudGVkLWNsaWNrXCIpLGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5yZW1vdmVDbGlja0V2ZW50V2hpbGVEcmFnZ2luZyl9KSl9KSl9Z2V0RXZlbnRYKGUpe3JldHVybiBlIGluc3RhbmNlb2YgTW91c2VFdmVudD9lLmNsaWVudFg6ZS50b3VjaGVzWzBdLmNsaWVudFh9Z2V0Q3VycmVudFNsaWRlc1F0eSgpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiB0aGlzLnNsaWRlc1F0eSl7Y29uc3QgZT1kb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoO2xldCB0PTA7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuc2xpZGVzUXR5KS5mb3JFYWNoKChpPT57ZT49KHR5cGVvZiBpKzE9PVwibnVtYmVyXCI/dGhpcy5zbGlkZXNRdHlbaV06bC5CUkVBS1BPSU5UU1tpXSkmJih0PXRoaXMuc2xpZGVzUXR5W2ldKX0pKSx0fXJldHVybiB0aGlzLnNsaWRlc1F0eX1idWlsZFNuYXBTcGFjZXJzKCl7Y29uc3QgZT10aGlzLmlubmVyLnF1ZXJ5U2VsZWN0b3IoXCIuc25hcC1iZWZvcmVcIiksdD10aGlzLmlubmVyLnF1ZXJ5U2VsZWN0b3IoXCIuc25hcC1hZnRlclwiKTtlJiZlLnJlbW92ZSgpLHQmJnQucmVtb3ZlKCk7Y29uc3QgaT10aGlzLnNsaWRlcldpZHRoLHM9aS8yLWkvdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCkvMixvPSgwLG4uaHRtbFRvRWxlbWVudCkoYDxkaXYgY2xhc3M9XCJzbmFwLWJlZm9yZVwiIHN0eWxlPVwiaGVpZ2h0OiAxMDAlOyB3aWR0aDogJHtzfXB4XCI+PC9kaXY+YCksbD0oMCxuLmh0bWxUb0VsZW1lbnQpKGA8ZGl2IGNsYXNzPVwic25hcC1hZnRlclwiIHN0eWxlPVwiaGVpZ2h0OiAxMDAlOyB3aWR0aDogJHtzfXB4XCI+PC9kaXY+YCk7dGhpcy5pbm5lci5wcmVwZW5kKG8pLHRoaXMuaW5uZXIuYXBwZW5kQ2hpbGQobCl9aW5pdERvdHMoKXt0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuY2Fyb3VzZWwtcGFnaW5hdGlvbi1pdGVtXCIpLmxlbmd0aD90aGlzLnNldERvdHMoKTp0aGlzLmJ1aWxkRG90cygpLHRoaXMuZG90cyYmdGhpcy5zZXRDdXJyZW50RG90KCl9YnVpbGREb3RzKCl7dGhpcy5kb3RzLmlubmVySFRNTD1cIlwiO2NvbnN0IGU9IXRoaXMuaXNDZW50ZXJlZCYmdGhpcy5zbGlkZXNRdHk/dGhpcy5zbGlkZXMubGVuZ3RoLSh0aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKS0xKTp0aGlzLnNsaWRlcy5sZW5ndGg7Zm9yKGxldCB0PTA7dDxlO3QrKyl7Y29uc3QgZT10aGlzLmJ1aWxkU2luZ2xlRG90KHQpO3RoaXMuZG90cy5hcHBlbmQoZSl9fXNldERvdHMoKXt0aGlzLmRvdHNJdGVtcz10aGlzLmRvdHMucXVlcnlTZWxlY3RvckFsbChcIi5jYXJvdXNlbC1wYWdpbmF0aW9uLWl0ZW1cIiksdGhpcy5kb3RzSXRlbXMuZm9yRWFjaCgoKGUsdCk9Pntjb25zdCBpPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1jYXJvdXNlbC1wYWdpbmF0aW9uLWl0ZW0tdGFyZ2V0XCIpO3RoaXMuc2luZ2xlRG90RXZlbnRzKGUsaT8raTp0KX0pKX1nb1RvQ3VycmVudERvdCgpe2NvbnN0IGU9dGhpcy5kb3RzLHQ9ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxpPWUuc2Nyb2xsTGVmdCxzPWUuc2Nyb2xsVG9wLG49ZS5jbGllbnRXaWR0aCxvPWUuY2xpZW50SGVpZ2h0LGw9dGhpcy5kb3RzSXRlbXNbdGhpcy5jdXJyZW50SW5kZXhdLHI9bC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxhPXIubGVmdC10LmxlZnQraSxjPWErbC5jbGllbnRXaWR0aCxkPXIudG9wLXQudG9wK3MsaD1kK2wuY2xpZW50SGVpZ2h0O2xldCB1PWkscD1zOyhhPGl8fGM+aStuKSYmKHU9Yy1uKSwoZDxzfHxoPnMrbykmJihwPWgtbyksZS5zY3JvbGxUbyh7bGVmdDp1LHRvcDpwLGJlaGF2aW9yOlwic21vb3RoXCJ9KX1idWlsZEluZm8oKXt0aGlzLmluZm9Ub3RhbCYmdGhpcy5zZXRJbmZvVG90YWwoKSx0aGlzLmluZm9DdXJyZW50JiZ0aGlzLnNldEluZm9DdXJyZW50KCl9c2V0SW5mb1RvdGFsKCl7dGhpcy5pbmZvVG90YWwuaW5uZXJUZXh0PWAke3RoaXMuc2xpZGVzLmxlbmd0aH1gfXNldEluZm9DdXJyZW50KCl7dGhpcy5pbmZvQ3VycmVudC5pbm5lclRleHQ9YCR7dGhpcy5jdXJyZW50SW5kZXgrMX1gfWJ1aWxkU2luZ2xlRG90KGUpe2NvbnN0IHQ9KDAsbi5odG1sVG9FbGVtZW50KShcIjxzcGFuPjwvc3Bhbj5cIik7cmV0dXJuIHRoaXMuZG90c0l0ZW1DbGFzc2VzJiYoMCxuLmNsYXNzVG9DbGFzc0xpc3QpKHRoaXMuZG90c0l0ZW1DbGFzc2VzLHQpLHRoaXMuc2luZ2xlRG90RXZlbnRzKHQsZSksdH1zaW5nbGVEb3RFdmVudHMoZSx0KXt0aGlzLm9uRG90Q2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy5kb3RDbGljayh0KSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Eb3RDbGlja0xpc3RlbmVyKX1vYnNlcnZlUmVzaXplKCl7bmV3IFJlc2l6ZU9ic2VydmVyKCgwLG4uZGVib3VuY2UpKChlPT57Zm9yKGxldCB0IG9mIGUpe2NvbnN0IGU9dC5jb250ZW50UmVjdC53aWR0aDtlIT09dGhpcy5yZXNpemVDb250YWluZXJXaWR0aCYmKHRoaXMucmVjYWxjdWxhdGVXaWR0aCgpLHRoaXMuZG90cyYmdGhpcy5pbml0RG90cygpLHRoaXMuYWRkQ3VycmVudENsYXNzKCksdGhpcy5yZXNpemVDb250YWluZXJXaWR0aD1lKX19KSx0aGlzLnVwZGF0ZURlbGF5KSkub2JzZXJ2ZSh0aGlzLnJlc2l6ZUNvbnRhaW5lcil9Y2FsY3VsYXRlV2lkdGgoKXt0aGlzLmlzU25hcHx8KHRoaXMuaW5uZXIuc3R5bGUud2lkdGg9dGhpcy5zbGlkZXJXaWR0aCp0aGlzLnNsaWRlcy5sZW5ndGgvdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCkrXCJweFwiKSx0aGlzLnNsaWRlcy5mb3JFYWNoKChlPT57ZS5zdHlsZS53aWR0aD10aGlzLnNsaWRlcldpZHRoL3RoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpK1wicHhcIn0pKSx0aGlzLmNhbGN1bGF0ZVRyYW5zZm9ybSgpfWFkZEN1cnJlbnRDbGFzcygpe2lmKHRoaXMuaXNTbmFwKXtjb25zdCBlPU1hdGguZmxvb3IodGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCkvMik7Zm9yKGxldCB0PTA7dDx0aGlzLnNsaWRlcy5sZW5ndGg7dCsrKXtjb25zdCBpPXRoaXMuc2xpZGVzW3RdO3Q8PXRoaXMuY3VycmVudEluZGV4K2UmJnQ+PXRoaXMuY3VycmVudEluZGV4LWU/aS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpOmkuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKX19ZWxzZXtjb25zdCBlPXRoaXMuaXNDZW50ZXJlZD90aGlzLmN1cnJlbnRJbmRleCt0aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKSsodGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCktMSk6dGhpcy5jdXJyZW50SW5kZXgrdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCk7dGhpcy5zbGlkZXMuZm9yRWFjaCgoKHQsaSk9PntpPj10aGlzLmN1cnJlbnRJbmRleCYmaTxlP3QuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKTp0LmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIil9KSl9fXNldEN1cnJlbnREb3QoKXtjb25zdCBlPShlLHQpPT57bGV0IGk9ITE7Y29uc3Qgcz1NYXRoLmZsb29yKHRoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpLzIpO2k9dGhpcy5pc1NuYXAmJiF0aGlzLmhhc1NuYXBTcGFjZXJzP3Q9PT0odGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCklMj09MD90aGlzLmN1cnJlbnRJbmRleC1zKzE6dGhpcy5jdXJyZW50SW5kZXgtcyk6dD09PXRoaXMuY3VycmVudEluZGV4LGk/ZS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpOmUuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKX07dGhpcy5kb3RzSXRlbXM/dGhpcy5kb3RzSXRlbXMuZm9yRWFjaCgoKHQsaSk9PmUodCxpKSkpOnRoaXMuZG90cy5xdWVyeVNlbGVjdG9yQWxsKFwiOnNjb3BlID4gKlwiKS5mb3JFYWNoKCgodCxpKT0+ZSh0LGkpKSl9c2V0RWxlbWVudFRvRGlzYWJsZWQoZSl7ZS5jbGFzc0xpc3QuYWRkKFwiZGlzYWJsZWRcIiksXCJCVVRUT05cIiE9PWUudGFnTmFtZSYmXCJJTlBVVFwiIT09ZS50YWdOYW1lfHxlLnNldEF0dHJpYnV0ZShcImRpc2FibGVkXCIsXCJkaXNhYmxlZFwiKX11bnNldEVsZW1lbnRUb0Rpc2FibGVkKGUpe2UuY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpLFwiQlVUVE9OXCIhPT1lLnRhZ05hbWUmJlwiSU5QVVRcIiE9PWUudGFnTmFtZXx8ZS5yZW1vdmVBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKX1hZGREaXNhYmxlZENsYXNzKCl7aWYoIXRoaXMucHJldnx8IXRoaXMubmV4dClyZXR1cm4hMTtjb25zdCBlPWdldENvbXB1dGVkU3R5bGUodGhpcy5pbm5lcikuZ2V0UHJvcGVydHlWYWx1ZShcImdhcFwiKSx0PU1hdGguZmxvb3IodGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCkvMik7bGV0IGk9MCxzPTAsbj0hMSxvPSExO3RoaXMuaXNTbmFwPyhpPXRoaXMuY3VycmVudEluZGV4LHM9dGhpcy5oYXNTbmFwU3BhY2Vycz90aGlzLnNsaWRlcy5sZW5ndGgtMTp0aGlzLnNsaWRlcy5sZW5ndGgtdC0xLG49dGhpcy5oYXNTbmFwU3BhY2Vycz8wPT09aTp0aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKSUyPT0wP2ktdDwwOmktdD09MCxvPWk+PXMmJnRoaXMuY29udGFpbmVyLnNjcm9sbExlZnQrdGhpcy5jb250YWluZXIuY2xpZW50V2lkdGgrKHBhcnNlRmxvYXQoZSl8fDApPj10aGlzLmNvbnRhaW5lci5zY3JvbGxXaWR0aCk6KGk9dGhpcy5jdXJyZW50SW5kZXgscz10aGlzLmlzQ2VudGVyZWQ/dGhpcy5zbGlkZXMubGVuZ3RoLXRoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpKyh0aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKS0xKTp0aGlzLnNsaWRlcy5sZW5ndGgtdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCksbj0wPT09aSxvPWk+PXMpLG4/KHRoaXMudW5zZXRFbGVtZW50VG9EaXNhYmxlZCh0aGlzLm5leHQpLHRoaXMuc2V0RWxlbWVudFRvRGlzYWJsZWQodGhpcy5wcmV2KSk6bz8odGhpcy51bnNldEVsZW1lbnRUb0Rpc2FibGVkKHRoaXMucHJldiksdGhpcy5zZXRFbGVtZW50VG9EaXNhYmxlZCh0aGlzLm5leHQpKToodGhpcy51bnNldEVsZW1lbnRUb0Rpc2FibGVkKHRoaXMucHJldiksdGhpcy51bnNldEVsZW1lbnRUb0Rpc2FibGVkKHRoaXMubmV4dCkpfWF1dG9QbGF5KCl7dGhpcy5zZXRUaW1lcigpfXNldFRpbWVyKCl7dGhpcy50aW1lcj1zZXRJbnRlcnZhbCgoKCk9Pnt0aGlzLmN1cnJlbnRJbmRleD09PXRoaXMuc2xpZGVzLmxlbmd0aC0xP3RoaXMuZ29UbygwKTp0aGlzLmdvVG9OZXh0KCl9KSx0aGlzLnNwZWVkKX1yZXNldFRpbWVyKCl7Y2xlYXJJbnRlcnZhbCh0aGlzLnRpbWVyKX1kZXRlY3REaXJlY3Rpb24oKXtjb25zdHtzdGFydDplLGVuZDp0fT10aGlzLnRvdWNoWDt0PGUmJnRoaXMuZ29Ub05leHQoKSx0PmUmJnRoaXMuZ29Ub1ByZXYoKX1jYWxjdWxhdGVUcmFuc2Zvcm0oZSl7dm9pZCAwIT09ZSYmKHRoaXMuY3VycmVudEluZGV4PWUpO2NvbnN0IHQ9dGhpcy5zbGlkZXJXaWR0aCxpPXQvdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCk7bGV0IHM9dGhpcy5jdXJyZW50SW5kZXgqaTtpZih0aGlzLmlzU25hcCYmIXRoaXMuaXNDZW50ZXJlZCYmdGhpcy5jb250YWluZXIuc2Nyb2xsTGVmdDx0JiZ0aGlzLmNvbnRhaW5lci5zY3JvbGxMZWZ0K2kvMj50JiYodGhpcy5jb250YWluZXIuc2Nyb2xsTGVmdD10aGlzLmNvbnRhaW5lci5zY3JvbGxXaWR0aCksdGhpcy5pc0NlbnRlcmVkJiYhdGhpcy5pc1NuYXApe2NvbnN0IGU9KHQtaSkvMjtpZigwPT09dGhpcy5jdXJyZW50SW5kZXgpcz0tZTtlbHNlIGlmKHRoaXMuY3VycmVudEluZGV4Pj10aGlzLnNsaWRlcy5sZW5ndGgtdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCkrKHRoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpLTEpKXtzPXRoaXMuc2xpZGVzLmxlbmd0aCppLXQrZX1lbHNlIHM9dGhpcy5jdXJyZW50SW5kZXgqaS1lfXRoaXMuaXNTbmFwfHx0aGlzLnNldFRyYW5zZm9ybShzKSx0aGlzLmlzQXV0b0hlaWdodCYmKHRoaXMuaW5uZXIuc3R5bGUuaGVpZ2h0PWAke3RoaXMuc2xpZGVzW3RoaXMuY3VycmVudEluZGV4XS5jbGllbnRIZWlnaHR9cHhgKSx0aGlzLmRvdHNJdGVtcyYmdGhpcy5nb1RvQ3VycmVudERvdCgpLHRoaXMuYWRkQ3VycmVudENsYXNzKCksdGhpcy5pc0luZmluaXRlTG9vcHx8dGhpcy5hZGREaXNhYmxlZENsYXNzKCksdGhpcy5pc1NuYXAmJnRoaXMuaGFzU25hcFNwYWNlcnMmJnRoaXMuYnVpbGRTbmFwU3BhY2VycygpLHRoaXMuaW5mb0N1cnJlbnQmJnRoaXMuc2V0SW5mb0N1cnJlbnQoKX1zZXRUcmFuc2Zvcm0oZSl7dGhpcy5zbGlkZXMubGVuZ3RoPnRoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpP3RoaXMuaW5uZXIuc3R5bGUudHJhbnNmb3JtPXRoaXMuaXNSVEw/YHRyYW5zbGF0ZSgke2V9cHgsIDBweClgOmB0cmFuc2xhdGUoJHstZX1weCwgMHB4KWA6dGhpcy5pbm5lci5zdHlsZS50cmFuc2Zvcm09XCJ0cmFuc2xhdGUoMHB4LCAwcHgpXCJ9c2V0VHJhbnNsYXRlKGUpe3RoaXMuaW5uZXIuc3R5bGUudHJhbnNmb3JtPXRoaXMuaXNSVEw/YHRyYW5zbGF0ZSgkey1lfXB4LCAwcHgpYDpgdHJhbnNsYXRlKCR7ZX1weCwgMHB4KWB9c2V0SW5kZXgoZSl7dGhpcy5jdXJyZW50SW5kZXg9ZSx0aGlzLmFkZEN1cnJlbnRDbGFzcygpLHRoaXMuaXNJbmZpbml0ZUxvb3B8fHRoaXMuYWRkRGlzYWJsZWRDbGFzcygpfXJlY2FsY3VsYXRlV2lkdGgoKXt0aGlzLnNsaWRlcldpZHRoPXRoaXMuaW5uZXIucGFyZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCx0aGlzLmNhbGN1bGF0ZVdpZHRoKCksdGhpcy5zbGlkZXJXaWR0aCE9PXRoaXMuaW5uZXIucGFyZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCYmdGhpcy5yZWNhbGN1bGF0ZVdpZHRoKCl9Z29Ub1ByZXYoKXtpZih0aGlzLmN1cnJlbnRJbmRleD4wP3RoaXMuY3VycmVudEluZGV4LS06dGhpcy5jdXJyZW50SW5kZXg9dGhpcy5zbGlkZXMubGVuZ3RoLXRoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpLHRoaXMuaXNTbmFwKXtjb25zdCBlPXRoaXMuc2xpZGVyV2lkdGgvdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCk7dGhpcy5jb250YWluZXIuc2Nyb2xsQnkoe2xlZnQ6TWF0aC5tYXgoLXRoaXMuY29udGFpbmVyLnNjcm9sbExlZnQsLWUpLGJlaGF2aW9yOlwic21vb3RoXCJ9KSx0aGlzLmFkZEN1cnJlbnRDbGFzcygpLHRoaXMuaXNJbmZpbml0ZUxvb3B8fHRoaXMuYWRkRGlzYWJsZWRDbGFzcygpfWVsc2UgdGhpcy5jYWxjdWxhdGVUcmFuc2Zvcm0oKTt0aGlzLmRvdHMmJnRoaXMuc2V0Q3VycmVudERvdCgpfWdvVG9OZXh0KCl7Y29uc3QgZT10aGlzLmlzQ2VudGVyZWQ/dGhpcy5zbGlkZXMubGVuZ3RoLXRoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpKyh0aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKS0xKTp0aGlzLnNsaWRlcy5sZW5ndGgtdGhpcy5nZXRDdXJyZW50U2xpZGVzUXR5KCk7aWYodGhpcy5jdXJyZW50SW5kZXg8ZT90aGlzLmN1cnJlbnRJbmRleCsrOnRoaXMuY3VycmVudEluZGV4PTAsdGhpcy5pc1NuYXApe2NvbnN0IGU9dGhpcy5zbGlkZXJXaWR0aC90aGlzLmdldEN1cnJlbnRTbGlkZXNRdHkoKSx0PXRoaXMuY29udGFpbmVyLnNjcm9sbFdpZHRoLXRoaXMuY29udGFpbmVyLmNsaWVudFdpZHRoO3RoaXMuY29udGFpbmVyLnNjcm9sbEJ5KHtsZWZ0Ok1hdGgubWluKGUsdC10aGlzLmNvbnRhaW5lci5zY3JvbGxMZWZ0KSxiZWhhdmlvcjpcInNtb290aFwifSksdGhpcy5hZGRDdXJyZW50Q2xhc3MoKSx0aGlzLmlzSW5maW5pdGVMb29wfHx0aGlzLmFkZERpc2FibGVkQ2xhc3MoKX1lbHNlIHRoaXMuY2FsY3VsYXRlVHJhbnNmb3JtKCk7dGhpcy5kb3RzJiZ0aGlzLnNldEN1cnJlbnREb3QoKX1nb1RvKGUpe2NvbnN0IHQ9dGhpcy5jdXJyZW50SW5kZXg7aWYodGhpcy5jdXJyZW50SW5kZXg9ZSx0aGlzLmlzU25hcCl7Y29uc3QgZT10aGlzLnNsaWRlcldpZHRoL3RoaXMuZ2V0Q3VycmVudFNsaWRlc1F0eSgpLGk9dD50aGlzLmN1cnJlbnRJbmRleD90LXRoaXMuY3VycmVudEluZGV4OnRoaXMuY3VycmVudEluZGV4LXQscz10PnRoaXMuY3VycmVudEluZGV4Py1lKmk6ZSppO3RoaXMuY29udGFpbmVyLnNjcm9sbEJ5KHtsZWZ0OnMsYmVoYXZpb3I6XCJzbW9vdGhcIn0pLHRoaXMuYWRkQ3VycmVudENsYXNzKCksdGhpcy5pc0luZmluaXRlTG9vcHx8dGhpcy5hZGREaXNhYmxlZENsYXNzKCl9ZWxzZSB0aGlzLmNhbGN1bGF0ZVRyYW5zZm9ybSgpO3RoaXMuZG90cyYmdGhpcy5zZXRDdXJyZW50RG90KCl9ZGVzdHJveSgpe3ZhciBlLHQ7aWYodGhpcy5sb2FkaW5nQ2xhc3Nlc0FkZCYmKFwic3RyaW5nXCI9PXR5cGVvZiB0aGlzLmxvYWRpbmdDbGFzc2VzQWRkP3RoaXMuaW5uZXIuY2xhc3NMaXN0LnJlbW92ZSh0aGlzLmxvYWRpbmdDbGFzc2VzQWRkKTp0aGlzLmlubmVyLmNsYXNzTGlzdC5yZW1vdmUoLi4udGhpcy5sb2FkaW5nQ2xhc3Nlc0FkZCkpLHRoaXMuaW5uZXImJnRoaXMuYWZ0ZXJMb2FkaW5nQ2xhc3Nlc0FkZCYmc2V0VGltZW91dCgoKCk9PntcInN0cmluZ1wiPT10eXBlb2YgdGhpcy5hZnRlckxvYWRpbmdDbGFzc2VzQWRkP3RoaXMuaW5uZXIuY2xhc3NMaXN0LnJlbW92ZSh0aGlzLmFmdGVyTG9hZGluZ0NsYXNzZXNBZGQpOnRoaXMuaW5uZXIuY2xhc3NMaXN0LnJlbW92ZSguLi50aGlzLmFmdGVyTG9hZGluZ0NsYXNzZXNBZGQpfSkpLHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcImluaXRcIiksdGhpcy5pbm5lci5jbGFzc0xpc3QucmVtb3ZlKFwiZHJhZ2dpbmdcIiksdGhpcy5zbGlkZXMuZm9yRWFjaCgoZT0+ZS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpKSksKG51bGw9PT0oZT1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLmRvdHNJdGVtcyl8fHZvaWQgMD09PWU/dm9pZCAwOmUubGVuZ3RoKSYmdGhpcy5kb3RzSXRlbXMuZm9yRWFjaCgoZT0+ZS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpKSksdGhpcy5wcmV2LmNsYXNzTGlzdC5yZW1vdmUoXCJkaXNhYmxlZFwiKSx0aGlzLm5leHQuY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpLHRoaXMuaW5uZXIuc3R5bGUud2lkdGg9XCJcIix0aGlzLnNsaWRlcy5mb3JFYWNoKChlPT5lLnN0eWxlLndpZHRoPVwiXCIpKSx0aGlzLmlzU25hcHx8KHRoaXMuaW5uZXIuc3R5bGUudHJhbnNmb3JtPVwiXCIpLHRoaXMuaXNBdXRvSGVpZ2h0JiYodGhpcy5pbm5lci5zdHlsZS5oZWlnaHQ9XCJcIiksdGhpcy5wcmV2LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25QcmV2Q2xpY2tMaXN0ZW5lciksdGhpcy5uZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25OZXh0Q2xpY2tMaXN0ZW5lciksdGhpcy5jb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLHRoaXMub25Db250YWluZXJTY3JvbGxMaXN0ZW5lciksdGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLHRoaXMub25FbGVtZW50VG91Y2hTdGFydExpc3RlbmVyKSx0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLHRoaXMub25FbGVtZW50VG91Y2hFbmRMaXN0ZW5lciksdGhpcy5pbm5lci5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsdGhpcy5vbklubmVyTW91c2VEb3duTGlzdGVuZXIpLHRoaXMuaW5uZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIix0aGlzLm9uSW5uZXJUb3VjaFN0YXJ0TGlzdGVuZXIpLGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIix0aGlzLm9uRG9jdW1lbnRNb3VzZU1vdmVMaXN0ZW5lciksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLHRoaXMub25Eb2N1bWVudFRvdWNoTW92ZUxpc3RlbmVyKSxkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLHRoaXMub25Eb2N1bWVudE1vdXNlVXBMaXN0ZW5lciksZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsdGhpcy5vbkRvY3VtZW50VG91Y2hFbmRMaXN0ZW5lciksdGhpcy5pbm5lci5xdWVyeVNlbGVjdG9yQWxsKFwiYTpub3QoLnByZXZlbnRlZC1jbGljaylcIikuZm9yRWFjaCgoZT0+e2UuY2xhc3NMaXN0LnJlbW92ZShcInByZXZlbnRlZC1jbGlja1wiKSxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMucmVtb3ZlQ2xpY2tFdmVudFdoaWxlRHJhZ2dpbmcpfSkpLChudWxsPT09KHQ9bnVsbD09dGhpcz92b2lkIDA6dGhpcy5kb3RzSXRlbXMpfHx2b2lkIDA9PT10P3ZvaWQgMDp0Lmxlbmd0aCl8fHRoaXMuZG90cy5xdWVyeVNlbGVjdG9yQWxsKFwiOnNjb3BlID4gKlwiKS5sZW5ndGgpeygobnVsbD09dGhpcz92b2lkIDA6dGhpcy5kb3RzSXRlbXMpfHx0aGlzLmRvdHMucXVlcnlTZWxlY3RvckFsbChcIjpzY29wZSA+ICpcIikpLmZvckVhY2goKGU9PmUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkRvdENsaWNrTGlzdGVuZXIpKSksdGhpcy5kb3RzLmlubmVySFRNTD1udWxsfXRoaXMuaW5uZXIucXVlcnlTZWxlY3RvcihcIi5zbmFwLWJlZm9yZVwiKS5yZW1vdmUoKSx0aGlzLmlubmVyLnF1ZXJ5U2VsZWN0b3IoXCIuc25hcC1hZnRlclwiKS5yZW1vdmUoKSx0aGlzLmRvdHNJdGVtcz1udWxsLHRoaXMuaXNEcmFnZ2luZz0hMSx0aGlzLmRyYWdTdGFydFg9bnVsbCx0aGlzLmluaXRpYWxUcmFuc2xhdGVYPW51bGwsd2luZG93LiRoc0Nhcm91c2VsQ29sbGVjdGlvbj13aW5kb3cuJGhzQ2Fyb3VzZWxDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZS5lbCE9PXRoaXMuZWwpKX1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0KXtjb25zdCBpPXdpbmRvdy4kaHNDYXJvdXNlbENvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50Om51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0Nhcm91c2VsQ29sbGVjdGlvbnx8KHdpbmRvdy4kaHNDYXJvdXNlbENvbGxlY3Rpb249W10pLHdpbmRvdy4kaHNDYXJvdXNlbENvbGxlY3Rpb24mJih3aW5kb3cuJGhzQ2Fyb3VzZWxDb2xsZWN0aW9uPXdpbmRvdy4kaHNDYXJvdXNlbENvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtY2Fyb3VzZWxdOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNDYXJvdXNlbENvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgcihlKX0pKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57ci5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNDYXJvdXNlbD1yKSx0LmRlZmF1bHQ9cn0sMzA2OmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU0FjY29yZGlvblxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCxpKXtzdXBlcihlLHQsaSksdGhpcy50b2dnbGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLmFjY29yZGlvbi10b2dnbGVcIil8fG51bGwsdGhpcy5jb250ZW50PXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIi5hY2NvcmRpb24tY29udGVudFwiKXx8bnVsbCx0aGlzLmdyb3VwPXRoaXMuZWwuY2xvc2VzdChcIi5hY2NvcmRpb25cIil8fG51bGwsdGhpcy51cGRhdGUoKSx0aGlzLmlzVG9nZ2xlU3RvcFByb3BhZ2F0ZWQ9KDAsbi5zdHJpbmdUb0Jvb2xlYW4pKCgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy50b2dnbGUsXCItLXN0b3AtcHJvcGFnYXRpb25cIixcImZhbHNlXCIpfHxcImZhbHNlXCIpLHRoaXMua2VlcE9uZU9wZW49ISF0aGlzLmdyb3VwJiYoMCxuLnN0cmluZ1RvQm9vbGVhbikoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmdyb3VwLFwiLS1rZWVwLW9uZS1vcGVuXCIsXCJmYWxzZVwiKXx8XCJmYWxzZVwiKSx0aGlzLnRvZ2dsZSYmdGhpcy5jb250ZW50JiZ0aGlzLmluaXQoKX1pbml0KCl7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNBY2NvcmRpb25Db2xsZWN0aW9uLHRoaXMpLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyPWU9PnRoaXMudG9nZ2xlQ2xpY2soZSksdGhpcy50b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblRvZ2dsZUNsaWNrTGlzdGVuZXIpfXRvZ2dsZUNsaWNrKGUpe2lmKHRoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwiYWN0aXZlXCIpJiZ0aGlzLmtlZXBPbmVPcGVuKXJldHVybiExO3RoaXMuaXNUb2dnbGVTdG9wUHJvcGFnYXRlZCYmZS5zdG9wUHJvcGFnYXRpb24oKSx0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcImFjdGl2ZVwiKT90aGlzLmhpZGUoKTp0aGlzLnNob3coKX1zaG93KCl7dmFyIGU7aWYodGhpcy5ncm91cCYmIXRoaXMuaXNBbHdheXNPcGVuZWQmJnRoaXMuZ3JvdXAucXVlcnlTZWxlY3RvcihcIjpzY29wZSA+IC5hY2NvcmRpb24taXRlbS5hY3RpdmVcIikmJnRoaXMuZ3JvdXAucXVlcnlTZWxlY3RvcihcIjpzY29wZSA+IC5hY2NvcmRpb24taXRlbS5hY3RpdmVcIikhPT10aGlzLmVsKXt3aW5kb3cuJGhzQWNjb3JkaW9uQ29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWw9PT10aGlzLmdyb3VwLnF1ZXJ5U2VsZWN0b3IoXCI6c2NvcGUgPiAuYWNjb3JkaW9uLWl0ZW0uYWN0aXZlXCIpKSkuZWxlbWVudC5oaWRlKCl9aWYodGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJhY3RpdmVcIikpcmV0dXJuITE7dGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLChudWxsPT09KGU9bnVsbD09dGhpcz92b2lkIDA6dGhpcy50b2dnbGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmFyaWFFeHBhbmRlZCkmJih0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJ0cnVlXCIpLHRoaXMuZmlyZUV2ZW50KFwiYmVmb3JlT3BlblwiLHRoaXMuZWwpLCgwLG4uZGlzcGF0Y2gpKFwiYmVmb3JlT3Blbi5hY2NvcmRpb24uaXRlbVwiLHRoaXMuZWwsdGhpcy5lbCksdGhpcy5jb250ZW50LnN0eWxlLmRpc3BsYXk9XCJibG9ja1wiLHRoaXMuY29udGVudC5zdHlsZS5oZWlnaHQ9XCIwXCIsc2V0VGltZW91dCgoKCk9Pnt0aGlzLmNvbnRlbnQuc3R5bGUuaGVpZ2h0PWAke3RoaXMuY29udGVudC5zY3JvbGxIZWlnaHR9cHhgLCgwLG4uYWZ0ZXJUcmFuc2l0aW9uKSh0aGlzLmNvbnRlbnQsKCgpPT57dGhpcy5jb250ZW50LnN0eWxlLmRpc3BsYXk9XCJibG9ja1wiLHRoaXMuY29udGVudC5zdHlsZS5oZWlnaHQ9XCJcIix0aGlzLmZpcmVFdmVudChcIm9wZW5cIix0aGlzLmVsKSwoMCxuLmRpc3BhdGNoKShcIm9wZW4uYWNjb3JkaW9uLml0ZW1cIix0aGlzLmVsLHRoaXMuZWwpfSkpfSkpfWhpZGUoKXt2YXIgZTtpZighdGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJhY3RpdmVcIikpcmV0dXJuITE7dGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpLChudWxsPT09KGU9bnVsbD09dGhpcz92b2lkIDA6dGhpcy50b2dnbGUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmFyaWFFeHBhbmRlZCkmJih0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJmYWxzZVwiKSx0aGlzLmZpcmVFdmVudChcImJlZm9yZUNsb3NlXCIsdGhpcy5lbCksKDAsbi5kaXNwYXRjaCkoXCJiZWZvcmVDbG9zZS5hY2NvcmRpb24uaXRlbVwiLHRoaXMuZWwsdGhpcy5lbCksdGhpcy5jb250ZW50LnN0eWxlLmhlaWdodD1gJHt0aGlzLmNvbnRlbnQuc2Nyb2xsSGVpZ2h0fXB4YCxzZXRUaW1lb3V0KCgoKT0+e3RoaXMuY29udGVudC5zdHlsZS5oZWlnaHQ9XCIwXCJ9KSksKDAsbi5hZnRlclRyYW5zaXRpb24pKHRoaXMuY29udGVudCwoKCk9Pnt0aGlzLmNvbnRlbnQuc3R5bGUuZGlzcGxheT1cIm5vbmVcIix0aGlzLmNvbnRlbnQuc3R5bGUuaGVpZ2h0PVwiXCIsdGhpcy5maXJlRXZlbnQoXCJjbG9zZVwiLHRoaXMuZWwpLCgwLG4uZGlzcGF0Y2gpKFwiY2xvc2UuYWNjb3JkaW9uLml0ZW1cIix0aGlzLmVsLHRoaXMuZWwpfSkpfXVwZGF0ZSgpe2lmKHRoaXMuZ3JvdXA9dGhpcy5lbC5jbG9zZXN0KFwiLmFjY29yZGlvblwiKXx8bnVsbCwhdGhpcy5ncm91cClyZXR1cm4hMTt0aGlzLmlzQWx3YXlzT3BlbmVkPXRoaXMuZ3JvdXAuaGFzQXR0cmlidXRlKFwiZGF0YS1hY2NvcmRpb24tYWx3YXlzLW9wZW5cIil8fCExLHdpbmRvdy4kaHNBY2NvcmRpb25Db2xsZWN0aW9uLm1hcCgoZT0+KGUuaWQ9PT10aGlzLmVsLmlkJiYoZS5lbGVtZW50Lmdyb3VwPXRoaXMuZ3JvdXAsZS5lbGVtZW50LmlzQWx3YXlzT3BlbmVkPXRoaXMuaXNBbHdheXNPcGVuZWQpLGUpKSl9ZGVzdHJveSgpe3ZhciBlOyhudWxsPT09KGU9bnVsbD09bD92b2lkIDA6bC5zZWxlY3RhYmxlKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5sZW5ndGgpJiZsLnNlbGVjdGFibGUuZm9yRWFjaCgoZT0+e2UubGlzdGVuZXJzLmZvckVhY2goKCh7ZWw6ZSxsaXN0ZW5lcjp0fSk9PntlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHQpfSkpfSkpLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyJiZ0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lciksdGhpcy50b2dnbGU9bnVsbCx0aGlzLmNvbnRlbnQ9bnVsbCx0aGlzLmdyb3VwPW51bGwsdGhpcy5vblRvZ2dsZUNsaWNrTGlzdGVuZXI9bnVsbCx3aW5kb3cuJGhzQWNjb3JkaW9uQ29sbGVjdGlvbj13aW5kb3cuJGhzQWNjb3JkaW9uQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGZpbmRJbkNvbGxlY3Rpb24oZSl7cmV0dXJuIHdpbmRvdy4kaHNBY2NvcmRpb25Db2xsZWN0aW9uLmZpbmQoKHQ9PmUgaW5zdGFuY2VvZiBsP3QuZWxlbWVudC5lbD09PWUuZWw6XCJzdHJpbmdcIj09dHlwZW9mIGU/dC5lbGVtZW50LmVsPT09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTp0LmVsZW1lbnQuZWw9PT1lKSl8fG51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0FjY29yZGlvbkNvbGxlY3Rpb258fCh3aW5kb3cuJGhzQWNjb3JkaW9uQ29sbGVjdGlvbj1bXSksd2luZG93LiRoc0FjY29yZGlvbkNvbGxlY3Rpb24mJih3aW5kb3cuJGhzQWNjb3JkaW9uQ29sbGVjdGlvbj13aW5kb3cuJGhzQWNjb3JkaW9uQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmRvY3VtZW50LmNvbnRhaW5zKGUuZWwpKSkpLGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuYWNjb3JkaW9uLWl0ZW06bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57d2luZG93LiRoc0FjY29yZGlvbkNvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgbChlKX0pKX1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0KXtjb25zdCBpPXdpbmRvdy4kaHNBY2NvcmRpb25Db2xsZWN0aW9uLmZpbmQoKHQ9PnQuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSk7cmV0dXJuIGk/dD9pOmkuZWxlbWVudC5lbDpudWxsfXN0YXRpYyBzaG93KGUpe2NvbnN0IHQ9bC5maW5kSW5Db2xsZWN0aW9uKGUpO3QmJlwiYmxvY2tcIiE9PXQuZWxlbWVudC5jb250ZW50LnN0eWxlLmRpc3BsYXkmJnQuZWxlbWVudC5zaG93KCl9c3RhdGljIGhpZGUoZSl7Y29uc3QgdD1sLmZpbmRJbkNvbGxlY3Rpb24oZSksaT10P3dpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHQuZWxlbWVudC5jb250ZW50KTpudWxsO3QmJlwibm9uZVwiIT09aS5kaXNwbGF5JiZ0LmVsZW1lbnQuaGlkZSgpfXN0YXRpYyB0cmVlVmlldygpe2lmKCFkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmFjY29yZGlvbi10cmVldmlldy1yb290XCIpLmxlbmd0aClyZXR1cm4hMTt0aGlzLnNlbGVjdGFibGU9W10sZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5hY2NvcmRpb24tdHJlZXZpZXctcm9vdFwiKS5mb3JFYWNoKChlPT57Y29uc3QgdD1udWxsPT1lP3ZvaWQgMDplLmdldEF0dHJpYnV0ZShcImRhdGEtYWNjb3JkaW9uLW9wdGlvbnNcIiksaT10P0pTT04ucGFyc2UodCk6e307dGhpcy5zZWxlY3RhYmxlLnB1c2goe2VsOmUsb3B0aW9uczpPYmplY3QuYXNzaWduKHt9LGkpLGxpc3RlbmVyczpbXX0pfSkpLHRoaXMuc2VsZWN0YWJsZS5sZW5ndGgmJnRoaXMuc2VsZWN0YWJsZS5mb3JFYWNoKChlPT57Y29uc3R7ZWw6dH09ZTt0LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuYWNjb3JkaW9uLXNlbGVjdGFibGVcIikuZm9yRWFjaCgodD0+e2NvbnN0IGk9aT0+dGhpcy5vblNlbGVjdGFibGVDbGljayhpLGUsdCk7dC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIixpKSxlLmxpc3RlbmVycy5wdXNoKHtlbDp0LGxpc3RlbmVyOml9KX0pKX0pKX1zdGF0aWMgdG9nZ2xlU2VsZWN0ZWQoZSx0KXt0LmNsYXNzTGlzdC5jb250YWlucyhcInNlbGVjdGVkXCIpP3QuY2xhc3NMaXN0LnJlbW92ZShcInNlbGVjdGVkXCIpOihlLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCIuYWNjb3JkaW9uLXNlbGVjdGFibGVcIikuZm9yRWFjaCgoZT0+ZS5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIikpKSx0LmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKSl9c3RhdGljIG9uKGUsdCxpKXtjb25zdCBzPWwuZmluZEluQ29sbGVjdGlvbih0KTtzJiYocy5lbGVtZW50LmV2ZW50c1tlXT1pKX19bC5vblNlbGVjdGFibGVDbGljaz0oZSx0LGkpPT57ZS5zdG9wUHJvcGFnYXRpb24oKSxsLnRvZ2dsZVNlbGVjdGVkKHQsaSl9LHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCgoKT0+e2wuYXV0b0luaXQoKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmFjY29yZGlvbi10cmVldmlldy1yb290XCIpLmxlbmd0aCYmbC50cmVlVmlldygpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNBY2NvcmRpb249bCksdC5kZWZhdWx0PWx9LDMxOTooZSx0LGkpPT57XG4vKlxuICogSFNTdGF0aWNNZXRob2RzXG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IHM9aSg4MDYpLG49aSgzOTMpLG89e2dldENsYXNzUHJvcGVydHk6cy5nZXRDbGFzc1Byb3BlcnR5LGFmdGVyVHJhbnNpdGlvbjpzLmFmdGVyVHJhbnNpdGlvbixhdXRvSW5pdChlPVwiYWxsXCIpe1wiYWxsXCI9PT1lP24uQ09MTEVDVElPTlMuZm9yRWFjaCgoKHtmbjplfSk9PntudWxsPT1lfHxlLmF1dG9Jbml0KCl9KSk6bi5DT0xMRUNUSU9OUy5mb3JFYWNoKCgoe2tleTp0LGZuOml9KT0+e2UuaW5jbHVkZXModCkmJihudWxsPT1pfHxpLmF1dG9Jbml0KCkpfSkpfSxjbGVhbkNvbGxlY3Rpb24oZT1cImFsbFwiKXtcImFsbFwiPT09ZT9uLkNPTExFQ1RJT05TLmZvckVhY2goKCh7Y29sbGVjdGlvbjplfSk9Pnt3aW5kb3dbZV1pbnN0YW5jZW9mIEFycmF5JiYod2luZG93W2VdPVtdKX0pKTpuLkNPTExFQ1RJT05TLmZvckVhY2goKCh7a2V5OnQsY29sbGVjdGlvbjppfSk9PntlLmluY2x1ZGVzKHQpJiZ3aW5kb3dbaV1pbnN0YW5jZW9mIEFycmF5JiYod2luZG93W2ldPVtdKX0pKX19O1widW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNTdGF0aWNNZXRob2RzPW8pLHQuZGVmYXVsdD1vfSwzOTM6ZnVuY3Rpb24oZSx0LGkpe3ZhciBzPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pLHQuQ09MTEVDVElPTlM9dm9pZCAwO2NvbnN0IG49cyhpKDEyKSksbz1zKGkoMzA2KSksbD1zKGkoMzAyKSkscj1zKGkoNzYzKSksYT1zKGkoNzUpKSxjPXMoaSg3OTIpKSxkPXMoaSg3NTMpKSxoPXMoaSgxOTIpKSx1PXMoaSg4NikpLHA9cyhpKDE2NCkpLG09cyhpKDU5NCkpLGc9cyhpKDk3NykpLGY9cyhpKDExMykpLHY9cyhpKDg4MSkpLHc9cyhpKDk1NikpLHk9cyhpKDIxMykpLGI9cyhpKDIwNykpLEM9cyhpKDk0NCkpLFM9cyhpKDEyNikpLEw9cyhpKDIzNCkpLEk9cyhpKDQ4NykpLEU9cyhpKDc4MikpO3QuQ09MTEVDVElPTlM9W3trZXk6XCJjb3B5LW1hcmt1cFwiLGZuOm4uZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzQ29weU1hcmt1cENvbGxlY3Rpb25cIn0se2tleTpcImFjY29yZGlvblwiLGZuOm8uZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzQWNjb3JkaW9uQ29sbGVjdGlvblwifSx7a2V5OlwiY2Fyb3VzZWxcIixmbjpsLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc0Nhcm91c2VsQ29sbGVjdGlvblwifSx7a2V5OlwiY29sbGFwc2VcIixmbjpyLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc0NvbGxhcHNlQ29sbGVjdGlvblwifSx7a2V5OlwiY29tYm9ib3hcIixmbjphLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc0NvbWJvQm94Q29sbGVjdGlvblwifSx7a2V5OlwiZGF0YXRhYmxlXCIsZm46Yy5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNEYXRhVGFibGVDb2xsZWN0aW9uXCJ9LHtrZXk6XCJkcm9wZG93blwiLGZuOmQuZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzRHJvcGRvd25Db2xsZWN0aW9uXCJ9LHtrZXk6XCJmaWxlLXVwbG9hZFwiLGZuOmguZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzRmlsZVVwbG9hZENvbGxlY3Rpb25cIn0se2tleTpcImlucHV0LW51bWJlclwiLGZuOnUuZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzSW5wdXROdW1iZXJDb2xsZWN0aW9uXCJ9LHtrZXk6XCJvdmVybGF5XCIsZm46cC5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNPdmVybGF5Q29sbGVjdGlvblwifSx7a2V5OlwicGluLWlucHV0XCIsZm46bS5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNQaW5JbnB1dENvbGxlY3Rpb25cIn0se2tleTpcInJhbmdlLXNsaWRlclwiLGZuOmcuZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzUmFuZ2VTbGlkZXJDb2xsZWN0aW9uXCJ9LHtrZXk6XCJyZW1vdmUtZWxlbWVudFwiLGZuOmYuZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzUmVtb3ZlRWxlbWVudENvbGxlY3Rpb25cIn0se2tleTpcInNjcm9sbHNweVwiLGZuOnYuZGVmYXVsdCxjb2xsZWN0aW9uOlwiJGhzU2Nyb2xsc3B5Q29sbGVjdGlvblwifSx7a2V5Olwic2VsZWN0XCIsZm46dy5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNTZWxlY3RDb2xsZWN0aW9uXCJ9LHtrZXk6XCJzdGVwcGVyXCIsZm46eS5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNTdGVwcGVyQ29sbGVjdGlvblwifSx7a2V5Olwic3Ryb25nLXBhc3N3b3JkXCIsZm46Yi5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNTdHJvbmdQYXNzd29yZENvbGxlY3Rpb25cIn0se2tleTpcInRhYnNcIixmbjpDLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc1RhYnNDb2xsZWN0aW9uXCJ9LHtrZXk6XCJ0b2dnbGUtY291bnRcIixmbjpTLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc1RvZ2dsZUNvdW50Q29sbGVjdGlvblwifSx7a2V5OlwidG9nZ2xlLXBhc3N3b3JkXCIsZm46TC5kZWZhdWx0LGNvbGxlY3Rpb246XCIkaHNUb2dnbGVQYXNzd29yZENvbGxlY3Rpb25cIn0se2tleTpcInRvb2x0aXBcIixmbjpJLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc1Rvb2x0aXBDb2xsZWN0aW9uXCJ9LHtrZXk6XCJ0cmVlLXZpZXdcIixmbjpFLmRlZmF1bHQsY29sbGVjdGlvbjpcIiRoc1RyZWVWaWV3Q29sbGVjdGlvblwifV19LDQ4NzpmdW5jdGlvbihlLHQsaSl7XG4vKlxuICogSFNUb29sdGlwXG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbnZhciBzPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IG49aSg5NDkpLG89aSg4MDYpLGw9cyhpKDI4NykpLHI9aSg5MTcpO2NsYXNzIGEgZXh0ZW5kcyBsLmRlZmF1bHR7Y29uc3RydWN0b3IoZSx0LGkpe3N1cGVyKGUsdCxpKSx0aGlzLmNsZWFudXBBdXRvVXBkYXRlPW51bGwsdGhpcy5lbCYmKHRoaXMudG9nZ2xlPXRoaXMuZWwucXVlcnlTZWxlY3RvcihcIi50b29sdGlwLXRvZ2dsZVwiKXx8dGhpcy5lbCx0aGlzLmNvbnRlbnQ9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiLnRvb2x0aXAtY29udGVudFwiKSx0aGlzLmV2ZW50TW9kZT0oMCxvLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLXRyaWdnZXJcIil8fFwiaG92ZXJcIix0aGlzLnByZXZlbnRGbG9hdGluZ1VJPSgwLG8uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tcHJldmVudC1wb3BwZXJcIixcImZhbHNlXCIpLHRoaXMucGxhY2VtZW50PSgwLG8uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tcGxhY2VtZW50XCIpLHRoaXMuaW50ZXJhY3Rpb249KDAsby5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS1pbnRlcmFjdGlvblwiLFwidHJ1ZVwiKSx0aGlzLnN0cmF0ZWd5PSgwLG8uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tc3RyYXRlZ3lcIiksdGhpcy5zY29wZT0oMCxvLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLXNjb3BlXCIpfHxcInBhcmVudFwiKSx0aGlzLmVsJiZ0aGlzLnRvZ2dsZSYmdGhpcy5jb250ZW50JiZ0aGlzLmluaXQoKX10b2dnbGVDbGljaygpe3RoaXMuY2xpY2soKX10b2dnbGVGb2N1cygpe3RoaXMuZm9jdXMoKX10b2dnbGVNb3VzZUVudGVyKCl7dGhpcy5lbnRlcigpfXRvZ2dsZU1vdXNlTGVhdmUoKXt0aGlzLmxlYXZlKCl9dG9nZ2xlSGFuZGxlKCl7dGhpcy5oaWRlKCksdGhpcy50b2dnbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblRvZ2dsZUhhbmRsZUxpc3RlbmVyLCEwKSx0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiYmx1clwiLHRoaXMub25Ub2dnbGVIYW5kbGVMaXN0ZW5lciwhMCl9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzVG9vbHRpcENvbGxlY3Rpb24sdGhpcyksXCJjbGlja1wiPT09dGhpcy5ldmVudE1vZGU/KHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyPSgpPT50aGlzLnRvZ2dsZUNsaWNrKCksdGhpcy50b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vblRvZ2dsZUNsaWNrTGlzdGVuZXIpKTpcImZvY3VzXCI9PT10aGlzLmV2ZW50TW9kZT8odGhpcy5vblRvZ2dsZUZvY3VzTGlzdGVuZXI9KCk9PnRoaXMudG9nZ2xlRm9jdXMoKSx0aGlzLnRvZ2dsZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlRm9jdXNMaXN0ZW5lcikpOlwiaG92ZXJcIj09PXRoaXMuZXZlbnRNb2RlJiYodGhpcy5vblRvZ2dsZU1vdXNlRW50ZXJMaXN0ZW5lcj0oKT0+dGhpcy50b2dnbGVNb3VzZUVudGVyKCksdGhpcy5vblRvZ2dsZU1vdXNlTGVhdmVMaXN0ZW5lcj0oKT0+dGhpcy50b2dnbGVNb3VzZUxlYXZlKCksdGhpcy50b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNlZW50ZXJcIix0aGlzLm9uVG9nZ2xlTW91c2VFbnRlckxpc3RlbmVyKSx0aGlzLnRvZ2dsZS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLHRoaXMub25Ub2dnbGVNb3VzZUxlYXZlTGlzdGVuZXIpKSx0aGlzLmJ1aWxkRmxvYXRpbmdVSSgpfWVudGVyKCl7dGhpcy5fc2hvdygpfWxlYXZlKCl7dGhpcy5oaWRlKCl9Y2xpY2soKXt0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcInNob3dcIik/dGhpcy5oaWRlKCk6KHRoaXMuX3Nob3coKSx0aGlzLm9uVG9nZ2xlSGFuZGxlTGlzdGVuZXI9KCk9PntzZXRUaW1lb3V0KCgoKT0+dGhpcy50b2dnbGVIYW5kbGUoKSkpfSx0aGlzLnRvZ2dsZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlSGFuZGxlTGlzdGVuZXIsITApLHRoaXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsdGhpcy5vblRvZ2dsZUhhbmRsZUxpc3RlbmVyLCEwKSl9Zm9jdXMoKXt2YXIgZTtpZih0aGlzLl9zaG93KCksXCJ0cnVlXCI9PT10aGlzLmludGVyYWN0aW9uKXtjb25zdCB0PWU9Pnt0aGlzLmNvbnRlbnQmJnRoaXMuY29udGVudC5jb250YWlucyhlLnRhcmdldCkmJmUuc3RvcFByb3BhZ2F0aW9uKCl9O251bGw9PT0oZT10aGlzLmNvbnRlbnQpfHx2b2lkIDA9PT1lfHxlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHQpO2NvbnN0IGk9ZT0+e3ZhciB0OyhudWxsPT09KHQ9dGhpcy5jb250ZW50KXx8dm9pZCAwPT09dD92b2lkIDA6dC5jb250YWlucyhlLnRhcmdldCkpfHx0aGlzLmVsLmNvbnRhaW5zKGUudGFyZ2V0KXx8dGhpcy5oaWRlKCl9O2RvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsaSl9ZWxzZXtjb25zdCBlPSgpPT57dGhpcy5oaWRlKCksdGhpcy50b2dnbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIixlLCEwKX07dGhpcy50b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcImJsdXJcIixlLCEwKX19YnVpbGRGbG9hdGluZ1VJKCl7dmFyIGU7XCJ3aW5kb3dcIj09PXRoaXMuc2NvcGUmJmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5jb250ZW50KTtjb25zdCB0PW51bGwhPT0oZT1yLlBPU0lUSU9OU1t0aGlzLnBsYWNlbWVudF0pJiZ2b2lkIDAhPT1lP2U6XCJ0b3BcIixpPW5ldyBTZXQoW1widG9wXCIsXCJ0b3Atc3RhcnRcIixcInRvcC1lbmRcIixcImJvdHRvbVwiLFwiYm90dG9tLXN0YXJ0XCIsXCJib3R0b20tZW5kXCJdKS5oYXModCkscz1cImZhbHNlXCI9PT10aGlzLnByZXZlbnRGbG9hdGluZ1VJLG89cyYmaSxsPXMsYT1bKDAsbi5vZmZzZXQpKDApLC4uLm8/WygwLG4uc2hpZnQpKCldOltdLC4uLmw/WygwLG4uZmxpcCkoKV06W11dOygwLG4uY29tcHV0ZVBvc2l0aW9uKSh0aGlzLnRvZ2dsZSx0aGlzLmNvbnRlbnQse3BsYWNlbWVudDpyLlBPU0lUSU9OU1t0aGlzLnBsYWNlbWVudF18fFwidG9wXCIsc3RyYXRlZ3k6dGhpcy5zdHJhdGVneXx8XCJmaXhlZFwiLG1pZGRsZXdhcmU6YX0pLnRoZW4oKCh7eDplLHk6dH0pPT57T2JqZWN0LmFzc2lnbih0aGlzLmNvbnRlbnQuc3R5bGUse3Bvc2l0aW9uOnRoaXMuc3RyYXRlZ3l8fFwiZml4ZWRcIixsZWZ0OmAke2V9cHhgLHRvcDpgJHt0fXB4YH0pfSkpLHRoaXMuY2xlYW51cEF1dG9VcGRhdGU9KDAsbi5hdXRvVXBkYXRlKSh0aGlzLnRvZ2dsZSx0aGlzLmNvbnRlbnQsKCgpPT57KDAsbi5jb21wdXRlUG9zaXRpb24pKHRoaXMudG9nZ2xlLHRoaXMuY29udGVudCx7cGxhY2VtZW50OnIuUE9TSVRJT05TW3RoaXMucGxhY2VtZW50XXx8XCJ0b3BcIixzdHJhdGVneTp0aGlzLnN0cmF0ZWd5fHxcImZpeGVkXCIsbWlkZGxld2FyZTphfSkudGhlbigoKHt4OmUseTp0fSk9PntPYmplY3QuYXNzaWduKHRoaXMuY29udGVudC5zdHlsZSx7bGVmdDpgJHtlfXB4YCx0b3A6YCR7dH1weGB9KX0pKX0pKX1fc2hvdygpe3RoaXMuY29udGVudC5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpLFwid2luZG93XCI9PT10aGlzLnNjb3BlJiZ0aGlzLmNvbnRlbnQuY2xhc3NMaXN0LmFkZChcInNob3dcIiksdGhpcy5jbGVhbnVwQXV0b1VwZGF0ZXx8dGhpcy5idWlsZEZsb2F0aW5nVUkoKSxzZXRUaW1lb3V0KCgoKT0+e3RoaXMuZWwuY2xhc3NMaXN0LmFkZChcInNob3dcIiksdGhpcy5maXJlRXZlbnQoXCJzaG93XCIsdGhpcy5lbCksKDAsby5kaXNwYXRjaCkoXCJzaG93LnRvb2x0aXBcIix0aGlzLmVsLHRoaXMuZWwpfSkpfXNob3coKXtzd2l0Y2godGhpcy5ldmVudE1vZGUpe2Nhc2VcImNsaWNrXCI6dGhpcy5jbGljaygpO2JyZWFrO2Nhc2VcImZvY3VzXCI6dGhpcy5mb2N1cygpO2JyZWFrO2RlZmF1bHQ6dGhpcy5lbnRlcigpfXRoaXMudG9nZ2xlLmZvY3VzKCksdGhpcy50b2dnbGUuc3R5bGUub3V0bGluZT1cIm5vbmVcIn1oaWRlKCl7dGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwic2hvd1wiKSxcIndpbmRvd1wiPT09dGhpcy5zY29wZSYmdGhpcy5jb250ZW50LmNsYXNzTGlzdC5yZW1vdmUoXCJzaG93XCIpLHRoaXMuY2xlYW51cEF1dG9VcGRhdGUmJih0aGlzLmNsZWFudXBBdXRvVXBkYXRlKCksdGhpcy5jbGVhbnVwQXV0b1VwZGF0ZT1udWxsKSx0aGlzLmZpcmVFdmVudChcImhpZGVcIix0aGlzLmVsKSwoMCxvLmRpc3BhdGNoKShcImhpZGUudG9vbHRpcFwiLHRoaXMuZWwsdGhpcy5lbCksKDAsby5hZnRlclRyYW5zaXRpb24pKHRoaXMuY29udGVudCwoKCk9PntpZih0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcInNob3dcIikpcmV0dXJuITE7dGhpcy5jb250ZW50LmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIiksdGhpcy50b2dnbGUuc3R5bGUub3V0bGluZT1cIlwifSkpfWRlc3Ryb3koKXt0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJzaG93XCIpLHRoaXMuY29udGVudC5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpLFwiY2xpY2tcIj09PXRoaXMuZXZlbnRNb2RlP3RoaXMudG9nZ2xlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyKTpcImZvY3VzXCI9PT10aGlzLmV2ZW50TW9kZT90aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlRm9jdXNMaXN0ZW5lcik6XCJob3ZlclwiPT09dGhpcy5ldmVudE1vZGUmJih0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2VlbnRlclwiLHRoaXMub25Ub2dnbGVNb3VzZUVudGVyTGlzdGVuZXIpLHRoaXMudG9nZ2xlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZWxlYXZlXCIsdGhpcy5vblRvZ2dsZU1vdXNlTGVhdmVMaXN0ZW5lcikpLHRoaXMudG9nZ2xlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVIYW5kbGVMaXN0ZW5lciwhMCksdGhpcy50b2dnbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJsdXJcIix0aGlzLm9uVG9nZ2xlSGFuZGxlTGlzdGVuZXIsITApLHRoaXMuY2xlYW51cEF1dG9VcGRhdGUmJih0aGlzLmNsZWFudXBBdXRvVXBkYXRlKCksdGhpcy5jbGVhbnVwQXV0b1VwZGF0ZT1udWxsKSx3aW5kb3cuJGhzVG9vbHRpcENvbGxlY3Rpb249d2luZG93LiRoc1Rvb2x0aXBDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZS5lbCE9PXRoaXMuZWwpKX1zdGF0aWMgZmluZEluQ29sbGVjdGlvbihlKXtyZXR1cm4gd2luZG93LiRoc1Rvb2x0aXBDb2xsZWN0aW9uLmZpbmQoKHQ9PmUgaW5zdGFuY2VvZiBhP3QuZWxlbWVudC5lbD09PWUuZWw6XCJzdHJpbmdcIj09dHlwZW9mIGU/dC5lbGVtZW50LmVsPT09ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTp0LmVsZW1lbnQuZWw9PT1lKSl8fG51bGx9c3RhdGljIGdldEluc3RhbmNlKGUsdD0hMSl7Y29uc3QgaT13aW5kb3cuJGhzVG9vbHRpcENvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50LmVsOm51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc1Rvb2x0aXBDb2xsZWN0aW9ufHwod2luZG93LiRoc1Rvb2x0aXBDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzVG9vbHRpcENvbGxlY3Rpb24mJih3aW5kb3cuJGhzVG9vbHRpcENvbGxlY3Rpb249d2luZG93LiRoc1Rvb2x0aXBDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi50b29sdGlwOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNUb29sdGlwQ29sbGVjdGlvbi5maW5kKCh0PT57dmFyIGk7cmV0dXJuKG51bGw9PT0oaT1udWxsPT10P3ZvaWQgMDp0LmVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmVsKT09PWV9KSl8fG5ldyBhKGUpfSkpfXN0YXRpYyBzaG93KGUpe2NvbnN0IHQ9YS5maW5kSW5Db2xsZWN0aW9uKGUpO3QmJnQuZWxlbWVudC5zaG93KCl9c3RhdGljIGhpZGUoZSl7Y29uc3QgdD1hLmZpbmRJbkNvbGxlY3Rpb24oZSk7dCYmdC5lbGVtZW50LmhpZGUoKX1zdGF0aWMgb24oZSx0LGkpe2NvbnN0IHM9YS5maW5kSW5Db2xsZWN0aW9uKHQpO3MmJihzLmVsZW1lbnQuZXZlbnRzW2VdPWkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PnthLmF1dG9Jbml0KCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1Rvb2x0aXA9YSksdC5kZWZhdWx0PWF9LDU5NDpmdW5jdGlvbihlLHQsaSl7XG4vKlxuICogSFNQaW5JbnB1dFxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2VsZW1lbnRJbnB1dChlLHQpe3RoaXMub25JbnB1dChlLHQpfWVsZW1lbnRQYXN0ZShlKXt0aGlzLm9uUGFzdGUoZSl9ZWxlbWVudEtleWRvd24oZSx0KXt0aGlzLm9uS2V5ZG93bihlLHQpfWVsZW1lbnRGb2N1c2luKGUpe3RoaXMub25Gb2N1c0luKGUpfWVsZW1lbnRGb2N1c291dChlKXt0aGlzLm9uRm9jdXNPdXQoZSl9Y29uc3RydWN0b3IoZSx0KXtzdXBlcihlLHQpO2NvbnN0IGk9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBpbi1pbnB1dFwiKSxzPWk/SlNPTi5wYXJzZShpKTp7fSxuPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KTt0aGlzLml0ZW1zPXRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXBpbi1pbnB1dC1pdGVtXVwiKSx0aGlzLmN1cnJlbnRJdGVtPW51bGwsdGhpcy5jdXJyZW50VmFsdWU9bmV3IEFycmF5KHRoaXMuaXRlbXMubGVuZ3RoKS5maWxsKFwiXCIpLHRoaXMucGxhY2Vob2xkZXJzPVtdLHRoaXMuYXZhaWxhYmxlQ2hhcnNSRT1uZXcgUmVnRXhwKChudWxsPT1uP3ZvaWQgMDpuLmF2YWlsYWJsZUNoYXJzUkUpfHxcIl5bYS16QS1aMC05XSskXCIpLHRoaXMub25FbGVtZW50SW5wdXRMaXN0ZW5lcj1bXSx0aGlzLm9uRWxlbWVudFBhc3RlTGlzdGVuZXI9W10sdGhpcy5vbkVsZW1lbnRLZXlkb3duTGlzdGVuZXI9W10sdGhpcy5vbkVsZW1lbnRGb2N1c2luTGlzdGVuZXI9W10sdGhpcy5vbkVsZW1lbnRGb2N1c291dExpc3RlbmVyPVtdLHRoaXMuaW5pdCgpfWluaXQoKXt0aGlzLmNyZWF0ZUNvbGxlY3Rpb24od2luZG93LiRoc1BpbklucHV0Q29sbGVjdGlvbix0aGlzKSx0aGlzLml0ZW1zLmxlbmd0aCYmdGhpcy5idWlsZCgpfWJ1aWxkKCl7dGhpcy5idWlsZElucHV0SXRlbXMoKX1idWlsZElucHV0SXRlbXMoKXt0aGlzLml0ZW1zLmZvckVhY2goKChlLHQpPT57dGhpcy5wbGFjZWhvbGRlcnMucHVzaChlLmdldEF0dHJpYnV0ZShcInBsYWNlaG9sZGVyXCIpfHxcIlwiKSxlLmhhc0F0dHJpYnV0ZShcImF1dG9mb2N1c1wiKSYmdGhpcy5vbkZvY3VzSW4odCksdGhpcy5vbkVsZW1lbnRJbnB1dExpc3RlbmVyLnB1c2goe2VsOmUsZm46ZT0+dGhpcy5lbGVtZW50SW5wdXQoZSx0KX0pLHRoaXMub25FbGVtZW50UGFzdGVMaXN0ZW5lci5wdXNoKHtlbDplLGZuOmU9PnRoaXMuZWxlbWVudFBhc3RlKGUpfSksdGhpcy5vbkVsZW1lbnRLZXlkb3duTGlzdGVuZXIucHVzaCh7ZWw6ZSxmbjplPT50aGlzLmVsZW1lbnRLZXlkb3duKGUsdCl9KSx0aGlzLm9uRWxlbWVudEZvY3VzaW5MaXN0ZW5lci5wdXNoKHtlbDplLGZuOigpPT50aGlzLmVsZW1lbnRGb2N1c2luKHQpfSksdGhpcy5vbkVsZW1lbnRGb2N1c291dExpc3RlbmVyLnB1c2goe2VsOmUsZm46KCk9PnRoaXMuZWxlbWVudEZvY3Vzb3V0KHQpfSksZS5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uRWxlbWVudElucHV0TGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbiksZS5hZGRFdmVudExpc3RlbmVyKFwicGFzdGVcIix0aGlzLm9uRWxlbWVudFBhc3RlTGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbiksZS5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLHRoaXMub25FbGVtZW50S2V5ZG93bkxpc3RlbmVyLmZpbmQoKHQ9PnQuZWw9PT1lKSkuZm4pLGUuYWRkRXZlbnRMaXN0ZW5lcihcImZvY3VzaW5cIix0aGlzLm9uRWxlbWVudEZvY3VzaW5MaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c291dFwiLHRoaXMub25FbGVtZW50Rm9jdXNvdXRMaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKX0pKX1jaGVja0lmTnVtYmVyKGUpe3JldHVybiBlLm1hdGNoKHRoaXMuYXZhaWxhYmxlQ2hhcnNSRSl9YXV0b0ZpbGxBbGwoZSl7QXJyYXkuZnJvbShlKS5mb3JFYWNoKCgoZSx0KT0+e2lmKCEobnVsbD09dGhpcz92b2lkIDA6dGhpcy5pdGVtc1t0XSkpcmV0dXJuITE7dGhpcy5pdGVtc1t0XS52YWx1ZT1lLHRoaXMuaXRlbXNbdF0uZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJpbnB1dFwiLHtidWJibGVzOiEwfSkpfSkpfXNldEN1cnJlbnRWYWx1ZSgpe3RoaXMuY3VycmVudFZhbHVlPUFycmF5LmZyb20odGhpcy5pdGVtcykubWFwKChlPT5lLnZhbHVlKSl9dG9nZ2xlQ29tcGxldGVkKCl7dGhpcy5jdXJyZW50VmFsdWUuaW5jbHVkZXMoXCJcIik/dGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpOnRoaXMuZWwuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKX1vbklucHV0KGUsdCl7Y29uc3QgaT1lLnRhcmdldC52YWx1ZTtpZih0aGlzLmN1cnJlbnRJdGVtPWUudGFyZ2V0LHRoaXMuY3VycmVudEl0ZW0udmFsdWU9XCJcIix0aGlzLmN1cnJlbnRJdGVtLnZhbHVlPWlbaS5sZW5ndGgtMV0sIXRoaXMuY2hlY2tJZk51bWJlcih0aGlzLmN1cnJlbnRJdGVtLnZhbHVlKSlyZXR1cm4gdGhpcy5jdXJyZW50SXRlbS52YWx1ZT10aGlzLmN1cnJlbnRWYWx1ZVt0XXx8XCJcIiwhMTtpZih0aGlzLnNldEN1cnJlbnRWYWx1ZSgpLHRoaXMuY3VycmVudEl0ZW0udmFsdWUpe2lmKHQ8dGhpcy5pdGVtcy5sZW5ndGgtMSYmdGhpcy5pdGVtc1t0KzFdLmZvY3VzKCksIXRoaXMuY3VycmVudFZhbHVlLmluY2x1ZGVzKFwiXCIpKXtjb25zdCBlPXtjdXJyZW50VmFsdWU6dGhpcy5jdXJyZW50VmFsdWV9O3RoaXMuZmlyZUV2ZW50KFwiY29tcGxldGVkXCIsZSksKDAsbi5kaXNwYXRjaCkoXCJjb21wbGV0ZWQucGluSW5wdXRcIix0aGlzLmVsLGUpfXRoaXMudG9nZ2xlQ29tcGxldGVkKCl9ZWxzZSB0PjAmJnRoaXMuaXRlbXNbdC0xXS5mb2N1cygpfW9uS2V5ZG93bihlLHQpe1wiQmFja3NwYWNlXCI9PT1lLmtleSYmdD4wJiYoXCJcIj09PXRoaXMuaXRlbXNbdF0udmFsdWU/KHRoaXMuaXRlbXNbdC0xXS52YWx1ZT1cIlwiLHRoaXMuaXRlbXNbdC0xXS5mb2N1cygpKTp0aGlzLml0ZW1zW3RdLnZhbHVlPVwiXCIpLHRoaXMuc2V0Q3VycmVudFZhbHVlKCksdGhpcy50b2dnbGVDb21wbGV0ZWQoKX1vbkZvY3VzSW4oZSl7dGhpcy5pdGVtc1tlXS5zZXRBdHRyaWJ1dGUoXCJwbGFjZWhvbGRlclwiLFwiXCIpfW9uRm9jdXNPdXQoZSl7dGhpcy5pdGVtc1tlXS5zZXRBdHRyaWJ1dGUoXCJwbGFjZWhvbGRlclwiLHRoaXMucGxhY2Vob2xkZXJzW2VdKX1vblBhc3RlKGUpe2UucHJldmVudERlZmF1bHQoKSx0aGlzLml0ZW1zLmZvckVhY2goKHQ9Pntkb2N1bWVudC5hY3RpdmVFbGVtZW50PT09dCYmdGhpcy5hdXRvRmlsbEFsbChlLmNsaXBib2FyZERhdGEuZ2V0RGF0YShcInRleHRcIikpfSkpfWRlc3Ryb3koKXt0aGlzLmVsLmNsYXNzTGlzdC5yZW1vdmUoXCJhY3RpdmVcIiksdGhpcy5pdGVtcy5sZW5ndGgmJnRoaXMuaXRlbXMuZm9yRWFjaCgoZT0+e2UucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vbkVsZW1lbnRJbnB1dExpc3RlbmVyLmZpbmQoKHQ9PnQuZWw9PT1lKSkuZm4pLGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInBhc3RlXCIsdGhpcy5vbkVsZW1lbnRQYXN0ZUxpc3RlbmVyLmZpbmQoKHQ9PnQuZWw9PT1lKSkuZm4pLGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIix0aGlzLm9uRWxlbWVudEtleWRvd25MaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKSxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJmb2N1c2luXCIsdGhpcy5vbkVsZW1lbnRGb2N1c2luTGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbiksZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiZm9jdXNvdXRcIix0aGlzLm9uRWxlbWVudEZvY3Vzb3V0TGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbil9KSksdGhpcy5pdGVtcz1udWxsLHRoaXMuY3VycmVudEl0ZW09bnVsbCx0aGlzLmN1cnJlbnRWYWx1ZT1udWxsLHdpbmRvdy4kaHNQaW5JbnB1dENvbGxlY3Rpb249d2luZG93LiRoc1BpbklucHV0Q29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGdldEluc3RhbmNlKGUsdCl7Y29uc3QgaT13aW5kb3cuJGhzUGluSW5wdXRDb2xsZWN0aW9uLmZpbmQoKHQ9PnQuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSk7cmV0dXJuIGk/dD9pOmkuZWxlbWVudDpudWxsfXN0YXRpYyBhdXRvSW5pdCgpe3dpbmRvdy4kaHNQaW5JbnB1dENvbGxlY3Rpb258fCh3aW5kb3cuJGhzUGluSW5wdXRDb2xsZWN0aW9uPVtdKSx3aW5kb3cuJGhzUGluSW5wdXRDb2xsZWN0aW9uJiYod2luZG93LiRoc1BpbklucHV0Q29sbGVjdGlvbj13aW5kb3cuJGhzUGluSW5wdXRDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZG9jdW1lbnQuY29udGFpbnMoZS5lbCkpKSksZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXBpbi1pbnB1dF06bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KVwiKS5mb3JFYWNoKChlPT57d2luZG93LiRoc1BpbklucHV0Q29sbGVjdGlvbi5maW5kKCh0PT57dmFyIGk7cmV0dXJuKG51bGw9PT0oaT1udWxsPT10P3ZvaWQgMDp0LmVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmVsKT09PWV9KSl8fG5ldyBsKGUpfSkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PntsLmF1dG9Jbml0KCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1BpbklucHV0PWwpLHQuZGVmYXVsdD1sfSw3NTM6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTRHJvcGRvd25cbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1pKDgwNiksbz1pKDk0OSksbD1zKGkoMjg3KSkscj1pKDkxNyk7Y2xhc3MgYSBleHRlbmRzIGwuZGVmYXVsdHtjb25zdHJ1Y3RvcihlLHQsaSl7c3VwZXIoZSx0LGkpLHRoaXMubG9uZ1ByZXNzVGltZXI9bnVsbCx0aGlzLm9uVG91Y2hTdGFydExpc3RlbmVyPW51bGwsdGhpcy5vblRvdWNoRW5kTGlzdGVuZXI9bnVsbCx0aGlzLnRvZ2dsZT10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCI6c2NvcGUgPiAuZHJvcGRvd24tdG9nZ2xlXCIpfHx0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCI6c2NvcGUgPiAuZHJvcGRvd24tdG9nZ2xlLXdyYXBwZXIgPiAuZHJvcGRvd24tdG9nZ2xlXCIpfHx0aGlzLmVsLmNoaWxkcmVuWzBdLHRoaXMuY2xvc2Vycz1BcnJheS5mcm9tKHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIjpzY29wZSAuZHJvcGRvd24tY2xvc2VcIikpfHxudWxsLHRoaXMubWVudT10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCI6c2NvcGUgPiAuZHJvcGRvd24tbWVudVwiKSx0aGlzLmV2ZW50TW9kZT0oMCxuLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLXRyaWdnZXJcIixcImNsaWNrXCIpLHRoaXMuY2xvc2VNb2RlPSgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tYXV0by1jbG9zZVwiLFwidHJ1ZVwiKSx0aGlzLmhhc0F1dG9mb2N1cz0oMCxuLnN0cmluZ1RvQm9vbGVhbikoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS1oYXMtYXV0b2ZvY3VzXCIsXCJ0cnVlXCIpfHxcInRydWVcIiksdGhpcy5hbmltYXRpb25JblByb2Nlc3M9ITEsdGhpcy5vbkNsb3NlckNsaWNrTGlzdGVuZXI9W10sdGhpcy50b2dnbGUmJnRoaXMubWVudSYmdGhpcy5pbml0KCl9ZWxlbWVudE1vdXNlRW50ZXIoKXt0aGlzLm9uTW91c2VFbnRlckhhbmRsZXIoKX1lbGVtZW50TW91c2VMZWF2ZSgpe3RoaXMub25Nb3VzZUxlYXZlSGFuZGxlcigpfXRvZ2dsZUNsaWNrKGUpe3RoaXMub25DbGlja0hhbmRsZXIoZSl9dG9nZ2xlQ29udGV4dE1lbnUoZSl7ZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMub25Db250ZXh0TWVudUhhbmRsZXIoZSl9aGFuZGxlVG91Y2hTdGFydChlKXt0aGlzLmxvbmdQcmVzc1RpbWVyPXdpbmRvdy5zZXRUaW1lb3V0KCgoKT0+e2UucHJldmVudERlZmF1bHQoKTtjb25zdCB0PWUudG91Y2hlc1swXSxpPW5ldyBNb3VzZUV2ZW50KFwiY29udGV4dG1lbnVcIix7YnViYmxlczohMCxjYW5jZWxhYmxlOiEwLHZpZXc6d2luZG93LGNsaWVudFg6dC5jbGllbnRYLGNsaWVudFk6dC5jbGllbnRZfSk7dGhpcy50b2dnbGUmJnRoaXMudG9nZ2xlLmRpc3BhdGNoRXZlbnQoaSl9KSw0MDApfWhhbmRsZVRvdWNoRW5kKGUpe3RoaXMubG9uZ1ByZXNzVGltZXImJihjbGVhclRpbWVvdXQodGhpcy5sb25nUHJlc3NUaW1lciksdGhpcy5sb25nUHJlc3NUaW1lcj1udWxsKX1jbG9zZXJDbGljaygpe3RoaXMuY2xvc2UoKX1pbml0KCl7aWYodGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24sdGhpcyksdGhpcy50b2dnbGUuZGlzYWJsZWQpcmV0dXJuITE7dGhpcy50b2dnbGUmJnRoaXMuYnVpbGRUb2dnbGUoKSx0aGlzLm1lbnUmJnRoaXMuYnVpbGRNZW51KCksdGhpcy5jbG9zZXJzJiZ0aGlzLmJ1aWxkQ2xvc2VycygpLCgwLG4uaXNJT1MpKCl8fCgwLG4uaXNJcGFkT1MpKCl8fCh0aGlzLm9uRWxlbWVudE1vdXNlRW50ZXJMaXN0ZW5lcj0oKT0+dGhpcy5lbGVtZW50TW91c2VFbnRlcigpLHRoaXMub25FbGVtZW50TW91c2VMZWF2ZUxpc3RlbmVyPSgpPT50aGlzLmVsZW1lbnRNb3VzZUxlYXZlKCksdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKFwibW91c2VlbnRlclwiLHRoaXMub25FbGVtZW50TW91c2VFbnRlckxpc3RlbmVyKSx0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWxlYXZlXCIsdGhpcy5vbkVsZW1lbnRNb3VzZUxlYXZlTGlzdGVuZXIpKX1yZXNpemVIYW5kbGVyKCl7dGhpcy5ldmVudE1vZGU9KDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS10cmlnZ2VyXCIsXCJjbGlja1wiKSx0aGlzLmNsb3NlTW9kZT0oMCxuLmdldENsYXNzUHJvcGVydHkpKHRoaXMuZWwsXCItLWF1dG8tY2xvc2VcIixcInRydWVcIil9YnVpbGRUb2dnbGUoKXt2YXIgZTsobnVsbD09PShlPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMudG9nZ2xlKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5hcmlhRXhwYW5kZWQpJiYodGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJvcGVuXCIpP3RoaXMudG9nZ2xlLmFyaWFFeHBhbmRlZD1cInRydWVcIjp0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJmYWxzZVwiKSxcImNvbnRleHRtZW51XCI9PT10aGlzLmV2ZW50TW9kZT8odGhpcy5vblRvZ2dsZUNvbnRleHRNZW51TGlzdGVuZXI9ZT0+dGhpcy50b2dnbGVDb250ZXh0TWVudShlKSx0aGlzLm9uVG91Y2hTdGFydExpc3RlbmVyPXRoaXMuaGFuZGxlVG91Y2hTdGFydC5iaW5kKHRoaXMpLHRoaXMub25Ub3VjaEVuZExpc3RlbmVyPXRoaXMuaGFuZGxlVG91Y2hFbmQuYmluZCh0aGlzKSx0aGlzLnRvZ2dsZS5hZGRFdmVudExpc3RlbmVyKFwiY29udGV4dG1lbnVcIix0aGlzLm9uVG9nZ2xlQ29udGV4dE1lbnVMaXN0ZW5lciksdGhpcy50b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoc3RhcnRcIix0aGlzLm9uVG91Y2hTdGFydExpc3RlbmVyLHtwYXNzaXZlOiExfSksdGhpcy50b2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsdGhpcy5vblRvdWNoRW5kTGlzdGVuZXIpLHRoaXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIix0aGlzLm9uVG91Y2hFbmRMaXN0ZW5lcikpOih0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lcj1lPT50aGlzLnRvZ2dsZUNsaWNrKGUpLHRoaXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyKSl9YnVpbGRNZW51KCl7dGhpcy5tZW51LnJvbGU9dGhpcy5tZW51LmdldEF0dHJpYnV0ZShcInJvbGVcIil8fFwibWVudVwiO2NvbnN0IGU9dGhpcy5tZW51LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tyb2xlPVwibWVudWl0ZW1jaGVja2JveFwiXScpLHQ9dGhpcy5tZW51LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tyb2xlPVwibWVudWl0ZW1yYWRpb1wiXScpO2UuZm9yRWFjaCgoZT0+ZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwoKCk9PnRoaXMuc2VsZWN0Q2hlY2tib3goZSkpKSkpLHQuZm9yRWFjaCgoZT0+ZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwoKCk9PnRoaXMuc2VsZWN0UmFkaW8oZSkpKSkpfWJ1aWxkQ2xvc2Vycygpe3RoaXMuY2xvc2Vycy5mb3JFYWNoKChlPT57dGhpcy5vbkNsb3NlckNsaWNrTGlzdGVuZXIucHVzaCh7ZWw6ZSxmbjooKT0+dGhpcy5jbG9zZXJDbGljaygpfSksZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uQ2xvc2VyQ2xpY2tMaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKX0pKX1nZXRTY3JvbGxiYXJTaXplKCl7bGV0IGU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtlLnN0eWxlLm92ZXJmbG93PVwic2Nyb2xsXCIsZS5zdHlsZS53aWR0aD1cIjEwMHB4XCIsZS5zdHlsZS5oZWlnaHQ9XCIxMDBweFwiLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZSk7bGV0IHQ9ZS5vZmZzZXRXaWR0aC1lLmNsaWVudFdpZHRoO3JldHVybiBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGUpLHR9b25Db250ZXh0TWVudUhhbmRsZXIoZSl7Y29uc3QgdD17Z2V0Qm91bmRpbmdDbGllbnRSZWN0OigoKT0+bmV3IERPTVJlY3QsKCk9Pm5ldyBET01SZWN0KGUuY2xpZW50WCxlLmNsaWVudFksMCwwKSl9O2EuY2xvc2VDdXJyZW50bHlPcGVuZWQoKSx0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikmJiF0aGlzLm1lbnUuY2xhc3NMaXN0LmNvbnRhaW5zKFwiaGlkZGVuXCIpPyh0aGlzLmNsb3NlKCksZG9jdW1lbnQuYm9keS5zdHlsZS5vdmVyZmxvdz1cIlwiLGRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZ1JpZ2h0PVwiXCIpOihkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93PVwiaGlkZGVuXCIsZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQ9YCR7dGhpcy5nZXRTY3JvbGxiYXJTaXplKCl9cHhgLHRoaXMub3Blbih0KSl9b25DbGlja0hhbmRsZXIoZSl7dGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJvcGVuXCIpJiYhdGhpcy5tZW51LmNsYXNzTGlzdC5jb250YWlucyhcImhpZGRlblwiKT90aGlzLmNsb3NlKCk6dGhpcy5vcGVuKCl9b25Nb3VzZUVudGVySGFuZGxlcigpe2lmKFwiaG92ZXJcIiE9PXRoaXMuZXZlbnRNb2RlKXJldHVybiExOyghdGhpcy5lbC5fZmxvYXRpbmdVSXx8dGhpcy5lbC5fZmxvYXRpbmdVSSYmIXRoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKSkmJnRoaXMuZm9yY2VDbGVhclN0YXRlKCksIXRoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKSYmdGhpcy5tZW51LmNsYXNzTGlzdC5jb250YWlucyhcImhpZGRlblwiKSYmdGhpcy5vcGVuKCl9b25Nb3VzZUxlYXZlSGFuZGxlcigpe2lmKFwiaG92ZXJcIiE9PXRoaXMuZXZlbnRNb2RlKXJldHVybiExO3RoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKSYmIXRoaXMubWVudS5jbGFzc0xpc3QuY29udGFpbnMoXCJoaWRkZW5cIikmJnRoaXMuY2xvc2UoKX1kZXN0cm95RmxvYXRpbmdVSSgpe2NvbnN0IGU9KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWwpLmdldFByb3BlcnR5VmFsdWUoXCItLXNjb3BlXCIpfHxcIlwiKS50cmltKCk7dGhpcy5tZW51LmNsYXNzTGlzdC5yZW1vdmUoXCJibG9ja1wiKSx0aGlzLm1lbnUuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKSx0aGlzLm1lbnUuc3R5bGUuaW5zZXQ9bnVsbCx0aGlzLm1lbnUuc3R5bGUucG9zaXRpb249bnVsbCx0aGlzLmVsJiZ0aGlzLmVsLl9mbG9hdGluZ1VJJiYodGhpcy5lbC5fZmxvYXRpbmdVSS5kZXN0cm95KCksdGhpcy5lbC5fZmxvYXRpbmdVST1udWxsKSxcIndpbmRvd1wiPT09ZSYmdGhpcy5lbC5hcHBlbmRDaGlsZCh0aGlzLm1lbnUpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExfWZvY3VzRWxlbWVudCgpe2NvbnN0IGU9dGhpcy5tZW51LnF1ZXJ5U2VsZWN0b3IoXCJbYXV0b2ZvY3VzXVwiKTtpZighZSlyZXR1cm4hMTtlLmZvY3VzKCl9c2V0dXBGbG9hdGluZ1VJKGUpe2NvbnN0IHQ9ZXx8dGhpcy5lbCxpPXdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWwpLHM9KGkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tcGxhY2VtZW50XCIpfHxcIlwiKS50cmltKCksbj0oaS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1mbGlwXCIpfHxcInRydWVcIikudHJpbSgpLGw9KGkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tc3RyYXRlZ3lcIil8fFwiZml4ZWRcIikudHJpbSgpLGE9KGkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tb2Zmc2V0XCIpfHxcIjZcIikudHJpbSgpLGM9KGkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tZ3B1LWFjY2VsZXJhdGlvblwiKXx8XCJ0cnVlXCIpLnRyaW0oKSxkPSh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsKS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1hZGFwdGl2ZVwiKXx8XCJhZGFwdGl2ZVwiKS5yZXBsYWNlKFwiIFwiLFwiXCIpLGg9bCx1PXBhcnNlSW50KGEsMTApLHA9ci5QT1NJVElPTlNbc118fFwiYm90dG9tLXN0YXJ0XCIsbT1bLi4uXCJ0cnVlXCI9PT1uP1soMCxvLmZsaXApKCldOltdLCgwLG8ub2Zmc2V0KSh1KV0sZz17cGxhY2VtZW50OnAsc3RyYXRlZ3k6aCxtaWRkbGV3YXJlOm19LGY9KCk9PnsoMCxvLmNvbXB1dGVQb3NpdGlvbikodCx0aGlzLm1lbnUsZykudGhlbigoKHt4OmUseTp0LHBsYWNlbWVudDppfSk9PntcImFic29sdXRlXCI9PT1oJiZcIm5vbmVcIj09PWQ/T2JqZWN0LmFzc2lnbih0aGlzLm1lbnUuc3R5bGUse3Bvc2l0aW9uOmgsbWFyZ2luOlwiMFwifSk6XCJhYnNvbHV0ZVwiPT09aD9PYmplY3QuYXNzaWduKHRoaXMubWVudS5zdHlsZSx7cG9zaXRpb246aCx0cmFuc2Zvcm06YHRyYW5zbGF0ZTNkKCR7ZX1weCwgJHt0fXB4LCAwcHgpYCxtYXJnaW46XCIwXCJ9KTpcInRydWVcIj09PWM/T2JqZWN0LmFzc2lnbih0aGlzLm1lbnUuc3R5bGUse3Bvc2l0aW9uOmgsbGVmdDpcIlwiLHRvcDpcIlwiLGluc2V0OlwiMHB4IGF1dG8gYXV0byAwcHhcIixtYXJnaW46XCIwXCIsdHJhbnNmb3JtOmB0cmFuc2xhdGUzZCgke1wiYWRhcHRpdmVcIj09PWQ/ZTowfXB4LCAke3R9cHgsIDApYH0pOk9iamVjdC5hc3NpZ24odGhpcy5tZW51LnN0eWxlLHtwb3NpdGlvbjpoLGxlZnQ6YCR7ZX1weGAsdG9wOmAke3R9cHhgLG1hcmdpbjpcIjBcIix0cmFuc2Zvcm06XCJcIn0pLHRoaXMubWVudS5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBsYWNlbWVudFwiLGkpfSkpfTtmKCk7cmV0dXJue3VwZGF0ZTpmLGRlc3Ryb3k6KDAsby5hdXRvVXBkYXRlKSh0LHRoaXMubWVudSxmKX19c2VsZWN0Q2hlY2tib3goZSl7ZS5hcmlhQ2hlY2tlZD1cInRydWVcIj09PWUuYXJpYUNoZWNrZWQ/XCJmYWxzZVwiOlwidHJ1ZVwifXNlbGVjdFJhZGlvKGUpe2lmKFwidHJ1ZVwiPT09ZS5hcmlhQ2hlY2tlZClyZXR1cm4hMTtjb25zdCB0PWUuY2xvc2VzdChcIi5ncm91cFwiKS5xdWVyeVNlbGVjdG9yQWxsKCdbcm9sZT1cIm1lbnVpdGVtcmFkaW9cIl0nKTtBcnJheS5mcm9tKHQpLmZpbHRlcigodD0+dCE9PWUpKS5mb3JFYWNoKChlPT57ZS5hcmlhQ2hlY2tlZD1cImZhbHNlXCJ9KSksZS5hcmlhQ2hlY2tlZD1cInRydWVcIn1jYWxjdWxhdGVGTG9hdGluZ1VJUG9zaXRpb24oZSl7Y29uc3QgdD10aGlzLnNldHVwRmxvYXRpbmdVSShlKSxpPXRoaXMubWVudS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBsYWNlbWVudFwiKTtyZXR1cm4gdC51cGRhdGUoKSx0LmRlc3Ryb3koKSxpfW9wZW4oZSl7aWYodGhpcy5lbC5jbGFzc0xpc3QuY29udGFpbnMoXCJvcGVuXCIpfHx0aGlzLmFuaW1hdGlvbkluUHJvY2VzcylyZXR1cm4hMTt0aGlzLmFuaW1hdGlvbkluUHJvY2Vzcz0hMDtjb25zdCB0PWV8fHRoaXMuZWwsaT13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmVsKSxzPShpLmdldFByb3BlcnR5VmFsdWUoXCItLXNjb3BlXCIpfHxcIlwiKS50cmltKCksbz0oaS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1zdHJhdGVneVwiKXx8XCJmaXhlZFwiKS50cmltKCk7XCJ3aW5kb3dcIj09PXMmJmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5tZW51KSxcInN0YXRpY1wiIT09byYmKHRoaXMuZWwuX2Zsb2F0aW5nVUk9dGhpcy5zZXR1cEZsb2F0aW5nVUkodCkpLHRoaXMubWVudS5zdHlsZS5tYXJnaW49bnVsbCx0aGlzLm1lbnUuY2xhc3NMaXN0LnJlbW92ZShcImhpZGRlblwiKSx0aGlzLm1lbnUuY2xhc3NMaXN0LmFkZChcImJsb2NrXCIpLHNldFRpbWVvdXQoKCgpPT57dmFyIGU7KG51bGw9PT0oZT1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLnRvZ2dsZSl8fHZvaWQgMD09PWU/dm9pZCAwOmUuYXJpYUV4cGFuZGVkKSYmKHRoaXMudG9nZ2xlLmFyaWFFeHBhbmRlZD1cInRydWVcIiksdGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwib3BlblwiKSxcIndpbmRvd1wiPT09cyYmdGhpcy5tZW51LmNsYXNzTGlzdC5hZGQoXCJvcGVuXCIpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExLHRoaXMuaGFzQXV0b2ZvY3VzJiZ0aGlzLmZvY3VzRWxlbWVudCgpLHRoaXMuZmlyZUV2ZW50KFwib3BlblwiLHRoaXMuZWwpLCgwLG4uZGlzcGF0Y2gpKFwib3Blbi5kcm9wZG93blwiLHRoaXMuZWwsdGhpcy5lbCl9KSl9Y2xvc2UoZT0hMCl7aWYodGhpcy5hbmltYXRpb25JblByb2Nlc3N8fCF0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpcmV0dXJuITE7Y29uc3QgdD0od2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tc2NvcGVcIil8fFwiXCIpLnRyaW0oKTtpZih0aGlzLmFuaW1hdGlvbkluUHJvY2Vzcz0hMCxcIndpbmRvd1wiPT09dCYmdGhpcy5tZW51LmNsYXNzTGlzdC5yZW1vdmUoXCJvcGVuXCIpLGUpe2NvbnN0IGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZHJvcGRvd24tdHJhbnNpdGlvbl1cIil8fHRoaXMubWVudTsoMCxuLmFmdGVyVHJhbnNpdGlvbikoZSwoKCk9PnRoaXMuZGVzdHJveUZsb2F0aW5nVUkoKSkpfWVsc2UgdGhpcy5kZXN0cm95RmxvYXRpbmdVSSgpOygoKT0+e3ZhciBlO3RoaXMubWVudS5zdHlsZS5tYXJnaW49bnVsbCwobnVsbD09PShlPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMudG9nZ2xlKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5hcmlhRXhwYW5kZWQpJiYodGhpcy50b2dnbGUuYXJpYUV4cGFuZGVkPVwiZmFsc2VcIiksdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwib3BlblwiKSx0aGlzLmZpcmVFdmVudChcImNsb3NlXCIsdGhpcy5lbCksKDAsbi5kaXNwYXRjaCkoXCJjbG9zZS5kcm9wZG93blwiLHRoaXMuZWwsdGhpcy5lbCl9KSgpfWZvcmNlQ2xlYXJTdGF0ZSgpe3RoaXMuZGVzdHJveUZsb2F0aW5nVUkoKSx0aGlzLm1lbnUuc3R5bGUubWFyZ2luPW51bGwsdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwib3BlblwiKSx0aGlzLm1lbnUuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKX1kZXN0cm95KCl7KDAsbi5pc0lPUykoKXx8KDAsbi5pc0lwYWRPUykoKXx8KHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlZW50ZXJcIix0aGlzLm9uRWxlbWVudE1vdXNlRW50ZXJMaXN0ZW5lciksdGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLCgoKT0+dGhpcy5vbkVsZW1lbnRNb3VzZUxlYXZlTGlzdGVuZXIpKSx0aGlzLm9uRWxlbWVudE1vdXNlRW50ZXJMaXN0ZW5lcj1udWxsLHRoaXMub25FbGVtZW50TW91c2VMZWF2ZUxpc3RlbmVyPW51bGwpLFwiY29udGV4dG1lbnVcIj09PXRoaXMuZXZlbnRNb2RlPyh0aGlzLnRvZ2dsZSYmKHRoaXMudG9nZ2xlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjb250ZXh0bWVudVwiLHRoaXMub25Ub2dnbGVDb250ZXh0TWVudUxpc3RlbmVyKSx0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2hzdGFydFwiLHRoaXMub25Ub3VjaFN0YXJ0TGlzdGVuZXIpLHRoaXMudG9nZ2xlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLHRoaXMub25Ub3VjaEVuZExpc3RlbmVyKSx0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsdGhpcy5vblRvdWNoRW5kTGlzdGVuZXIpKSx0aGlzLm9uVG9nZ2xlQ29udGV4dE1lbnVMaXN0ZW5lcj1udWxsLHRoaXMub25Ub3VjaFN0YXJ0TGlzdGVuZXI9bnVsbCx0aGlzLm9uVG91Y2hFbmRMaXN0ZW5lcj1udWxsKToodGhpcy50b2dnbGUmJnRoaXMudG9nZ2xlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyKSx0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lcj1udWxsKSx0aGlzLmNsb3NlcnMubGVuZ3RoJiYodGhpcy5jbG9zZXJzLmZvckVhY2goKGU9PntlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25DbG9zZXJDbGlja0xpc3RlbmVyLmZpbmQoKHQ9PnQuZWw9PT1lKSkuZm4pfSkpLHRoaXMub25DbG9zZXJDbGlja0xpc3RlbmVyPW51bGwpLHRoaXMuZWwuY2xhc3NMaXN0LnJlbW92ZShcIm9wZW5cIiksdGhpcy5kZXN0cm95RmxvYXRpbmdVSSgpLHdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb249d2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGZpbmRJbkNvbGxlY3Rpb24oZSl7cmV0dXJuIHdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmluZCgodD0+ZSBpbnN0YW5jZW9mIGE/dC5lbGVtZW50LmVsPT09ZS5lbDpcInN0cmluZ1wiPT10eXBlb2YgZT90LmVsZW1lbnQuZWw9PT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOnQuZWxlbWVudC5lbD09PWUpKXx8bnVsbH1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0KXtjb25zdCBpPXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50LmVsOm51bGx9c3RhdGljIGF1dG9Jbml0KCl7aWYoIXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24pe3dpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb249W10sZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwoZT0+YS5hY2Nlc3NpYmlsaXR5KGUpKSksd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLChlPT57Y29uc3QgdD1lLnRhcmdldDthLmNsb3NlQ3VycmVudGx5T3BlbmVkKHQpfSkpO2xldCBlPXdpbmRvdy5pbm5lcldpZHRoO3dpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsKCgpPT57d2luZG93LmlubmVyV2lkdGghPT1lJiYoZT1pbm5lcldpZHRoLGEuY2xvc2VDdXJyZW50bHlPcGVuZWQobnVsbCwhMSkpfSkpfXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24mJih3aW5kb3cuJGhzRHJvcGRvd25Db2xsZWN0aW9uPXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmRyb3Bkb3duOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgYShlKX0pKX1zdGF0aWMgb3BlbihlKXtjb25zdCB0PWEuZmluZEluQ29sbGVjdGlvbihlKTt0JiZ0LmVsZW1lbnQubWVudS5jbGFzc0xpc3QuY29udGFpbnMoXCJoaWRkZW5cIikmJnQuZWxlbWVudC5vcGVuKCl9c3RhdGljIGNsb3NlKGUpe2NvbnN0IHQ9YS5maW5kSW5Db2xsZWN0aW9uKGUpO3QmJiF0LmVsZW1lbnQubWVudS5jbGFzc0xpc3QuY29udGFpbnMoXCJoaWRkZW5cIikmJnQuZWxlbWVudC5jbG9zZSgpfXN0YXRpYyBhY2Nlc3NpYmlsaXR5KGUpe3RoaXMuaGlzdG9yeT1uLm1lbnVTZWFyY2hIaXN0b3J5O2NvbnN0IHQ9d2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKSkpO2lmKHQmJihyLkRST1BET1dOX0FDQ0VTU0lCSUxJVFlfS0VZX1NFVC5pbmNsdWRlcyhlLmNvZGUpfHw0PT09ZS5jb2RlLmxlbmd0aCYmZS5jb2RlW2UuY29kZS5sZW5ndGgtMV0ubWF0Y2goL15bQS1aXSokLykpJiYhZS5tZXRhS2V5JiYhdC5lbGVtZW50Lm1lbnUucXVlcnlTZWxlY3RvcihcImlucHV0OmZvY3VzXCIpJiYhdC5lbGVtZW50Lm1lbnUucXVlcnlTZWxlY3RvcihcInRleHRhcmVhOmZvY3VzXCIpKXN3aXRjaChlLmNvZGUpe2Nhc2VcIkVzY2FwZVwiOnQuZWxlbWVudC5tZW51LnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0LmFjdGl2ZVwiKXx8KGUucHJldmVudERlZmF1bHQoKSx0aGlzLm9uRXNjYXBlKGUpKTticmVhaztjYXNlXCJFbnRlclwiOnQuZWxlbWVudC5tZW51LnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0IGJ1dHRvbjpmb2N1c1wiKXx8dC5lbGVtZW50Lm1lbnUucXVlcnlTZWxlY3RvcihcIi5jb2xsYXBzZS10b2dnbGU6Zm9jdXNcIil8fHRoaXMub25FbnRlcihlKTticmVhaztjYXNlXCJBcnJvd1VwXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vbkFycm93KCk7YnJlYWs7Y2FzZVwiQXJyb3dEb3duXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vbkFycm93KCExKTticmVhaztjYXNlXCJBcnJvd1JpZ2h0XCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vbkFycm93WChlLFwicmlnaHRcIik7YnJlYWs7Y2FzZVwiQXJyb3dMZWZ0XCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vbkFycm93WChlLFwibGVmdFwiKTticmVhaztjYXNlXCJIb21lXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vblN0YXJ0RW5kKCk7YnJlYWs7Y2FzZVwiRW5kXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vblN0YXJ0RW5kKCExKTticmVhaztkZWZhdWx0OmUucHJldmVudERlZmF1bHQoKSx0aGlzLm9uRmlyc3RMZXR0ZXIoZS5rZXkpfX1zdGF0aWMgb25Fc2NhcGUoZSl7Y29uc3QgdD1lLnRhcmdldC5jbG9zZXN0KFwiLmRyb3Bkb3duLm9wZW5cIik7aWYod2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWw9PT10KSkpe2NvbnN0IGU9d2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWw9PT10KSk7ZSYmKGUuZWxlbWVudC5jbG9zZSgpLGUuZWxlbWVudC50b2dnbGUuZm9jdXMoKSl9ZWxzZSB0aGlzLmNsb3NlQ3VycmVudGx5T3BlbmVkKCl9c3RhdGljIG9uRW50ZXIoZSl7dmFyIHQ7Y29uc3QgaT1lLnRhcmdldCx7ZWxlbWVudDpzfT1udWxsIT09KHQ9d2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWw9PT1pLmNsb3Nlc3QoXCIuZHJvcGRvd25cIikpKSkmJnZvaWQgMCE9PXQ/dDpudWxsO2lmKHMmJmkuY2xhc3NMaXN0LmNvbnRhaW5zKFwiZHJvcGRvd24tdG9nZ2xlXCIpKWUucHJldmVudERlZmF1bHQoKSxzLm9wZW4oKTtlbHNlIGlmKHMmJlwibWVudWl0ZW1jaGVja2JveFwiPT09aS5nZXRBdHRyaWJ1dGUoXCJyb2xlXCIpKXMuc2VsZWN0Q2hlY2tib3goaSkscy5jbG9zZSgpO2Vsc2V7aWYoIXN8fFwibWVudWl0ZW1yYWRpb1wiIT09aS5nZXRBdHRyaWJ1dGUoXCJyb2xlXCIpKXJldHVybiExO3Muc2VsZWN0UmFkaW8oaSkscy5jbG9zZSgpfX1zdGF0aWMgb25BcnJvdyhlPSEwKXtjb25zdCB0PXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpKTtpZih0KXtjb25zdCBpPXQuZWxlbWVudC5tZW51O2lmKCFpKXJldHVybiExO2NvbnN0IHM9ZT9BcnJheS5mcm9tKGkucXVlcnlTZWxlY3RvckFsbCgnYTpub3QoW2hpZGRlbl0pLCA6c2NvcGUgYnV0dG9uOm5vdChbaGlkZGVuXSksIFtyb2xlPVwiYnV0dG9uXCJdOm5vdChbaGlkZGVuXSksIFtyb2xlXj1cIm1lbnVpdGVtXCJdOm5vdChbaGlkZGVuXSknKSkucmV2ZXJzZSgpOkFycmF5LmZyb20oaS5xdWVyeVNlbGVjdG9yQWxsKCdhOm5vdChbaGlkZGVuXSksIDpzY29wZSBidXR0b246bm90KFtoaWRkZW5dKSwgW3JvbGU9XCJidXR0b25cIl06bm90KFtoaWRkZW5dKSwgW3JvbGVePVwibWVudWl0ZW1cIl06bm90KFtoaWRkZW5dLCAuZHJvcGRvd24taXRlbSwgZm9ybSknKSksbj1BcnJheS5mcm9tKHMpLmZpbHRlcigoZT0+e2NvbnN0IHQ9ZTtyZXR1cm4gbnVsbD09PXQuY2xvc2VzdChcIltoaWRkZW5dXCIpJiZudWxsIT09dC5vZmZzZXRQYXJlbnR9KSkuZmlsdGVyKChlPT4hZS5jbGFzc0xpc3QuY29udGFpbnMoXCJkaXNhYmxlZFwiKSkpLG89aS5xdWVyeVNlbGVjdG9yKCdhOmZvY3VzLCBidXR0b246Zm9jdXMsIFtyb2xlPVwiYnV0dG9uXCJdOmZvY3VzLCBbcm9sZV49XCJtZW51aXRlbVwiXTpmb2N1cywgLmRyb3Bkb3duLWl0ZW06Zm9jdXMsIGJ1dHRvbjpmb2N1cycpO2xldCBsPW4uZmluZEluZGV4KChlPT5lPT09bykpO2wrMTxuLmxlbmd0aCYmbCsrLG5bbF0uZm9jdXMoKX19c3RhdGljIG9uQXJyb3dYKGUsdCl7dmFyIGkscztjb25zdCBuPWUudGFyZ2V0LG89bi5jbG9zZXN0KFwiLmRyb3Bkb3duLm9wZW5cIiksbD0hIW8mJiEobnVsbD09bz92b2lkIDA6by5wYXJlbnRFbGVtZW50LmNsb3Nlc3QoXCIuZHJvcGRvd25cIikpLHI9bnVsbCE9PShpPWEuZ2V0SW5zdGFuY2Uobi5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpLCEwKSkmJnZvaWQgMCE9PWk/aTpudWxsLGM9ci5lbGVtZW50Lm1lbnUucXVlcnlTZWxlY3RvcignYSwgYnV0dG9uLCBbcm9sZT1cImJ1dHRvblwiXSwgW3JvbGVePVwibWVudWl0ZW1cIl0nKTtpZihsJiYhbi5jbGFzc0xpc3QuY29udGFpbnMoXCJkcm9wZG93bi10b2dnbGVcIikpcmV0dXJuITE7Y29uc3QgZD1udWxsIT09KHM9YS5nZXRJbnN0YW5jZShuLmNsb3Nlc3QoXCIuZHJvcGRvd24ub3BlblwiKSwhMCkpJiZ2b2lkIDAhPT1zP3M6bnVsbDtpZihyLmVsZW1lbnQuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKSYmci5lbGVtZW50LmVsLl9mbG9hdGluZ1VJLnN0YXRlLnBsYWNlbWVudC5pbmNsdWRlcyh0KSlyZXR1cm4gYy5mb2N1cygpLCExO2NvbnN0IGg9ci5lbGVtZW50LmNhbGN1bGF0ZUZMb2F0aW5nVUlQb3NpdGlvbigpO2lmKGwmJiFoLmluY2x1ZGVzKHQpKXJldHVybiExO2guaW5jbHVkZXModCkmJm4uY2xhc3NMaXN0LmNvbnRhaW5zKFwiZHJvcGRvd24tdG9nZ2xlXCIpPyhyLmVsZW1lbnQub3BlbigpLGMuZm9jdXMoKSk6KGQuZWxlbWVudC5jbG9zZSghMSksZC5lbGVtZW50LnRvZ2dsZS5mb2N1cygpKX1zdGF0aWMgb25TdGFydEVuZChlPSEwKXtjb25zdCB0PXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpKTtpZih0KXtjb25zdCBpPXQuZWxlbWVudC5tZW51O2lmKCFpKXJldHVybiExO2NvbnN0IHM9KGU/QXJyYXkuZnJvbShpLnF1ZXJ5U2VsZWN0b3JBbGwoJ2EsIGJ1dHRvbiwgW3JvbGU9XCJidXR0b25cIl0sIFtyb2xlXj1cIm1lbnVpdGVtXCJdJykpOkFycmF5LmZyb20oaS5xdWVyeVNlbGVjdG9yQWxsKCdhLCBidXR0b24sIFtyb2xlPVwiYnV0dG9uXCJdLCBbcm9sZV49XCJtZW51aXRlbVwiXScpKS5yZXZlcnNlKCkpLmZpbHRlcigoZT0+IWUuY2xhc3NMaXN0LmNvbnRhaW5zKFwiZGlzYWJsZWRcIikpKTtzLmxlbmd0aCYmc1swXS5mb2N1cygpfX1zdGF0aWMgb25GaXJzdExldHRlcihlKXtjb25zdCB0PXdpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpKTtpZih0KXtjb25zdCBpPXQuZWxlbWVudC5tZW51O2lmKCFpKXJldHVybiExO2NvbnN0IHM9QXJyYXkuZnJvbShpLnF1ZXJ5U2VsZWN0b3JBbGwoJ2EsIFtyb2xlPVwiYnV0dG9uXCJdLCBbcm9sZV49XCJtZW51aXRlbVwiXScpKSxuPSgpPT5zLmZpbmRJbmRleCgoKHQsaSk9PnQuaW5uZXJUZXh0LnRvTG93ZXJDYXNlKCkuY2hhckF0KDApPT09ZS50b0xvd2VyQ2FzZSgpJiZ0aGlzLmhpc3RvcnkuZXhpc3RzSW5IaXN0b3J5KGkpKSk7bGV0IG89bigpOy0xPT09byYmKHRoaXMuaGlzdG9yeS5jbGVhckhpc3RvcnkoKSxvPW4oKSksLTEhPT1vJiYoc1tvXS5mb2N1cygpLHRoaXMuaGlzdG9yeS5hZGRIaXN0b3J5KG8pKX19c3RhdGljIGNsb3NlQ3VycmVudGx5T3BlbmVkKGU9bnVsbCx0PSEwKXtjb25zdCBpPWUmJmUuY2xvc2VzdChcIi5kcm9wZG93blwiKSYmZS5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpLnBhcmVudEVsZW1lbnQuY2xvc2VzdChcIi5kcm9wZG93blwiKT9lLmNsb3Nlc3QoXCIuZHJvcGRvd25cIikucGFyZW50RWxlbWVudC5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpOm51bGw7bGV0IHM9aT93aW5kb3cuJGhzRHJvcGRvd25Db2xsZWN0aW9uLmZpbHRlcigoZT0+ZS5lbGVtZW50LmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikmJmUuZWxlbWVudC5tZW51LmNsb3Nlc3QoXCIuZHJvcGRvd25cIikucGFyZW50RWxlbWVudC5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpPT09aSkpOndpbmRvdy4kaHNEcm9wZG93bkNvbGxlY3Rpb24uZmlsdGVyKChlPT5lLmVsZW1lbnQuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKSkpO2UmJmUuY2xvc2VzdChcIi5kcm9wZG93blwiKSYmXCJpbnNpZGVcIj09PSgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eUFsdCkoZS5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpLFwiLS1hdXRvLWNsb3NlXCIpJiYocz1zLmZpbHRlcigodD0+dC5lbGVtZW50LmVsIT09ZS5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpKSkpLGUmJmUuY2xvc2VzdChcIi5kcm9wZG93blwiKSYmXCJvdXRzaWRlXCI9PT0oMCxuLmdldENsYXNzUHJvcGVydHlBbHQpKGUuY2xvc2VzdChcIi5kcm9wZG93blwiKSxcIi0tYXV0by1jbG9zZVwiKSYmKHM9cy5maWx0ZXIoKHQ9PnQuZWxlbWVudC5lbD09ZS5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpKSkscy5mb3JFYWNoKChlPT5lLmVsZW1lbnQuY2xvc2UodCkpKSkscyYmcy5mb3JFYWNoKChlPT57aWYoXCJmYWxzZVwiPT09ZS5lbGVtZW50LmNsb3NlTW9kZXx8XCJvdXRzaWRlXCI9PT1lLmVsZW1lbnQuY2xvc2VNb2RlKXJldHVybiExO2UuZWxlbWVudC5jbG9zZSh0KX0pKSxzJiZzLmZvckVhY2goKGU9PntpZihcImNvbnRleHRtZW51XCIhPT0oMCxuLmdldENsYXNzUHJvcGVydHlBbHQpKGUuZWxlbWVudC5lbCxcIi0tdHJpZ2dlclwiKSlyZXR1cm4hMTtkb2N1bWVudC5ib2R5LnN0eWxlLm92ZXJmbG93PVwiXCIsZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nUmlnaHQ9XCJcIn0pKX1zdGF0aWMgb24oZSx0LGkpe2NvbnN0IHM9YS5maW5kSW5Db2xsZWN0aW9uKHQpO3MmJihzLmVsZW1lbnQuZXZlbnRzW2VdPWkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PnthLmF1dG9Jbml0KCl9KSksd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIiwoKCk9Pnt3aW5kb3cuJGhzRHJvcGRvd25Db2xsZWN0aW9ufHwod2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbj1bXSksd2luZG93LiRoc0Ryb3Bkb3duQ29sbGVjdGlvbi5mb3JFYWNoKChlPT5lLmVsZW1lbnQucmVzaXplSGFuZGxlcigpKSl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU0Ryb3Bkb3duPWEpLHQuZGVmYXVsdD1hfSw3NjM6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTQ29sbGFwc2VcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSk7Y29uc3Qgbj1pKDgwNiksbz1zKGkoMjg3KSksbD1zKGkoNzUzKSk7Y2xhc3MgciBleHRlbmRzIG8uZGVmYXVsdHtjb25zdHJ1Y3RvcihlLHQsaSl7c3VwZXIoZSx0LGkpLHRoaXMuY29udGVudElkPXRoaXMuZWwuZGF0YXNldC5jb2xsYXBzZSx0aGlzLmNvbnRlbnQ9ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmNvbnRlbnRJZCksdGhpcy5hbmltYXRpb25JblByb2Nlc3M9ITEsdGhpcy5jb250ZW50JiZ0aGlzLmluaXQoKX1lbGVtZW50Q2xpY2soKXt0aGlzLmNvbnRlbnQuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKT90aGlzLmhpZGUoKTp0aGlzLnNob3coKX1pbml0KCl7dmFyIGU7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb24sdGhpcyksdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyPSgpPT50aGlzLmVsZW1lbnRDbGljaygpLChudWxsPT09KGU9bnVsbD09dGhpcz92b2lkIDA6dGhpcy5lbCl8fHZvaWQgMD09PWU/dm9pZCAwOmUuYXJpYUV4cGFuZGVkKSYmKHRoaXMuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKFwib3BlblwiKT90aGlzLmVsLmFyaWFFeHBhbmRlZD1cInRydWVcIjp0aGlzLmVsLmFyaWFFeHBhbmRlZD1cImZhbHNlXCIpLHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyKX1oaWRlQWxsTWVnYU1lbnVJdGVtcygpe3RoaXMuY29udGVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLm1lZ2EtbWVudS1jb250ZW50LmJsb2NrXCIpLmZvckVhY2goKGU9PntlLmNsYXNzTGlzdC5yZW1vdmUoXCJibG9ja1wiKSxlLmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIil9KSl9Y2xvc2VEcm9wZG93bnMoKXtpZighdGhpcy5jb250ZW50KXJldHVybjt0aGlzLmNvbnRlbnQucXVlcnlTZWxlY3RvckFsbChcIi5kcm9wZG93blwiKS5mb3JFYWNoKChlPT57dHJ5e2NvbnN0IHQ9bC5kZWZhdWx0LmdldEluc3RhbmNlKGUsITApO2lmKCEobnVsbD09dD92b2lkIDA6dC5lbGVtZW50KSlyZXR1cm47ZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50JiZlLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikmJnQuZWxlbWVudC5jbG9zZSghMSl9Y2F0Y2goZSl7Y29uc29sZS53YXJuKFwiRXJyb3IgY2xvc2luZyBkcm9wZG93bjpcIixlKX19KSl9c2hvdygpe3ZhciBlO2lmKHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzfHx0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpcmV0dXJuITE7dGhpcy5hbmltYXRpb25JblByb2Nlc3M9ITAsdGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwib3BlblwiKSwobnVsbD09PShlPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMuZWwpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmFyaWFFeHBhbmRlZCkmJih0aGlzLmVsLmFyaWFFeHBhbmRlZD1cInRydWVcIiksdGhpcy5jb250ZW50LmNsYXNzTGlzdC5hZGQoXCJvcGVuXCIpLHRoaXMuY29udGVudC5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpLHRoaXMuY29udGVudC5zdHlsZS5oZWlnaHQ9XCIwXCIsc2V0VGltZW91dCgoKCk9Pnt0aGlzLmNvbnRlbnQuc3R5bGUuaGVpZ2h0PWAke3RoaXMuY29udGVudC5zY3JvbGxIZWlnaHR9cHhgLHRoaXMuZmlyZUV2ZW50KFwiYmVmb3JlT3BlblwiLHRoaXMuZWwpLCgwLG4uZGlzcGF0Y2gpKFwiYmVmb3JlT3Blbi5jb2xsYXBzZVwiLHRoaXMuZWwsdGhpcy5lbCl9KSksKDAsbi5hZnRlclRyYW5zaXRpb24pKHRoaXMuY29udGVudCwoKCk9Pnt0aGlzLmNvbnRlbnQuc3R5bGUuaGVpZ2h0PVwiXCIsdGhpcy5maXJlRXZlbnQoXCJvcGVuXCIsdGhpcy5lbCksKDAsbi5kaXNwYXRjaCkoXCJvcGVuLmNvbGxhcHNlXCIsdGhpcy5lbCx0aGlzLmVsKSx0aGlzLmFuaW1hdGlvbkluUHJvY2Vzcz0hMX0pKX1oaWRlKCl7dmFyIGU7aWYodGhpcy5hbmltYXRpb25JblByb2Nlc3N8fCF0aGlzLmVsLmNsYXNzTGlzdC5jb250YWlucyhcIm9wZW5cIikpcmV0dXJuITE7dGhpcy5hbmltYXRpb25JblByb2Nlc3M9ITAsdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFwib3BlblwiKSwobnVsbD09PShlPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMuZWwpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmFyaWFFeHBhbmRlZCkmJih0aGlzLmVsLmFyaWFFeHBhbmRlZD1cImZhbHNlXCIpLHRoaXMuY29udGVudC5zdHlsZS5oZWlnaHQ9YCR7dGhpcy5jb250ZW50LnNjcm9sbEhlaWdodH1weGAsc2V0VGltZW91dCgoKCk9Pnt0aGlzLmNvbnRlbnQuc3R5bGUuaGVpZ2h0PVwiMFwifSkpLHRoaXMuY29udGVudC5jbGFzc0xpc3QucmVtb3ZlKFwib3BlblwiKSwoMCxuLmFmdGVyVHJhbnNpdGlvbikodGhpcy5jb250ZW50LCgoKT0+e3RoaXMuY29udGVudC5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpLHRoaXMuY29udGVudC5zdHlsZS5oZWlnaHQ9XCJcIix0aGlzLmZpcmVFdmVudChcImhpZGVcIix0aGlzLmVsKSwoMCxuLmRpc3BhdGNoKShcImhpZGUuY29sbGFwc2VcIix0aGlzLmVsLHRoaXMuZWwpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExfSkpLHRoaXMuY29udGVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLm1lZ2EtbWVudS1jb250ZW50LmJsb2NrXCIpLmxlbmd0aCYmdGhpcy5oaWRlQWxsTWVnYU1lbnVJdGVtcygpLHRoaXMuY2xvc2VEcm9wZG93bnMoKX1kZXN0cm95KCl7dGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXIpLHRoaXMuY29udGVudD1udWxsLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExLHdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb249d2luZG93LiRoc0NvbGxhcHNlQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSl9c3RhdGljIGZpbmRJbkNvbGxlY3Rpb24oZSl7cmV0dXJuIHdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb24uZmluZCgodD0+ZSBpbnN0YW5jZW9mIHI/dC5lbGVtZW50LmVsPT09ZS5lbDpcInN0cmluZ1wiPT10eXBlb2YgZT90LmVsZW1lbnQuZWw9PT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOnQuZWxlbWVudC5lbD09PWUpKXx8bnVsbH1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0PSExKXtjb25zdCBpPXdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50LmVsOm51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0NvbGxhcHNlQ29sbGVjdGlvbnx8KHdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb249W10pLHdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb24mJih3aW5kb3cuJGhzQ29sbGFwc2VDb2xsZWN0aW9uPXdpbmRvdy4kaHNDb2xsYXBzZUNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmNvbGxhcHNlLXRvZ2dsZTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmZvckVhY2goKGU9Pnt3aW5kb3cuJGhzQ29sbGFwc2VDb2xsZWN0aW9uLmZpbmQoKHQ9Pnt2YXIgaTtyZXR1cm4obnVsbD09PShpPW51bGw9PXQ/dm9pZCAwOnQuZWxlbWVudCl8fHZvaWQgMD09PWk/dm9pZCAwOmkuZWwpPT09ZX0pKXx8bmV3IHIoZSl9KSl9c3RhdGljIHNob3coZSl7Y29uc3QgdD1yLmZpbmRJbkNvbGxlY3Rpb24oZSk7dCYmdC5lbGVtZW50LmNvbnRlbnQuY2xhc3NMaXN0LmNvbnRhaW5zKFwiaGlkZGVuXCIpJiZ0LmVsZW1lbnQuc2hvdygpfXN0YXRpYyBoaWRlKGUpe2NvbnN0IHQ9ci5maW5kSW5Db2xsZWN0aW9uKGUpO3QmJiF0LmVsZW1lbnQuY29udGVudC5jbGFzc0xpc3QuY29udGFpbnMoXCJoaWRkZW5cIikmJnQuZWxlbWVudC5oaWRlKCl9c3RhdGljIG9uKGUsdCxpKXtjb25zdCBzPXIuZmluZEluQ29sbGVjdGlvbih0KTtzJiYocy5lbGVtZW50LmV2ZW50c1tlXT1pKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57ci5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNDb2xsYXBzZT1yKSx0LmRlZmF1bHQ9cn0sNzgyOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU1RyZWVWaWV3XG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbnZhciBzPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IG49aSg4MDYpLG89cyhpKDI4NykpO2NsYXNzIGwgZXh0ZW5kcyBvLmRlZmF1bHR7Y29uc3RydWN0b3IoZSx0LGkpe3N1cGVyKGUsdCxpKSx0aGlzLml0ZW1zPVtdO2NvbnN0IHM9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRyZWUtdmlld1wiKSxuPXM/SlNPTi5wYXJzZShzKTp7fSxvPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxuKSx0KTt0aGlzLmNvbnRyb2xCeT0obnVsbD09bz92b2lkIDA6by5jb250cm9sQnkpfHxcImJ1dHRvblwiLHRoaXMuYXV0b1NlbGVjdENoaWxkcmVuPShudWxsPT1vP3ZvaWQgMDpvLmF1dG9TZWxlY3RDaGlsZHJlbil8fCExLHRoaXMuaXNJbmRldGVybWluYXRlPShudWxsPT1vP3ZvaWQgMDpvLmlzSW5kZXRlcm1pbmF0ZSl8fCEwLHRoaXMub25FbGVtZW50Q2xpY2tMaXN0ZW5lcj1bXSx0aGlzLm9uQ29udHJvbENoYW5nZUxpc3RlbmVyPVtdLHRoaXMuaW5pdCgpfWVsZW1lbnRDbGljayhlLHQsaSl7aWYoZS5zdG9wUHJvcGFnYXRpb24oKSx0LmNsYXNzTGlzdC5jb250YWlucyhcImRpc2FibGVkXCIpKXJldHVybiExO2UubWV0YUtleXx8ZS5zaGlmdEtleXx8dGhpcy51bnNlbGVjdEl0ZW0oaSksdGhpcy5zZWxlY3RJdGVtKHQsaSksdGhpcy5maXJlRXZlbnQoXCJjbGlja1wiLHtlbDp0LGRhdGE6aX0pLCgwLG4uZGlzcGF0Y2gpKFwiY2xpY2sudHJlZVZpZXdcIix0aGlzLmVsLHtlbDp0LGRhdGE6aX0pfWNvbnRyb2xDaGFuZ2UoZSx0KXt0aGlzLmF1dG9TZWxlY3RDaGlsZHJlbj8odGhpcy5zZWxlY3RJdGVtKGUsdCksdC5pc0RpciYmdGhpcy5zZWxlY3RDaGlsZHJlbihlLHQpLHRoaXMudG9nZ2xlUGFyZW50KGUpKTp0aGlzLnNlbGVjdEl0ZW0oZSx0KX1pbml0KCl7dGhpcy5jcmVhdGVDb2xsZWN0aW9uKHdpbmRvdy4kaHNUcmVlVmlld0NvbGxlY3Rpb24sdGhpcyksbC5ncm91cCs9MSx0aGlzLmluaXRJdGVtcygpfWluaXRJdGVtcygpe3RoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXRyZWUtdmlldy1pdGVtXVwiKS5mb3JFYWNoKCgoZSx0KT0+e3ZhciBpLHM7Y29uc3Qgbj1KU09OLnBhcnNlKGUuZ2V0QXR0cmlidXRlKFwiZGF0YS10cmVlLXZpZXctaXRlbVwiKSk7ZS5pZHx8KGUuaWQ9YHRyZWUtdmlldy1pdGVtLSR7bC5ncm91cH0tJHt0fWApO2NvbnN0IG89T2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LG4pLHtpZDpudWxsIT09KGk9bi5pZCkmJnZvaWQgMCE9PWk/aTplLmlkLHBhdGg6dGhpcy5nZXRQYXRoKGUpLGlzU2VsZWN0ZWQ6bnVsbCE9PShzPW4uaXNTZWxlY3RlZCkmJnZvaWQgMCE9PXMmJnN9KTt0aGlzLml0ZW1zLnB1c2gobyksXCJjaGVja2JveFwiPT09dGhpcy5jb250cm9sQnk/dGhpcy5jb250cm9sQnlDaGVja2JveChlLG8pOnRoaXMuY29udHJvbEJ5QnV0dG9uKGUsbyl9KSl9Y29udHJvbEJ5QnV0dG9uKGUsdCl7dGhpcy5vbkVsZW1lbnRDbGlja0xpc3RlbmVyLnB1c2goe2VsOmUsZm46aT0+dGhpcy5lbGVtZW50Q2xpY2soaSxlLHQpfSksZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbil9Y29udHJvbEJ5Q2hlY2tib3goZSx0KXtjb25zdCBpPWUucXVlcnlTZWxlY3RvcihgaW5wdXRbdmFsdWU9XCIke3QudmFsdWV9XCJdYCk7aSYmKHRoaXMub25Db250cm9sQ2hhbmdlTGlzdGVuZXIucHVzaCh7ZWw6aSxmbjooKT0+dGhpcy5jb250cm9sQ2hhbmdlKGUsdCl9KSxpLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIix0aGlzLm9uQ29udHJvbENoYW5nZUxpc3RlbmVyLmZpbmQoKGU9PmUuZWw9PT1pKSkuZm4pKX1nZXRJdGVtKGUpe3JldHVybiB0aGlzLml0ZW1zLmZpbmQoKHQ9PnQuaWQ9PT1lKSl9Z2V0UGF0aChlKXt2YXIgdDtjb25zdCBpPVtdO2xldCBzPWUuY2xvc2VzdChcIltkYXRhLXRyZWUtdmlldy1pdGVtXVwiKTtmb3IoO3M7KXtjb25zdCBlPUpTT04ucGFyc2Uocy5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRyZWUtdmlldy1pdGVtXCIpKTtpLnB1c2goZS52YWx1ZSkscz1udWxsPT09KHQ9cy5wYXJlbnRFbGVtZW50KXx8dm9pZCAwPT09dD92b2lkIDA6dC5jbG9zZXN0KFwiW2RhdGEtdHJlZS12aWV3LWl0ZW1dXCIpfXJldHVybiBpLnJldmVyc2UoKS5qb2luKFwiL1wiKX11bnNlbGVjdEl0ZW0oZT1udWxsKXtsZXQgdD10aGlzLmdldFNlbGVjdGVkSXRlbXMoKTtlJiYodD10LmZpbHRlcigodD0+dC5pZCE9PWUuaWQpKSksdC5sZW5ndGgmJnQuZm9yRWFjaCgoZT0+e2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoYCMke2UuaWR9YCkuY2xhc3NMaXN0LnJlbW92ZShcInNlbGVjdGVkXCIpLHRoaXMuY2hhbmdlSXRlbVByb3AoZS5pZCxcImlzU2VsZWN0ZWRcIiwhMSl9KSl9c2VsZWN0SXRlbShlLHQpe3QuaXNTZWxlY3RlZD8oZS5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIiksdGhpcy5jaGFuZ2VJdGVtUHJvcCh0LmlkLFwiaXNTZWxlY3RlZFwiLCExKSk6KGUuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpLHRoaXMuY2hhbmdlSXRlbVByb3AodC5pZCxcImlzU2VsZWN0ZWRcIiwhMCkpfXNlbGVjdENoaWxkcmVuKGUsdCl7Y29uc3QgaT1lLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS10cmVlLXZpZXctaXRlbV1cIik7QXJyYXkuZnJvbShpKS5maWx0ZXIoKGU9PiFlLmNsYXNzTGlzdC5jb250YWlucyhcImRpc2FibGVkXCIpKSkuZm9yRWFjaCgoZT0+e2NvbnN0IGk9ZS5pZD90aGlzLmdldEl0ZW0oZS5pZCk6bnVsbDtpZighaSlyZXR1cm4hMTt0LmlzU2VsZWN0ZWQ/KGUuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpLHRoaXMuY2hhbmdlSXRlbVByb3AoaS5pZCxcImlzU2VsZWN0ZWRcIiwhMCkpOihlLmNsYXNzTGlzdC5yZW1vdmUoXCJzZWxlY3RlZFwiKSx0aGlzLmNoYW5nZUl0ZW1Qcm9wKGkuaWQsXCJpc1NlbGVjdGVkXCIsITEpKTtjb25zdCBzPXRoaXMuZ2V0SXRlbShlLmlkKSxuPWUucXVlcnlTZWxlY3RvcihgaW5wdXRbdmFsdWU9XCIke3MudmFsdWV9XCJdYCk7dGhpcy5pc0luZGV0ZXJtaW5hdGUmJihuLmluZGV0ZXJtaW5hdGU9ITEpLHMuaXNTZWxlY3RlZD9uLmNoZWNrZWQ9ITA6bi5jaGVja2VkPSExfSkpfXRvZ2dsZVBhcmVudChlKXt2YXIgdCxpO2xldCBzPW51bGw9PT0odD1lLnBhcmVudEVsZW1lbnQpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmNsb3Nlc3QoXCJbZGF0YS10cmVlLXZpZXctaXRlbV1cIik7Zm9yKDtzOyl7Y29uc3QgZT1zLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS10cmVlLXZpZXctaXRlbV06bm90KC5kaXNhYmxlZClcIiksdD1KU09OLnBhcnNlKHMuZ2V0QXR0cmlidXRlKFwiZGF0YS10cmVlLXZpZXctaXRlbVwiKSksbj1zLnF1ZXJ5U2VsZWN0b3IoYGlucHV0W3ZhbHVlPVwiJHt0LnZhbHVlfVwiXWApO2xldCBvPSExLGw9MDtlLmZvckVhY2goKGU9Pntjb25zdCB0PXRoaXMuZ2V0SXRlbShlLmlkKTt0LmlzU2VsZWN0ZWQmJihsKz0xKSx0LmlzU2VsZWN0ZWR8fChvPSEwKX0pKSxvPyhzLmNsYXNzTGlzdC5yZW1vdmUoXCJzZWxlY3RlZFwiKSx0aGlzLmNoYW5nZUl0ZW1Qcm9wKHMuaWQsXCJpc1NlbGVjdGVkXCIsITEpLG4uY2hlY2tlZD0hMSk6KHMuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpLHRoaXMuY2hhbmdlSXRlbVByb3Aocy5pZCxcImlzU2VsZWN0ZWRcIiwhMCksbi5jaGVja2VkPSEwKSx0aGlzLmlzSW5kZXRlcm1pbmF0ZSYmKGw+MCYmbDxlLmxlbmd0aD9uLmluZGV0ZXJtaW5hdGU9ITA6bi5pbmRldGVybWluYXRlPSExKSxzPW51bGw9PT0oaT1zLnBhcmVudEVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmNsb3Nlc3QoXCJbZGF0YS10cmVlLXZpZXctaXRlbV1cIil9fXVwZGF0ZSgpe3RoaXMuaXRlbXMubWFwKChlPT57Y29uc3QgdD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAjJHtlLmlkfWApO3JldHVybiBlLnBhdGghPT10aGlzLmdldFBhdGgodCkmJihlLnBhdGg9dGhpcy5nZXRQYXRoKHQpKSxlfSkpfWdldFNlbGVjdGVkSXRlbXMoKXtyZXR1cm4gdGhpcy5pdGVtcy5maWx0ZXIoKGU9PmUuaXNTZWxlY3RlZCkpfWNoYW5nZUl0ZW1Qcm9wKGUsdCxpKXt0aGlzLml0ZW1zLm1hcCgocz0+KHMuaWQ9PT1lJiYoc1t0XT1pKSxzKSkpfWRlc3Ryb3koKXt0aGlzLm9uRWxlbWVudENsaWNrTGlzdGVuZXIuZm9yRWFjaCgoKHtlbDplLGZuOnR9KT0+e2UucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdCl9KSksdGhpcy5vbkNvbnRyb2xDaGFuZ2VMaXN0ZW5lci5sZW5ndGgmJnRoaXMub25FbGVtZW50Q2xpY2tMaXN0ZW5lci5mb3JFYWNoKCgoe2VsOmUsZm46dH0pPT57ZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsdCl9KSksdGhpcy51bnNlbGVjdEl0ZW0oKSx0aGlzLml0ZW1zPVtdLHdpbmRvdy4kaHNUcmVlVmlld0NvbGxlY3Rpb249d2luZG93LiRoc1RyZWVWaWV3Q29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmUuZWwhPT10aGlzLmVsKSksbC5ncm91cC09MX1zdGF0aWMgZmluZEluQ29sbGVjdGlvbihlKXtyZXR1cm4gd2luZG93LiRoc1RyZWVWaWV3Q29sbGVjdGlvbi5maW5kKCh0PT5lIGluc3RhbmNlb2YgbD90LmVsZW1lbnQuZWw9PT1lLmVsOlwic3RyaW5nXCI9PXR5cGVvZiBlP3QuZWxlbWVudC5lbD09PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6dC5lbGVtZW50LmVsPT09ZSkpfHxudWxsfXN0YXRpYyBnZXRJbnN0YW5jZShlLHQpe2NvbnN0IGk9d2luZG93LiRoc1RyZWVWaWV3Q29sbGVjdGlvbi5maW5kKCh0PT50LmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKSkpO3JldHVybiBpP3Q/aTppLmVsZW1lbnQuZWw6bnVsbH1zdGF0aWMgYXV0b0luaXQoKXt3aW5kb3cuJGhzVHJlZVZpZXdDb2xsZWN0aW9ufHwod2luZG93LiRoc1RyZWVWaWV3Q29sbGVjdGlvbj1bXSksd2luZG93LiRoc1RyZWVWaWV3Q29sbGVjdGlvbiYmKHdpbmRvdy4kaHNUcmVlVmlld0NvbGxlY3Rpb249d2luZG93LiRoc1RyZWVWaWV3Q29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmRvY3VtZW50LmNvbnRhaW5zKGUuZWwpKSkpLGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS10cmVlLXZpZXddOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNUcmVlVmlld0NvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgbChlKX0pKX1zdGF0aWMgb24oZSx0LGkpe2NvbnN0IHM9bC5maW5kSW5Db2xsZWN0aW9uKHQpO3MmJihzLmVsZW1lbnQuZXZlbnRzW2VdPWkpfX1sLmdyb3VwPTAsd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57bC5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNUcmVlVmlldz1sKSx0LmRlZmF1bHQ9bH0sNzkyOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU0RhdGFUYWJsZVxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCxpKXt2YXIgcyxuLG8sbCxyLGEsYyxkLGgsdSxwLG0sZyxmLHYsdyx5LGIsQyxTLEwsSTtzdXBlcihlLHQsaSksdGhpcy5lbD1cInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmU7Y29uc3QgRT1bXTtBcnJheS5mcm9tKHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcInRoZWFkIHRoLCB0aGVhZCB0ZFwiKSkuZm9yRWFjaCgoKGUsdCk9PntlLmNsYXNzTGlzdC5jb250YWlucyhcIi0tZXhjbHVkZS1mcm9tLW9yZGVyaW5nXCIpJiZFLnB1c2goe3RhcmdldHM6dCxvcmRlcmFibGU6ITF9KX0pKTtjb25zdCBUPXRoaXMuZWwuZ2V0QXR0cmlidXRlKFwiZGF0YS1kYXRhdGFibGVcIikseD1UP0pTT04ucGFyc2UoVCk6e307dGhpcy5jb25jYXRPcHRpb25zPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7c2VhcmNoaW5nOiEwLGxlbmd0aENoYW5nZTohMSxvcmRlcjpbXSxjb2x1bW5EZWZzOlsuLi5FXX0seCksdCksdGhpcy50YWJsZT10aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoXCJ0YWJsZVwiKSx0aGlzLnNlYXJjaGVzPW51bGwhPT0ocz1BcnJheS5mcm9tKHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWRhdGF0YWJsZS1zZWFyY2hdXCIpKSkmJnZvaWQgMCE9PXM/czpudWxsLHRoaXMucGFnZUVudGl0aWVzTGlzdD1udWxsIT09KG49QXJyYXkuZnJvbSh0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kYXRhdGFibGUtcGFnZS1lbnRpdGllc11cIikpKSYmdm9pZCAwIT09bj9uOm51bGwsdGhpcy5wYWdpbmdMaXN0PW51bGwhPT0obz1BcnJheS5mcm9tKHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWRhdGF0YWJsZS1wYWdpbmddXCIpKSkmJnZvaWQgMCE9PW8/bzpudWxsLHRoaXMucGFnaW5nUGFnZXNMaXN0PW51bGwhPT0obD1BcnJheS5mcm9tKHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWRhdGF0YWJsZS1wYWdpbmctcGFnZXNdXCIpKSkmJnZvaWQgMCE9PWw/bDpudWxsLHRoaXMucGFnaW5nUHJldkxpc3Q9bnVsbCE9PShyPUFycmF5LmZyb20odGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtZGF0YXRhYmxlLXBhZ2luZy1wcmV2XVwiKSkpJiZ2b2lkIDAhPT1yP3I6bnVsbCx0aGlzLnBhZ2luZ05leHRMaXN0PW51bGwhPT0oYT1BcnJheS5mcm9tKHRoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLWRhdGF0YWJsZS1wYWdpbmctbmV4dF1cIikpKSYmdm9pZCAwIT09YT9hOm51bGwsdGhpcy5pbmZvTGlzdD1udWxsIT09KGM9QXJyYXkuZnJvbSh0aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kYXRhdGFibGUtaW5mb11cIikpKSYmdm9pZCAwIT09Yz9jOm51bGwsKG51bGw9PT0oZD10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1kP3ZvaWQgMDpkLnJvd1NlbGVjdGluZ09wdGlvbnMpJiYodGhpcy5yb3dTZWxlY3RpbmdBbGw9bnVsbCE9PShnPShudWxsPT09KHU9bnVsbD09PShoPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PWg/dm9pZCAwOmgucm93U2VsZWN0aW5nT3B0aW9ucyl8fHZvaWQgMD09PXU/dm9pZCAwOnUuc2VsZWN0QWxsU2VsZWN0b3IpP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IobnVsbD09PShtPW51bGw9PT0ocD10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1wP3ZvaWQgMDpwLnJvd1NlbGVjdGluZ09wdGlvbnMpfHx2b2lkIDA9PT1tP3ZvaWQgMDptLnNlbGVjdEFsbFNlbGVjdG9yKTpkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZGF0YXRhYmxlLXJvdy1zZWxlY3RpbmctYWxsXVwiKSkmJnZvaWQgMCE9PWc/ZzpudWxsKSwobnVsbD09PShmPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PWY/dm9pZCAwOmYucm93U2VsZWN0aW5nT3B0aW9ucykmJih0aGlzLnJvd1NlbGVjdGluZ0luZGl2aWR1YWw9bnVsbCE9PShiPW51bGwhPT0oeT1udWxsPT09KHc9bnVsbD09PSh2PXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PXY/dm9pZCAwOnYucm93U2VsZWN0aW5nT3B0aW9ucyl8fHZvaWQgMD09PXc/dm9pZCAwOncuaW5kaXZpZHVhbFNlbGVjdG9yKSYmdm9pZCAwIT09eT95OlwiW2RhdGEtZGF0YXRhYmxlLXJvdy1zZWxlY3RpbmctaW5kaXZpZHVhbF1cIikmJnZvaWQgMCE9PWI/YjpudWxsKSx0aGlzLnBhZ2VFbnRpdGllc0xpc3QubGVuZ3RoJiYodGhpcy5jb25jYXRPcHRpb25zLnBhZ2VMZW5ndGg9cGFyc2VJbnQodGhpcy5wYWdlRW50aXRpZXNMaXN0WzBdLnZhbHVlKSksdGhpcy5tYXhQYWdlc1RvU2hvdz0zLHRoaXMuaXNSb3dTZWxlY3Rpbmc9ISEobnVsbD09PShDPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PUM/dm9pZCAwOkMucm93U2VsZWN0aW5nT3B0aW9ucyksdGhpcy5wYWdlQnRuQ2xhc3Nlcz1udWxsIT09KEk9bnVsbD09PShMPW51bGw9PT0oUz10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1TP3ZvaWQgMDpTLnBhZ2luZ09wdGlvbnMpfHx2b2lkIDA9PT1MP3ZvaWQgMDpMLnBhZ2VCdG5DbGFzc2VzKSYmdm9pZCAwIT09ST9JOm51bGwsdGhpcy5vblNlYXJjaElucHV0TGlzdGVuZXI9W10sdGhpcy5vblBhZ2VFbnRpdGllc0NoYW5nZUxpc3RlbmVyPVtdLHRoaXMub25TaW5nbGVQYWdpbmdDbGlja0xpc3RlbmVyPVtdLHRoaXMub25QYWdpbmdQcmV2Q2xpY2tMaXN0ZW5lcj1bXSx0aGlzLm9uUGFnaW5nTmV4dENsaWNrTGlzdGVuZXI9W10sdGhpcy5pbml0KCl9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzRGF0YVRhYmxlQ29sbGVjdGlvbix0aGlzKSx0aGlzLmluaXRUYWJsZSgpLHRoaXMuc2VhcmNoZXMubGVuZ3RoJiZ0aGlzLmluaXRTZWFyY2goKSx0aGlzLnBhZ2VFbnRpdGllc0xpc3QubGVuZ3RoJiZ0aGlzLmluaXRQYWdlRW50aXRpZXMoKSx0aGlzLnBhZ2luZ0xpc3QubGVuZ3RoJiZ0aGlzLmluaXRQYWdpbmcoKSx0aGlzLnBhZ2luZ1BhZ2VzTGlzdC5sZW5ndGgmJnRoaXMuYnVpbGRQYWdpbmdQYWdlcygpLHRoaXMucGFnaW5nUHJldkxpc3QubGVuZ3RoJiZ0aGlzLmluaXRQYWdpbmdQcmV2KCksdGhpcy5wYWdpbmdOZXh0TGlzdC5sZW5ndGgmJnRoaXMuaW5pdFBhZ2luZ05leHQoKSx0aGlzLmluZm9MaXN0Lmxlbmd0aCYmdGhpcy5pbml0SW5mbygpLHRoaXMuaXNSb3dTZWxlY3RpbmcmJnRoaXMuaW5pdFJvd1NlbGVjdGluZygpfWluaXRUYWJsZSgpe3RoaXMuZGF0YVRhYmxlPW5ldyBEYXRhVGFibGUodGhpcy50YWJsZSx0aGlzLmNvbmNhdE9wdGlvbnMpLHRoaXMuaXNSb3dTZWxlY3RpbmcmJnRoaXMudHJpZ2dlckNoYW5nZUV2ZW50VG9Sb3coKSx0aGlzLmRhdGFUYWJsZS5vbihcImRyYXdcIiwoKCk9Pnt0aGlzLmlzUm93U2VsZWN0aW5nJiZ0aGlzLnVwZGF0ZVNlbGVjdEFsbENoZWNrYm94KCksdGhpcy5pc1Jvd1NlbGVjdGluZyYmdGhpcy50cmlnZ2VyQ2hhbmdlRXZlbnRUb1JvdygpLHRoaXMudXBkYXRlSW5mbygpLHRoaXMucGFnaW5nUGFnZXNMaXN0LmZvckVhY2goKGU9PnRoaXMudXBkYXRlUGFnaW5nKGUpKSl9KSl9c2VhcmNoSW5wdXQoZSl7dGhpcy5vblNlYXJjaElucHV0KGUudGFyZ2V0LnZhbHVlKX1wYWdlRW50aXRpZXNDaGFuZ2UoZSl7dGhpcy5vbkVudGl0aWVzQ2hhbmdlKHBhcnNlSW50KGUudGFyZ2V0LnZhbHVlKSxlLnRhcmdldCl9cGFnaW5nUHJldkNsaWNrKCl7dGhpcy5vblByZXZDbGljaygpfXBhZ2luZ05leHRDbGljaygpe3RoaXMub25OZXh0Q2xpY2soKX1yb3dTZWxlY3RpbmdBbGxDaGFuZ2UoKXt0aGlzLm9uU2VsZWN0QWxsQ2hhbmdlKCl9c2luZ2xlUGFnaW5nQ2xpY2soZSl7dGhpcy5vblBhZ2VDbGljayhlKX1pbml0U2VhcmNoKCl7dGhpcy5zZWFyY2hlcy5mb3JFYWNoKChlPT57dGhpcy5vblNlYXJjaElucHV0TGlzdGVuZXIucHVzaCh7ZWw6ZSxmbjooMCxuLmRlYm91bmNlKSgoZT0+dGhpcy5zZWFyY2hJbnB1dChlKSkpfSksZS5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uU2VhcmNoSW5wdXRMaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKX0pKX1vblNlYXJjaElucHV0KGUpe3RoaXMuZGF0YVRhYmxlLnNlYXJjaChlKS5kcmF3KCl9aW5pdFBhZ2VFbnRpdGllcygpe3RoaXMucGFnZUVudGl0aWVzTGlzdC5mb3JFYWNoKChlPT57dGhpcy5vblBhZ2VFbnRpdGllc0NoYW5nZUxpc3RlbmVyLnB1c2goe2VsOmUsZm46ZT0+dGhpcy5wYWdlRW50aXRpZXNDaGFuZ2UoZSl9KSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJjaGFuZ2VcIix0aGlzLm9uUGFnZUVudGl0aWVzQ2hhbmdlTGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbil9KSl9b25FbnRpdGllc0NoYW5nZShlLHQpe2NvbnN0IGk9dGhpcy5wYWdlRW50aXRpZXNMaXN0LmZpbHRlcigoZT0+ZSE9PXQpKTtpLmxlbmd0aCYmaS5mb3JFYWNoKCh0PT57aWYod2luZG93LkhTU2VsZWN0KXtjb25zdCBpPXdpbmRvdy5IU1NlbGVjdC5nZXRJbnN0YW5jZSh0LCEwKTtpJiZpLmVsZW1lbnQuc2V0VmFsdWUoYCR7ZX1gKX1lbHNlIHQudmFsdWU9YCR7ZX1gfSkpLHRoaXMuZGF0YVRhYmxlLnBhZ2UubGVuKGUpLmRyYXcoKX1pbml0SW5mbygpe3RoaXMuaW5mb0xpc3QuZm9yRWFjaCgoZT0+e3RoaXMuaW5pdEluZm9Gcm9tKGUpLHRoaXMuaW5pdEluZm9UbyhlKSx0aGlzLmluaXRJbmZvTGVuZ3RoKGUpfSkpfWluaXRJbmZvRnJvbShlKXt2YXIgdDtjb25zdCBpPW51bGwhPT0odD1lLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1kYXRhdGFibGUtaW5mby1mcm9tXVwiKSkmJnZvaWQgMCE9PXQ/dDpudWxsLHtzdGFydDpzfT10aGlzLmRhdGFUYWJsZS5wYWdlLmluZm8oKTtpJiYoaS5pbm5lclRleHQ9YCR7cysxfWApfWluaXRJbmZvVG8oZSl7dmFyIHQ7Y29uc3QgaT1udWxsIT09KHQ9ZS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZGF0YXRhYmxlLWluZm8tdG9dXCIpKSYmdm9pZCAwIT09dD90Om51bGwse2VuZDpzfT10aGlzLmRhdGFUYWJsZS5wYWdlLmluZm8oKTtpJiYoaS5pbm5lclRleHQ9YCR7c31gKX1pbml0SW5mb0xlbmd0aChlKXt2YXIgdDtjb25zdCBpPW51bGwhPT0odD1lLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1kYXRhdGFibGUtaW5mby1sZW5ndGhdXCIpKSYmdm9pZCAwIT09dD90Om51bGwse3JlY29yZHNUb3RhbDpzfT10aGlzLmRhdGFUYWJsZS5wYWdlLmluZm8oKTtpJiYoaS5pbm5lclRleHQ9YCR7c31gKX11cGRhdGVJbmZvKCl7dGhpcy5pbml0SW5mbygpfWluaXRQYWdpbmcoKXt0aGlzLnBhZ2luZ0xpc3QuZm9yRWFjaCgoZT0+dGhpcy5oaWRlUGFnaW5nSWZTaW5nbGVQYWdlKGUpKSl9aGlkZVBhZ2luZ0lmU2luZ2xlUGFnZShlKXtjb25zdHtwYWdlczp0fT10aGlzLmRhdGFUYWJsZS5wYWdlLmluZm8oKTt0PDI/KGUuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKSxlLnN0eWxlLmRpc3BsYXk9XCJub25lXCIpOihlLmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRkZW5cIiksZS5zdHlsZS5kaXNwbGF5PVwiXCIpfWluaXRQYWdpbmdQcmV2KCl7dGhpcy5wYWdpbmdQcmV2TGlzdC5mb3JFYWNoKChlPT57dGhpcy5vblBhZ2luZ1ByZXZDbGlja0xpc3RlbmVyLnB1c2goe2VsOmUsZm46KCk9PnRoaXMucGFnaW5nUHJldkNsaWNrKCl9KSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25QYWdpbmdQcmV2Q2xpY2tMaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKX0pKX1vblByZXZDbGljaygpe3RoaXMuZGF0YVRhYmxlLnBhZ2UoXCJwcmV2aW91c1wiKS5kcmF3KFwicGFnZVwiKX1kaXNhYmxlUGFnaW5nQXJyb3coZSx0KXt0PyhlLmNsYXNzTGlzdC5hZGQoXCJkaXNhYmxlZFwiKSxlLnNldEF0dHJpYnV0ZShcImRpc2FibGVkXCIsXCJkaXNhYmxlZFwiKSk6KGUuY2xhc3NMaXN0LnJlbW92ZShcImRpc2FibGVkXCIpLGUucmVtb3ZlQXR0cmlidXRlKFwiZGlzYWJsZWRcIikpfWluaXRQYWdpbmdOZXh0KCl7dGhpcy5wYWdpbmdOZXh0TGlzdC5mb3JFYWNoKChlPT57dGhpcy5vblBhZ2luZ05leHRDbGlja0xpc3RlbmVyLnB1c2goe2VsOmUsZm46KCk9PnRoaXMucGFnaW5nTmV4dENsaWNrKCl9KSxlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25QYWdpbmdOZXh0Q2xpY2tMaXN0ZW5lci5maW5kKCh0PT50LmVsPT09ZSkpLmZuKX0pKX1vbk5leHRDbGljaygpe3RoaXMuZGF0YVRhYmxlLnBhZ2UoXCJuZXh0XCIpLmRyYXcoXCJwYWdlXCIpfWJ1aWxkUGFnaW5nUGFnZXMoKXt0aGlzLnBhZ2luZ1BhZ2VzTGlzdC5mb3JFYWNoKChlPT50aGlzLnVwZGF0ZVBhZ2luZyhlKSkpfXVwZGF0ZVBhZ2luZyhlKXtjb25zdHtwYWdlOnQscGFnZXM6aSxsZW5ndGg6c309dGhpcy5kYXRhVGFibGUucGFnZS5pbmZvKCksbz10aGlzLmRhdGFUYWJsZS5yb3dzKHtzZWFyY2g6XCJhcHBsaWVkXCJ9KS5jb3VudCgpLGw9TWF0aC5jZWlsKG8vcykscj10KzE7bGV0IGE9TWF0aC5tYXgoMSxyLU1hdGguZmxvb3IodGhpcy5tYXhQYWdlc1RvU2hvdy8yKSksYz1NYXRoLm1pbihsLGErKHRoaXMubWF4UGFnZXNUb1Nob3ctMSkpO2MtYSsxPHRoaXMubWF4UGFnZXNUb1Nob3cmJihhPU1hdGgubWF4KDEsYy10aGlzLm1heFBhZ2VzVG9TaG93KzEpKSxlLmlubmVySFRNTD1cIlwiLGE+MSYmKHRoaXMuYnVpbGRQYWdpbmdQYWdlKDEsZSksYT4yJiZlLmFwcGVuZENoaWxkKCgwLG4uaHRtbFRvRWxlbWVudCkoJzxzcGFuIGNsYXNzPVwiZWxsaXBzaXNcIj4uLi48L3NwYW4+JykpKTtmb3IobGV0IHQ9YTt0PD1jO3QrKyl0aGlzLmJ1aWxkUGFnaW5nUGFnZSh0LGUpO2M8bCYmKGM8bC0xJiZlLmFwcGVuZENoaWxkKCgwLG4uaHRtbFRvRWxlbWVudCkoJzxzcGFuIGNsYXNzPVwiZWxsaXBzaXNcIj4uLi48L3NwYW4+JykpLHRoaXMuYnVpbGRQYWdpbmdQYWdlKGwsZSkpLHRoaXMucGFnaW5nUHJldkxpc3QuZm9yRWFjaCgoZT0+dGhpcy5kaXNhYmxlUGFnaW5nQXJyb3coZSwwPT09dCkpKSx0aGlzLnBhZ2luZ05leHRMaXN0LmZvckVhY2goKGU9PnRoaXMuZGlzYWJsZVBhZ2luZ0Fycm93KGUsdD09PWktMSkpKSx0aGlzLnBhZ2luZ0xpc3QuZm9yRWFjaCgoZT0+dGhpcy5oaWRlUGFnaW5nSWZTaW5nbGVQYWdlKGUpKSl9YnVpbGRQYWdpbmdQYWdlKGUsdCl7Y29uc3R7cGFnZTppfT10aGlzLmRhdGFUYWJsZS5wYWdlLmluZm8oKSxzPSgwLG4uaHRtbFRvRWxlbWVudCkoJzxidXR0b24gdHlwZT1cImJ1dHRvblwiPjwvYnV0dG9uPicpO3MuaW5uZXJUZXh0PWAke2V9YCxzLnNldEF0dHJpYnV0ZShcImRhdGEtcGFnZVwiLGAke2V9YCksdGhpcy5wYWdlQnRuQ2xhc3NlcyYmKDAsbi5jbGFzc1RvQ2xhc3NMaXN0KSh0aGlzLnBhZ2VCdG5DbGFzc2VzLHMpLGk9PT1lLTEmJnMuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKSx0aGlzLm9uU2luZ2xlUGFnaW5nQ2xpY2tMaXN0ZW5lci5wdXNoKHtlbDpzLGZuOigpPT50aGlzLnNpbmdsZVBhZ2luZ0NsaWNrKGUpfSkscy5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uU2luZ2xlUGFnaW5nQ2xpY2tMaXN0ZW5lci5maW5kKChlPT5lLmVsPT09cykpLmZuKSx0LmFwcGVuZChzKX1vblBhZ2VDbGljayhlKXt0aGlzLmRhdGFUYWJsZS5wYWdlKGUtMSkuZHJhdyhcInBhZ2VcIil9aW5pdFJvd1NlbGVjdGluZygpe3RoaXMub25Sb3dTZWxlY3RpbmdBbGxDaGFuZ2VMaXN0ZW5lcj0oKT0+dGhpcy5yb3dTZWxlY3RpbmdBbGxDaGFuZ2UoKSx0aGlzLnJvd1NlbGVjdGluZ0FsbC5hZGRFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsdGhpcy5vblJvd1NlbGVjdGluZ0FsbENoYW5nZUxpc3RlbmVyKX10cmlnZ2VyQ2hhbmdlRXZlbnRUb1Jvdygpe3RoaXMudGFibGUucXVlcnlTZWxlY3RvckFsbChgdGJvZHkgJHt0aGlzLnJvd1NlbGVjdGluZ0luZGl2aWR1YWx9YCkuZm9yRWFjaCgoZT0+e2UuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCgoKT0+e3RoaXMudXBkYXRlU2VsZWN0QWxsQ2hlY2tib3goKX0pKX0pKX1vblNlbGVjdEFsbENoYW5nZSgpe2xldCBlPXRoaXMucm93U2VsZWN0aW5nQWxsLmNoZWNrZWQ7QXJyYXkuZnJvbSh0aGlzLmRhdGFUYWJsZS5yb3dzKHtwYWdlOlwiY3VycmVudFwiLHNlYXJjaDpcImFwcGxpZWRcIn0pLm5vZGVzKCkpLmZvckVhY2goKHQ9Pntjb25zdCBpPXQucXVlcnlTZWxlY3Rvcih0aGlzLnJvd1NlbGVjdGluZ0luZGl2aWR1YWwpO2kmJihpLmNoZWNrZWQ9ZSl9KSksdGhpcy51cGRhdGVTZWxlY3RBbGxDaGVja2JveCgpfXVwZGF0ZVNlbGVjdEFsbENoZWNrYm94KCl7aWYoIXRoaXMuZGF0YVRhYmxlLnJvd3Moe3NlYXJjaDpcImFwcGxpZWRcIn0pLmNvdW50KCkpcmV0dXJuIHRoaXMucm93U2VsZWN0aW5nQWxsLmNoZWNrZWQ9ITEsITE7bGV0IGU9ITA7QXJyYXkuZnJvbSh0aGlzLmRhdGFUYWJsZS5yb3dzKHtwYWdlOlwiY3VycmVudFwiLHNlYXJjaDpcImFwcGxpZWRcIn0pLm5vZGVzKCkpLmZvckVhY2goKHQ9Pntjb25zdCBpPXQucXVlcnlTZWxlY3Rvcih0aGlzLnJvd1NlbGVjdGluZ0luZGl2aWR1YWwpO2lmKGkmJiFpLmNoZWNrZWQpcmV0dXJuIGU9ITEsITF9KSksdGhpcy5yb3dTZWxlY3RpbmdBbGwuY2hlY2tlZD1lfWRlc3Ryb3koKXt0aGlzLnNlYXJjaGVzJiZ0aGlzLm9uU2VhcmNoSW5wdXRMaXN0ZW5lci5mb3JFYWNoKCgoe2VsOmUsZm46dH0pPT5lLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHQpKSksdGhpcy5wYWdlRW50aXRpZXNMaXN0JiZ0aGlzLm9uUGFnZUVudGl0aWVzQ2hhbmdlTGlzdGVuZXIuZm9yRWFjaCgoKHtlbDplLGZuOnR9KT0+ZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2hhbmdlXCIsdCkpKSx0aGlzLnBhZ2luZ1BhZ2VzTGlzdC5sZW5ndGgmJih0aGlzLm9uU2luZ2xlUGFnaW5nQ2xpY2tMaXN0ZW5lci5mb3JFYWNoKCgoe2VsOmUsZm46dH0pPT5lLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHQpKSksdGhpcy5wYWdpbmdQYWdlc0xpc3QuZm9yRWFjaCgoZT0+ZS5pbm5lckhUTUw9XCJcIikpKSx0aGlzLnBhZ2luZ1ByZXZMaXN0Lmxlbmd0aCYmdGhpcy5vblBhZ2luZ1ByZXZDbGlja0xpc3RlbmVyLmZvckVhY2goKCh7ZWw6ZSxmbjp0fSk9PmUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdCkpKSx0aGlzLnBhZ2luZ05leHRMaXN0Lmxlbmd0aCYmdGhpcy5vblBhZ2luZ05leHRDbGlja0xpc3RlbmVyLmZvckVhY2goKCh7ZWw6ZSxmbjp0fSk9PmUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdCkpKSx0aGlzLnJvd1NlbGVjdGluZ0FsbCYmdGhpcy5yb3dTZWxlY3RpbmdBbGwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLHRoaXMub25Sb3dTZWxlY3RpbmdBbGxDaGFuZ2VMaXN0ZW5lciksdGhpcy5kYXRhVGFibGUuZGVzdHJveSgpLHRoaXMucm93U2VsZWN0aW5nQWxsPW51bGwsdGhpcy5yb3dTZWxlY3RpbmdJbmRpdmlkdWFsPW51bGwsd2luZG93LiRoc0RhdGFUYWJsZUNvbGxlY3Rpb249d2luZG93LiRoc0RhdGFUYWJsZUNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5lLmVsIT09dGhpcy5lbCkpfXN0YXRpYyBnZXRJbnN0YW5jZShlLHQpe2NvbnN0IGk9d2luZG93LiRoc0RhdGFUYWJsZUNvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50LmVsOm51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc0RhdGFUYWJsZUNvbGxlY3Rpb258fCh3aW5kb3cuJGhzRGF0YVRhYmxlQ29sbGVjdGlvbj1bXSksd2luZG93LiRoc0RhdGFUYWJsZUNvbGxlY3Rpb24mJih3aW5kb3cuJGhzRGF0YVRhYmxlQ29sbGVjdGlvbj13aW5kb3cuJGhzRGF0YVRhYmxlQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmRvY3VtZW50LmNvbnRhaW5zKGUuZWwpKSkpLGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kYXRhdGFibGVdOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNEYXRhVGFibGVDb2xsZWN0aW9uLmZpbmQoKHQ9Pnt2YXIgaTtyZXR1cm4obnVsbD09PShpPW51bGw9PXQ/dm9pZCAwOnQuZWxlbWVudCl8fHZvaWQgMD09PWk/dm9pZCAwOmkuZWwpPT09ZX0pKXx8bmV3IGwoZSl9KSl9fXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCgoKT0+e2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1kYXRhdGFibGVdOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikubGVuZ3RoJiYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIGpRdWVyeSYmY29uc29sZS5lcnJvcihcIkhTRGF0YVRhYmxlOiBqUXVlcnkgaXMgbm90IGF2YWlsYWJsZSwgcGxlYXNlIGFkZCBpdCB0byB0aGUgcGFnZS5cIiksXCJ1bmRlZmluZWRcIj09dHlwZW9mIERhdGFUYWJsZSYmY29uc29sZS5lcnJvcihcIkhTRGF0YVRhYmxlOiBEYXRhVGFibGUgaXMgbm90IGF2YWlsYWJsZSwgcGxlYXNlIGFkZCBpdCB0byB0aGUgcGFnZS5cIikpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBEYXRhVGFibGUmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBqUXVlcnkmJmwuYXV0b0luaXQoKX0pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYod2luZG93LkhTRGF0YVRhYmxlPWwpLHQuZGVmYXVsdD1sfSw4MDA6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xudmFyIHM9dGhpcyYmdGhpcy5fX2ltcG9ydERlZmF1bHR8fGZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX07bGV0IG4sbyxsO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pLHQuSFNSYW5nZVNsaWRlcj10LkhTRmlsZVVwbG9hZD10LkhTRGF0YVRhYmxlPXQuSFNTdGF0aWNNZXRob2RzPXQuSFNUcmVlVmlldz10LkhTVG9vbHRpcD10LkhTVG9nZ2xlUGFzc3dvcmQ9dC5IU1RvZ2dsZUNvdW50PXQuSFNUYWJzPXQuSFNTdHJvbmdQYXNzd29yZD10LkhTU3RlcHBlcj10LkhTU2VsZWN0PXQuSFNTY3JvbGxzcHk9dC5IU1JlbW92ZUVsZW1lbnQ9dC5IU1BpbklucHV0PXQuSFNPdmVybGF5PXQuSFNJbnB1dE51bWJlcj10LkhTRHJvcGRvd249dC5IU0NvbWJvQm94PXQuSFNDb2xsYXBzZT10LkhTQ2Fyb3VzZWw9dC5IU0FjY29yZGlvbj10LkhTQ29weU1hcmt1cD12b2lkIDA7dmFyIHI9aSgxMik7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU0NvcHlNYXJrdXBcIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyhyKS5kZWZhdWx0fX0pO3ZhciBhPWkoMzA2KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTQWNjb3JkaW9uXCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoYSkuZGVmYXVsdH19KTt2YXIgYz1pKDMwMik7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU0Nhcm91c2VsXCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoYykuZGVmYXVsdH19KTt2YXIgZD1pKDc2Myk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU0NvbGxhcHNlXCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoZCkuZGVmYXVsdH19KTt2YXIgaD1pKDc1KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTQ29tYm9Cb3hcIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyhoKS5kZWZhdWx0fX0pO3ZhciB1PWkoNzUzKTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTRHJvcGRvd25cIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyh1KS5kZWZhdWx0fX0pO3ZhciBwPWkoODYpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiSFNJbnB1dE51bWJlclwiLHtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiBzKHApLmRlZmF1bHR9fSk7dmFyIG09aSgxNjQpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiSFNPdmVybGF5XCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMobSkuZGVmYXVsdH19KTt2YXIgZz1pKDU5NCk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU1BpbklucHV0XCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoZykuZGVmYXVsdH19KTt2YXIgZj1pKDExMyk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU1JlbW92ZUVsZW1lbnRcIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyhmKS5kZWZhdWx0fX0pO3ZhciB2PWkoODgxKTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTU2Nyb2xsc3B5XCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHModikuZGVmYXVsdH19KTt2YXIgdz1pKDk1Nik7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU1NlbGVjdFwiLHtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiBzKHcpLmRlZmF1bHR9fSk7dmFyIHk9aSgyMTMpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiSFNTdGVwcGVyXCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoeSkuZGVmYXVsdH19KTt2YXIgYj1pKDIwNyk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU1N0cm9uZ1Bhc3N3b3JkXCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoYikuZGVmYXVsdH19KTt2YXIgQz1pKDk0NCk7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJIU1RhYnNcIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyhDKS5kZWZhdWx0fX0pO3ZhciBTPWkoMTI2KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTVG9nZ2xlQ291bnRcIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyhTKS5kZWZhdWx0fX0pO3ZhciBMPWkoMjM0KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTVG9nZ2xlUGFzc3dvcmRcIix7ZW51bWVyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gcyhMKS5kZWZhdWx0fX0pO3ZhciBJPWkoNDg3KTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIkhTVG9vbHRpcFwiLHtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiBzKEkpLmRlZmF1bHR9fSk7dmFyIEU9aSg3ODIpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiSFNUcmVlVmlld1wiLHtlbnVtZXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiBzKEUpLmRlZmF1bHR9fSk7dmFyIFQ9aSgzMTkpO09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiSFNTdGF0aWNNZXRob2RzXCIse2VudW1lcmFibGU6ITAsZ2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHMoVCkuZGVmYXVsdH19KSxcInVuZGVmaW5lZFwiIT10eXBlb2YgRGF0YVRhYmxlJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgalF1ZXJ5P3QuSFNEYXRhVGFibGU9bj1pKDc5MikuZGVmYXVsdDp0LkhTRGF0YVRhYmxlPW49bnVsbCxcInVuZGVmaW5lZFwiIT10eXBlb2YgXyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIERyb3B6b25lP3QuSFNGaWxlVXBsb2FkPW89aSgxOTIpLmRlZmF1bHQ6dC5IU0ZpbGVVcGxvYWQ9bz1udWxsLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBub1VpU2xpZGVyP3QuSFNSYW5nZVNsaWRlcj1sPWkoOTc3KS5kZWZhdWx0OnQuSFNSYW5nZVNsaWRlcj1sPW51bGx9LDgwNjpmdW5jdGlvbihlLHQpe1xuLypcbiAqIEB2ZXJzaW9uOiAzLjAuMFxuICogQGF1dGhvcjogUHJlbGluZSBMYWJzIEx0ZC5cbiAqIEBsaWNlbnNlOiBMaWNlbnNlZCB1bmRlciBNSVQgYW5kIFByZWxpbmUgVUkgRmFpciBVc2UgTGljZW5zZSAoaHR0cHM6Ly9wcmVsaW5lLmNvL2RvY3MvbGljZW5zZS5odG1sKVxuICogQ29weXJpZ2h0IDIwMjQgUHJlbGluZSBMYWJzIEx0ZC5cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSksdC5tZW51U2VhcmNoSGlzdG9yeT10LmNsYXNzVG9DbGFzc0xpc3Q9dC5odG1sVG9FbGVtZW50PXQuYWZ0ZXJUcmFuc2l0aW9uPXQuZGlzcGF0Y2g9dC5kZWJvdW5jZT10LmlzU2Nyb2xsYWJsZT10LmlzUGFyZW50T3JFbGVtZW50SGlkZGVuPXQuaXNKc29uPXQuaXNJcGFkT1M9dC5pc0lPUz10LmlzRGlyZWN0Q2hpbGQ9dC5pc0Zvcm1FbGVtZW50PXQuaXNGb2N1c2VkPXQuaXNFbm91Z2hTcGFjZT10LmdldEhpZ2hlc3RaSW5kZXg9dC5nZXRaSW5kZXg9dC5nZXRDbGFzc1Byb3BlcnR5QWx0PXQuZ2V0Q2xhc3NQcm9wZXJ0eT10LnN0cmluZ1RvQm9vbGVhbj12b2lkIDA7dC5zdHJpbmdUb0Jvb2xlYW49ZT0+XCJ0cnVlXCI9PT1lO3QuZ2V0Q2xhc3NQcm9wZXJ0eT0oZSx0LGk9XCJcIik9Pih3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKS5nZXRQcm9wZXJ0eVZhbHVlKHQpfHxpKS5yZXBsYWNlKFwiIFwiLFwiXCIpO3QuZ2V0Q2xhc3NQcm9wZXJ0eUFsdD0oZSx0LGk9XCJcIik9PntsZXQgcz1cIlwiO3JldHVybiBlLmNsYXNzTGlzdC5mb3JFYWNoKChlPT57ZS5pbmNsdWRlcyh0KSYmKHM9ZSl9KSkscy5tYXRjaCgvOiguKildLyk/cy5tYXRjaCgvOiguKildLylbMV06aX07Y29uc3QgaT1lPT53aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKS5nZXRQcm9wZXJ0eVZhbHVlKFwiei1pbmRleFwiKTt0LmdldFpJbmRleD1pO3QuZ2V0SGlnaGVzdFpJbmRleD1lPT57bGV0IHQ9TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO3JldHVybiBlLmZvckVhY2goKGU9PntsZXQgcz1pKGUpO1wiYXV0b1wiIT09cyYmKHM9cGFyc2VJbnQocywxMCkscz50JiYodD1zKSl9KSksdH07dC5pc0RpcmVjdENoaWxkPShlLHQpPT57Y29uc3QgaT1lLmNoaWxkcmVuO2ZvcihsZXQgZT0wO2U8aS5sZW5ndGg7ZSsrKWlmKGlbZV09PT10KXJldHVybiEwO3JldHVybiExfTt0LmlzRW5vdWdoU3BhY2U9KGUsdCxpPVwiYXV0b1wiLHM9MTAsbj1udWxsKT0+e2NvbnN0IG89dC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxsPW4/bi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTpudWxsLHI9d2luZG93LmlubmVySGVpZ2h0LGE9bD9vLnRvcC1sLnRvcDpvLnRvcCxjPShuP2wuYm90dG9tOnIpLW8uYm90dG9tLGQ9ZS5jbGllbnRIZWlnaHQrcztyZXR1cm5cImJvdHRvbVwiPT09aT9jPj1kOlwidG9wXCI9PT1pP2E+PWQ6YT49ZHx8Yz49ZH07dC5pc0ZvY3VzZWQ9ZT0+ZG9jdW1lbnQuYWN0aXZlRWxlbWVudD09PWU7dC5pc0Zvcm1FbGVtZW50PWU9PmUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50fHxlIGluc3RhbmNlb2YgSFRNTFRleHRBcmVhRWxlbWVudHx8ZSBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50O3QuaXNJT1M9KCk9PiEhL2lQYWR8aVBob25lfGlQb2QvLnRlc3QobmF2aWdhdG9yLnBsYXRmb3JtKXx8bmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzJiZuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHM+MiYmL01hY0ludGVsLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7dC5pc0lwYWRPUz0oKT0+bmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzJiZuYXZpZ2F0b3IubWF4VG91Y2hQb2ludHM+MiYmL01hY0ludGVsLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7dC5pc0pzb249ZT0+e2lmKFwic3RyaW5nXCIhPXR5cGVvZiBlKXJldHVybiExO2NvbnN0IHQ9ZS50cmltKClbMF0saT1lLnRyaW0oKS5zbGljZSgtMSk7aWYoXCJ7XCI9PT10JiZcIn1cIj09PWl8fFwiW1wiPT09dCYmXCJdXCI9PT1pKXRyeXtyZXR1cm4gSlNPTi5wYXJzZShlKSwhMH1jYXRjaChlKXtyZXR1cm4hMX1yZXR1cm4hMX07Y29uc3Qgcz1lPT57aWYoIWUpcmV0dXJuITE7cmV0dXJuXCJub25lXCI9PT13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKS5kaXNwbGF5fHxzKGUucGFyZW50RWxlbWVudCl9O3QuaXNQYXJlbnRPckVsZW1lbnRIaWRkZW49czt0LmlzU2Nyb2xsYWJsZT1lPT57Y29uc3QgdD13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKSxpPXQub3ZlcmZsb3dZLHM9dC5vdmVyZmxvd1gsbj0oXCJzY3JvbGxcIj09PWl8fFwiYXV0b1wiPT09aSkmJmUuc2Nyb2xsSGVpZ2h0PmUuY2xpZW50SGVpZ2h0LG89KFwic2Nyb2xsXCI9PT1zfHxcImF1dG9cIj09PXMpJiZlLnNjcm9sbFdpZHRoPmUuY2xpZW50V2lkdGg7cmV0dXJuIG58fG99O3QuZGVib3VuY2U9KGUsdD0yMDApPT57bGV0IGk7cmV0dXJuKC4uLnMpPT57Y2xlYXJUaW1lb3V0KGkpLGk9c2V0VGltZW91dCgoKCk9PntlLmFwcGx5KHRoaXMscyl9KSx0KX19O3QuZGlzcGF0Y2g9KGUsdCxpPW51bGwpPT57Y29uc3Qgcz1uZXcgQ3VzdG9tRXZlbnQoZSx7ZGV0YWlsOntwYXlsb2FkOml9LGJ1YmJsZXM6ITAsY2FuY2VsYWJsZTohMCxjb21wb3NlZDohMX0pO3QuZGlzcGF0Y2hFdmVudChzKX07dC5hZnRlclRyYW5zaXRpb249KGUsdCk9Pntjb25zdCBpPSgpPT57dCgpLGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25lbmRcIixpLCEwKX0scz13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKSxuPXMuZ2V0UHJvcGVydHlWYWx1ZShcInRyYW5zaXRpb24tZHVyYXRpb25cIik7XCJub25lXCIhPT1zLmdldFByb3BlcnR5VmFsdWUoXCJ0cmFuc2l0aW9uLXByb3BlcnR5XCIpJiZwYXJzZUZsb2F0KG4pPjA/ZS5hZGRFdmVudExpc3RlbmVyKFwidHJhbnNpdGlvbmVuZFwiLGksITApOnQoKX07dC5odG1sVG9FbGVtZW50PWU9Pntjb25zdCB0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKTtyZXR1cm4gZT1lLnRyaW0oKSx0LmlubmVySFRNTD1lLHQuY29udGVudC5maXJzdENoaWxkfTt0LmNsYXNzVG9DbGFzc0xpc3Q9KGUsdCxpPVwiIFwiLHM9XCJhZGRcIik9PntlLnNwbGl0KGkpLmZvckVhY2goKGU9PlwiYWRkXCI9PT1zP3QuY2xhc3NMaXN0LmFkZChlKTp0LmNsYXNzTGlzdC5yZW1vdmUoZSkpKX07Y29uc3Qgbj17aGlzdG9yeUluZGV4Oi0xLGFkZEhpc3RvcnkoZSl7dGhpcy5oaXN0b3J5SW5kZXg9ZX0sZXhpc3RzSW5IaXN0b3J5KGUpe3JldHVybiBlPnRoaXMuaGlzdG9yeUluZGV4fSxjbGVhckhpc3RvcnkoKXt0aGlzLmhpc3RvcnlJbmRleD0tMX19O3QubWVudVNlYXJjaEhpc3Rvcnk9bn0sODgxOmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU1Njcm9sbHNweVxuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKTtjbGFzcyBsIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdD17fSl7c3VwZXIoZSx0KSx0aGlzLmlzU2Nyb2xsaW5nRG93bj0hMSx0aGlzLmxhc3RTY3JvbGxUb3A9MDtjb25zdCBpPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1zY3JvbGxzcHktb3B0aW9uc1wiKSxzPWk/SlNPTi5wYXJzZShpKTp7fSxuPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KTt0aGlzLmlnbm9yZVNjcm9sbFVwPXZvaWQgMCE9PW4uaWdub3JlU2Nyb2xsVXAmJm4uaWdub3JlU2Nyb2xsVXAsdGhpcy5saW5rcz10aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbaHJlZl1cIiksdGhpcy5zZWN0aW9ucz1bXSx0aGlzLnNjcm9sbGFibGVJZD10aGlzLmVsLmdldEF0dHJpYnV0ZShcImRhdGEtc2Nyb2xsc3B5LXNjcm9sbGFibGUtcGFyZW50XCIpLHRoaXMuc2Nyb2xsYWJsZT10aGlzLnNjcm9sbGFibGVJZD9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuc2Nyb2xsYWJsZUlkKTpkb2N1bWVudCx0aGlzLm9uTGlua0NsaWNrTGlzdGVuZXI9W10sdGhpcy5pbml0KCl9c2Nyb2xsYWJsZVNjcm9sbChlKXtjb25zdCB0PXRoaXMuc2Nyb2xsYWJsZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50P3RoaXMuc2Nyb2xsYWJsZS5zY3JvbGxUb3A6d2luZG93LnNjcm9sbFk7dGhpcy5pc1Njcm9sbGluZ0Rvd249dD50aGlzLmxhc3RTY3JvbGxUb3AsdGhpcy5sYXN0U2Nyb2xsVG9wPXQ8PTA/MDp0LEFycmF5LmZyb20odGhpcy5zZWN0aW9ucykuZm9yRWFjaCgodD0+e2lmKCF0LmdldEF0dHJpYnV0ZShcImlkXCIpKXJldHVybiExO3RoaXMudXBkYXRlKGUsdCl9KSl9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzU2Nyb2xsc3B5Q29sbGVjdGlvbix0aGlzKSx0aGlzLmxpbmtzLmZvckVhY2goKGU9Pnt0aGlzLnNlY3Rpb25zLnB1c2godGhpcy5zY3JvbGxhYmxlLnF1ZXJ5U2VsZWN0b3IoZS5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpKSl9KSksdGhpcy5vblNjcm9sbGFibGVTY3JvbGxMaXN0ZW5lcj1lPT50aGlzLnNjcm9sbGFibGVTY3JvbGwoZSksdGhpcy5zY3JvbGxhYmxlLmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIix0aGlzLm9uU2Nyb2xsYWJsZVNjcm9sbExpc3RlbmVyKSx0aGlzLmxpbmtzLmZvckVhY2goKGU9Pnt0aGlzLm9uTGlua0NsaWNrTGlzdGVuZXIucHVzaCh7ZWw6ZSxmbjp0PT50aGlzLmxpbmtDbGljayh0LGUpfSksZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uTGlua0NsaWNrTGlzdGVuZXIuZmluZCgodD0+dC5lbD09PWUpKS5mbil9KSl9ZGV0ZXJtaW5lU2Nyb2xsRGlyZWN0aW9uKGUpe2NvbnN0IHQ9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiYS5hY3RpdmVcIik7aWYoIXQpcmV0dXJuITA7Y29uc3QgaT1BcnJheS5mcm9tKHRoaXMubGlua3MpLmluZGV4T2YodCkscz1BcnJheS5mcm9tKHRoaXMubGlua3MpLmluZGV4T2YoZSk7cmV0dXJuLTE9PT1zfHxzPml9bGlua0NsaWNrKGUsdCl7ZS5wcmV2ZW50RGVmYXVsdCgpO2NvbnN0IGk9dC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpO2lmKCFpfHxcImphdmFzY3JpcHQ6O1wiPT09aSlyZXR1cm47KGk/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihpKTpudWxsKSYmKHRoaXMuaXNTY3JvbGxpbmdEb3duPXRoaXMuZGV0ZXJtaW5lU2Nyb2xsRGlyZWN0aW9uKHQpLHRoaXMuc2Nyb2xsVG8odCkpfXVwZGF0ZShlLHQpe2NvbnN0IGk9cGFyc2VJbnQoKDAsbi5nZXRDbGFzc1Byb3BlcnR5KSh0aGlzLmVsLFwiLS1zY3JvbGxzcHktb2Zmc2V0XCIsXCIwXCIpKSxzPXBhcnNlSW50KCgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodCxcIi0tc2Nyb2xsc3B5LW9mZnNldFwiKSl8fGksbz1lLnRhcmdldD09PWRvY3VtZW50PzA6cGFyc2VJbnQoU3RyaW5nKGUudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCkpLGw9cGFyc2VJbnQoU3RyaW5nKHQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wKSktcy1vLHI9dC5vZmZzZXRIZWlnaHQ7aWYodGhpcy5pZ25vcmVTY3JvbGxVcHx8dGhpcy5pc1Njcm9sbGluZ0Rvd24/bDw9MCYmbCtyPjA6bDw9MCYmbDxyKXt0aGlzLmxpbmtzLmZvckVhY2goKGU9PmUuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKSkpO2NvbnN0IGU9dGhpcy5lbC5xdWVyeVNlbGVjdG9yKGBbaHJlZj1cIiMke3QuZ2V0QXR0cmlidXRlKFwiaWRcIil9XCJdYCk7aWYoZSl7ZS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpO2NvbnN0IHQ9ZS5jbG9zZXN0KFwiW2RhdGEtc2Nyb2xsc3B5LWdyb3VwXVwiKTtpZih0KXtjb25zdCBlPXQucXVlcnlTZWxlY3RvcihcIltocmVmXVwiKTtlJiZlLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIil9fXRoaXMuZmlyZUV2ZW50KFwiYWZ0ZXJTY3JvbGxcIixlKSwoMCxuLmRpc3BhdGNoKShcImFmdGVyU2Nyb2xsLnNjcm9sbHNweVwiLGUsdGhpcy5lbCl9fXNjcm9sbFRvKGUpe2NvbnN0IHQ9ZS5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpLGk9ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0KSxzPXBhcnNlSW50KCgwLG4uZ2V0Q2xhc3NQcm9wZXJ0eSkodGhpcy5lbCxcIi0tc2Nyb2xsc3B5LW9mZnNldFwiLFwiMFwiKSksbz1wYXJzZUludCgoMCxuLmdldENsYXNzUHJvcGVydHkpKGksXCItLXNjcm9sbHNweS1vZmZzZXRcIikpfHxzLGw9dGhpcy5zY3JvbGxhYmxlPT09ZG9jdW1lbnQ/MDp0aGlzLnNjcm9sbGFibGUub2Zmc2V0VG9wLHI9aS5vZmZzZXRUb3Atby1sLGE9dGhpcy5zY3JvbGxhYmxlPT09ZG9jdW1lbnQ/d2luZG93OnRoaXMuc2Nyb2xsYWJsZSxjPSgpPT57d2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsbnVsbCxlLmdldEF0dHJpYnV0ZShcImhyZWZcIikpLFwic2Nyb2xsVG9cImluIGEmJmEuc2Nyb2xsVG8oe3RvcDpyLGxlZnQ6MCxiZWhhdmlvcjpcInNtb290aFwifSl9LGQ9dGhpcy5maXJlRXZlbnQoXCJiZWZvcmVTY3JvbGxcIix0aGlzLmVsKTsoMCxuLmRpc3BhdGNoKShcImJlZm9yZVNjcm9sbC5zY3JvbGxzcHlcIix0aGlzLmVsLHRoaXMuZWwpLGQgaW5zdGFuY2VvZiBQcm9taXNlP2QudGhlbigoKCk9PmMoKSkpOmMoKX1kZXN0cm95KCl7dGhpcy5lbC5xdWVyeVNlbGVjdG9yKFwiW2hyZWZdLmFjdGl2ZVwiKS5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpLHRoaXMuc2Nyb2xsYWJsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsdGhpcy5vblNjcm9sbGFibGVTY3JvbGxMaXN0ZW5lciksdGhpcy5vbkxpbmtDbGlja0xpc3RlbmVyLmxlbmd0aCYmdGhpcy5vbkxpbmtDbGlja0xpc3RlbmVyLmZvckVhY2goKCh7ZWw6ZSxmbjp0fSk9PntlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHQpfSkpLHdpbmRvdy4kaHNTY3JvbGxzcHlDb2xsZWN0aW9uPXdpbmRvdy4kaHNTY3JvbGxzcHlDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZS5lbCE9PXRoaXMuZWwpKX1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0PSExKXtjb25zdCBpPXdpbmRvdy4kaHNTY3JvbGxzcHlDb2xsZWN0aW9uLmZpbmQoKHQ9PnQuZWxlbWVudC5lbD09PShcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSk7cmV0dXJuIGk/dD9pOmkuZWxlbWVudC5lbDpudWxsfXN0YXRpYyBhdXRvSW5pdCgpe3dpbmRvdy4kaHNTY3JvbGxzcHlDb2xsZWN0aW9ufHwod2luZG93LiRoc1Njcm9sbHNweUNvbGxlY3Rpb249W10pLHdpbmRvdy4kaHNTY3JvbGxzcHlDb2xsZWN0aW9uJiYod2luZG93LiRoc1Njcm9sbHNweUNvbGxlY3Rpb249d2luZG93LiRoc1Njcm9sbHNweUNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtc2Nyb2xsc3B5XTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmZvckVhY2goKGU9Pnt3aW5kb3cuJGhzU2Nyb2xsc3B5Q29sbGVjdGlvbi5maW5kKCh0PT57dmFyIGk7cmV0dXJuKG51bGw9PT0oaT1udWxsPT10P3ZvaWQgMDp0LmVsZW1lbnQpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmVsKT09PWV9KSl8fG5ldyBsKGUpfSkpfX13aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIiwoKCk9PntsLmF1dG9Jbml0KCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1Njcm9sbHNweT1sKSx0LmRlZmF1bHQ9bH0sOTE3OihlLHQpPT57T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSksdC5CUkVBS1BPSU5UUz10LkNPTUJPX0JPWF9BQ0NFU1NJQklMSVRZX0tFWV9TRVQ9dC5TRUxFQ1RfQUNDRVNTSUJJTElUWV9LRVlfU0VUPXQuVEFCU19BQ0NFU1NJQklMSVRZX0tFWV9TRVQ9dC5PVkVSTEFZX0FDQ0VTU0lCSUxJVFlfS0VZX1NFVD10LkRST1BET1dOX0FDQ0VTU0lCSUxJVFlfS0VZX1NFVD10LlBPU0lUSU9OUz12b2lkIDAsdC5QT1NJVElPTlM9e2F1dG86XCJhdXRvXCIsXCJhdXRvLXN0YXJ0XCI6XCJhdXRvLXN0YXJ0XCIsXCJhdXRvLWVuZFwiOlwiYXV0by1lbmRcIix0b3A6XCJ0b3BcIixcInRvcC1zdGFydFwiOlwidG9wLXN0YXJ0XCIsXCJ0b3AtZW5kXCI6XCJ0b3AtZW5kXCIsYm90dG9tOlwiYm90dG9tXCIsXCJib3R0b20tc3RhcnRcIjpcImJvdHRvbS1zdGFydFwiLFwiYm90dG9tLWVuZFwiOlwiYm90dG9tLWVuZFwiLHJpZ2h0OlwicmlnaHRcIixcInJpZ2h0LXN0YXJ0XCI6XCJyaWdodC1zdGFydFwiLFwicmlnaHQtZW5kXCI6XCJyaWdodC1lbmRcIixsZWZ0OlwibGVmdFwiLFwibGVmdC1zdGFydFwiOlwibGVmdC1zdGFydFwiLFwibGVmdC1lbmRcIjpcImxlZnQtZW5kXCJ9LHQuRFJPUERPV05fQUNDRVNTSUJJTElUWV9LRVlfU0VUPVtcIkVzY2FwZVwiLFwiQXJyb3dVcFwiLFwiQXJyb3dEb3duXCIsXCJBcnJvd1JpZ2h0XCIsXCJBcnJvd0xlZnRcIixcIkhvbWVcIixcIkVuZFwiLFwiRW50ZXJcIl0sdC5PVkVSTEFZX0FDQ0VTU0lCSUxJVFlfS0VZX1NFVD1bXCJFc2NhcGVcIixcIlRhYlwiXSx0LlRBQlNfQUNDRVNTSUJJTElUWV9LRVlfU0VUPVtcIkFycm93VXBcIixcIkFycm93TGVmdFwiLFwiQXJyb3dEb3duXCIsXCJBcnJvd1JpZ2h0XCIsXCJIb21lXCIsXCJFbmRcIl0sdC5TRUxFQ1RfQUNDRVNTSUJJTElUWV9LRVlfU0VUPVtcIkFycm93VXBcIixcIkFycm93TGVmdFwiLFwiQXJyb3dEb3duXCIsXCJBcnJvd1JpZ2h0XCIsXCJIb21lXCIsXCJFbmRcIixcIkVzY2FwZVwiLFwiRW50ZXJcIixcIlNwYWNlXCIsXCJUYWJcIl0sdC5DT01CT19CT1hfQUNDRVNTSUJJTElUWV9LRVlfU0VUPVtcIkFycm93VXBcIixcIkFycm93TGVmdFwiLFwiQXJyb3dEb3duXCIsXCJBcnJvd1JpZ2h0XCIsXCJIb21lXCIsXCJFbmRcIixcIkVzY2FwZVwiLFwiRW50ZXJcIl0sdC5CUkVBS1BPSU5UUz17eHM6MCxzbTo2NDAsbWQ6NzY4LGxnOjEwMjQseGw6MTI4MCxcIjJ4bFwiOjE1MzZ9fSw5NDQ6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTVGFic1xuICogQHZlcnNpb246IDMuMC4wXG4gKiBAYXV0aG9yOiBQcmVsaW5lIExhYnMgTHRkLlxuICogQGxpY2Vuc2U6IExpY2Vuc2VkIHVuZGVyIE1JVCBhbmQgUHJlbGluZSBVSSBGYWlyIFVzZSBMaWNlbnNlIChodHRwczovL3ByZWxpbmUuY28vZG9jcy9saWNlbnNlLmh0bWwpXG4gKiBDb3B5cmlnaHQgMjAyNCBQcmVsaW5lIExhYnMgTHRkLlxuICovXG52YXIgcz10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBuPWkoODA2KSxvPXMoaSgyODcpKSxsPWkoOTE3KTtjbGFzcyByIGV4dGVuZHMgby5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCxpKXt2YXIgcyxuO3N1cGVyKGUsdCxpKTtjb25zdCBvPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS10YWJzXCIpLHI9bz9KU09OLnBhcnNlKG8pOnt9LGE9T2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LHIpLHQpO3RoaXMuZXZlbnRUeXBlPW51bGwhPT0ocz1hLmV2ZW50VHlwZSkmJnZvaWQgMCE9PXM/czpcImNsaWNrXCIsdGhpcy5wcmV2ZW50TmF2aWdhdGlvblJlc29sdXRpb249XCJudW1iZXJcIj09dHlwZW9mIGEucHJldmVudE5hdmlnYXRpb25SZXNvbHV0aW9uP2EucHJldmVudE5hdmlnYXRpb25SZXNvbHV0aW9uOmwuQlJFQUtQT0lOVFNbYS5wcmV2ZW50TmF2aWdhdGlvblJlc29sdXRpb25dfHxudWxsLHRoaXMudG9nZ2xlcz10aGlzLmVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS10YWJdXCIpLHRoaXMuZXh0cmFUb2dnbGVJZD10aGlzLmVsLmdldEF0dHJpYnV0ZShcImRhdGEtdGFiLXNlbGVjdFwiKSx0aGlzLmV4dHJhVG9nZ2xlPXRoaXMuZXh0cmFUb2dnbGVJZD9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZXh0cmFUb2dnbGVJZCk6bnVsbCx0aGlzLmN1cnJlbnQ9QXJyYXkuZnJvbSh0aGlzLnRvZ2dsZXMpLmZpbmQoKGU9PmUuY2xhc3NMaXN0LmNvbnRhaW5zKFwiYWN0aXZlXCIpKSksdGhpcy5jdXJyZW50Q29udGVudElkPShudWxsPT09KG49dGhpcy5jdXJyZW50KXx8dm9pZCAwPT09bj92b2lkIDA6bi5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRhYlwiKSl8fG51bGwsdGhpcy5jdXJyZW50Q29udGVudD10aGlzLmN1cnJlbnRDb250ZW50SWQ/ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmN1cnJlbnRDb250ZW50SWQpOm51bGwsdGhpcy5wcmV2PW51bGwsdGhpcy5wcmV2Q29udGVudElkPW51bGwsdGhpcy5wcmV2Q29udGVudD1udWxsLHRoaXMub25Ub2dnbGVIYW5kbGVyPVtdLHRoaXMuaW5pdCgpfXRvZ2dsZShlKXt0aGlzLm9wZW4oZSl9ZXh0cmFUb2dnbGVDaGFuZ2UoZSl7dGhpcy5jaGFuZ2UoZSl9aW5pdCgpe3RoaXMuY3JlYXRlQ29sbGVjdGlvbih3aW5kb3cuJGhzVGFic0NvbGxlY3Rpb24sdGhpcyksdGhpcy50b2dnbGVzLmZvckVhY2goKGU9Pntjb25zdCB0PXQ9PntcImNsaWNrXCI9PT10aGlzLmV2ZW50VHlwZSYmdGhpcy5wcmV2ZW50TmF2aWdhdGlvblJlc29sdXRpb24mJmRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGg8PSt0aGlzLnByZXZlbnROYXZpZ2F0aW9uUmVzb2x1dGlvbiYmdC5wcmV2ZW50RGVmYXVsdCgpLHRoaXMudG9nZ2xlKGUpfSxpPWU9Pnt0aGlzLnByZXZlbnROYXZpZ2F0aW9uUmVzb2x1dGlvbiYmZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aDw9K3RoaXMucHJldmVudE5hdmlnYXRpb25SZXNvbHV0aW9uJiZlLnByZXZlbnREZWZhdWx0KCl9O3RoaXMub25Ub2dnbGVIYW5kbGVyLnB1c2goe2VsOmUsZm46dCxwcmV2ZW50Q2xpY2tGbjppfSksXCJjbGlja1wiPT09dGhpcy5ldmVudFR5cGU/ZS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0KTooZS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VlbnRlclwiLHQpLGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsaSkpfSkpLHRoaXMuZXh0cmFUb2dnbGUmJih0aGlzLm9uRXh0cmFUb2dnbGVDaGFuZ2VMaXN0ZW5lcj1lPT50aGlzLmV4dHJhVG9nZ2xlQ2hhbmdlKGUpLHRoaXMuZXh0cmFUb2dnbGUuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLHRoaXMub25FeHRyYVRvZ2dsZUNoYW5nZUxpc3RlbmVyKSl9b3BlbihlKXt2YXIgdCxpLHMsbyxsO3RoaXMucHJldj10aGlzLmN1cnJlbnQsdGhpcy5wcmV2Q29udGVudElkPXRoaXMuY3VycmVudENvbnRlbnRJZCx0aGlzLnByZXZDb250ZW50PXRoaXMuY3VycmVudENvbnRlbnQsdGhpcy5jdXJyZW50PWUsdGhpcy5jdXJyZW50Q29udGVudElkPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS10YWJcIiksdGhpcy5jdXJyZW50Q29udGVudD10aGlzLmN1cnJlbnRDb250ZW50SWQ/ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLmN1cnJlbnRDb250ZW50SWQpOm51bGwsKG51bGw9PT0odD1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLnByZXYpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmFyaWFTZWxlY3RlZCkmJih0aGlzLnByZXYuYXJpYVNlbGVjdGVkPVwiZmFsc2VcIiksbnVsbD09PShpPXRoaXMucHJldil8fHZvaWQgMD09PWl8fGkuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKSxudWxsPT09KHM9dGhpcy5wcmV2Q29udGVudCl8fHZvaWQgMD09PXN8fHMuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKSwobnVsbD09PShvPW51bGw9PXRoaXM/dm9pZCAwOnRoaXMuY3VycmVudCl8fHZvaWQgMD09PW8/dm9pZCAwOm8uYXJpYVNlbGVjdGVkKSYmKHRoaXMuY3VycmVudC5hcmlhU2VsZWN0ZWQ9XCJ0cnVlXCIpLHRoaXMuY3VycmVudC5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLG51bGw9PT0obD10aGlzLmN1cnJlbnRDb250ZW50KXx8dm9pZCAwPT09bHx8bC5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpLHRoaXMuZmlyZUV2ZW50KFwiY2hhbmdlXCIse2VsOmUscHJldjp0aGlzLnByZXZDb250ZW50SWQsY3VycmVudDp0aGlzLmN1cnJlbnRDb250ZW50SWQsdGFic0lkOnRoaXMuZWwuaWR9KSwoMCxuLmRpc3BhdGNoKShcImNoYW5nZS50YWJcIixlLHtlbDplLHByZXY6dGhpcy5wcmV2Q29udGVudElkLGN1cnJlbnQ6dGhpcy5jdXJyZW50Q29udGVudElkLHRhYnNJZDp0aGlzLmVsLmlkfSl9Y2hhbmdlKGUpe2NvbnN0IHQ9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW2RhdGEtdGFiPVwiJHtlLnRhcmdldC52YWx1ZX1cIl1gKTt0JiYoXCJob3ZlclwiPT09dGhpcy5ldmVudFR5cGU/dC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcIm1vdXNlZW50ZXJcIikpOnQuY2xpY2soKSl9ZGVzdHJveSgpe3RoaXMudG9nZ2xlcy5mb3JFYWNoKChlPT57dmFyIHQ7Y29uc3QgaT1udWxsPT09KHQ9dGhpcy5vblRvZ2dsZUhhbmRsZXIpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmZpbmQoKCh7ZWw6dH0pPT50PT09ZSkpO2kmJihcImNsaWNrXCI9PT10aGlzLmV2ZW50VHlwZT9lLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLGkuZm4pOihlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZWVudGVyXCIsaS5mbiksZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIixpLnByZXZlbnRDbGlja0ZuKSkpfSkpLHRoaXMub25Ub2dnbGVIYW5kbGVyPVtdLHRoaXMuZXh0cmFUb2dnbGUmJnRoaXMuZXh0cmFUb2dnbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLHRoaXMub25FeHRyYVRvZ2dsZUNoYW5nZUxpc3RlbmVyKSx3aW5kb3cuJGhzVGFic0NvbGxlY3Rpb249d2luZG93LiRoc1RhYnNDb2xsZWN0aW9uLmZpbHRlcigoKHtlbGVtZW50OmV9KT0+ZS5lbCE9PXRoaXMuZWwpKX1zdGF0aWMgZ2V0SW5zdGFuY2UoZSx0KXtjb25zdCBpPXdpbmRvdy4kaHNUYWJzQ29sbGVjdGlvbi5maW5kKCh0PT50LmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKSkpO3JldHVybiBpP3Q/aTppLmVsZW1lbnQ6bnVsbH1zdGF0aWMgYXV0b0luaXQoKXt3aW5kb3cuJGhzVGFic0NvbGxlY3Rpb258fCh3aW5kb3cuJGhzVGFic0NvbGxlY3Rpb249W10sZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwoZT0+ci5hY2Nlc3NpYmlsaXR5KGUpKSkpLHdpbmRvdy4kaHNUYWJzQ29sbGVjdGlvbiYmKHdpbmRvdy4kaHNUYWJzQ29sbGVjdGlvbj13aW5kb3cuJGhzVGFic0NvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbcm9sZT1cInRhYmxpc3RcIl06bm90KHNlbGVjdCk6bm90KC4tLXByZXZlbnQtb24tbG9hZC1pbml0KScpLmZvckVhY2goKGU9Pnt3aW5kb3cuJGhzVGFic0NvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgcihlKX0pKX1zdGF0aWMgb3BlbihlKXtjb25zdCB0PXdpbmRvdy4kaHNUYWJzQ29sbGVjdGlvbi5maW5kKCh0PT5BcnJheS5mcm9tKHQuZWxlbWVudC50b2dnbGVzKS5pbmNsdWRlcyhcInN0cmluZ1wiPT10eXBlb2YgZT9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGUpOmUpKSksaT10P0FycmF5LmZyb20odC5lbGVtZW50LnRvZ2dsZXMpLmZpbmQoKHQ9PnQ9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKSkpOm51bGw7aSYmIWkuY2xhc3NMaXN0LmNvbnRhaW5zKFwiYWN0aXZlXCIpJiZ0LmVsZW1lbnQub3BlbihpKX1zdGF0aWMgYWNjZXNzaWJpbGl0eShlKXt2YXIgdDtjb25zdCBpPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS10YWJdOmZvY3VzXCIpO2lmKGkmJmwuVEFCU19BQ0NFU1NJQklMSVRZX0tFWV9TRVQuaW5jbHVkZXMoZS5jb2RlKSYmIWUubWV0YUtleSl7Y29uc3Qgcz1udWxsPT09KHQ9aS5jbG9zZXN0KCdbcm9sZT1cInRhYmxpc3RcIl0nKSl8fHZvaWQgMD09PXQ/dm9pZCAwOnQuZ2V0QXR0cmlidXRlKFwiZGF0YS10YWJzLXZlcnRpY2FsXCIpO3N3aXRjaChlLnByZXZlbnREZWZhdWx0KCksZS5jb2RlKXtjYXNlXCJ0cnVlXCI9PT1zP1wiQXJyb3dVcFwiOlwiQXJyb3dMZWZ0XCI6dGhpcy5vbkFycm93KCk7YnJlYWs7Y2FzZVwidHJ1ZVwiPT09cz9cIkFycm93RG93blwiOlwiQXJyb3dSaWdodFwiOnRoaXMub25BcnJvdyghMSk7YnJlYWs7Y2FzZVwiSG9tZVwiOnRoaXMub25TdGFydEVuZCgpO2JyZWFrO2Nhc2VcIkVuZFwiOnRoaXMub25TdGFydEVuZCghMSl9fX1zdGF0aWMgb25BcnJvdyhlPSEwKXt2YXIgdDtjb25zdCBpPW51bGw9PT0odD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtdGFiXTpmb2N1c1wiKSl8fHZvaWQgMD09PXQ/dm9pZCAwOnQuY2xvc2VzdCgnW3JvbGU9XCJ0YWJsaXN0XCJdJyk7aWYoIWkpcmV0dXJuO2NvbnN0IHM9d2luZG93LiRoc1RhYnNDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5lbD09PWkpKTtpZihzKXtjb25zdCB0PWU/QXJyYXkuZnJvbShzLmVsZW1lbnQudG9nZ2xlcykucmV2ZXJzZSgpOkFycmF5LmZyb20ocy5lbGVtZW50LnRvZ2dsZXMpLGk9dC5maW5kKChlPT5kb2N1bWVudC5hY3RpdmVFbGVtZW50PT09ZSkpO2xldCBuPXQuZmluZEluZGV4KChlPT5lPT09aSkpO249bisxPHQubGVuZ3RoP24rMTowLHRbbl0uZm9jdXMoKSx0W25dLmNsaWNrKCl9fXN0YXRpYyBvblN0YXJ0RW5kKGU9ITApe3ZhciB0O2NvbnN0IGk9bnVsbD09PSh0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS10YWJdOmZvY3VzXCIpKXx8dm9pZCAwPT09dD92b2lkIDA6dC5jbG9zZXN0KCdbcm9sZT1cInRhYmxpc3RcIl0nKTtpZighaSlyZXR1cm47Y29uc3Qgcz13aW5kb3cuJGhzVGFic0NvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmVsPT09aSkpO2lmKHMpe2NvbnN0IHQ9ZT9BcnJheS5mcm9tKHMuZWxlbWVudC50b2dnbGVzKTpBcnJheS5mcm9tKHMuZWxlbWVudC50b2dnbGVzKS5yZXZlcnNlKCk7dC5sZW5ndGgmJih0WzBdLmZvY3VzKCksdFswXS5jbGljaygpKX19c3RhdGljIG9uKGUsdCxpKXtjb25zdCBzPXdpbmRvdy4kaHNUYWJzQ29sbGVjdGlvbi5maW5kKChlPT5BcnJheS5mcm9tKGUuZWxlbWVudC50b2dnbGVzKS5pbmNsdWRlcyhcInN0cmluZ1wiPT10eXBlb2YgdD9kb2N1bWVudC5xdWVyeVNlbGVjdG9yKHQpOnQpKSk7cyYmKHMuZWxlbWVudC5ldmVudHNbZV09aSl9fXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCgoKT0+e3IuYXV0b0luaXQoKX0pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYod2luZG93LkhTVGFicz1yKSx0LmRlZmF1bHQ9cn0sOTQ5OihlLHQsaSk9PntpLnIodCksaS5kKHQse2Fycm93OigpPT5DZSxhdXRvUGxhY2VtZW50OigpPT5mZSxhdXRvVXBkYXRlOigpPT5wZSxjb21wdXRlUG9zaXRpb246KCk9PkllLGRldGVjdE92ZXJmbG93OigpPT5tZSxmbGlwOigpPT53ZSxnZXRPdmVyZmxvd0FuY2VzdG9yczooKT0+WixoaWRlOigpPT5iZSxpbmxpbmU6KCk9PlNlLGxpbWl0U2hpZnQ6KCk9PkxlLG9mZnNldDooKT0+Z2UscGxhdGZvcm06KCk9PmhlLHNoaWZ0OigpPT52ZSxzaXplOigpPT55ZX0pO2NvbnN0IHM9W1widG9wXCIsXCJyaWdodFwiLFwiYm90dG9tXCIsXCJsZWZ0XCJdLG49W1wic3RhcnRcIixcImVuZFwiXSxvPXMucmVkdWNlKCgoZSx0KT0+ZS5jb25jYXQodCx0K1wiLVwiK25bMF0sdCtcIi1cIituWzFdKSksW10pLGw9TWF0aC5taW4scj1NYXRoLm1heCxhPU1hdGgucm91bmQsYz1NYXRoLmZsb29yLGQ9ZT0+KHt4OmUseTplfSksaD17bGVmdDpcInJpZ2h0XCIscmlnaHQ6XCJsZWZ0XCIsYm90dG9tOlwidG9wXCIsdG9wOlwiYm90dG9tXCJ9LHU9e3N0YXJ0OlwiZW5kXCIsZW5kOlwic3RhcnRcIn07ZnVuY3Rpb24gcChlLHQsaSl7cmV0dXJuIHIoZSxsKHQsaSkpfWZ1bmN0aW9uIG0oZSx0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiBlP2UodCk6ZX1mdW5jdGlvbiBnKGUpe3JldHVybiBlLnNwbGl0KFwiLVwiKVswXX1mdW5jdGlvbiBmKGUpe3JldHVybiBlLnNwbGl0KFwiLVwiKVsxXX1mdW5jdGlvbiB2KGUpe3JldHVyblwieFwiPT09ZT9cInlcIjpcInhcIn1mdW5jdGlvbiB3KGUpe3JldHVyblwieVwiPT09ZT9cImhlaWdodFwiOlwid2lkdGhcIn1mdW5jdGlvbiB5KGUpe3JldHVybltcInRvcFwiLFwiYm90dG9tXCJdLmluY2x1ZGVzKGcoZSkpP1wieVwiOlwieFwifWZ1bmN0aW9uIGIoZSl7cmV0dXJuIHYoeShlKSl9ZnVuY3Rpb24gQyhlLHQsaSl7dm9pZCAwPT09aSYmKGk9ITEpO2NvbnN0IHM9ZihlKSxuPWIoZSksbz13KG4pO2xldCBsPVwieFwiPT09bj9zPT09KGk/XCJlbmRcIjpcInN0YXJ0XCIpP1wicmlnaHRcIjpcImxlZnRcIjpcInN0YXJ0XCI9PT1zP1wiYm90dG9tXCI6XCJ0b3BcIjtyZXR1cm4gdC5yZWZlcmVuY2Vbb10+dC5mbG9hdGluZ1tvXSYmKGw9TChsKSksW2wsTChsKV19ZnVuY3Rpb24gUyhlKXtyZXR1cm4gZS5yZXBsYWNlKC9zdGFydHxlbmQvZywoZT0+dVtlXSkpfWZ1bmN0aW9uIEwoZSl7cmV0dXJuIGUucmVwbGFjZSgvbGVmdHxyaWdodHxib3R0b218dG9wL2csKGU9PmhbZV0pKX1mdW5jdGlvbiBJKGUpe3JldHVyblwibnVtYmVyXCIhPXR5cGVvZiBlP2Z1bmN0aW9uKGUpe3JldHVybnt0b3A6MCxyaWdodDowLGJvdHRvbTowLGxlZnQ6MCwuLi5lfX0oZSk6e3RvcDplLHJpZ2h0OmUsYm90dG9tOmUsbGVmdDplfX1mdW5jdGlvbiBFKGUpe2NvbnN0e3g6dCx5Omksd2lkdGg6cyxoZWlnaHQ6bn09ZTtyZXR1cm57d2lkdGg6cyxoZWlnaHQ6bix0b3A6aSxsZWZ0OnQscmlnaHQ6dCtzLGJvdHRvbTppK24seDp0LHk6aX19ZnVuY3Rpb24gVChlLHQsaSl7bGV0e3JlZmVyZW5jZTpzLGZsb2F0aW5nOm59PWU7Y29uc3Qgbz15KHQpLGw9Yih0KSxyPXcobCksYT1nKHQpLGM9XCJ5XCI9PT1vLGQ9cy54K3Mud2lkdGgvMi1uLndpZHRoLzIsaD1zLnkrcy5oZWlnaHQvMi1uLmhlaWdodC8yLHU9c1tyXS8yLW5bcl0vMjtsZXQgcDtzd2l0Y2goYSl7Y2FzZVwidG9wXCI6cD17eDpkLHk6cy55LW4uaGVpZ2h0fTticmVhaztjYXNlXCJib3R0b21cIjpwPXt4OmQseTpzLnkrcy5oZWlnaHR9O2JyZWFrO2Nhc2VcInJpZ2h0XCI6cD17eDpzLngrcy53aWR0aCx5Omh9O2JyZWFrO2Nhc2VcImxlZnRcIjpwPXt4OnMueC1uLndpZHRoLHk6aH07YnJlYWs7ZGVmYXVsdDpwPXt4OnMueCx5OnMueX19c3dpdGNoKGYodCkpe2Nhc2VcInN0YXJ0XCI6cFtsXS09dSooaSYmYz8tMToxKTticmVhaztjYXNlXCJlbmRcIjpwW2xdKz11KihpJiZjPy0xOjEpfXJldHVybiBwfWFzeW5jIGZ1bmN0aW9uIHgoZSx0KXt2YXIgaTt2b2lkIDA9PT10JiYodD17fSk7Y29uc3R7eDpzLHk6bixwbGF0Zm9ybTpvLHJlY3RzOmwsZWxlbWVudHM6cixzdHJhdGVneTphfT1lLHtib3VuZGFyeTpjPVwiY2xpcHBpbmdBbmNlc3RvcnNcIixyb290Qm91bmRhcnk6ZD1cInZpZXdwb3J0XCIsZWxlbWVudENvbnRleHQ6aD1cImZsb2F0aW5nXCIsYWx0Qm91bmRhcnk6dT0hMSxwYWRkaW5nOnA9MH09bSh0LGUpLGc9SShwKSxmPXJbdT9cImZsb2F0aW5nXCI9PT1oP1wicmVmZXJlbmNlXCI6XCJmbG9hdGluZ1wiOmhdLHY9RShhd2FpdCBvLmdldENsaXBwaW5nUmVjdCh7ZWxlbWVudDpudWxsPT0oaT1hd2FpdChudWxsPT1vLmlzRWxlbWVudD92b2lkIDA6by5pc0VsZW1lbnQoZikpKXx8aT9mOmYuY29udGV4dEVsZW1lbnR8fGF3YWl0KG51bGw9PW8uZ2V0RG9jdW1lbnRFbGVtZW50P3ZvaWQgMDpvLmdldERvY3VtZW50RWxlbWVudChyLmZsb2F0aW5nKSksYm91bmRhcnk6Yyxyb290Qm91bmRhcnk6ZCxzdHJhdGVneTphfSkpLHc9XCJmbG9hdGluZ1wiPT09aD97eDpzLHk6bix3aWR0aDpsLmZsb2F0aW5nLndpZHRoLGhlaWdodDpsLmZsb2F0aW5nLmhlaWdodH06bC5yZWZlcmVuY2UseT1hd2FpdChudWxsPT1vLmdldE9mZnNldFBhcmVudD92b2lkIDA6by5nZXRPZmZzZXRQYXJlbnQoci5mbG9hdGluZykpLGI9YXdhaXQobnVsbD09by5pc0VsZW1lbnQ/dm9pZCAwOm8uaXNFbGVtZW50KHkpKSYmYXdhaXQobnVsbD09by5nZXRTY2FsZT92b2lkIDA6by5nZXRTY2FsZSh5KSl8fHt4OjEseToxfSxDPUUoby5jb252ZXJ0T2Zmc2V0UGFyZW50UmVsYXRpdmVSZWN0VG9WaWV3cG9ydFJlbGF0aXZlUmVjdD9hd2FpdCBvLmNvbnZlcnRPZmZzZXRQYXJlbnRSZWxhdGl2ZVJlY3RUb1ZpZXdwb3J0UmVsYXRpdmVSZWN0KHtlbGVtZW50czpyLHJlY3Q6dyxvZmZzZXRQYXJlbnQ6eSxzdHJhdGVneTphfSk6dyk7cmV0dXJue3RvcDoodi50b3AtQy50b3ArZy50b3ApL2IueSxib3R0b206KEMuYm90dG9tLXYuYm90dG9tK2cuYm90dG9tKS9iLnksbGVmdDoodi5sZWZ0LUMubGVmdCtnLmxlZnQpL2IueCxyaWdodDooQy5yaWdodC12LnJpZ2h0K2cucmlnaHQpL2IueH19ZnVuY3Rpb24gayhlLHQpe3JldHVybnt0b3A6ZS50b3AtdC5oZWlnaHQscmlnaHQ6ZS5yaWdodC10LndpZHRoLGJvdHRvbTplLmJvdHRvbS10LmhlaWdodCxsZWZ0OmUubGVmdC10LndpZHRofX1mdW5jdGlvbiBBKGUpe3JldHVybiBzLnNvbWUoKHQ9PmVbdF0+PTApKX1mdW5jdGlvbiBPKGUpe2NvbnN0IHQ9bCguLi5lLm1hcCgoZT0+ZS5sZWZ0KSkpLGk9bCguLi5lLm1hcCgoZT0+ZS50b3ApKSk7cmV0dXJue3g6dCx5Omksd2lkdGg6ciguLi5lLm1hcCgoZT0+ZS5yaWdodCkpKS10LGhlaWdodDpyKC4uLmUubWFwKChlPT5lLmJvdHRvbSkpKS1pfX1mdW5jdGlvbiBQKCl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvd31mdW5jdGlvbiAkKGUpe3JldHVybiBNKGUpPyhlLm5vZGVOYW1lfHxcIlwiKS50b0xvd2VyQ2FzZSgpOlwiI2RvY3VtZW50XCJ9ZnVuY3Rpb24gQihlKXt2YXIgdDtyZXR1cm4obnVsbD09ZXx8bnVsbD09KHQ9ZS5vd25lckRvY3VtZW50KT92b2lkIDA6dC5kZWZhdWx0Vmlldyl8fHdpbmRvd31mdW5jdGlvbiBEKGUpe3ZhciB0O3JldHVybiBudWxsPT0odD0oTShlKT9lLm93bmVyRG9jdW1lbnQ6ZS5kb2N1bWVudCl8fHdpbmRvdy5kb2N1bWVudCk/dm9pZCAwOnQuZG9jdW1lbnRFbGVtZW50fWZ1bmN0aW9uIE0oZSl7cmV0dXJuISFQKCkmJihlIGluc3RhbmNlb2YgTm9kZXx8ZSBpbnN0YW5jZW9mIEIoZSkuTm9kZSl9ZnVuY3Rpb24gcShlKXtyZXR1cm4hIVAoKSYmKGUgaW5zdGFuY2VvZiBFbGVtZW50fHxlIGluc3RhbmNlb2YgQihlKS5FbGVtZW50KX1mdW5jdGlvbiBOKGUpe3JldHVybiEhUCgpJiYoZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50fHxlIGluc3RhbmNlb2YgQihlKS5IVE1MRWxlbWVudCl9ZnVuY3Rpb24gSChlKXtyZXR1cm4hKCFQKCl8fFwidW5kZWZpbmVkXCI9PXR5cGVvZiBTaGFkb3dSb290KSYmKGUgaW5zdGFuY2VvZiBTaGFkb3dSb290fHxlIGluc3RhbmNlb2YgQihlKS5TaGFkb3dSb290KX1mdW5jdGlvbiBGKGUpe2NvbnN0e292ZXJmbG93OnQsb3ZlcmZsb3dYOmksb3ZlcmZsb3dZOnMsZGlzcGxheTpufT1VKGUpO3JldHVybi9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbnxjbGlwLy50ZXN0KHQrcytpKSYmIVtcImlubGluZVwiLFwiY29udGVudHNcIl0uaW5jbHVkZXMobil9ZnVuY3Rpb24gUihlKXtyZXR1cm5bXCJ0YWJsZVwiLFwidGRcIixcInRoXCJdLmluY2x1ZGVzKCQoZSkpfWZ1bmN0aW9uIF8oZSl7cmV0dXJuW1wiOnBvcG92ZXItb3BlblwiLFwiOm1vZGFsXCJdLnNvbWUoKHQ9Pnt0cnl7cmV0dXJuIGUubWF0Y2hlcyh0KX1jYXRjaChlKXtyZXR1cm4hMX19KSl9ZnVuY3Rpb24gVihlKXtjb25zdCB0PWooKSxpPXEoZSk/VShlKTplO3JldHVybltcInRyYW5zZm9ybVwiLFwidHJhbnNsYXRlXCIsXCJzY2FsZVwiLFwicm90YXRlXCIsXCJwZXJzcGVjdGl2ZVwiXS5zb21lKChlPT4hIWlbZV0mJlwibm9uZVwiIT09aVtlXSkpfHwhIWkuY29udGFpbmVyVHlwZSYmXCJub3JtYWxcIiE9PWkuY29udGFpbmVyVHlwZXx8IXQmJiEhaS5iYWNrZHJvcEZpbHRlciYmXCJub25lXCIhPT1pLmJhY2tkcm9wRmlsdGVyfHwhdCYmISFpLmZpbHRlciYmXCJub25lXCIhPT1pLmZpbHRlcnx8W1widHJhbnNmb3JtXCIsXCJ0cmFuc2xhdGVcIixcInNjYWxlXCIsXCJyb3RhdGVcIixcInBlcnNwZWN0aXZlXCIsXCJmaWx0ZXJcIl0uc29tZSgoZT0+KGkud2lsbENoYW5nZXx8XCJcIikuaW5jbHVkZXMoZSkpKXx8W1wicGFpbnRcIixcImxheW91dFwiLFwic3RyaWN0XCIsXCJjb250ZW50XCJdLnNvbWUoKGU9PihpLmNvbnRhaW58fFwiXCIpLmluY2x1ZGVzKGUpKSl9ZnVuY3Rpb24gaigpe3JldHVybiEoXCJ1bmRlZmluZWRcIj09dHlwZW9mIENTU3x8IUNTUy5zdXBwb3J0cykmJkNTUy5zdXBwb3J0cyhcIi13ZWJraXQtYmFja2Ryb3AtZmlsdGVyXCIsXCJub25lXCIpfWZ1bmN0aW9uIFcoZSl7cmV0dXJuW1wiaHRtbFwiLFwiYm9keVwiLFwiI2RvY3VtZW50XCJdLmluY2x1ZGVzKCQoZSkpfWZ1bmN0aW9uIFUoZSl7cmV0dXJuIEIoZSkuZ2V0Q29tcHV0ZWRTdHlsZShlKX1mdW5jdGlvbiB6KGUpe3JldHVybiBxKGUpP3tzY3JvbGxMZWZ0OmUuc2Nyb2xsTGVmdCxzY3JvbGxUb3A6ZS5zY3JvbGxUb3B9OntzY3JvbGxMZWZ0OmUuc2Nyb2xsWCxzY3JvbGxUb3A6ZS5zY3JvbGxZfX1mdW5jdGlvbiBRKGUpe2lmKFwiaHRtbFwiPT09JChlKSlyZXR1cm4gZTtjb25zdCB0PWUuYXNzaWduZWRTbG90fHxlLnBhcmVudE5vZGV8fEgoZSkmJmUuaG9zdHx8RChlKTtyZXR1cm4gSCh0KT90Lmhvc3Q6dH1mdW5jdGlvbiBKKGUpe2NvbnN0IHQ9UShlKTtyZXR1cm4gVyh0KT9lLm93bmVyRG9jdW1lbnQ/ZS5vd25lckRvY3VtZW50LmJvZHk6ZS5ib2R5Ok4odCkmJkYodCk/dDpKKHQpfWZ1bmN0aW9uIFooZSx0LGkpe3ZhciBzO3ZvaWQgMD09PXQmJih0PVtdKSx2b2lkIDA9PT1pJiYoaT0hMCk7Y29uc3Qgbj1KKGUpLG89bj09PShudWxsPT0ocz1lLm93bmVyRG9jdW1lbnQpP3ZvaWQgMDpzLmJvZHkpLGw9QihuKTtpZihvKXtjb25zdCBlPUsobCk7cmV0dXJuIHQuY29uY2F0KGwsbC52aXN1YWxWaWV3cG9ydHx8W10sRihuKT9uOltdLGUmJmk/WihlKTpbXSl9cmV0dXJuIHQuY29uY2F0KG4sWihuLFtdLGkpKX1mdW5jdGlvbiBLKGUpe3JldHVybiBlLnBhcmVudCYmT2JqZWN0LmdldFByb3RvdHlwZU9mKGUucGFyZW50KT9lLmZyYW1lRWxlbWVudDpudWxsfWZ1bmN0aW9uIFgoZSl7Y29uc3QgdD1VKGUpO2xldCBpPXBhcnNlRmxvYXQodC53aWR0aCl8fDAscz1wYXJzZUZsb2F0KHQuaGVpZ2h0KXx8MDtjb25zdCBuPU4oZSksbz1uP2Uub2Zmc2V0V2lkdGg6aSxsPW4/ZS5vZmZzZXRIZWlnaHQ6cyxyPWEoaSkhPT1vfHxhKHMpIT09bDtyZXR1cm4gciYmKGk9byxzPWwpLHt3aWR0aDppLGhlaWdodDpzLCQ6cn19ZnVuY3Rpb24gWShlKXtyZXR1cm4gcShlKT9lOmUuY29udGV4dEVsZW1lbnR9ZnVuY3Rpb24gRyhlKXtjb25zdCB0PVkoZSk7aWYoIU4odCkpcmV0dXJuIGQoMSk7Y29uc3QgaT10LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHt3aWR0aDpzLGhlaWdodDpuLCQ6b309WCh0KTtsZXQgbD0obz9hKGkud2lkdGgpOmkud2lkdGgpL3Mscj0obz9hKGkuaGVpZ2h0KTppLmhlaWdodCkvbjtyZXR1cm4gbCYmTnVtYmVyLmlzRmluaXRlKGwpfHwobD0xKSxyJiZOdW1iZXIuaXNGaW5pdGUocil8fChyPTEpLHt4OmwseTpyfX1jb25zdCBlZT1kKDApO2Z1bmN0aW9uIHRlKGUpe2NvbnN0IHQ9QihlKTtyZXR1cm4gaigpJiZ0LnZpc3VhbFZpZXdwb3J0P3t4OnQudmlzdWFsVmlld3BvcnQub2Zmc2V0TGVmdCx5OnQudmlzdWFsVmlld3BvcnQub2Zmc2V0VG9wfTplZX1mdW5jdGlvbiBpZShlLHQsaSxzKXt2b2lkIDA9PT10JiYodD0hMSksdm9pZCAwPT09aSYmKGk9ITEpO2NvbnN0IG49ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxvPVkoZSk7bGV0IGw9ZCgxKTt0JiYocz9xKHMpJiYobD1HKHMpKTpsPUcoZSkpO2NvbnN0IHI9ZnVuY3Rpb24oZSx0LGkpe3JldHVybiB2b2lkIDA9PT10JiYodD0hMSksISghaXx8dCYmaSE9PUIoZSkpJiZ0fShvLGkscyk/dGUobyk6ZCgwKTtsZXQgYT0obi5sZWZ0K3IueCkvbC54LGM9KG4udG9wK3IueSkvbC55LGg9bi53aWR0aC9sLngsdT1uLmhlaWdodC9sLnk7aWYobyl7Y29uc3QgZT1CKG8pLHQ9cyYmcShzKT9CKHMpOnM7bGV0IGk9ZSxuPUsoaSk7Zm9yKDtuJiZzJiZ0IT09aTspe2NvbnN0IGU9RyhuKSx0PW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkscz1VKG4pLG89dC5sZWZ0KyhuLmNsaWVudExlZnQrcGFyc2VGbG9hdChzLnBhZGRpbmdMZWZ0KSkqZS54LGw9dC50b3ArKG4uY2xpZW50VG9wK3BhcnNlRmxvYXQocy5wYWRkaW5nVG9wKSkqZS55O2EqPWUueCxjKj1lLnksaCo9ZS54LHUqPWUueSxhKz1vLGMrPWwsaT1CKG4pLG49SyhpKX19cmV0dXJuIEUoe3dpZHRoOmgsaGVpZ2h0OnUseDphLHk6Y30pfWZ1bmN0aW9uIHNlKGUsdCl7Y29uc3QgaT16KGUpLnNjcm9sbExlZnQ7cmV0dXJuIHQ/dC5sZWZ0K2k6aWUoRChlKSkubGVmdCtpfWZ1bmN0aW9uIG5lKGUsdCxpKXt2b2lkIDA9PT1pJiYoaT0hMSk7Y29uc3Qgcz1lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO3JldHVybnt4OnMubGVmdCt0LnNjcm9sbExlZnQtKGk/MDpzZShlLHMpKSx5OnMudG9wK3Quc2Nyb2xsVG9wfX1mdW5jdGlvbiBvZShlLHQsaSl7bGV0IHM7aWYoXCJ2aWV3cG9ydFwiPT09dClzPWZ1bmN0aW9uKGUsdCl7Y29uc3QgaT1CKGUpLHM9RChlKSxuPWkudmlzdWFsVmlld3BvcnQ7bGV0IG89cy5jbGllbnRXaWR0aCxsPXMuY2xpZW50SGVpZ2h0LHI9MCxhPTA7aWYobil7bz1uLndpZHRoLGw9bi5oZWlnaHQ7Y29uc3QgZT1qKCk7KCFlfHxlJiZcImZpeGVkXCI9PT10KSYmKHI9bi5vZmZzZXRMZWZ0LGE9bi5vZmZzZXRUb3ApfXJldHVybnt3aWR0aDpvLGhlaWdodDpsLHg6cix5OmF9fShlLGkpO2Vsc2UgaWYoXCJkb2N1bWVudFwiPT09dClzPWZ1bmN0aW9uKGUpe2NvbnN0IHQ9RChlKSxpPXooZSkscz1lLm93bmVyRG9jdW1lbnQuYm9keSxuPXIodC5zY3JvbGxXaWR0aCx0LmNsaWVudFdpZHRoLHMuc2Nyb2xsV2lkdGgscy5jbGllbnRXaWR0aCksbz1yKHQuc2Nyb2xsSGVpZ2h0LHQuY2xpZW50SGVpZ2h0LHMuc2Nyb2xsSGVpZ2h0LHMuY2xpZW50SGVpZ2h0KTtsZXQgbD0taS5zY3JvbGxMZWZ0K3NlKGUpO2NvbnN0IGE9LWkuc2Nyb2xsVG9wO3JldHVyblwicnRsXCI9PT1VKHMpLmRpcmVjdGlvbiYmKGwrPXIodC5jbGllbnRXaWR0aCxzLmNsaWVudFdpZHRoKS1uKSx7d2lkdGg6bixoZWlnaHQ6byx4OmwseTphfX0oRChlKSk7ZWxzZSBpZihxKHQpKXM9ZnVuY3Rpb24oZSx0KXtjb25zdCBpPWllKGUsITAsXCJmaXhlZFwiPT09dCkscz1pLnRvcCtlLmNsaWVudFRvcCxuPWkubGVmdCtlLmNsaWVudExlZnQsbz1OKGUpP0coZSk6ZCgxKTtyZXR1cm57d2lkdGg6ZS5jbGllbnRXaWR0aCpvLngsaGVpZ2h0OmUuY2xpZW50SGVpZ2h0Km8ueSx4Om4qby54LHk6cypvLnl9fSh0LGkpO2Vsc2V7Y29uc3QgaT10ZShlKTtzPXt4OnQueC1pLngseTp0LnktaS55LHdpZHRoOnQud2lkdGgsaGVpZ2h0OnQuaGVpZ2h0fX1yZXR1cm4gRShzKX1mdW5jdGlvbiBsZShlLHQpe2NvbnN0IGk9UShlKTtyZXR1cm4hKGk9PT10fHwhcShpKXx8VyhpKSkmJihcImZpeGVkXCI9PT1VKGkpLnBvc2l0aW9ufHxsZShpLHQpKX1mdW5jdGlvbiByZShlLHQsaSl7Y29uc3Qgcz1OKHQpLG49RCh0KSxvPVwiZml4ZWRcIj09PWksbD1pZShlLCEwLG8sdCk7bGV0IHI9e3Njcm9sbExlZnQ6MCxzY3JvbGxUb3A6MH07Y29uc3QgYT1kKDApO2lmKHN8fCFzJiYhbylpZigoXCJib2R5XCIhPT0kKHQpfHxGKG4pKSYmKHI9eih0KSkscyl7Y29uc3QgZT1pZSh0LCEwLG8sdCk7YS54PWUueCt0LmNsaWVudExlZnQsYS55PWUueSt0LmNsaWVudFRvcH1lbHNlIG4mJihhLng9c2UobikpO2NvbnN0IGM9IW58fHN8fG8/ZCgwKTpuZShuLHIpO3JldHVybnt4OmwubGVmdCtyLnNjcm9sbExlZnQtYS54LWMueCx5OmwudG9wK3Iuc2Nyb2xsVG9wLWEueS1jLnksd2lkdGg6bC53aWR0aCxoZWlnaHQ6bC5oZWlnaHR9fWZ1bmN0aW9uIGFlKGUpe3JldHVyblwic3RhdGljXCI9PT1VKGUpLnBvc2l0aW9ufWZ1bmN0aW9uIGNlKGUsdCl7aWYoIU4oZSl8fFwiZml4ZWRcIj09PVUoZSkucG9zaXRpb24pcmV0dXJuIG51bGw7aWYodClyZXR1cm4gdChlKTtsZXQgaT1lLm9mZnNldFBhcmVudDtyZXR1cm4gRChlKT09PWkmJihpPWkub3duZXJEb2N1bWVudC5ib2R5KSxpfWZ1bmN0aW9uIGRlKGUsdCl7Y29uc3QgaT1CKGUpO2lmKF8oZSkpcmV0dXJuIGk7aWYoIU4oZSkpe2xldCB0PVEoZSk7Zm9yKDt0JiYhVyh0KTspe2lmKHEodCkmJiFhZSh0KSlyZXR1cm4gdDt0PVEodCl9cmV0dXJuIGl9bGV0IHM9Y2UoZSx0KTtmb3IoO3MmJlIocykmJmFlKHMpOylzPWNlKHMsdCk7cmV0dXJuIHMmJlcocykmJmFlKHMpJiYhVihzKT9pOnN8fGZ1bmN0aW9uKGUpe2xldCB0PVEoZSk7Zm9yKDtOKHQpJiYhVyh0KTspe2lmKFYodCkpcmV0dXJuIHQ7aWYoXyh0KSlyZXR1cm4gbnVsbDt0PVEodCl9cmV0dXJuIG51bGx9KGUpfHxpfWNvbnN0IGhlPXtjb252ZXJ0T2Zmc2V0UGFyZW50UmVsYXRpdmVSZWN0VG9WaWV3cG9ydFJlbGF0aXZlUmVjdDpmdW5jdGlvbihlKXtsZXR7ZWxlbWVudHM6dCxyZWN0Omksb2Zmc2V0UGFyZW50OnMsc3RyYXRlZ3k6bn09ZTtjb25zdCBvPVwiZml4ZWRcIj09PW4sbD1EKHMpLHI9ISF0JiZfKHQuZmxvYXRpbmcpO2lmKHM9PT1sfHxyJiZvKXJldHVybiBpO2xldCBhPXtzY3JvbGxMZWZ0OjAsc2Nyb2xsVG9wOjB9LGM9ZCgxKTtjb25zdCBoPWQoMCksdT1OKHMpO2lmKCh1fHwhdSYmIW8pJiYoKFwiYm9keVwiIT09JChzKXx8RihsKSkmJihhPXoocykpLE4ocykpKXtjb25zdCBlPWllKHMpO2M9RyhzKSxoLng9ZS54K3MuY2xpZW50TGVmdCxoLnk9ZS55K3MuY2xpZW50VG9wfWNvbnN0IHA9IWx8fHV8fG8/ZCgwKTpuZShsLGEsITApO3JldHVybnt3aWR0aDppLndpZHRoKmMueCxoZWlnaHQ6aS5oZWlnaHQqYy55LHg6aS54KmMueC1hLnNjcm9sbExlZnQqYy54K2gueCtwLngseTppLnkqYy55LWEuc2Nyb2xsVG9wKmMueStoLnkrcC55fX0sZ2V0RG9jdW1lbnRFbGVtZW50OkQsZ2V0Q2xpcHBpbmdSZWN0OmZ1bmN0aW9uKGUpe2xldHtlbGVtZW50OnQsYm91bmRhcnk6aSxyb290Qm91bmRhcnk6cyxzdHJhdGVneTpufT1lO2NvbnN0IG89Wy4uLlwiY2xpcHBpbmdBbmNlc3RvcnNcIj09PWk/Xyh0KT9bXTpmdW5jdGlvbihlLHQpe2NvbnN0IGk9dC5nZXQoZSk7aWYoaSlyZXR1cm4gaTtsZXQgcz1aKGUsW10sITEpLmZpbHRlcigoZT0+cShlKSYmXCJib2R5XCIhPT0kKGUpKSksbj1udWxsO2NvbnN0IG89XCJmaXhlZFwiPT09VShlKS5wb3NpdGlvbjtsZXQgbD1vP1EoZSk6ZTtmb3IoO3EobCkmJiFXKGwpOyl7Y29uc3QgdD1VKGwpLGk9VihsKTtpfHxcImZpeGVkXCIhPT10LnBvc2l0aW9ufHwobj1udWxsKSwobz8haSYmIW46IWkmJlwic3RhdGljXCI9PT10LnBvc2l0aW9uJiZuJiZbXCJhYnNvbHV0ZVwiLFwiZml4ZWRcIl0uaW5jbHVkZXMobi5wb3NpdGlvbil8fEYobCkmJiFpJiZsZShlLGwpKT9zPXMuZmlsdGVyKChlPT5lIT09bCkpOm49dCxsPVEobCl9cmV0dXJuIHQuc2V0KGUscyksc30odCx0aGlzLl9jKTpbXS5jb25jYXQoaSksc10sYT1vWzBdLGM9by5yZWR1Y2UoKChlLGkpPT57Y29uc3Qgcz1vZSh0LGksbik7cmV0dXJuIGUudG9wPXIocy50b3AsZS50b3ApLGUucmlnaHQ9bChzLnJpZ2h0LGUucmlnaHQpLGUuYm90dG9tPWwocy5ib3R0b20sZS5ib3R0b20pLGUubGVmdD1yKHMubGVmdCxlLmxlZnQpLGV9KSxvZSh0LGEsbikpO3JldHVybnt3aWR0aDpjLnJpZ2h0LWMubGVmdCxoZWlnaHQ6Yy5ib3R0b20tYy50b3AseDpjLmxlZnQseTpjLnRvcH19LGdldE9mZnNldFBhcmVudDpkZSxnZXRFbGVtZW50UmVjdHM6YXN5bmMgZnVuY3Rpb24oZSl7Y29uc3QgdD10aGlzLmdldE9mZnNldFBhcmVudHx8ZGUsaT10aGlzLmdldERpbWVuc2lvbnMscz1hd2FpdCBpKGUuZmxvYXRpbmcpO3JldHVybntyZWZlcmVuY2U6cmUoZS5yZWZlcmVuY2UsYXdhaXQgdChlLmZsb2F0aW5nKSxlLnN0cmF0ZWd5KSxmbG9hdGluZzp7eDowLHk6MCx3aWR0aDpzLndpZHRoLGhlaWdodDpzLmhlaWdodH19fSxnZXRDbGllbnRSZWN0czpmdW5jdGlvbihlKXtyZXR1cm4gQXJyYXkuZnJvbShlLmdldENsaWVudFJlY3RzKCkpfSxnZXREaW1lbnNpb25zOmZ1bmN0aW9uKGUpe2NvbnN0e3dpZHRoOnQsaGVpZ2h0Oml9PVgoZSk7cmV0dXJue3dpZHRoOnQsaGVpZ2h0Oml9fSxnZXRTY2FsZTpHLGlzRWxlbWVudDpxLGlzUlRMOmZ1bmN0aW9uKGUpe3JldHVyblwicnRsXCI9PT1VKGUpLmRpcmVjdGlvbn19O2Z1bmN0aW9uIHVlKGUsdCl7cmV0dXJuIGUueD09PXQueCYmZS55PT09dC55JiZlLndpZHRoPT09dC53aWR0aCYmZS5oZWlnaHQ9PT10LmhlaWdodH1mdW5jdGlvbiBwZShlLHQsaSxzKXt2b2lkIDA9PT1zJiYocz17fSk7Y29uc3R7YW5jZXN0b3JTY3JvbGw6bj0hMCxhbmNlc3RvclJlc2l6ZTpvPSEwLGVsZW1lbnRSZXNpemU6YT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBSZXNpemVPYnNlcnZlcixsYXlvdXRTaGlmdDpkPVwiZnVuY3Rpb25cIj09dHlwZW9mIEludGVyc2VjdGlvbk9ic2VydmVyLGFuaW1hdGlvbkZyYW1lOmg9ITF9PXMsdT1ZKGUpLHA9bnx8bz9bLi4udT9aKHUpOltdLC4uLloodCldOltdO3AuZm9yRWFjaCgoZT0+e24mJmUuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLGkse3Bhc3NpdmU6ITB9KSxvJiZlLmFkZEV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIixpKX0pKTtjb25zdCBtPXUmJmQ/ZnVuY3Rpb24oZSx0KXtsZXQgaSxzPW51bGw7Y29uc3Qgbj1EKGUpO2Z1bmN0aW9uIG8oKXt2YXIgZTtjbGVhclRpbWVvdXQoaSksbnVsbD09KGU9cyl8fGUuZGlzY29ubmVjdCgpLHM9bnVsbH1yZXR1cm4gZnVuY3Rpb24gYShkLGgpe3ZvaWQgMD09PWQmJihkPSExKSx2b2lkIDA9PT1oJiYoaD0xKSxvKCk7Y29uc3QgdT1lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHtsZWZ0OnAsdG9wOm0sd2lkdGg6ZyxoZWlnaHQ6Zn09dTtpZihkfHx0KCksIWd8fCFmKXJldHVybjtjb25zdCB2PXtyb290TWFyZ2luOi1jKG0pK1wicHggXCIrLWMobi5jbGllbnRXaWR0aC0ocCtnKSkrXCJweCBcIistYyhuLmNsaWVudEhlaWdodC0obStmKSkrXCJweCBcIistYyhwKStcInB4XCIsdGhyZXNob2xkOnIoMCxsKDEsaCkpfHwxfTtsZXQgdz0hMDtmdW5jdGlvbiB5KHQpe2NvbnN0IHM9dFswXS5pbnRlcnNlY3Rpb25SYXRpbztpZihzIT09aCl7aWYoIXcpcmV0dXJuIGEoKTtzP2EoITEscyk6aT1zZXRUaW1lb3V0KCgoKT0+e2EoITEsMWUtNyl9KSwxZTMpfTEhPT1zfHx1ZSh1LGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpfHxhKCksdz0hMX10cnl7cz1uZXcgSW50ZXJzZWN0aW9uT2JzZXJ2ZXIoeSx7Li4udixyb290Om4ub3duZXJEb2N1bWVudH0pfWNhdGNoKGUpe3M9bmV3IEludGVyc2VjdGlvbk9ic2VydmVyKHksdil9cy5vYnNlcnZlKGUpfSghMCksb30odSxpKTpudWxsO2xldCBnLGY9LTEsdj1udWxsO2EmJih2PW5ldyBSZXNpemVPYnNlcnZlcigoZT0+e2xldFtzXT1lO3MmJnMudGFyZ2V0PT09dSYmdiYmKHYudW5vYnNlcnZlKHQpLGNhbmNlbEFuaW1hdGlvbkZyYW1lKGYpLGY9cmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgoKT0+e3ZhciBlO251bGw9PShlPXYpfHxlLm9ic2VydmUodCl9KSkpLGkoKX0pKSx1JiYhaCYmdi5vYnNlcnZlKHUpLHYub2JzZXJ2ZSh0KSk7bGV0IHc9aD9pZShlKTpudWxsO3JldHVybiBoJiZmdW5jdGlvbiB0KCl7Y29uc3Qgcz1pZShlKTt3JiYhdWUodyxzKSYmaSgpO3c9cyxnPXJlcXVlc3RBbmltYXRpb25GcmFtZSh0KX0oKSxpKCksKCk9Pnt2YXIgZTtwLmZvckVhY2goKGU9PntuJiZlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIixpKSxvJiZlLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJyZXNpemVcIixpKX0pKSxudWxsPT1tfHxtKCksbnVsbD09KGU9dil8fGUuZGlzY29ubmVjdCgpLHY9bnVsbCxoJiZjYW5jZWxBbmltYXRpb25GcmFtZShnKX19Y29uc3QgbWU9eCxnZT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9MCkse25hbWU6XCJvZmZzZXRcIixvcHRpb25zOmUsYXN5bmMgZm4odCl7dmFyIGkscztjb25zdHt4Om4seTpvLHBsYWNlbWVudDpsLG1pZGRsZXdhcmVEYXRhOnJ9PXQsYT1hd2FpdCBhc3luYyBmdW5jdGlvbihlLHQpe2NvbnN0e3BsYWNlbWVudDppLHBsYXRmb3JtOnMsZWxlbWVudHM6bn09ZSxvPWF3YWl0KG51bGw9PXMuaXNSVEw/dm9pZCAwOnMuaXNSVEwobi5mbG9hdGluZykpLGw9ZyhpKSxyPWYoaSksYT1cInlcIj09PXkoaSksYz1bXCJsZWZ0XCIsXCJ0b3BcIl0uaW5jbHVkZXMobCk/LTE6MSxkPW8mJmE/LTE6MSxoPW0odCxlKTtsZXR7bWFpbkF4aXM6dSxjcm9zc0F4aXM6cCxhbGlnbm1lbnRBeGlzOnZ9PVwibnVtYmVyXCI9PXR5cGVvZiBoP3ttYWluQXhpczpoLGNyb3NzQXhpczowLGFsaWdubWVudEF4aXM6bnVsbH06e21haW5BeGlzOmgubWFpbkF4aXN8fDAsY3Jvc3NBeGlzOmguY3Jvc3NBeGlzfHwwLGFsaWdubWVudEF4aXM6aC5hbGlnbm1lbnRBeGlzfTtyZXR1cm4gciYmXCJudW1iZXJcIj09dHlwZW9mIHYmJihwPVwiZW5kXCI9PT1yPy0xKnY6diksYT97eDpwKmQseTp1KmN9Ont4OnUqYyx5OnAqZH19KHQsZSk7cmV0dXJuIGw9PT0obnVsbD09KGk9ci5vZmZzZXQpP3ZvaWQgMDppLnBsYWNlbWVudCkmJm51bGwhPShzPXIuYXJyb3cpJiZzLmFsaWdubWVudE9mZnNldD97fTp7eDpuK2EueCx5Om8rYS55LGRhdGE6ey4uLmEscGxhY2VtZW50Omx9fX19fSxmZT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9e30pLHtuYW1lOlwiYXV0b1BsYWNlbWVudFwiLG9wdGlvbnM6ZSxhc3luYyBmbih0KXt2YXIgaSxzLG47Y29uc3R7cmVjdHM6bCxtaWRkbGV3YXJlRGF0YTpyLHBsYWNlbWVudDphLHBsYXRmb3JtOmMsZWxlbWVudHM6ZH09dCx7Y3Jvc3NBeGlzOmg9ITEsYWxpZ25tZW50OnUsYWxsb3dlZFBsYWNlbWVudHM6cD1vLGF1dG9BbGlnbm1lbnQ6dj0hMCwuLi53fT1tKGUsdCkseT12b2lkIDAhPT11fHxwPT09bz9mdW5jdGlvbihlLHQsaSl7cmV0dXJuKGU/Wy4uLmkuZmlsdGVyKCh0PT5mKHQpPT09ZSkpLC4uLmkuZmlsdGVyKCh0PT5mKHQpIT09ZSkpXTppLmZpbHRlcigoZT0+ZyhlKT09PWUpKSkuZmlsdGVyKChpPT4hZXx8ZihpKT09PWV8fCEhdCYmUyhpKSE9PWkpKX0odXx8bnVsbCx2LHApOnAsYj1hd2FpdCB4KHQsdyksTD0obnVsbD09KGk9ci5hdXRvUGxhY2VtZW50KT92b2lkIDA6aS5pbmRleCl8fDAsST15W0xdO2lmKG51bGw9PUkpcmV0dXJue307Y29uc3QgRT1DKEksbCxhd2FpdChudWxsPT1jLmlzUlRMP3ZvaWQgMDpjLmlzUlRMKGQuZmxvYXRpbmcpKSk7aWYoYSE9PUkpcmV0dXJue3Jlc2V0OntwbGFjZW1lbnQ6eVswXX19O2NvbnN0IFQ9W2JbZyhJKV0sYltFWzBdXSxiW0VbMV1dXSxrPVsuLi4obnVsbD09KHM9ci5hdXRvUGxhY2VtZW50KT92b2lkIDA6cy5vdmVyZmxvd3MpfHxbXSx7cGxhY2VtZW50Okksb3ZlcmZsb3dzOlR9XSxBPXlbTCsxXTtpZihBKXJldHVybntkYXRhOntpbmRleDpMKzEsb3ZlcmZsb3dzOmt9LHJlc2V0OntwbGFjZW1lbnQ6QX19O2NvbnN0IE89ay5tYXAoKGU9Pntjb25zdCB0PWYoZS5wbGFjZW1lbnQpO3JldHVybltlLnBsYWNlbWVudCx0JiZoP2Uub3ZlcmZsb3dzLnNsaWNlKDAsMikucmVkdWNlKCgoZSx0KT0+ZSt0KSwwKTplLm92ZXJmbG93c1swXSxlLm92ZXJmbG93c119KSkuc29ydCgoKGUsdCk9PmVbMV0tdFsxXSkpLFA9KG51bGw9PShuPU8uZmlsdGVyKChlPT5lWzJdLnNsaWNlKDAsZihlWzBdKT8yOjMpLmV2ZXJ5KChlPT5lPD0wKSkpKVswXSk/dm9pZCAwOm5bMF0pfHxPWzBdWzBdO3JldHVybiBQIT09YT97ZGF0YTp7aW5kZXg6TCsxLG92ZXJmbG93czprfSxyZXNldDp7cGxhY2VtZW50OlB9fTp7fX19fSx2ZT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9e30pLHtuYW1lOlwic2hpZnRcIixvcHRpb25zOmUsYXN5bmMgZm4odCl7Y29uc3R7eDppLHk6cyxwbGFjZW1lbnQ6bn09dCx7bWFpbkF4aXM6bz0hMCxjcm9zc0F4aXM6bD0hMSxsaW1pdGVyOnI9e2ZuOmU9PntsZXR7eDp0LHk6aX09ZTtyZXR1cm57eDp0LHk6aX19fSwuLi5hfT1tKGUsdCksYz17eDppLHk6c30sZD1hd2FpdCB4KHQsYSksaD15KGcobikpLHU9dihoKTtsZXQgZj1jW3VdLHc9Y1toXTtpZihvKXtjb25zdCBlPVwieVwiPT09dT9cImJvdHRvbVwiOlwicmlnaHRcIjtmPXAoZitkW1wieVwiPT09dT9cInRvcFwiOlwibGVmdFwiXSxmLGYtZFtlXSl9aWYobCl7Y29uc3QgZT1cInlcIj09PWg/XCJib3R0b21cIjpcInJpZ2h0XCI7dz1wKHcrZFtcInlcIj09PWg/XCJ0b3BcIjpcImxlZnRcIl0sdyx3LWRbZV0pfWNvbnN0IGI9ci5mbih7Li4udCxbdV06ZixbaF06d30pO3JldHVybnsuLi5iLGRhdGE6e3g6Yi54LWkseTpiLnktcyxlbmFibGVkOntbdV06byxbaF06bH19fX19fSx3ZT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9e30pLHtuYW1lOlwiZmxpcFwiLG9wdGlvbnM6ZSxhc3luYyBmbih0KXt2YXIgaSxzO2NvbnN0e3BsYWNlbWVudDpuLG1pZGRsZXdhcmVEYXRhOm8scmVjdHM6bCxpbml0aWFsUGxhY2VtZW50OnIscGxhdGZvcm06YSxlbGVtZW50czpjfT10LHttYWluQXhpczpkPSEwLGNyb3NzQXhpczpoPSEwLGZhbGxiYWNrUGxhY2VtZW50czp1LGZhbGxiYWNrU3RyYXRlZ3k6cD1cImJlc3RGaXRcIixmYWxsYmFja0F4aXNTaWRlRGlyZWN0aW9uOnY9XCJub25lXCIsZmxpcEFsaWdubWVudDp3PSEwLC4uLmJ9PW0oZSx0KTtpZihudWxsIT0oaT1vLmFycm93KSYmaS5hbGlnbm1lbnRPZmZzZXQpcmV0dXJue307Y29uc3QgST1nKG4pLEU9eShyKSxUPWcocik9PT1yLGs9YXdhaXQobnVsbD09YS5pc1JUTD92b2lkIDA6YS5pc1JUTChjLmZsb2F0aW5nKSksQT11fHwoVHx8IXc/W0wocildOmZ1bmN0aW9uKGUpe2NvbnN0IHQ9TChlKTtyZXR1cm5bUyhlKSx0LFModCldfShyKSksTz1cIm5vbmVcIiE9PXY7IXUmJk8mJkEucHVzaCguLi5mdW5jdGlvbihlLHQsaSxzKXtjb25zdCBuPWYoZSk7bGV0IG89ZnVuY3Rpb24oZSx0LGkpe2NvbnN0IHM9W1wibGVmdFwiLFwicmlnaHRcIl0sbj1bXCJyaWdodFwiLFwibGVmdFwiXSxvPVtcInRvcFwiLFwiYm90dG9tXCJdLGw9W1wiYm90dG9tXCIsXCJ0b3BcIl07c3dpdGNoKGUpe2Nhc2VcInRvcFwiOmNhc2VcImJvdHRvbVwiOnJldHVybiBpP3Q/bjpzOnQ/czpuO2Nhc2VcImxlZnRcIjpjYXNlXCJyaWdodFwiOnJldHVybiB0P286bDtkZWZhdWx0OnJldHVybltdfX0oZyhlKSxcInN0YXJ0XCI9PT1pLHMpO3JldHVybiBuJiYobz1vLm1hcCgoZT0+ZStcIi1cIituKSksdCYmKG89by5jb25jYXQoby5tYXAoUykpKSksb30ocix3LHYsaykpO2NvbnN0IFA9W3IsLi4uQV0sJD1hd2FpdCB4KHQsYiksQj1bXTtsZXQgRD0obnVsbD09KHM9by5mbGlwKT92b2lkIDA6cy5vdmVyZmxvd3MpfHxbXTtpZihkJiZCLnB1c2goJFtJXSksaCl7Y29uc3QgZT1DKG4sbCxrKTtCLnB1c2goJFtlWzBdXSwkW2VbMV1dKX1pZihEPVsuLi5ELHtwbGFjZW1lbnQ6bixvdmVyZmxvd3M6Qn1dLCFCLmV2ZXJ5KChlPT5lPD0wKSkpe3ZhciBNLHE7Y29uc3QgZT0oKG51bGw9PShNPW8uZmxpcCk/dm9pZCAwOk0uaW5kZXgpfHwwKSsxLHQ9UFtlXTtpZih0KXJldHVybntkYXRhOntpbmRleDplLG92ZXJmbG93czpEfSxyZXNldDp7cGxhY2VtZW50OnR9fTtsZXQgaT1udWxsPT0ocT1ELmZpbHRlcigoZT0+ZS5vdmVyZmxvd3NbMF08PTApKS5zb3J0KCgoZSx0KT0+ZS5vdmVyZmxvd3NbMV0tdC5vdmVyZmxvd3NbMV0pKVswXSk/dm9pZCAwOnEucGxhY2VtZW50O2lmKCFpKXN3aXRjaChwKXtjYXNlXCJiZXN0Rml0XCI6e3ZhciBOO2NvbnN0IGU9bnVsbD09KE49RC5maWx0ZXIoKGU9PntpZihPKXtjb25zdCB0PXkoZS5wbGFjZW1lbnQpO3JldHVybiB0PT09RXx8XCJ5XCI9PT10fXJldHVybiEwfSkpLm1hcCgoZT0+W2UucGxhY2VtZW50LGUub3ZlcmZsb3dzLmZpbHRlcigoZT0+ZT4wKSkucmVkdWNlKCgoZSx0KT0+ZSt0KSwwKV0pKS5zb3J0KCgoZSx0KT0+ZVsxXS10WzFdKSlbMF0pP3ZvaWQgMDpOWzBdO2UmJihpPWUpO2JyZWFrfWNhc2VcImluaXRpYWxQbGFjZW1lbnRcIjppPXJ9aWYobiE9PWkpcmV0dXJue3Jlc2V0OntwbGFjZW1lbnQ6aX19fXJldHVybnt9fX19LHllPWZ1bmN0aW9uKGUpe3JldHVybiB2b2lkIDA9PT1lJiYoZT17fSkse25hbWU6XCJzaXplXCIsb3B0aW9uczplLGFzeW5jIGZuKHQpe3ZhciBpLHM7Y29uc3R7cGxhY2VtZW50Om4scmVjdHM6byxwbGF0Zm9ybTphLGVsZW1lbnRzOmN9PXQse2FwcGx5OmQ9KCk9Pnt9LC4uLmh9PW0oZSx0KSx1PWF3YWl0IHgodCxoKSxwPWcobiksdj1mKG4pLHc9XCJ5XCI9PT15KG4pLHt3aWR0aDpiLGhlaWdodDpDfT1vLmZsb2F0aW5nO2xldCBTLEw7XCJ0b3BcIj09PXB8fFwiYm90dG9tXCI9PT1wPyhTPXAsTD12PT09KGF3YWl0KG51bGw9PWEuaXNSVEw/dm9pZCAwOmEuaXNSVEwoYy5mbG9hdGluZykpP1wic3RhcnRcIjpcImVuZFwiKT9cImxlZnRcIjpcInJpZ2h0XCIpOihMPXAsUz1cImVuZFwiPT09dj9cInRvcFwiOlwiYm90dG9tXCIpO2NvbnN0IEk9Qy11LnRvcC11LmJvdHRvbSxFPWItdS5sZWZ0LXUucmlnaHQsVD1sKEMtdVtTXSxJKSxrPWwoYi11W0xdLEUpLEE9IXQubWlkZGxld2FyZURhdGEuc2hpZnQ7bGV0IE89VCxQPWs7aWYobnVsbCE9KGk9dC5taWRkbGV3YXJlRGF0YS5zaGlmdCkmJmkuZW5hYmxlZC54JiYoUD1FKSxudWxsIT0ocz10Lm1pZGRsZXdhcmVEYXRhLnNoaWZ0KSYmcy5lbmFibGVkLnkmJihPPUkpLEEmJiF2KXtjb25zdCBlPXIodS5sZWZ0LDApLHQ9cih1LnJpZ2h0LDApLGk9cih1LnRvcCwwKSxzPXIodS5ib3R0b20sMCk7dz9QPWItMiooMCE9PWV8fDAhPT10P2UrdDpyKHUubGVmdCx1LnJpZ2h0KSk6Tz1DLTIqKDAhPT1pfHwwIT09cz9pK3M6cih1LnRvcCx1LmJvdHRvbSkpfWF3YWl0IGQoey4uLnQsYXZhaWxhYmxlV2lkdGg6UCxhdmFpbGFibGVIZWlnaHQ6T30pO2NvbnN0ICQ9YXdhaXQgYS5nZXREaW1lbnNpb25zKGMuZmxvYXRpbmcpO3JldHVybiBiIT09JC53aWR0aHx8QyE9PSQuaGVpZ2h0P3tyZXNldDp7cmVjdHM6ITB9fTp7fX19fSxiZT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9e30pLHtuYW1lOlwiaGlkZVwiLG9wdGlvbnM6ZSxhc3luYyBmbih0KXtjb25zdHtyZWN0czppfT10LHtzdHJhdGVneTpzPVwicmVmZXJlbmNlSGlkZGVuXCIsLi4ubn09bShlLHQpO3N3aXRjaChzKXtjYXNlXCJyZWZlcmVuY2VIaWRkZW5cIjp7Y29uc3QgZT1rKGF3YWl0IHgodCx7Li4ubixlbGVtZW50Q29udGV4dDpcInJlZmVyZW5jZVwifSksaS5yZWZlcmVuY2UpO3JldHVybntkYXRhOntyZWZlcmVuY2VIaWRkZW5PZmZzZXRzOmUscmVmZXJlbmNlSGlkZGVuOkEoZSl9fX1jYXNlXCJlc2NhcGVkXCI6e2NvbnN0IGU9ayhhd2FpdCB4KHQsey4uLm4sYWx0Qm91bmRhcnk6ITB9KSxpLmZsb2F0aW5nKTtyZXR1cm57ZGF0YTp7ZXNjYXBlZE9mZnNldHM6ZSxlc2NhcGVkOkEoZSl9fX1kZWZhdWx0OnJldHVybnt9fX19fSxDZT1lPT4oe25hbWU6XCJhcnJvd1wiLG9wdGlvbnM6ZSxhc3luYyBmbih0KXtjb25zdHt4OmkseTpzLHBsYWNlbWVudDpuLHJlY3RzOm8scGxhdGZvcm06cixlbGVtZW50czphLG1pZGRsZXdhcmVEYXRhOmN9PXQse2VsZW1lbnQ6ZCxwYWRkaW5nOmg9MH09bShlLHQpfHx7fTtpZihudWxsPT1kKXJldHVybnt9O2NvbnN0IHU9SShoKSxnPXt4OmkseTpzfSx2PWIobikseT13KHYpLEM9YXdhaXQgci5nZXREaW1lbnNpb25zKGQpLFM9XCJ5XCI9PT12LEw9Uz9cInRvcFwiOlwibGVmdFwiLEU9Uz9cImJvdHRvbVwiOlwicmlnaHRcIixUPVM/XCJjbGllbnRIZWlnaHRcIjpcImNsaWVudFdpZHRoXCIseD1vLnJlZmVyZW5jZVt5XStvLnJlZmVyZW5jZVt2XS1nW3ZdLW8uZmxvYXRpbmdbeV0saz1nW3ZdLW8ucmVmZXJlbmNlW3ZdLEE9YXdhaXQobnVsbD09ci5nZXRPZmZzZXRQYXJlbnQ/dm9pZCAwOnIuZ2V0T2Zmc2V0UGFyZW50KGQpKTtsZXQgTz1BP0FbVF06MDtPJiZhd2FpdChudWxsPT1yLmlzRWxlbWVudD92b2lkIDA6ci5pc0VsZW1lbnQoQSkpfHwoTz1hLmZsb2F0aW5nW1RdfHxvLmZsb2F0aW5nW3ldKTtjb25zdCBQPXgvMi1rLzIsJD1PLzItQ1t5XS8yLTEsQj1sKHVbTF0sJCksRD1sKHVbRV0sJCksTT1CLHE9Ty1DW3ldLUQsTj1PLzItQ1t5XS8yK1AsSD1wKE0sTixxKSxGPSFjLmFycm93JiZudWxsIT1mKG4pJiZOIT09SCYmby5yZWZlcmVuY2VbeV0vMi0oTjxNP0I6RCktQ1t5XS8yPDAsUj1GP048TT9OLU06Ti1xOjA7cmV0dXJue1t2XTpnW3ZdK1IsZGF0YTp7W3ZdOkgsY2VudGVyT2Zmc2V0Ok4tSC1SLC4uLkYmJnthbGlnbm1lbnRPZmZzZXQ6Un19LHJlc2V0OkZ9fX0pLFNlPWZ1bmN0aW9uKGUpe3JldHVybiB2b2lkIDA9PT1lJiYoZT17fSkse25hbWU6XCJpbmxpbmVcIixvcHRpb25zOmUsYXN5bmMgZm4odCl7Y29uc3R7cGxhY2VtZW50OmksZWxlbWVudHM6cyxyZWN0czpuLHBsYXRmb3JtOm8sc3RyYXRlZ3k6YX09dCx7cGFkZGluZzpjPTIseDpkLHk6aH09bShlLHQpLHU9QXJyYXkuZnJvbShhd2FpdChudWxsPT1vLmdldENsaWVudFJlY3RzP3ZvaWQgMDpvLmdldENsaWVudFJlY3RzKHMucmVmZXJlbmNlKSl8fFtdKSxwPWZ1bmN0aW9uKGUpe2NvbnN0IHQ9ZS5zbGljZSgpLnNvcnQoKChlLHQpPT5lLnktdC55KSksaT1bXTtsZXQgcz1udWxsO2ZvcihsZXQgZT0wO2U8dC5sZW5ndGg7ZSsrKXtjb25zdCBuPXRbZV07IXN8fG4ueS1zLnk+cy5oZWlnaHQvMj9pLnB1c2goW25dKTppW2kubGVuZ3RoLTFdLnB1c2gobikscz1ufXJldHVybiBpLm1hcCgoZT0+RShPKGUpKSkpfSh1KSxmPUUoTyh1KSksdj1JKGMpO2NvbnN0IHc9YXdhaXQgby5nZXRFbGVtZW50UmVjdHMoe3JlZmVyZW5jZTp7Z2V0Qm91bmRpbmdDbGllbnRSZWN0OmZ1bmN0aW9uKCl7aWYoMj09PXAubGVuZ3RoJiZwWzBdLmxlZnQ+cFsxXS5yaWdodCYmbnVsbCE9ZCYmbnVsbCE9aClyZXR1cm4gcC5maW5kKChlPT5kPmUubGVmdC12LmxlZnQmJmQ8ZS5yaWdodCt2LnJpZ2h0JiZoPmUudG9wLXYudG9wJiZoPGUuYm90dG9tK3YuYm90dG9tKSl8fGY7aWYocC5sZW5ndGg+PTIpe2lmKFwieVwiPT09eShpKSl7Y29uc3QgZT1wWzBdLHQ9cFtwLmxlbmd0aC0xXSxzPVwidG9wXCI9PT1nKGkpLG49ZS50b3Asbz10LmJvdHRvbSxsPXM/ZS5sZWZ0OnQubGVmdCxyPXM/ZS5yaWdodDp0LnJpZ2h0O3JldHVybnt0b3A6bixib3R0b206byxsZWZ0OmwscmlnaHQ6cix3aWR0aDpyLWwsaGVpZ2h0Om8tbix4OmwseTpufX1jb25zdCBlPVwibGVmdFwiPT09ZyhpKSx0PXIoLi4ucC5tYXAoKGU9PmUucmlnaHQpKSkscz1sKC4uLnAubWFwKChlPT5lLmxlZnQpKSksbj1wLmZpbHRlcigoaT0+ZT9pLmxlZnQ9PT1zOmkucmlnaHQ9PT10KSksbz1uWzBdLnRvcCxhPW5bbi5sZW5ndGgtMV0uYm90dG9tO3JldHVybnt0b3A6byxib3R0b206YSxsZWZ0OnMscmlnaHQ6dCx3aWR0aDp0LXMsaGVpZ2h0OmEtbyx4OnMseTpvfX1yZXR1cm4gZn19LGZsb2F0aW5nOnMuZmxvYXRpbmcsc3RyYXRlZ3k6YX0pO3JldHVybiBuLnJlZmVyZW5jZS54IT09dy5yZWZlcmVuY2UueHx8bi5yZWZlcmVuY2UueSE9PXcucmVmZXJlbmNlLnl8fG4ucmVmZXJlbmNlLndpZHRoIT09dy5yZWZlcmVuY2Uud2lkdGh8fG4ucmVmZXJlbmNlLmhlaWdodCE9PXcucmVmZXJlbmNlLmhlaWdodD97cmVzZXQ6e3JlY3RzOnd9fTp7fX19fSxMZT1mdW5jdGlvbihlKXtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9e30pLHtvcHRpb25zOmUsZm4odCl7Y29uc3R7eDppLHk6cyxwbGFjZW1lbnQ6bixyZWN0czpvLG1pZGRsZXdhcmVEYXRhOmx9PXQse29mZnNldDpyPTAsbWFpbkF4aXM6YT0hMCxjcm9zc0F4aXM6Yz0hMH09bShlLHQpLGQ9e3g6aSx5OnN9LGg9eShuKSx1PXYoaCk7bGV0IHA9ZFt1XSxmPWRbaF07Y29uc3Qgdz1tKHIsdCksYj1cIm51bWJlclwiPT10eXBlb2Ygdz97bWFpbkF4aXM6dyxjcm9zc0F4aXM6MH06e21haW5BeGlzOjAsY3Jvc3NBeGlzOjAsLi4ud307aWYoYSl7Y29uc3QgZT1cInlcIj09PXU/XCJoZWlnaHRcIjpcIndpZHRoXCIsdD1vLnJlZmVyZW5jZVt1XS1vLmZsb2F0aW5nW2VdK2IubWFpbkF4aXMsaT1vLnJlZmVyZW5jZVt1XStvLnJlZmVyZW5jZVtlXS1iLm1haW5BeGlzO3A8dD9wPXQ6cD5pJiYocD1pKX1pZihjKXt2YXIgQyxTO2NvbnN0IGU9XCJ5XCI9PT11P1wid2lkdGhcIjpcImhlaWdodFwiLHQ9W1widG9wXCIsXCJsZWZ0XCJdLmluY2x1ZGVzKGcobikpLGk9by5yZWZlcmVuY2VbaF0tby5mbG9hdGluZ1tlXSsodCYmKG51bGw9PShDPWwub2Zmc2V0KT92b2lkIDA6Q1toXSl8fDApKyh0PzA6Yi5jcm9zc0F4aXMpLHM9by5yZWZlcmVuY2VbaF0rby5yZWZlcmVuY2VbZV0rKHQ/MDoobnVsbD09KFM9bC5vZmZzZXQpP3ZvaWQgMDpTW2hdKXx8MCktKHQ/Yi5jcm9zc0F4aXM6MCk7ZjxpP2Y9aTpmPnMmJihmPXMpfXJldHVybntbdV06cCxbaF06Zn19fX0sSWU9KGUsdCxpKT0+e2NvbnN0IHM9bmV3IE1hcCxuPXtwbGF0Zm9ybTpoZSwuLi5pfSxvPXsuLi5uLnBsYXRmb3JtLF9jOnN9O3JldHVybihhc3luYyhlLHQsaSk9Pntjb25zdHtwbGFjZW1lbnQ6cz1cImJvdHRvbVwiLHN0cmF0ZWd5Om49XCJhYnNvbHV0ZVwiLG1pZGRsZXdhcmU6bz1bXSxwbGF0Zm9ybTpsfT1pLHI9by5maWx0ZXIoQm9vbGVhbiksYT1hd2FpdChudWxsPT1sLmlzUlRMP3ZvaWQgMDpsLmlzUlRMKHQpKTtsZXQgYz1hd2FpdCBsLmdldEVsZW1lbnRSZWN0cyh7cmVmZXJlbmNlOmUsZmxvYXRpbmc6dCxzdHJhdGVneTpufSkse3g6ZCx5Omh9PVQoYyxzLGEpLHU9cyxwPXt9LG09MDtmb3IobGV0IGk9MDtpPHIubGVuZ3RoO2krKyl7Y29uc3R7bmFtZTpvLGZuOmd9PXJbaV0se3g6Zix5OnYsZGF0YTp3LHJlc2V0Onl9PWF3YWl0IGcoe3g6ZCx5OmgsaW5pdGlhbFBsYWNlbWVudDpzLHBsYWNlbWVudDp1LHN0cmF0ZWd5Om4sbWlkZGxld2FyZURhdGE6cCxyZWN0czpjLHBsYXRmb3JtOmwsZWxlbWVudHM6e3JlZmVyZW5jZTplLGZsb2F0aW5nOnR9fSk7ZD1udWxsIT1mP2Y6ZCxoPW51bGwhPXY/djpoLHA9ey4uLnAsW29dOnsuLi5wW29dLC4uLnd9fSx5JiZtPD01MCYmKG0rKyxcIm9iamVjdFwiPT10eXBlb2YgeSYmKHkucGxhY2VtZW50JiYodT15LnBsYWNlbWVudCkseS5yZWN0cyYmKGM9ITA9PT15LnJlY3RzP2F3YWl0IGwuZ2V0RWxlbWVudFJlY3RzKHtyZWZlcmVuY2U6ZSxmbG9hdGluZzp0LHN0cmF0ZWd5Om59KTp5LnJlY3RzKSwoe3g6ZCx5Omh9PVQoYyx1LGEpKSksaT0tMSl9cmV0dXJue3g6ZCx5OmgscGxhY2VtZW50OnUsc3RyYXRlZ3k6bixtaWRkbGV3YXJlRGF0YTpwfX0pKGUsdCx7Li4ubixwbGF0Zm9ybTpvfSl9fSw5NTY6ZnVuY3Rpb24oZSx0LGkpe1xuLypcbiAqIEhTU2VsZWN0XG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbnZhciBzPXRoaXMmJnRoaXMuX19hd2FpdGVyfHxmdW5jdGlvbihlLHQsaSxzKXtyZXR1cm4gbmV3KGl8fChpPVByb21pc2UpKSgoZnVuY3Rpb24obixvKXtmdW5jdGlvbiBsKGUpe3RyeXthKHMubmV4dChlKSl9Y2F0Y2goZSl7byhlKX19ZnVuY3Rpb24gcihlKXt0cnl7YShzLnRocm93KGUpKX1jYXRjaChlKXtvKGUpfX1mdW5jdGlvbiBhKGUpe3ZhciB0O2UuZG9uZT9uKGUudmFsdWUpOih0PWUudmFsdWUsdCBpbnN0YW5jZW9mIGk/dDpuZXcgaSgoZnVuY3Rpb24oZSl7ZSh0KX0pKSkudGhlbihsLHIpfWEoKHM9cy5hcHBseShlLHR8fFtdKSkubmV4dCgpKX0pKX0sbj10aGlzJiZ0aGlzLl9faW1wb3J0RGVmYXVsdHx8ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fTtPYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KTtjb25zdCBvPWkoODA2KSxsPWkoOTQ5KSxyPW4oaSgyODcpKSxhPWkoOTE3KTtjbGFzcyBjIGV4dGVuZHMgci5kZWZhdWx0e2NvbnN0cnVjdG9yKGUsdCl7dmFyIGkscyxuLG87c3VwZXIoZSx0KSx0aGlzLm9wdGlvbklkPTA7Y29uc3QgbD1lLmdldEF0dHJpYnV0ZShcImRhdGEtc2VsZWN0XCIpLHI9bD9KU09OLnBhcnNlKGwpOnt9LGE9T2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LHIpLHQpO3RoaXMudmFsdWU9KG51bGw9PWE/dm9pZCAwOmEudmFsdWUpfHx0aGlzLmVsLnZhbHVlfHxudWxsLHRoaXMucGxhY2Vob2xkZXI9KG51bGw9PWE/dm9pZCAwOmEucGxhY2Vob2xkZXIpfHxcIlNlbGVjdC4uLlwiLHRoaXMuaGFzU2VhcmNoPShudWxsPT1hP3ZvaWQgMDphLmhhc1NlYXJjaCl8fCExLHRoaXMubWluU2VhcmNoTGVuZ3RoPW51bGwhPT0oaT1udWxsPT1hP3ZvaWQgMDphLm1pblNlYXJjaExlbmd0aCkmJnZvaWQgMCE9PWk/aTowLHRoaXMucHJldmVudFNlYXJjaEZvY3VzPShudWxsPT1hP3ZvaWQgMDphLnByZXZlbnRTZWFyY2hGb2N1cyl8fCExLHRoaXMubW9kZT0obnVsbD09YT92b2lkIDA6YS5tb2RlKXx8XCJkZWZhdWx0XCIsdGhpcy52aWV3cG9ydD12b2lkIDAhPT0obnVsbD09YT92b2lkIDA6YS52aWV3cG9ydCk/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihudWxsPT1hP3ZvaWQgMDphLnZpZXdwb3J0KTpudWxsLHRoaXMuaXNPcGVuZWQ9Qm9vbGVhbihudWxsPT1hP3ZvaWQgMDphLmlzT3BlbmVkKXx8ITEsdGhpcy5pc011bHRpcGxlPXRoaXMuZWwuaGFzQXR0cmlidXRlKFwibXVsdGlwbGVcIil8fCExLHRoaXMuaXNEaXNhYmxlZD10aGlzLmVsLmhhc0F0dHJpYnV0ZShcImRpc2FibGVkXCIpfHwhMSx0aGlzLnNlbGVjdGVkSXRlbXM9W10sdGhpcy5hcGlVcmw9KG51bGw9PWE/dm9pZCAwOmEuYXBpVXJsKXx8bnVsbCx0aGlzLmFwaVF1ZXJ5PShudWxsPT1hP3ZvaWQgMDphLmFwaVF1ZXJ5KXx8bnVsbCx0aGlzLmFwaU9wdGlvbnM9KG51bGw9PWE/dm9pZCAwOmEuYXBpT3B0aW9ucyl8fG51bGwsdGhpcy5hcGlTZWFyY2hRdWVyeUtleT0obnVsbD09YT92b2lkIDA6YS5hcGlTZWFyY2hRdWVyeUtleSl8fG51bGwsdGhpcy5hcGlEYXRhUGFydD0obnVsbD09YT92b2lkIDA6YS5hcGlEYXRhUGFydCl8fG51bGwsdGhpcy5hcGlGaWVsZHNNYXA9KG51bGw9PWE/dm9pZCAwOmEuYXBpRmllbGRzTWFwKXx8bnVsbCx0aGlzLmFwaUljb25UYWc9KG51bGw9PWE/dm9pZCAwOmEuYXBpSWNvblRhZyl8fG51bGwsdGhpcy53cmFwcGVyQ2xhc3Nlcz0obnVsbD09YT92b2lkIDA6YS53cmFwcGVyQ2xhc3Nlcyl8fG51bGwsdGhpcy50b2dnbGVUYWc9KG51bGw9PWE/dm9pZCAwOmEudG9nZ2xlVGFnKXx8bnVsbCx0aGlzLnRvZ2dsZUNsYXNzZXM9KG51bGw9PWE/dm9pZCAwOmEudG9nZ2xlQ2xhc3Nlcyl8fG51bGwsdGhpcy50b2dnbGVDb3VudFRleHQ9dm9pZCAwPT09dHlwZW9mKG51bGw9PWE/dm9pZCAwOmEudG9nZ2xlQ291bnRUZXh0KT9udWxsOmEudG9nZ2xlQ291bnRUZXh0LHRoaXMudG9nZ2xlQ291bnRUZXh0UGxhY2VtZW50PShudWxsPT1hP3ZvaWQgMDphLnRvZ2dsZUNvdW50VGV4dFBsYWNlbWVudCl8fFwicG9zdGZpeFwiLHRoaXMudG9nZ2xlQ291bnRUZXh0TWluSXRlbXM9KG51bGw9PWE/dm9pZCAwOmEudG9nZ2xlQ291bnRUZXh0TWluSXRlbXMpfHwxLHRoaXMudG9nZ2xlQ291bnRUZXh0TW9kZT0obnVsbD09YT92b2lkIDA6YS50b2dnbGVDb3VudFRleHRNb2RlKXx8XCJjb3VudEFmdGVyTGltaXRcIix0aGlzLnRvZ2dsZVNlcGFyYXRvcnM9e2l0ZW1zOihudWxsPT09KHM9bnVsbD09YT92b2lkIDA6YS50b2dnbGVTZXBhcmF0b3JzKXx8dm9pZCAwPT09cz92b2lkIDA6cy5pdGVtcyl8fFwiLCBcIixiZXR3ZWVuSXRlbXNBbmRDb3VudGVyOihudWxsPT09KG49bnVsbD09YT92b2lkIDA6YS50b2dnbGVTZXBhcmF0b3JzKXx8dm9pZCAwPT09bj92b2lkIDA6bi5iZXR3ZWVuSXRlbXNBbmRDb3VudGVyKXx8XCJhbmRcIn0sdGhpcy50YWdzSXRlbVRlbXBsYXRlPShudWxsPT1hP3ZvaWQgMDphLnRhZ3NJdGVtVGVtcGxhdGUpfHxudWxsLHRoaXMudGFnc0l0ZW1DbGFzc2VzPShudWxsPT1hP3ZvaWQgMDphLnRhZ3NJdGVtQ2xhc3Nlcyl8fG51bGwsdGhpcy50YWdzSW5wdXRJZD0obnVsbD09YT92b2lkIDA6YS50YWdzSW5wdXRJZCl8fG51bGwsdGhpcy50YWdzSW5wdXRDbGFzc2VzPShudWxsPT1hP3ZvaWQgMDphLnRhZ3NJbnB1dENsYXNzZXMpfHxudWxsLHRoaXMuZHJvcGRvd25UYWc9KG51bGw9PWE/dm9pZCAwOmEuZHJvcGRvd25UYWcpfHxudWxsLHRoaXMuZHJvcGRvd25DbGFzc2VzPShudWxsPT1hP3ZvaWQgMDphLmRyb3Bkb3duQ2xhc3Nlcyl8fG51bGwsdGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXM9KG51bGw9PWE/dm9pZCAwOmEuZHJvcGRvd25EaXJlY3Rpb25DbGFzc2VzKXx8bnVsbCx0aGlzLmRyb3Bkb3duU3BhY2U9KG51bGw9PWE/dm9pZCAwOmEuZHJvcGRvd25TcGFjZSl8fDEwLHRoaXMuZHJvcGRvd25QbGFjZW1lbnQ9KG51bGw9PWE/dm9pZCAwOmEuZHJvcGRvd25QbGFjZW1lbnQpfHxudWxsLHRoaXMuZHJvcGRvd25WZXJ0aWNhbEZpeGVkUGxhY2VtZW50PShudWxsPT1hP3ZvaWQgMDphLmRyb3Bkb3duVmVydGljYWxGaXhlZFBsYWNlbWVudCl8fG51bGwsdGhpcy5kcm9wZG93blNjb3BlPShudWxsPT1hP3ZvaWQgMDphLmRyb3Bkb3duU2NvcGUpfHxcInBhcmVudFwiLHRoaXMuc2VhcmNoVGVtcGxhdGU9KG51bGw9PWE/dm9pZCAwOmEuc2VhcmNoVGVtcGxhdGUpfHxudWxsLHRoaXMuc2VhcmNoV3JhcHBlclRlbXBsYXRlPShudWxsPT1hP3ZvaWQgMDphLnNlYXJjaFdyYXBwZXJUZW1wbGF0ZSl8fG51bGwsdGhpcy5zZWFyY2hXcmFwcGVyQ2xhc3Nlcz0obnVsbD09YT92b2lkIDA6YS5zZWFyY2hXcmFwcGVyQ2xhc3Nlcyl8fFwiYmctYmFzZS0xMDAgc3RpY2t5IHRvcC0wIG1iLTIgcHgtMiBwdC0zXCIsdGhpcy5zZWFyY2hJZD0obnVsbD09YT92b2lkIDA6YS5zZWFyY2hJZCl8fG51bGwsdGhpcy5zZWFyY2hMaW1pdD0obnVsbD09YT92b2lkIDA6YS5zZWFyY2hMaW1pdCl8fDEvMCx0aGlzLmlzU2VhcmNoRGlyZWN0TWF0Y2g9dm9pZCAwPT09KG51bGw9PWE/dm9pZCAwOmEuaXNTZWFyY2hEaXJlY3RNYXRjaCl8fChudWxsPT1hP3ZvaWQgMDphLmlzU2VhcmNoRGlyZWN0TWF0Y2gpLHRoaXMuc2VhcmNoQ2xhc3Nlcz0obnVsbD09YT92b2lkIDA6YS5zZWFyY2hDbGFzc2VzKXx8XCJib3JkZXItYmFzZS1jb250ZW50LzQwIGZvY3VzOmJvcmRlci1wcmltYXJ5IGZvY3VzOm91dGxpbmUtcHJpbWFyeSBiZy1iYXNlLTEwMCBibG9jayB3LWZ1bGwgcm91bmRlZC1maWVsZCBib3JkZXIgcHgtMyBweS0yIHRleHQtYmFzZSBmb2N1czpvdXRsaW5lLTFcIix0aGlzLnNlYXJjaFBsYWNlaG9sZGVyPShudWxsPT1hP3ZvaWQgMDphLnNlYXJjaFBsYWNlaG9sZGVyKXx8XCJTZWFyY2guLi5cIix0aGlzLnNlYXJjaE5vUmVzdWx0VGVtcGxhdGU9KG51bGw9PWE/dm9pZCAwOmEuc2VhcmNoTm9SZXN1bHRUZW1wbGF0ZSl8fFwiPHNwYW4+PC9zcGFuPlwiLHRoaXMuc2VhcmNoTm9SZXN1bHRUZXh0PShudWxsPT1hP3ZvaWQgMDphLnNlYXJjaE5vUmVzdWx0VGV4dCl8fFwiTm8gcmVzdWx0cyBmb3VuZFwiLHRoaXMuc2VhcmNoTm9SZXN1bHRDbGFzc2VzPShudWxsPT1hP3ZvaWQgMDphLnNlYXJjaE5vUmVzdWx0Q2xhc3Nlcyl8fFwiYmxvY2sgYWR2YW5jZS1zZWxlY3Qtb3B0aW9uXCIsdGhpcy5vcHRpb25BbGxvd0VtcHR5T3B0aW9uPXZvaWQgMCE9PShudWxsPT1hP3ZvaWQgMDphLm9wdGlvbkFsbG93RW1wdHlPcHRpb24pJiYobnVsbD09YT92b2lkIDA6YS5vcHRpb25BbGxvd0VtcHR5T3B0aW9uKSx0aGlzLm9wdGlvblRlbXBsYXRlPShudWxsPT1hP3ZvaWQgMDphLm9wdGlvblRlbXBsYXRlKXx8bnVsbCx0aGlzLm9wdGlvblRhZz0obnVsbD09YT92b2lkIDA6YS5vcHRpb25UYWcpfHxudWxsLHRoaXMub3B0aW9uQ2xhc3Nlcz0obnVsbD09YT92b2lkIDA6YS5vcHRpb25DbGFzc2VzKXx8bnVsbCx0aGlzLmV4dHJhTWFya3VwPShudWxsPT1hP3ZvaWQgMDphLmV4dHJhTWFya3VwKXx8bnVsbCx0aGlzLmRlc2NyaXB0aW9uQ2xhc3Nlcz0obnVsbD09YT92b2lkIDA6YS5kZXNjcmlwdGlvbkNsYXNzZXMpfHxudWxsLHRoaXMuaWNvbkNsYXNzZXM9KG51bGw9PWE/dm9pZCAwOmEuaWNvbkNsYXNzZXMpfHxudWxsLHRoaXMuaXNBZGRUYWdPbkVudGVyPW51bGw9PT0obz1udWxsPT1hP3ZvaWQgMDphLmlzQWRkVGFnT25FbnRlcil8fHZvaWQgMD09PW98fG8sdGhpcy5hbmltYXRpb25JblByb2Nlc3M9ITEsdGhpcy5zZWxlY3RPcHRpb25zPVtdLHRoaXMucmVtb3RlT3B0aW9ucz1bXSx0aGlzLnRhZ3NJbnB1dEhlbHBlcj1udWxsLHRoaXMuaW5pdCgpfXdyYXBwZXJDbGljayhlKXtlLnRhcmdldC5jbG9zZXN0KFwiW2RhdGEtc2VsZWN0LWRyb3Bkb3duXVwiKXx8ZS50YXJnZXQuY2xvc2VzdChcIltkYXRhLXRhZy12YWx1ZV1cIil8fHRoaXMudGFnc0lucHV0LmZvY3VzKCl9dG9nZ2xlQ2xpY2soKXtpZih0aGlzLmlzRGlzYWJsZWQpcmV0dXJuITE7dGhpcy50b2dnbGVGbigpfXRhZ3NJbnB1dEZvY3VzKCl7dGhpcy5pc09wZW5lZHx8dGhpcy5vcGVuKCl9dGFnc0lucHV0SW5wdXQoKXt0aGlzLmNhbGN1bGF0ZUlucHV0V2lkdGgoKX10YWdzSW5wdXRJbnB1dFNlY29uZChlKXt0aGlzLnNlYXJjaE9wdGlvbnMoZS50YXJnZXQudmFsdWUpfXRhZ3NJbnB1dEtleWRvd24oZSl7aWYoXCJFbnRlclwiPT09ZS5rZXkmJnRoaXMuaXNBZGRUYWdPbkVudGVyKXtjb25zdCB0PWUudGFyZ2V0LnZhbHVlO2lmKHRoaXMuc2VsZWN0T3B0aW9ucy5maW5kKChlPT5lLnZhbD09PXQpKSlyZXR1cm4hMTt0aGlzLmFkZFNlbGVjdE9wdGlvbih0LHQpLHRoaXMuYnVpbGRPcHRpb24odCx0KSx0aGlzLmRyb3Bkb3duLnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLXZhbHVlPVwiJHt0fVwiXWApLmNsaWNrKCksdGhpcy5yZXNldFRhZ3NJbnB1dEZpZWxkKCl9fXNlYXJjaElucHV0KGUpe2NvbnN0IHQ9ZS50YXJnZXQudmFsdWU7dGhpcy5hcGlVcmw/dGhpcy5yZW1vdGVTZWFyY2godCk6dGhpcy5zZWFyY2hPcHRpb25zKHQpfXNldFZhbHVlKGUpe2lmKHRoaXMudmFsdWU9ZSx0aGlzLmNsZWFyU2VsZWN0aW9ucygpLEFycmF5LmlzQXJyYXkoZSkpaWYoXCJ0YWdzXCI9PT10aGlzLm1vZGUpe3RoaXMudW5zZWxlY3RNdWx0aXBsZUl0ZW1zKCksdGhpcy5zZWxlY3RNdWx0aXBsZUl0ZW1zKCksdGhpcy5zZWxlY3RlZEl0ZW1zPVtdO3RoaXMud3JhcHBlci5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtdGFnLXZhbHVlXVwiKS5mb3JFYWNoKChlPT5lLnJlbW92ZSgpKSksdGhpcy5zZXRUYWdzSXRlbXMoKSx0aGlzLnJlYXNzaWduVGFnc0lucHV0UGxhY2Vob2xkZXIodGhpcy52YWx1ZS5sZW5ndGg/XCJcIjp0aGlzLnBsYWNlaG9sZGVyKX1lbHNlIHRoaXMudG9nZ2xlVGV4dFdyYXBwZXIuaW5uZXJIVE1MPXRoaXMudmFsdWUubGVuZ3RoP3RoaXMuc3RyaW5nRnJvbVZhbHVlKCk6dGhpcy5wbGFjZWhvbGRlcix0aGlzLnVuc2VsZWN0TXVsdGlwbGVJdGVtcygpLHRoaXMuc2VsZWN0TXVsdGlwbGVJdGVtcygpO2Vsc2UgdGhpcy5zZXRUb2dnbGVUaXRsZSgpLHRoaXMudG9nZ2xlLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pY29uXVwiKSYmdGhpcy5zZXRUb2dnbGVJY29uKCksdGhpcy50b2dnbGUucXVlcnlTZWxlY3RvcihcIltkYXRhLXRpdGxlXVwiKSYmdGhpcy5zZXRUb2dnbGVUaXRsZSgpLHRoaXMuc2VsZWN0U2luZ2xlSXRlbSgpfWluaXQoKXt0aGlzLmNyZWF0ZUNvbGxlY3Rpb24od2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24sdGhpcyksdGhpcy5idWlsZCgpfWJ1aWxkKCl7aWYodGhpcy5lbC5zdHlsZS5kaXNwbGF5PVwibm9uZVwiLHRoaXMuZWwuY2hpbGRyZW4mJkFycmF5LmZyb20odGhpcy5lbC5jaGlsZHJlbikuZmlsdGVyKChlPT50aGlzLm9wdGlvbkFsbG93RW1wdHlPcHRpb258fCF0aGlzLm9wdGlvbkFsbG93RW1wdHlPcHRpb24mJmUudmFsdWUmJlwiXCIhPT1lLnZhbHVlKSkuZm9yRWFjaCgoZT0+e2NvbnN0IHQ9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXNlbGVjdC1vcHRpb25cIik7dGhpcy5zZWxlY3RPcHRpb25zPVsuLi50aGlzLnNlbGVjdE9wdGlvbnMse3RpdGxlOmUudGV4dENvbnRlbnQsdmFsOmUudmFsdWUsZGlzYWJsZWQ6ZS5kaXNhYmxlZCxvcHRpb25zOlwidW5kZWZpbmVkXCIhPT10P0pTT04ucGFyc2UodCk6bnVsbH1dfSkpLHRoaXMuaXNNdWx0aXBsZSl7Y29uc3QgZT1BcnJheS5mcm9tKHRoaXMuZWwuY2hpbGRyZW4pLmZpbHRlcigoZT0+ZS5zZWxlY3RlZCkpO2lmKGUpe2NvbnN0IHQ9W107ZS5mb3JFYWNoKChlPT57dC5wdXNoKGUudmFsdWUpfSkpLHRoaXMudmFsdWU9dH19dGhpcy5idWlsZFdyYXBwZXIoKSxcInRhZ3NcIj09PXRoaXMubW9kZT90aGlzLmJ1aWxkVGFncygpOnRoaXMuYnVpbGRUb2dnbGUoKSx0aGlzLmJ1aWxkRHJvcGRvd24oKSx0aGlzLmV4dHJhTWFya3VwJiZ0aGlzLmJ1aWxkRXh0cmFNYXJrdXAoKX1idWlsZFdyYXBwZXIoKXt0aGlzLndyYXBwZXI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSx0aGlzLndyYXBwZXIuY2xhc3NMaXN0LmFkZChcImFkdmFuY2Utc2VsZWN0XCIsXCJyZWxhdGl2ZVwiKSxcInRhZ3NcIj09PXRoaXMubW9kZSYmKHRoaXMub25XcmFwcGVyQ2xpY2tMaXN0ZW5lcj1lPT50aGlzLndyYXBwZXJDbGljayhlKSx0aGlzLndyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsdGhpcy5vbldyYXBwZXJDbGlja0xpc3RlbmVyKSksdGhpcy53cmFwcGVyQ2xhc3NlcyYmKDAsby5jbGFzc1RvQ2xhc3NMaXN0KSh0aGlzLndyYXBwZXJDbGFzc2VzLHRoaXMud3JhcHBlciksdGhpcy5lbC5iZWZvcmUodGhpcy53cmFwcGVyKSx0aGlzLndyYXBwZXIuYXBwZW5kKHRoaXMuZWwpfWJ1aWxkRXh0cmFNYXJrdXAoKXtjb25zdCBlPWU9Pntjb25zdCB0PSgwLG8uaHRtbFRvRWxlbWVudCkoZSk7cmV0dXJuIHRoaXMud3JhcHBlci5hcHBlbmQodCksdH0sdD1lPT57ZS5jbGFzc0xpc3QuY29udGFpbnMoXCItLXByZXZlbnQtY2xpY2tcIil8fGUuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsKGU9PntlLnN0b3BQcm9wYWdhdGlvbigpLHRoaXMudG9nZ2xlRm4oKX0pKX07aWYoQXJyYXkuaXNBcnJheSh0aGlzLmV4dHJhTWFya3VwKSl0aGlzLmV4dHJhTWFya3VwLmZvckVhY2goKGk9Pntjb25zdCBzPWUoaSk7dChzKX0pKTtlbHNle2NvbnN0IGk9ZSh0aGlzLmV4dHJhTWFya3VwKTt0KGkpfX1idWlsZFRvZ2dsZSgpe3ZhciBlLHQ7bGV0IGksczt0aGlzLnRvZ2dsZVRleHRXcmFwcGVyPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpLHRoaXMudG9nZ2xlVGV4dFdyYXBwZXIuY2xhc3NMaXN0LmFkZChcInRydW5jYXRlXCIpLHRoaXMudG9nZ2xlPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy50b2dnbGVUYWd8fFwiPGRpdj48L2Rpdj5cIiksaT10aGlzLnRvZ2dsZS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtaWNvbl1cIikscz10aGlzLnRvZ2dsZS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtdGl0bGVdXCIpLCF0aGlzLmlzTXVsdGlwbGUmJmkmJnRoaXMuc2V0VG9nZ2xlSWNvbigpLCF0aGlzLmlzTXVsdGlwbGUmJnMmJnRoaXMuc2V0VG9nZ2xlVGl0bGUoKSx0aGlzLmlzTXVsdGlwbGU/dGhpcy50b2dnbGVUZXh0V3JhcHBlci5pbm5lckhUTUw9dGhpcy52YWx1ZS5sZW5ndGg/dGhpcy5zdHJpbmdGcm9tVmFsdWUoKTp0aGlzLnBsYWNlaG9sZGVyOnRoaXMudG9nZ2xlVGV4dFdyYXBwZXIuaW5uZXJIVE1MPShudWxsPT09KGU9dGhpcy5nZXRJdGVtQnlWYWx1ZSh0aGlzLnZhbHVlKSl8fHZvaWQgMD09PWU/dm9pZCAwOmUudGl0bGUpfHx0aGlzLnBsYWNlaG9sZGVyLHN8fHRoaXMudG9nZ2xlLmFwcGVuZCh0aGlzLnRvZ2dsZVRleHRXcmFwcGVyKSx0aGlzLnRvZ2dsZUNsYXNzZXMmJigwLG8uY2xhc3NUb0NsYXNzTGlzdCkodGhpcy50b2dnbGVDbGFzc2VzLHRoaXMudG9nZ2xlKSx0aGlzLmlzRGlzYWJsZWQmJnRoaXMudG9nZ2xlLmNsYXNzTGlzdC5hZGQoXCJkaXNhYmxlZFwiKSx0aGlzLndyYXBwZXImJnRoaXMud3JhcHBlci5hcHBlbmQodGhpcy50b2dnbGUpLChudWxsPT09KHQ9dGhpcy50b2dnbGUpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmFyaWFFeHBhbmRlZCkmJih0aGlzLmlzT3BlbmVkP3RoaXMudG9nZ2xlLmFyaWFFeHBhbmRlZD1cInRydWVcIjp0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJmYWxzZVwiKSx0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lcj0oKT0+dGhpcy50b2dnbGVDbGljaygpLHRoaXMudG9nZ2xlLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLHRoaXMub25Ub2dnbGVDbGlja0xpc3RlbmVyKX1zZXRUb2dnbGVJY29uKCl7dmFyIGU7Y29uc3QgdD10aGlzLmdldEl0ZW1CeVZhbHVlKHRoaXMudmFsdWUpLGk9dGhpcy50b2dnbGUucXVlcnlTZWxlY3RvcihcIltkYXRhLWljb25dXCIpO2lmKGkpe2kuaW5uZXJIVE1MPVwiXCI7Y29uc3Qgcz0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMuYXBpVXJsJiZ0aGlzLmFwaUljb25UYWc/dGhpcy5hcGlJY29uVGFnfHxcIlwiOihudWxsPT09KGU9bnVsbD09dD92b2lkIDA6dC5vcHRpb25zKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5pY29uKXx8XCJcIik7dGhpcy52YWx1ZSYmdGhpcy5hcGlVcmwmJnRoaXMuYXBpSWNvblRhZyYmdFt0aGlzLmFwaUZpZWxkc01hcC5pY29uXSYmKHMuc3JjPXRbdGhpcy5hcGlGaWVsZHNNYXAuaWNvbl18fFwiXCIpLGkuYXBwZW5kKHMpLHM/aS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpOmkuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKX19c2V0VG9nZ2xlVGl0bGUoKXt2YXIgZSx0O2NvbnN0IGk9dGhpcy50b2dnbGUucXVlcnlTZWxlY3RvcihcIltkYXRhLXRpdGxlXVwiKTtpPyhpLmlubmVySFRNTD0obnVsbD09PShlPXRoaXMuZ2V0SXRlbUJ5VmFsdWUodGhpcy52YWx1ZSkpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLnRpdGxlKXx8dGhpcy5wbGFjZWhvbGRlcixpLmNsYXNzTGlzdC5hZGQoXCJ0cnVuY2F0ZVwiKSx0aGlzLnRvZ2dsZS5hcHBlbmQoaSkpOnRoaXMudG9nZ2xlLmlubmVyVGV4dD0obnVsbD09PSh0PXRoaXMuZ2V0SXRlbUJ5VmFsdWUodGhpcy52YWx1ZSkpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LnRpdGxlKXx8dGhpcy5wbGFjZWhvbGRlcn1idWlsZFRhZ3MoKXt0aGlzLmlzRGlzYWJsZWQmJnRoaXMud3JhcHBlci5jbGFzc0xpc3QuYWRkKFwiZGlzYWJsZWRcIiksdGhpcy5idWlsZFRhZ3NJbnB1dCgpLHRoaXMuc2V0VGFnc0l0ZW1zKCl9cmVhc3NpZ25UYWdzSW5wdXRQbGFjZWhvbGRlcihlKXt0aGlzLnRhZ3NJbnB1dC5wbGFjZWhvbGRlcj1lLHRoaXMudGFnc0lucHV0SGVscGVyLmlubmVySFRNTD1lLHRoaXMuY2FsY3VsYXRlSW5wdXRXaWR0aCgpfWJ1aWxkVGFnc0l0ZW0oZSl7dmFyIHQsaSxzLG47Y29uc3QgbD10aGlzLmdldEl0ZW1CeVZhbHVlKGUpO2xldCByLGEsYyxkO2NvbnN0IGg9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtpZihoLnNldEF0dHJpYnV0ZShcImRhdGEtdGFnLXZhbHVlXCIsZSksdGhpcy50YWdzSXRlbUNsYXNzZXMmJigwLG8uY2xhc3NUb0NsYXNzTGlzdCkodGhpcy50YWdzSXRlbUNsYXNzZXMsaCksdGhpcy50YWdzSXRlbVRlbXBsYXRlJiYocj0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMudGFnc0l0ZW1UZW1wbGF0ZSksaC5hcHBlbmQocikpLChudWxsPT09KHQ9bnVsbD09bD92b2lkIDA6bC5vcHRpb25zKXx8dm9pZCAwPT09dD92b2lkIDA6dC5pY29uKXx8dGhpcy5hcGlJY29uVGFnKXtjb25zdCBlPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy5hcGlVcmwmJnRoaXMuYXBpSWNvblRhZz90aGlzLmFwaUljb25UYWc6bnVsbD09PShpPW51bGw9PWw/dm9pZCAwOmwub3B0aW9ucyl8fHZvaWQgMD09PWk/dm9pZCAwOmkuaWNvbik7dGhpcy5hcGlVcmwmJnRoaXMuYXBpSWNvblRhZyYmbFt0aGlzLmFwaUZpZWxkc01hcC5pY29uXSYmKGUuc3JjPWxbdGhpcy5hcGlGaWVsZHNNYXAuaWNvbl18fFwiXCIpLGQ9cj9yLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pY29uXVwiKTpkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKSxkLmFwcGVuZChlKSxyfHxoLmFwcGVuZChkKX0hcnx8IXIucXVlcnlTZWxlY3RvcihcIltkYXRhLWljb25dXCIpfHwobnVsbD09PShzPW51bGw9PWw/dm9pZCAwOmwub3B0aW9ucyl8fHZvaWQgMD09PXM/dm9pZCAwOnMuaWNvbil8fHRoaXMuYXBpVXJsfHx0aGlzLmFwaUljb25UYWd8fGxbbnVsbD09PShuPXRoaXMuYXBpRmllbGRzTWFwKXx8dm9pZCAwPT09bj92b2lkIDA6bi5pY29uXXx8ci5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtaWNvbl1cIikuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKSxhPXI/ci5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtdGl0bGVdXCIpOmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpLGEudGV4dENvbnRlbnQ9bC50aXRsZXx8XCJcIixyfHxoLmFwcGVuZChhKSxyP2M9ci5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtcmVtb3ZlXVwiKTooYz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKSxjLnRleHRDb250ZW50PVwiWFwiLGguYXBwZW5kKGMpKSxjLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCgoKT0+e3RoaXMudmFsdWU9dGhpcy52YWx1ZS5maWx0ZXIoKHQ9PnQhPT1lKSksdGhpcy5zZWxlY3RlZEl0ZW1zPXRoaXMuc2VsZWN0ZWRJdGVtcy5maWx0ZXIoKHQ9PnQhPT1lKSksdGhpcy52YWx1ZS5sZW5ndGh8fHRoaXMucmVhc3NpZ25UYWdzSW5wdXRQbGFjZWhvbGRlcih0aGlzLnBsYWNlaG9sZGVyKSx0aGlzLnVuc2VsZWN0TXVsdGlwbGVJdGVtcygpLHRoaXMuc2VsZWN0TXVsdGlwbGVJdGVtcygpLGgucmVtb3ZlKCksdGhpcy50cmlnZ2VyQ2hhbmdlRXZlbnRGb3JOYXRpdmVTZWxlY3QoKX0pKSx0aGlzLndyYXBwZXIuYXBwZW5kKGgpfWdldEl0ZW1CeVZhbHVlKGUpe3JldHVybiB0aGlzLmFwaVVybD90aGlzLnJlbW90ZU9wdGlvbnMuZmluZCgodD0+YCR7dFt0aGlzLmFwaUZpZWxkc01hcC52YWxdfWA9PT1lfHx0W3RoaXMuYXBpRmllbGRzTWFwLnRpdGxlXT09PWUpKTp0aGlzLnNlbGVjdE9wdGlvbnMuZmluZCgodD0+dC52YWw9PT1lKSl9c2V0VGFnc0l0ZW1zKCl7dGhpcy52YWx1ZSYmdGhpcy52YWx1ZS5mb3JFYWNoKChlPT57dGhpcy5zZWxlY3RlZEl0ZW1zLmluY2x1ZGVzKGUpfHx0aGlzLmJ1aWxkVGFnc0l0ZW0oZSksdGhpcy5zZWxlY3RlZEl0ZW1zPXRoaXMuc2VsZWN0ZWRJdGVtcy5pbmNsdWRlcyhlKT90aGlzLnNlbGVjdGVkSXRlbXM6Wy4uLnRoaXMuc2VsZWN0ZWRJdGVtcyxlXX0pKSx0aGlzLmlzT3BlbmVkJiZ0aGlzLmZsb2F0aW5nVUlJbnN0YW5jZSYmdGhpcy5mbG9hdGluZ1VJSW5zdGFuY2UudXBkYXRlKCl9YnVpbGRUYWdzSW5wdXQoKXt0aGlzLnRhZ3NJbnB1dD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIiksdGhpcy50YWdzSW5wdXRJZCYmKHRoaXMudGFnc0lucHV0LmlkPXRoaXMudGFnc0lucHV0SWQpLHRoaXMudGFnc0lucHV0Q2xhc3NlcyYmKDAsby5jbGFzc1RvQ2xhc3NMaXN0KSh0aGlzLnRhZ3NJbnB1dENsYXNzZXMsdGhpcy50YWdzSW5wdXQpLHRoaXMub25UYWdzSW5wdXRGb2N1c0xpc3RlbmVyPSgpPT50aGlzLnRhZ3NJbnB1dEZvY3VzKCksdGhpcy5vblRhZ3NJbnB1dElucHV0TGlzdGVuZXI9KCk9PnRoaXMudGFnc0lucHV0SW5wdXQoKSx0aGlzLm9uVGFnc0lucHV0SW5wdXRTZWNvbmRMaXN0ZW5lcj0oMCxvLmRlYm91bmNlKSgoZT0+dGhpcy50YWdzSW5wdXRJbnB1dFNlY29uZChlKSkpLHRoaXMub25UYWdzSW5wdXRLZXlkb3duTGlzdGVuZXI9ZT0+dGhpcy50YWdzSW5wdXRLZXlkb3duKGUpLHRoaXMudGFnc0lucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c1wiLHRoaXMub25UYWdzSW5wdXRGb2N1c0xpc3RlbmVyKSx0aGlzLnRhZ3NJbnB1dC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uVGFnc0lucHV0SW5wdXRMaXN0ZW5lciksdGhpcy50YWdzSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vblRhZ3NJbnB1dElucHV0U2Vjb25kTGlzdGVuZXIpLHRoaXMudGFnc0lucHV0LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsdGhpcy5vblRhZ3NJbnB1dEtleWRvd25MaXN0ZW5lciksdGhpcy53cmFwcGVyLmFwcGVuZCh0aGlzLnRhZ3NJbnB1dCksc2V0VGltZW91dCgoKCk9Pnt0aGlzLmFkanVzdElucHV0V2lkdGgoKSx0aGlzLnJlYXNzaWduVGFnc0lucHV0UGxhY2Vob2xkZXIodGhpcy52YWx1ZS5sZW5ndGg/XCJcIjp0aGlzLnBsYWNlaG9sZGVyKX0pKX1idWlsZERyb3Bkb3duKCl7dGhpcy5kcm9wZG93bj0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMuZHJvcGRvd25UYWd8fFwiPGRpdj48L2Rpdj5cIiksdGhpcy5kcm9wZG93bi5zZXRBdHRyaWJ1dGUoXCJkYXRhLXNlbGVjdC1kcm9wZG93blwiLFwiXCIpLFwicGFyZW50XCI9PT10aGlzLmRyb3Bkb3duU2NvcGUmJih0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5hZGQoXCJhYnNvbHV0ZVwiKSx0aGlzLmRyb3Bkb3duVmVydGljYWxGaXhlZFBsYWNlbWVudHx8dGhpcy5kcm9wZG93bi5jbGFzc0xpc3QuYWRkKFwidG9wLWZ1bGxcIikpLHRoaXMuZHJvcGRvd24ucm9sZT1cImxpc3Rib3hcIix0aGlzLmRyb3Bkb3duLnRhYkluZGV4PS0xLHRoaXMuZHJvcGRvd24uYXJpYU9yaWVudGF0aW9uPVwidmVydGljYWxcIix0aGlzLmlzT3BlbmVkfHx0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5hZGQoXCJoaWRkZW5cIiksdGhpcy5kcm9wZG93bkNsYXNzZXMmJigwLG8uY2xhc3NUb0NsYXNzTGlzdCkodGhpcy5kcm9wZG93bkNsYXNzZXMsdGhpcy5kcm9wZG93biksdGhpcy53cmFwcGVyJiZ0aGlzLndyYXBwZXIuYXBwZW5kKHRoaXMuZHJvcGRvd24pLHRoaXMuZHJvcGRvd24mJnRoaXMuaGFzU2VhcmNoJiZ0aGlzLmJ1aWxkU2VhcmNoKCksdGhpcy5zZWxlY3RPcHRpb25zJiZ0aGlzLnNlbGVjdE9wdGlvbnMuZm9yRWFjaCgoKGUsdCk9PnRoaXMuYnVpbGRPcHRpb24oZS50aXRsZSxlLnZhbCxlLmRpc2FibGVkLGUuc2VsZWN0ZWQsZS5vcHRpb25zLGAke3R9YCkpKSx0aGlzLmFwaVVybCYmdGhpcy5vcHRpb25zRnJvbVJlbW90ZURhdGEoKSxcIndpbmRvd1wiPT09dGhpcy5kcm9wZG93blNjb3BlJiZ0aGlzLmJ1aWxkRmxvYXRpbmdVSSgpfWJ1aWxkRmxvYXRpbmdVSSgpe2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5kcm9wZG93bik7Y29uc3QgZT1cInRhZ3NcIj09PXRoaXMubW9kZT90aGlzLndyYXBwZXI6dGhpcy50b2dnbGUsdD17cGxhY2VtZW50OmEuUE9TSVRJT05TW3RoaXMuZHJvcGRvd25QbGFjZW1lbnRdfHxcImJvdHRvbVwiLHN0cmF0ZWd5OlwiZml4ZWRcIixtaWRkbGV3YXJlOlsoMCxsLm9mZnNldCkoMCldfSxpPSgpPT57KDAsbC5jb21wdXRlUG9zaXRpb24pKGUsdGhpcy5kcm9wZG93bix0KS50aGVuKCgoe3g6ZSx5OnQscGxhY2VtZW50Oml9KT0+e09iamVjdC5hc3NpZ24odGhpcy5kcm9wZG93bi5zdHlsZSx7cG9zaXRpb246XCJmaXhlZFwiLGxlZnQ6YCR7ZX1weGAsdG9wOmAke3R9cHhgfSksdGhpcy5kcm9wZG93bi5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBsYWNlbWVudFwiLGkpfSkpfTtpKCk7Y29uc3Qgcz0oMCxsLmF1dG9VcGRhdGUpKGUsdGhpcy5kcm9wZG93bixpKTt0aGlzLmZsb2F0aW5nVUlJbnN0YW5jZT17dXBkYXRlOmksZGVzdHJveTpzfX11cGRhdGVEcm9wZG93bldpZHRoKCl7Y29uc3QgZT1cInRhZ3NcIj09PXRoaXMubW9kZT90aGlzLndyYXBwZXI6dGhpcy50b2dnbGU7dGhpcy5kcm9wZG93bi5zdHlsZS53aWR0aD1gJHtlLmNsaWVudFdpZHRofXB4YH1idWlsZFNlYXJjaCgpe2xldCBlO3RoaXMuc2VhcmNoV3JhcHBlcj0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMuc2VhcmNoV3JhcHBlclRlbXBsYXRlfHxcIjxkaXY+PC9kaXY+XCIpLHRoaXMuc2VhcmNoV3JhcHBlckNsYXNzZXMmJigwLG8uY2xhc3NUb0NsYXNzTGlzdCkodGhpcy5zZWFyY2hXcmFwcGVyQ2xhc3Nlcyx0aGlzLnNlYXJjaFdyYXBwZXIpLGU9dGhpcy5zZWFyY2hXcmFwcGVyLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pbnB1dF1cIik7Y29uc3QgdD0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMuc2VhcmNoVGVtcGxhdGV8fCc8aW5wdXQgdHlwZT1cInRleHRcIj4nKTt0aGlzLnNlYXJjaD1cIklOUFVUXCI9PT10LnRhZ05hbWU/dDp0LnF1ZXJ5U2VsZWN0b3IoXCI6c2NvcGUgaW5wdXRcIiksdGhpcy5zZWFyY2gucGxhY2Vob2xkZXI9dGhpcy5zZWFyY2hQbGFjZWhvbGRlcix0aGlzLnNlYXJjaENsYXNzZXMmJigwLG8uY2xhc3NUb0NsYXNzTGlzdCkodGhpcy5zZWFyY2hDbGFzc2VzLHRoaXMuc2VhcmNoKSx0aGlzLnNlYXJjaElkJiYodGhpcy5zZWFyY2guaWQ9dGhpcy5zZWFyY2hJZCksdGhpcy5vblNlYXJjaElucHV0TGlzdGVuZXI9KDAsby5kZWJvdW5jZSkoKGU9PnRoaXMuc2VhcmNoSW5wdXQoZSkpKSx0aGlzLnNlYXJjaC5hZGRFdmVudExpc3RlbmVyKFwiaW5wdXRcIix0aGlzLm9uU2VhcmNoSW5wdXRMaXN0ZW5lciksZT9lLmFwcGVuZCh0KTp0aGlzLnNlYXJjaFdyYXBwZXIuYXBwZW5kKHQpLHRoaXMuZHJvcGRvd24uYXBwZW5kKHRoaXMuc2VhcmNoV3JhcHBlcil9YnVpbGRPcHRpb24oZSx0LGk9ITEscz0hMSxuLGw9XCIxXCIscil7dmFyIGE7bGV0IGM9bnVsbCxkPW51bGwsaD1udWxsLHU9bnVsbDtjb25zdCBwPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy5vcHRpb25UYWd8fFwiPGRpdj48L2Rpdj5cIik7aWYocC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXZhbHVlXCIsdCkscC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXRpdGxlLXZhbHVlXCIsZSkscC5zZXRBdHRyaWJ1dGUoXCJ0YWJJbmRleFwiLGwpLHAuY2xhc3NMaXN0LmFkZChcImN1cnNvci1wb2ludGVyXCIpLHAuc2V0QXR0cmlidXRlKFwiZGF0YS1pZFwiLHJ8fGAke3RoaXMub3B0aW9uSWR9YCkscnx8dGhpcy5vcHRpb25JZCsrLGkmJnAuY2xhc3NMaXN0LmFkZChcImRpc2FibGVkXCIpLHMmJih0aGlzLmlzTXVsdGlwbGU/dGhpcy52YWx1ZT1bLi4udGhpcy52YWx1ZSx0XTp0aGlzLnZhbHVlPXQpLHRoaXMub3B0aW9uVGVtcGxhdGUmJihjPSgwLG8uaHRtbFRvRWxlbWVudCkodGhpcy5vcHRpb25UZW1wbGF0ZSkscC5hcHBlbmQoYykpLGM/KGQ9Yy5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtdGl0bGVdXCIpLGQudGV4dENvbnRlbnQ9ZXx8XCJcIik6cC50ZXh0Q29udGVudD1lfHxcIlwiLG4pe2lmKG4uaWNvbil7Y29uc3QgdD0oMCxvLmh0bWxUb0VsZW1lbnQpKG51bGwhPT0oYT10aGlzLmFwaUljb25UYWcpJiZ2b2lkIDAhPT1hP2E6bi5pY29uKTtpZih0LmNsYXNzTGlzdC5hZGQoXCJtYXgtdy1mdWxsXCIpLHRoaXMuYXBpVXJsJiYodC5zZXRBdHRyaWJ1dGUoXCJhbHRcIixlKSx0LnNldEF0dHJpYnV0ZShcInNyY1wiLG4uaWNvbikpLGMpaD1jLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pY29uXVwiKSxoLmFwcGVuZCh0KTtlbHNle2NvbnN0IGU9KDAsby5odG1sVG9FbGVtZW50KShcIjxkaXY+PC9kaXY+XCIpO3RoaXMuaWNvbkNsYXNzZXMmJigwLG8uY2xhc3NUb0NsYXNzTGlzdCkodGhpcy5pY29uQ2xhc3NlcyxlKSxlLmFwcGVuZCh0KSxwLmFwcGVuZChlKX19aWYobi5kZXNjcmlwdGlvbilpZihjKXU9Yy5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtZGVzY3JpcHRpb25dXCIpLHUmJnUuYXBwZW5kKG4uZGVzY3JpcHRpb24pO2Vsc2V7Y29uc3QgZT0oMCxvLmh0bWxUb0VsZW1lbnQpKFwiPGRpdj48L2Rpdj5cIik7ZS50ZXh0Q29udGVudD1uLmRlc2NyaXB0aW9uLHRoaXMuZGVzY3JpcHRpb25DbGFzc2VzJiYoMCxvLmNsYXNzVG9DbGFzc0xpc3QpKHRoaXMuZGVzY3JpcHRpb25DbGFzc2VzLGUpLHAuYXBwZW5kKGUpfX1jJiZjLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1pY29uXVwiKSYmIW4mJiEobnVsbD09bj92b2lkIDA6bi5pY29uKSYmYy5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtaWNvbl1cIikuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKSx0aGlzLnZhbHVlJiYodGhpcy5pc011bHRpcGxlP3RoaXMudmFsdWUuaW5jbHVkZXModCk6dGhpcy52YWx1ZT09PXQpJiZwLmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKSxpfHxwLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCgoKT0+dGhpcy5vblNlbGVjdE9wdGlvbih0KSkpLHRoaXMub3B0aW9uQ2xhc3NlcyYmKDAsby5jbGFzc1RvQ2xhc3NMaXN0KSh0aGlzLm9wdGlvbkNsYXNzZXMscCksdGhpcy5kcm9wZG93biYmdGhpcy5kcm9wZG93bi5hcHBlbmQocCkscyYmdGhpcy5zZXROZXdWYWx1ZSgpfWJ1aWxkT3B0aW9uRnJvbVJlbW90ZURhdGEoZSx0LGk9ITEscz0hMSxuPVwiMVwiLG8sbCl7bj90aGlzLmJ1aWxkT3B0aW9uKGUsdCxpLHMsbCxuLG8pOmFsZXJ0KFwiSUQgcGFyYW1ldGVyIGlzIHJlcXVpcmVkIGZvciBnZW5lcmF0aW5nIHJlbW90ZSBvcHRpb25zISBQbGVhc2UgY2hlY2sgeW91ciBBUEkgZW5kcG9pbnQgaGF2ZSBpdC5cIil9YnVpbGRPcHRpb25zRnJvbVJlbW90ZURhdGEoZSl7ZS5mb3JFYWNoKCgoZSx0KT0+e2xldCBpPW51bGwscz1cIlwiLG49XCJcIjtjb25zdCBvPXtpZDpcIlwiLHZhbDpcIlwiLHRpdGxlOlwiXCIsaWNvbjpudWxsLGRlc2NyaXB0aW9uOm51bGwscmVzdDp7fX07T2JqZWN0LmtleXMoZSkuZm9yRWFjaCgodD0+e3ZhciBsO2VbdGhpcy5hcGlGaWVsZHNNYXAuaWRdJiYoaT1lW3RoaXMuYXBpRmllbGRzTWFwLmlkXSksKGVbdGhpcy5hcGlGaWVsZHNNYXAudmFsXXx8ZVt0aGlzLmFwaUZpZWxkc01hcC50aXRsZV0pJiYobj1lW3RoaXMuYXBpRmllbGRzTWFwLnZhbF18fGVbdGhpcy5hcGlGaWVsZHNNYXAudGl0bGVdKSxlW3RoaXMuYXBpRmllbGRzTWFwLnRpdGxlXSYmKHM9ZVt0aGlzLmFwaUZpZWxkc01hcC50aXRsZV0pLGVbdGhpcy5hcGlGaWVsZHNNYXAuaWNvbl0mJihvLmljb249ZVt0aGlzLmFwaUZpZWxkc01hcC5pY29uXSksZVtudWxsPT09KGw9dGhpcy5hcGlGaWVsZHNNYXApfHx2b2lkIDA9PT1sP3ZvaWQgMDpsLmRlc2NyaXB0aW9uXSYmKG8uZGVzY3JpcHRpb249ZVt0aGlzLmFwaUZpZWxkc01hcC5kZXNjcmlwdGlvbl0pLG8ucmVzdFt0XT1lW3RdfSkpLHRoaXMuYnVpbGRPcmlnaW5hbE9wdGlvbihzLGAke259YCxpLCExLCExLG8pLHRoaXMuYnVpbGRPcHRpb25Gcm9tUmVtb3RlRGF0YShzLGAke259YCwhMSwhMSxgJHt0fWAsaSxvKX0pKSx0aGlzLnNvcnRFbGVtZW50cyh0aGlzLmVsLFwib3B0aW9uXCIpLHRoaXMuc29ydEVsZW1lbnRzKHRoaXMuZHJvcGRvd24sXCJbZGF0YS12YWx1ZV1cIil9b3B0aW9uc0Zyb21SZW1vdGVEYXRhKCl7cmV0dXJuIHModGhpcyxhcmd1bWVudHMsdm9pZCAwLChmdW5jdGlvbiooZT1cIlwiKXtjb25zdCB0PXlpZWxkIHRoaXMuYXBpUmVxdWVzdChlKTt0aGlzLnJlbW90ZU9wdGlvbnM9dCx0Lmxlbmd0aD90aGlzLmJ1aWxkT3B0aW9uc0Zyb21SZW1vdGVEYXRhKHRoaXMucmVtb3RlT3B0aW9ucyk6Y29uc29sZS5sb2coXCJUaGVyZSBpcyBubyBkYXRhIHdlcmUgcmVzcG9uZGVkIVwiKX0pKX1hcGlSZXF1ZXN0KCl7cmV0dXJuIHModGhpcyxhcmd1bWVudHMsdm9pZCAwLChmdW5jdGlvbiooZT1cIlwiKXt0cnl7bGV0IHQ9dGhpcy5hcGlVcmw7Y29uc3QgaT10aGlzLmFwaVNlYXJjaFF1ZXJ5S2V5P2Ake3RoaXMuYXBpU2VhcmNoUXVlcnlLZXl9PSR7ZS50b0xvd2VyQ2FzZSgpfWA6bnVsbCxzPWAke3RoaXMuYXBpUXVlcnl9YCxuPXRoaXMuYXBpT3B0aW9uc3x8e307aSYmKHQrPWA/JHtpfWApLHRoaXMuYXBpUXVlcnkmJih0Kz1gJHtpP1wiJlwiOlwiP1wifSR7c31gKTtjb25zdCBvPXlpZWxkIGZldGNoKHQsbiksbD15aWVsZCBvLmpzb24oKTtyZXR1cm4gdGhpcy5hcGlEYXRhUGFydD9sW3RoaXMuYXBpRGF0YVBhcnRdOmx9Y2F0Y2goZSl7Y29uc29sZS5lcnJvcihlKX19KSl9c29ydEVsZW1lbnRzKGUsdCl7Y29uc3QgaT1BcnJheS5mcm9tKGUucXVlcnlTZWxlY3RvckFsbCh0KSk7aS5zb3J0KCgoZSx0KT0+e2NvbnN0IGk9ZS5jbGFzc0xpc3QuY29udGFpbnMoXCJzZWxlY3RlZFwiKXx8ZS5oYXNBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSxzPXQuY2xhc3NMaXN0LmNvbnRhaW5zKFwic2VsZWN0ZWRcIil8fHQuaGFzQXR0cmlidXRlKFwic2VsZWN0ZWRcIik7cmV0dXJuIGkmJiFzPy0xOiFpJiZzPzE6MH0pKSxpLmZvckVhY2goKHQ9PmUuYXBwZW5kQ2hpbGQodCkpKX1yZW1vdGVTZWFyY2goZSl7cmV0dXJuIHModGhpcyx2b2lkIDAsdm9pZCAwLChmdW5jdGlvbiooKXtpZihlLmxlbmd0aDw9dGhpcy5taW5TZWFyY2hMZW5ndGgpe2NvbnN0IGU9eWllbGQgdGhpcy5hcGlSZXF1ZXN0KFwiXCIpO3JldHVybiB0aGlzLnJlbW90ZU9wdGlvbnM9ZSxBcnJheS5mcm9tKHRoaXMuZHJvcGRvd24ucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXZhbHVlXVwiKSkuZm9yRWFjaCgoZT0+ZS5yZW1vdmUoKSkpLEFycmF5LmZyb20odGhpcy5lbC5xdWVyeVNlbGVjdG9yQWxsKFwib3B0aW9uW3ZhbHVlXVwiKSkuZm9yRWFjaCgoZT0+e2UucmVtb3ZlKCl9KSksZS5sZW5ndGg/dGhpcy5idWlsZE9wdGlvbnNGcm9tUmVtb3RlRGF0YShlKTpjb25zb2xlLmxvZyhcIk5vIGRhdGEgcmVzcG9uZGVkIVwiKSwhMX1jb25zdCB0PXlpZWxkIHRoaXMuYXBpUmVxdWVzdChlKTt0aGlzLnJlbW90ZU9wdGlvbnM9dDtsZXQgaT10Lm1hcCgoZT0+YCR7ZS5pZH1gKSkscz1udWxsO2NvbnN0IG49dGhpcy5kcm9wZG93bi5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtdmFsdWVdXCIpO3RoaXMuZWwucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXNlbGVjdC1vcHRpb25dXCIpLmZvckVhY2goKGU9Pnt2YXIgdDtjb25zdCBzPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1pZFwiKTtpLmluY2x1ZGVzKHMpfHwobnVsbD09PSh0PXRoaXMudmFsdWUpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmluY2x1ZGVzKGUudmFsdWUpKXx8dGhpcy5kZXN0cm95T3JpZ2luYWxPcHRpb24oZS52YWx1ZSl9KSksbi5mb3JFYWNoKChlPT57dmFyIHQ7Y29uc3Qgcz1lLmdldEF0dHJpYnV0ZShcImRhdGEtaWRcIik7aS5pbmNsdWRlcyhzKXx8KG51bGw9PT0odD10aGlzLnZhbHVlKXx8dm9pZCAwPT09dD92b2lkIDA6dC5pbmNsdWRlcyhlLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIikpKT9pPWkuZmlsdGVyKChlPT5lIT09cykpOnRoaXMuZGVzdHJveU9wdGlvbihlLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIikpfSkpLHM9dC5maWx0ZXIoKGU9PmkuaW5jbHVkZXMoYCR7ZS5pZH1gKSkpLHMubGVuZ3RoP3RoaXMuYnVpbGRPcHRpb25zRnJvbVJlbW90ZURhdGEocyk6Y29uc29sZS5sb2coXCJUaGVyZSBpcyBubyBkYXRhIHdlcmUgcmVzcG9uZGVkIVwiKX0pKX1kZXN0cm95T3B0aW9uKGUpe2NvbnN0IHQ9dGhpcy5kcm9wZG93bi5xdWVyeVNlbGVjdG9yKGBbZGF0YS12YWx1ZT1cIiR7ZX1cIl1gKTtpZighdClyZXR1cm4hMTt0LnJlbW92ZSgpfWJ1aWxkT3JpZ2luYWxPcHRpb24oZSx0LGkscyxuLGwpe2NvbnN0IHI9KDAsby5odG1sVG9FbGVtZW50KShcIjxvcHRpb24+PC9vcHRpb24+XCIpO3Iuc2V0QXR0cmlidXRlKFwidmFsdWVcIix0KSxzJiZyLnNldEF0dHJpYnV0ZShcImRpc2FibGVkXCIsXCJkaXNhYmxlZFwiKSxuJiZyLnNldEF0dHJpYnV0ZShcInNlbGVjdGVkXCIsXCJzZWxlY3RlZFwiKSxpJiZyLnNldEF0dHJpYnV0ZShcImRhdGEtaWRcIixpKSxyLnNldEF0dHJpYnV0ZShcImRhdGEtc2VsZWN0LW9wdGlvblwiLEpTT04uc3RyaW5naWZ5KGwpKSxyLmlubmVyVGV4dD1lLHRoaXMuZWwuYXBwZW5kKHIpfWRlc3Ryb3lPcmlnaW5hbE9wdGlvbihlKXtjb25zdCB0PXRoaXMuZWwucXVlcnlTZWxlY3RvcihgW3ZhbHVlPVwiJHtlfVwiXWApO2lmKCF0KXJldHVybiExO3QucmVtb3ZlKCl9YnVpbGRUYWdzSW5wdXRIZWxwZXIoKXt0aGlzLnRhZ3NJbnB1dEhlbHBlcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKSx0aGlzLnRhZ3NJbnB1dEhlbHBlci5zdHlsZS5mb250U2l6ZT13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnRhZ3NJbnB1dCkuZm9udFNpemUsdGhpcy50YWdzSW5wdXRIZWxwZXIuc3R5bGUuZm9udEZhbWlseT13aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnRhZ3NJbnB1dCkuZm9udEZhbWlseSx0aGlzLnRhZ3NJbnB1dEhlbHBlci5zdHlsZS5mb250V2VpZ2h0PXdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMudGFnc0lucHV0KS5mb250V2VpZ2h0LHRoaXMudGFnc0lucHV0SGVscGVyLnN0eWxlLmxldHRlclNwYWNpbmc9d2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy50YWdzSW5wdXQpLmxldHRlclNwYWNpbmcsdGhpcy50YWdzSW5wdXRIZWxwZXIuc3R5bGUudmlzaWJpbGl0eT1cImhpZGRlblwiLHRoaXMudGFnc0lucHV0SGVscGVyLnN0eWxlLndoaXRlU3BhY2U9XCJwcmVcIix0aGlzLnRhZ3NJbnB1dEhlbHBlci5zdHlsZS5wb3NpdGlvbj1cImFic29sdXRlXCIsdGhpcy53cmFwcGVyLmFwcGVuZENoaWxkKHRoaXMudGFnc0lucHV0SGVscGVyKX1jYWxjdWxhdGVJbnB1dFdpZHRoKCl7dGhpcy50YWdzSW5wdXRIZWxwZXIudGV4dENvbnRlbnQ9dGhpcy50YWdzSW5wdXQudmFsdWV8fHRoaXMudGFnc0lucHV0LnBsYWNlaG9sZGVyO2NvbnN0IGU9cGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy50YWdzSW5wdXQpLnBhZGRpbmdMZWZ0KStwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnRhZ3NJbnB1dCkucGFkZGluZ1JpZ2h0KSx0PXBhcnNlSW50KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMudGFnc0lucHV0KS5ib3JkZXJMZWZ0V2lkdGgpK3BhcnNlSW50KHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMudGFnc0lucHV0KS5ib3JkZXJSaWdodFdpZHRoKSxpPXRoaXMudGFnc0lucHV0SGVscGVyLm9mZnNldFdpZHRoK2UrdCxzPXRoaXMud3JhcHBlci5vZmZzZXRXaWR0aC0ocGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy53cmFwcGVyKS5wYWRkaW5nTGVmdCkrcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy53cmFwcGVyKS5wYWRkaW5nUmlnaHQpKTt0aGlzLnRhZ3NJbnB1dC5zdHlsZS53aWR0aD1gJHtNYXRoLm1pbihpLHMpKzJ9cHhgfWFkanVzdElucHV0V2lkdGgoKXt0aGlzLmJ1aWxkVGFnc0lucHV0SGVscGVyKCksdGhpcy5jYWxjdWxhdGVJbnB1dFdpZHRoKCl9b25TZWxlY3RPcHRpb24oZSl7aWYodGhpcy5jbGVhclNlbGVjdGlvbnMoKSx0aGlzLmlzTXVsdGlwbGU/KHRoaXMudmFsdWU9dGhpcy52YWx1ZS5pbmNsdWRlcyhlKT9BcnJheS5mcm9tKHRoaXMudmFsdWUpLmZpbHRlcigodD0+dCE9PWUpKTpbLi4uQXJyYXkuZnJvbSh0aGlzLnZhbHVlKSxlXSx0aGlzLnNlbGVjdE11bHRpcGxlSXRlbXMoKSx0aGlzLnNldE5ld1ZhbHVlKCkpOih0aGlzLnZhbHVlPWUsdGhpcy5zZWxlY3RTaW5nbGVJdGVtKCksdGhpcy5zZXROZXdWYWx1ZSgpKSx0aGlzLmZpcmVFdmVudChcImNoYW5nZVwiLHRoaXMudmFsdWUpLFwidGFnc1wiPT09dGhpcy5tb2RlKXtjb25zdCBlPXRoaXMuc2VsZWN0ZWRJdGVtcy5maWx0ZXIoKGU9PiF0aGlzLnZhbHVlLmluY2x1ZGVzKGUpKSk7ZS5sZW5ndGgmJmUuZm9yRWFjaCgoZT0+e3RoaXMuc2VsZWN0ZWRJdGVtcz10aGlzLnNlbGVjdGVkSXRlbXMuZmlsdGVyKCh0PT50IT09ZSkpLHRoaXMud3JhcHBlci5xdWVyeVNlbGVjdG9yKGBbZGF0YS10YWctdmFsdWU9XCIke2V9XCJdYCkucmVtb3ZlKCl9KSksdGhpcy5yZXNldFRhZ3NJbnB1dEZpZWxkKCl9dGhpcy5pc011bHRpcGxlfHwodGhpcy50b2dnbGUucXVlcnlTZWxlY3RvcihcIltkYXRhLWljb25dXCIpJiZ0aGlzLnNldFRvZ2dsZUljb24oKSx0aGlzLnRvZ2dsZS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtdGl0bGVdXCIpJiZ0aGlzLnNldFRvZ2dsZVRpdGxlKCksdGhpcy5jbG9zZSghMCkpLHRoaXMudmFsdWUubGVuZ3RofHxcInRhZ3NcIiE9PXRoaXMubW9kZXx8dGhpcy5yZWFzc2lnblRhZ3NJbnB1dFBsYWNlaG9sZGVyKHRoaXMucGxhY2Vob2xkZXIpLHRoaXMuaXNPcGVuZWQmJlwidGFnc1wiPT09dGhpcy5tb2RlJiZ0aGlzLnRhZ3NJbnB1dCYmdGhpcy50YWdzSW5wdXQuZm9jdXMoKSx0aGlzLnRyaWdnZXJDaGFuZ2VFdmVudEZvck5hdGl2ZVNlbGVjdCgpfXRyaWdnZXJDaGFuZ2VFdmVudEZvck5hdGl2ZVNlbGVjdCgpe2NvbnN0IGU9bmV3IEV2ZW50KFwiY2hhbmdlXCIse2J1YmJsZXM6ITB9KTt0aGlzLmVsLmRpc3BhdGNoRXZlbnQoZSksKDAsby5kaXNwYXRjaCkoXCJjaGFuZ2UuYWR2YW5jZS5zZWxlY3RcIix0aGlzLmVsLHRoaXMudmFsdWUpfWFkZFNlbGVjdE9wdGlvbihlLHQsaSxzLG4pe3RoaXMuc2VsZWN0T3B0aW9ucz1bLi4udGhpcy5zZWxlY3RPcHRpb25zLHt0aXRsZTplLHZhbDp0LGRpc2FibGVkOmksc2VsZWN0ZWQ6cyxvcHRpb25zOm59XX1yZW1vdmVTZWxlY3RPcHRpb24oZSx0PSExKXtpZighISF0aGlzLnNlbGVjdE9wdGlvbnMuc29tZSgodD0+dC52YWw9PT1lKSkpcmV0dXJuITE7dGhpcy5zZWxlY3RPcHRpb25zPXRoaXMuc2VsZWN0T3B0aW9ucy5maWx0ZXIoKHQ9PnQudmFsIT09ZSkpLHRoaXMudmFsdWU9dD90aGlzLnZhbHVlLmZpbHRlcigodD0+dCE9PWUpKTplfXJlc2V0VGFnc0lucHV0RmllbGQoKXt0aGlzLnRhZ3NJbnB1dC52YWx1ZT1cIlwiLHRoaXMucmVhc3NpZ25UYWdzSW5wdXRQbGFjZWhvbGRlcihcIlwiKSx0aGlzLnNlYXJjaE9wdGlvbnMoXCJcIil9Y2xlYXJTZWxlY3Rpb25zKCl7QXJyYXkuZnJvbSh0aGlzLmRyb3Bkb3duLmNoaWxkcmVuKS5mb3JFYWNoKChlPT57ZS5jbGFzc0xpc3QuY29udGFpbnMoXCJzZWxlY3RlZFwiKSYmZS5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0ZWRcIil9KSksQXJyYXkuZnJvbSh0aGlzLmVsLmNoaWxkcmVuKS5mb3JFYWNoKChlPT57ZS5zZWxlY3RlZCYmKGUuc2VsZWN0ZWQ9ITEpfSkpfXNldE5ld1ZhbHVlKCl7dmFyIGU7XCJ0YWdzXCI9PT10aGlzLm1vZGU/dGhpcy5zZXRUYWdzSXRlbXMoKToobnVsbD09PShlPXRoaXMudmFsdWUpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmxlbmd0aCk/dGhpcy50b2dnbGVUZXh0V3JhcHBlci5pbm5lckhUTUw9dGhpcy5zdHJpbmdGcm9tVmFsdWUoKTp0aGlzLnRvZ2dsZVRleHRXcmFwcGVyLmlubmVySFRNTD10aGlzLnBsYWNlaG9sZGVyfXN0cmluZ0Zyb21WYWx1ZUJhc2ljKGUpe3ZhciB0O2NvbnN0IGk9W107bGV0IHM9XCJcIjtpZihlLmZvckVhY2goKGU9Pnt0aGlzLmlzTXVsdGlwbGU/dGhpcy52YWx1ZS5pbmNsdWRlcyhlLnZhbCkmJmkucHVzaChlLnRpdGxlKTp0aGlzLnZhbHVlPT09ZS52YWwmJmkucHVzaChlLnRpdGxlKX0pKSx2b2lkIDAhPT10aGlzLnRvZ2dsZUNvdW50VGV4dCYmbnVsbCE9PXRoaXMudG9nZ2xlQ291bnRUZXh0JiZpLmxlbmd0aD49dGhpcy50b2dnbGVDb3VudFRleHRNaW5JdGVtcylpZihcIm5JdGVtc0FuZENvdW50XCI9PT10aGlzLnRvZ2dsZUNvdW50VGV4dE1vZGUpe2NvbnN0IGU9aS5zbGljZSgwLHRoaXMudG9nZ2xlQ291bnRUZXh0TWluSXRlbXMtMSksbj1bZS5qb2luKHRoaXMudG9nZ2xlU2VwYXJhdG9ycy5pdGVtcyldLG89XCJcIisoaS5sZW5ndGgtZS5sZW5ndGgpO2lmKChudWxsPT09KHQ9bnVsbD09dGhpcz92b2lkIDA6dGhpcy50b2dnbGVTZXBhcmF0b3JzKXx8dm9pZCAwPT09dD92b2lkIDA6dC5iZXR3ZWVuSXRlbXNBbmRDb3VudGVyKSYmbi5wdXNoKHRoaXMudG9nZ2xlU2VwYXJhdG9ycy5iZXR3ZWVuSXRlbXNBbmRDb3VudGVyKSx0aGlzLnRvZ2dsZUNvdW50VGV4dClzd2l0Y2godGhpcy50b2dnbGVDb3VudFRleHRQbGFjZW1lbnQpe2Nhc2VcInBvc3RmaXgtbm8tc3BhY2VcIjpuLnB1c2goYCR7b30ke3RoaXMudG9nZ2xlQ291bnRUZXh0fWApO2JyZWFrO2Nhc2VcInByZWZpeC1uby1zcGFjZVwiOm4ucHVzaChgJHt0aGlzLnRvZ2dsZUNvdW50VGV4dH0ke299YCk7YnJlYWs7Y2FzZVwicHJlZml4XCI6bi5wdXNoKGAke3RoaXMudG9nZ2xlQ291bnRUZXh0fSAke299YCk7YnJlYWs7ZGVmYXVsdDpuLnB1c2goYCR7b30gJHt0aGlzLnRvZ2dsZUNvdW50VGV4dH1gKX1zPW4uam9pbihcIiBcIil9ZWxzZSBzPWAke2kubGVuZ3RofSAke3RoaXMudG9nZ2xlQ291bnRUZXh0fWA7ZWxzZSBzPWkuam9pbih0aGlzLnRvZ2dsZVNlcGFyYXRvcnMuaXRlbXMpO3JldHVybiBzfXN0cmluZ0Zyb21WYWx1ZVJlbW90ZURhdGEoKXtjb25zdCBlPXRoaXMuZHJvcGRvd24ucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXRpdGxlLXZhbHVlXVwiKSx0PVtdO2xldCBpPVwiXCI7aWYoZS5mb3JFYWNoKChlPT57Y29uc3QgaT1lLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIikscz1lLmdldEF0dHJpYnV0ZShcImRhdGEtdGl0bGUtdmFsdWVcIik7dGhpcy5pc011bHRpcGxlP3RoaXMudmFsdWUuaW5jbHVkZXMoaSkmJnQucHVzaChzKTp0aGlzLnZhbHVlPT09aSYmdC5wdXNoKHMpfSkpLHRoaXMudG9nZ2xlQ291bnRUZXh0JiZcIlwiIT09dGhpcy50b2dnbGVDb3VudFRleHQmJnQubGVuZ3RoPj10aGlzLnRvZ2dsZUNvdW50VGV4dE1pbkl0ZW1zKWlmKFwibkl0ZW1zQW5kQ291bnRcIj09PXRoaXMudG9nZ2xlQ291bnRUZXh0TW9kZSl7Y29uc3QgZT10LnNsaWNlKDAsdGhpcy50b2dnbGVDb3VudFRleHRNaW5JdGVtcy0xKTtpPWAke2Uuam9pbih0aGlzLnRvZ2dsZVNlcGFyYXRvcnMuaXRlbXMpfSAke3RoaXMudG9nZ2xlU2VwYXJhdG9ycy5iZXR3ZWVuSXRlbXNBbmRDb3VudGVyfSAke3QubGVuZ3RoLWUubGVuZ3RofSAke3RoaXMudG9nZ2xlQ291bnRUZXh0fWB9ZWxzZSBpPWAke3QubGVuZ3RofSAke3RoaXMudG9nZ2xlQ291bnRUZXh0fWA7ZWxzZSBpPXQuam9pbih0aGlzLnRvZ2dsZVNlcGFyYXRvcnMuaXRlbXMpO3JldHVybiBpfXN0cmluZ0Zyb21WYWx1ZSgpe3JldHVybiB0aGlzLmFwaVVybD90aGlzLnN0cmluZ0Zyb21WYWx1ZVJlbW90ZURhdGEoKTp0aGlzLnN0cmluZ0Zyb21WYWx1ZUJhc2ljKHRoaXMuc2VsZWN0T3B0aW9ucyl9c2VsZWN0U2luZ2xlSXRlbSgpe0FycmF5LmZyb20odGhpcy5lbC5jaGlsZHJlbikuZmluZCgoZT0+dGhpcy52YWx1ZT09PWUudmFsdWUpKS5zZWxlY3RlZD0hMDtjb25zdCBlPUFycmF5LmZyb20odGhpcy5kcm9wZG93bi5jaGlsZHJlbikuZmluZCgoZT0+dGhpcy52YWx1ZT09PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS12YWx1ZVwiKSkpO2UmJmUuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpfXNlbGVjdE11bHRpcGxlSXRlbXMoKXtBcnJheS5mcm9tKHRoaXMuZHJvcGRvd24uY2hpbGRyZW4pLmZpbHRlcigoZT0+dGhpcy52YWx1ZS5pbmNsdWRlcyhlLmdldEF0dHJpYnV0ZShcImRhdGEtdmFsdWVcIikpKSkuZm9yRWFjaCgoZT0+ZS5jbGFzc0xpc3QuYWRkKFwic2VsZWN0ZWRcIikpKSxBcnJheS5mcm9tKHRoaXMuZWwuY2hpbGRyZW4pLmZpbHRlcigoZT0+dGhpcy52YWx1ZS5pbmNsdWRlcyhlLnZhbHVlKSkpLmZvckVhY2goKGU9PmUuc2VsZWN0ZWQ9ITApKX11bnNlbGVjdE11bHRpcGxlSXRlbXMoKXtBcnJheS5mcm9tKHRoaXMuZHJvcGRvd24uY2hpbGRyZW4pLmZvckVhY2goKGU9PmUuY2xhc3NMaXN0LnJlbW92ZShcInNlbGVjdGVkXCIpKSksQXJyYXkuZnJvbSh0aGlzLmVsLmNoaWxkcmVuKS5mb3JFYWNoKChlPT5lLnNlbGVjdGVkPSExKSl9c2VhcmNoT3B0aW9ucyhlKXtpZihlLmxlbmd0aDw9dGhpcy5taW5TZWFyY2hMZW5ndGgpe3RoaXMuc2VhcmNoTm9SZXN1bHQmJih0aGlzLnNlYXJjaE5vUmVzdWx0LnJlbW92ZSgpLHRoaXMuc2VhcmNoTm9SZXN1bHQ9bnVsbCk7cmV0dXJuIHRoaXMuZHJvcGRvd24ucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXZhbHVlXVwiKS5mb3JFYWNoKChlPT57ZS5jbGFzc0xpc3QucmVtb3ZlKFwiaGlkZGVuXCIpfSkpLCExfXRoaXMuc2VhcmNoTm9SZXN1bHQmJih0aGlzLnNlYXJjaE5vUmVzdWx0LnJlbW92ZSgpLHRoaXMuc2VhcmNoTm9SZXN1bHQ9bnVsbCksdGhpcy5zZWFyY2hOb1Jlc3VsdD0oMCxvLmh0bWxUb0VsZW1lbnQpKHRoaXMuc2VhcmNoTm9SZXN1bHRUZW1wbGF0ZSksdGhpcy5zZWFyY2hOb1Jlc3VsdC5pbm5lclRleHQ9dGhpcy5zZWFyY2hOb1Jlc3VsdFRleHQsKDAsby5jbGFzc1RvQ2xhc3NMaXN0KSh0aGlzLnNlYXJjaE5vUmVzdWx0Q2xhc3Nlcyx0aGlzLnNlYXJjaE5vUmVzdWx0KTtjb25zdCB0PXRoaXMuZHJvcGRvd24ucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLXZhbHVlXVwiKTtsZXQgaSxzPSExO3RoaXMuc2VhcmNoTGltaXQmJihpPTApLHQuZm9yRWFjaCgodD0+e2NvbnN0IG49dC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRpdGxlLXZhbHVlXCIpLnRvTG9jYWxlTG93ZXJDYXNlKCk7bGV0IG87aWYodGhpcy5pc1NlYXJjaERpcmVjdE1hdGNoKW89IW4uaW5jbHVkZXMoZS50b0xvd2VyQ2FzZSgpKXx8dGhpcy5zZWFyY2hMaW1pdCYmaT49dGhpcy5zZWFyY2hMaW1pdDtlbHNle2NvbnN0IHQ9ZT9lLnNwbGl0KFwiXCIpLm1hcCgoZT0+L1xcdy8udGVzdChlKT9gJHtlfVtcXFxcV19dKmA6XCJcXFxcVypcIikpLmpvaW4oXCJcIik6XCJcIjtvPSFuZXcgUmVnRXhwKHQsXCJpXCIpLnRlc3Qobi50cmltKCkpfHx0aGlzLnNlYXJjaExpbWl0JiZpPj10aGlzLnNlYXJjaExpbWl0fW8/dC5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpOih0LmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRkZW5cIikscz0hMCx0aGlzLnNlYXJjaExpbWl0JiZpKyspfSkpLHN8fHRoaXMuZHJvcGRvd24uYXBwZW5kKHRoaXMuc2VhcmNoTm9SZXN1bHQpfWVyYXNlVG9nZ2xlSWNvbigpe2NvbnN0IGU9dGhpcy50b2dnbGUucXVlcnlTZWxlY3RvcihcIltkYXRhLWljb25dXCIpO2UmJihlLmlubmVySFRNTD1udWxsLGUuY2xhc3NMaXN0LmFkZChcImhpZGRlblwiKSl9ZXJhc2VUb2dnbGVUaXRsZSgpe2NvbnN0IGU9dGhpcy50b2dnbGUucXVlcnlTZWxlY3RvcihcIltkYXRhLXRpdGxlXVwiKTtlP2UuaW5uZXJIVE1MPXRoaXMucGxhY2Vob2xkZXI6dGhpcy50b2dnbGVUZXh0V3JhcHBlci5pbm5lckhUTUw9dGhpcy5wbGFjZWhvbGRlcn10b2dnbGVGbigpe3RoaXMuaXNPcGVuZWQ/dGhpcy5jbG9zZSgpOnRoaXMub3BlbigpfWRlc3Ryb3koKXt0aGlzLndyYXBwZXImJnRoaXMud3JhcHBlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uV3JhcHBlckNsaWNrTGlzdGVuZXIpLHRoaXMudG9nZ2xlJiZ0aGlzLnRvZ2dsZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIix0aGlzLm9uVG9nZ2xlQ2xpY2tMaXN0ZW5lciksdGhpcy50YWdzSW5wdXQmJih0aGlzLnRhZ3NJbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZm9jdXNcIix0aGlzLm9uVGFnc0lucHV0Rm9jdXNMaXN0ZW5lciksdGhpcy50YWdzSW5wdXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vblRhZ3NJbnB1dElucHV0TGlzdGVuZXIpLHRoaXMudGFnc0lucHV0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJpbnB1dFwiLHRoaXMub25UYWdzSW5wdXRJbnB1dFNlY29uZExpc3RlbmVyKSx0aGlzLnRhZ3NJbnB1dC5yZW1vdmVFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLHRoaXMub25UYWdzSW5wdXRLZXlkb3duTGlzdGVuZXIpKSx0aGlzLnNlYXJjaCYmdGhpcy5zZWFyY2gucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsdGhpcy5vblNlYXJjaElucHV0TGlzdGVuZXIpO2NvbnN0IGU9dGhpcy5lbC5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQ7dGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpLHRoaXMuZWwuc3R5bGUuZGlzcGxheT1cIlwiLGUucHJlcGVuZCh0aGlzLmVsKSxlLnF1ZXJ5U2VsZWN0b3IoXCIuYWR2YW5jZS1zZWxlY3RcIikucmVtb3ZlKCksdGhpcy53cmFwcGVyPW51bGwsd2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb249d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5lLmVsIT09dGhpcy5lbCkpfW9wZW4oKXt2YXIgZTtjb25zdCB0PShudWxsPT09KGU9bnVsbD09PXdpbmRvd3x8dm9pZCAwPT09d2luZG93P3ZvaWQgMDp3aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbil8fHZvaWQgMD09PWU/dm9pZCAwOmUuZmluZCgoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSkpfHxudWxsO2lmKHQmJnQuZWxlbWVudC5jbG9zZSgpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzKXJldHVybiExO3RoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSEwLFwid2luZG93XCI9PT10aGlzLmRyb3Bkb3duU2NvcGUmJnRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmFkZChcImludmlzaWJsZVwiKSx0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUoXCJoaWRkZW5cIiksdGhpcy5yZWNhbGN1bGF0ZURpcmVjdGlvbigpLHNldFRpbWVvdXQoKCgpPT57dmFyIGU7KG51bGw9PT0oZT1udWxsPT10aGlzP3ZvaWQgMDp0aGlzLnRvZ2dsZSl8fHZvaWQgMD09PWU/dm9pZCAwOmUuYXJpYUV4cGFuZGVkKSYmKHRoaXMudG9nZ2xlLmFyaWFFeHBhbmRlZD1cInRydWVcIiksdGhpcy53cmFwcGVyLmNsYXNzTGlzdC5hZGQoXCJhY3RpdmVcIiksdGhpcy5kcm9wZG93bi5jbGFzc0xpc3QuYWRkKFwib3BlbmVkXCIpLHRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmNvbnRhaW5zKFwidy1mdWxsXCIpJiZcIndpbmRvd1wiPT09dGhpcy5kcm9wZG93blNjb3BlJiZ0aGlzLnVwZGF0ZURyb3Bkb3duV2lkdGgoKSx0aGlzLmZsb2F0aW5nVUlJbnN0YW5jZSYmXCJ3aW5kb3dcIj09PXRoaXMuZHJvcGRvd25TY29wZSYmKHRoaXMuZmxvYXRpbmdVSUluc3RhbmNlLnVwZGF0ZSgpLHRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LnJlbW92ZShcImludmlzaWJsZVwiKSksdGhpcy5oYXNTZWFyY2gmJiF0aGlzLnByZXZlbnRTZWFyY2hGb2N1cyYmdGhpcy5zZWFyY2guZm9jdXMoKSx0aGlzLmFuaW1hdGlvbkluUHJvY2Vzcz0hMX0pKSx0aGlzLmlzT3BlbmVkPSEwfWNsb3NlKGU9ITEpe3ZhciB0LGkscyxuO2lmKHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzKXJldHVybiExO3RoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSEwLChudWxsPT09KHQ9bnVsbD09dGhpcz92b2lkIDA6dGhpcy50b2dnbGUpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmFyaWFFeHBhbmRlZCkmJih0aGlzLnRvZ2dsZS5hcmlhRXhwYW5kZWQ9XCJmYWxzZVwiKSx0aGlzLndyYXBwZXIuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKSx0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUoXCJvcGVuZWRcIixcImJvdHRvbS1mdWxsXCIsXCJ0b3AtZnVsbFwiKSwobnVsbD09PShpPXRoaXMuZHJvcGRvd25EaXJlY3Rpb25DbGFzc2VzKXx8dm9pZCAwPT09aT92b2lkIDA6aS5ib3R0b20pJiZ0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXMuYm90dG9tKSwobnVsbD09PShzPXRoaXMuZHJvcGRvd25EaXJlY3Rpb25DbGFzc2VzKXx8dm9pZCAwPT09cz92b2lkIDA6cy50b3ApJiZ0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXMudG9wKSx0aGlzLmRyb3Bkb3duLnN0eWxlLm1hcmdpblRvcD1cIlwiLHRoaXMuZHJvcGRvd24uc3R5bGUubWFyZ2luQm90dG9tPVwiXCIsKDAsby5hZnRlclRyYW5zaXRpb24pKHRoaXMuZHJvcGRvd24sKCgpPT57dGhpcy5kcm9wZG93bi5jbGFzc0xpc3QuYWRkKFwiaGlkZGVuXCIpLHRoaXMuaGFzU2VhcmNoJiYodGhpcy5zZWFyY2gudmFsdWU9XCJcIix0aGlzLnNlYXJjaC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIse2J1YmJsZXM6ITB9KSksdGhpcy5zZWFyY2guYmx1cigpKSxlJiZ0aGlzLnRvZ2dsZS5mb2N1cygpLHRoaXMuYW5pbWF0aW9uSW5Qcm9jZXNzPSExfSkpLG51bGw9PT0obj10aGlzLmRyb3Bkb3duLnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0LW9wdGlvbi1oaWdobGlnaHRlZFwiKSl8fHZvaWQgMD09PW58fG4uY2xhc3NMaXN0LnJlbW92ZShcInNlbGVjdC1vcHRpb24taGlnaGxpZ2h0ZWRcIiksdGhpcy5pc09wZW5lZD0hMX1hZGRPcHRpb24oZSl7bGV0IHQ9YCR7dGhpcy5zZWxlY3RPcHRpb25zLmxlbmd0aH1gO2NvbnN0IGk9ZT0+e2NvbnN0e3RpdGxlOmksdmFsOnMsZGlzYWJsZWQ6bixzZWxlY3RlZDpvLG9wdGlvbnM6bH09ZTshIXRoaXMuc2VsZWN0T3B0aW9ucy5zb21lKChlPT5lLnZhbD09PXMpKXx8KHRoaXMuYWRkU2VsZWN0T3B0aW9uKGkscyxuLG8sbCksdGhpcy5idWlsZE9wdGlvbihpLHMsbixvLGwsdCksdGhpcy5idWlsZE9yaWdpbmFsT3B0aW9uKGkscyxudWxsLG4sbyxsKSxvJiYhdGhpcy5pc011bHRpcGxlJiZ0aGlzLm9uU2VsZWN0T3B0aW9uKHMpKX07QXJyYXkuaXNBcnJheShlKT9lLmZvckVhY2goKGU9PntpKGUpfSkpOmkoZSl9cmVtb3ZlT3B0aW9uKGUpe2NvbnN0IHQ9KGUsdD0hMSk9PnshIXRoaXMuc2VsZWN0T3B0aW9ucy5zb21lKCh0PT50LnZhbD09PWUpKSYmKHRoaXMucmVtb3ZlU2VsZWN0T3B0aW9uKGUsdCksdGhpcy5kZXN0cm95T3B0aW9uKGUpLHRoaXMuZGVzdHJveU9yaWdpbmFsT3B0aW9uKGUpLHRoaXMudmFsdWU9PT1lJiYodGhpcy52YWx1ZT1udWxsLHRoaXMuZXJhc2VUb2dnbGVUaXRsZSgpLHRoaXMuZXJhc2VUb2dnbGVJY29uKCkpKX07QXJyYXkuaXNBcnJheShlKT9lLmZvckVhY2goKGU9Pnt0KGUsdGhpcy5pc011bHRpcGxlKX0pKTp0KGUsdGhpcy5pc011bHRpcGxlKSx0aGlzLnNldE5ld1ZhbHVlKCl9cmVjYWxjdWxhdGVEaXJlY3Rpb24oKXt2YXIgZSx0LGkscztpZigobnVsbD09dGhpcz92b2lkIDA6dGhpcy5kcm9wZG93blZlcnRpY2FsRml4ZWRQbGFjZW1lbnQpJiYodGhpcy5kcm9wZG93bi5jbGFzc0xpc3QuY29udGFpbnMoXCJib3R0b20tZnVsbFwiKXx8dGhpcy5kcm9wZG93bi5jbGFzc0xpc3QuY29udGFpbnMoXCJ0b3AtZnVsbFwiKSkpcmV0dXJuITE7XCJ0b3BcIj09PShudWxsPT10aGlzP3ZvaWQgMDp0aGlzLmRyb3Bkb3duVmVydGljYWxGaXhlZFBsYWNlbWVudCk/KHRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmFkZChcImJvdHRvbS1mdWxsXCIpLHRoaXMuZHJvcGRvd24uc3R5bGUubWFyZ2luQm90dG9tPWAke3RoaXMuZHJvcGRvd25TcGFjZX1weGApOlwiYm90dG9tXCI9PT0obnVsbD09dGhpcz92b2lkIDA6dGhpcy5kcm9wZG93blZlcnRpY2FsRml4ZWRQbGFjZW1lbnQpPyh0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5hZGQoXCJ0b3AtZnVsbFwiKSx0aGlzLmRyb3Bkb3duLnN0eWxlLm1hcmdpblRvcD1gJHt0aGlzLmRyb3Bkb3duU3BhY2V9cHhgKTooMCxvLmlzRW5vdWdoU3BhY2UpKHRoaXMuZHJvcGRvd24sdGhpcy50b2dnbGV8fHRoaXMudGFnc0lucHV0LFwiYm90dG9tXCIsdGhpcy5kcm9wZG93blNwYWNlLHRoaXMudmlld3BvcnQpPyh0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUoXCJib3R0b20tZnVsbFwiKSwobnVsbD09PShlPXRoaXMuZHJvcGRvd25EaXJlY3Rpb25DbGFzc2VzKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS5ib3R0b20pJiZ0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXMuYm90dG9tKSx0aGlzLmRyb3Bkb3duLnN0eWxlLm1hcmdpbkJvdHRvbT1cIlwiLHRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmFkZChcInRvcC1mdWxsXCIpLChudWxsPT09KHQ9dGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXMpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LnRvcCkmJnRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmFkZCh0aGlzLmRyb3Bkb3duRGlyZWN0aW9uQ2xhc3Nlcy50b3ApLHRoaXMuZHJvcGRvd24uc3R5bGUubWFyZ2luVG9wPWAke3RoaXMuZHJvcGRvd25TcGFjZX1weGApOih0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUoXCJ0b3AtZnVsbFwiKSwobnVsbD09PShpPXRoaXMuZHJvcGRvd25EaXJlY3Rpb25DbGFzc2VzKXx8dm9pZCAwPT09aT92b2lkIDA6aS50b3ApJiZ0aGlzLmRyb3Bkb3duLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXMudG9wKSx0aGlzLmRyb3Bkb3duLnN0eWxlLm1hcmdpblRvcD1cIlwiLHRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmFkZChcImJvdHRvbS1mdWxsXCIpLChudWxsPT09KHM9dGhpcy5kcm9wZG93bkRpcmVjdGlvbkNsYXNzZXMpfHx2b2lkIDA9PT1zP3ZvaWQgMDpzLmJvdHRvbSkmJnRoaXMuZHJvcGRvd24uY2xhc3NMaXN0LmFkZCh0aGlzLmRyb3Bkb3duRGlyZWN0aW9uQ2xhc3Nlcy5ib3R0b20pLHRoaXMuZHJvcGRvd24uc3R5bGUubWFyZ2luQm90dG9tPWAke3RoaXMuZHJvcGRvd25TcGFjZX1weGApfXN0YXRpYyBmaW5kSW5Db2xsZWN0aW9uKGUpe3JldHVybiB3aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbi5maW5kKCh0PT5lIGluc3RhbmNlb2YgYz90LmVsZW1lbnQuZWw9PT1lLmVsOlwic3RyaW5nXCI9PXR5cGVvZiBlP3QuZWxlbWVudC5lbD09PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6dC5lbGVtZW50LmVsPT09ZSkpfHxudWxsfXN0YXRpYyBnZXRJbnN0YW5jZShlLHQpe2NvbnN0IGk9d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmluZCgodD0+dC5lbGVtZW50LmVsPT09KFwic3RyaW5nXCI9PXR5cGVvZiBlP2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZSk6ZSkpKTtyZXR1cm4gaT90P2k6aS5lbGVtZW50Om51bGx9c3RhdGljIGF1dG9Jbml0KCl7d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb258fCh3aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbj1bXSx3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsKGU9Pntjb25zdCB0PWUudGFyZ2V0O2MuY2xvc2VDdXJyZW50bHlPcGVuZWQodCl9KSksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleWRvd25cIiwoZT0+Yy5hY2Nlc3NpYmlsaXR5KGUpKSkpLHdpbmRvdy4kaHNTZWxlY3RDb2xsZWN0aW9uJiYod2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb249d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5kb2N1bWVudC5jb250YWlucyhlLmVsKSkpKSxkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiW2RhdGEtc2VsZWN0XTpub3QoLi0tcHJldmVudC1vbi1sb2FkLWluaXQpXCIpLmZvckVhY2goKGU9PntpZighd2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpKXtjb25zdCB0PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1zZWxlY3RcIiksaT10P0pTT04ucGFyc2UodCk6e307bmV3IGMoZSxpKX19KSl9c3RhdGljIG9wZW4oZSl7Y29uc3QgdD1jLmZpbmRJbkNvbGxlY3Rpb24oZSk7dCYmIXQuZWxlbWVudC5pc09wZW5lZCYmdC5lbGVtZW50Lm9wZW4oKX1zdGF0aWMgY2xvc2UoZSl7Y29uc3QgdD1jLmZpbmRJbkNvbGxlY3Rpb24oZSk7dCYmdC5lbGVtZW50LmlzT3BlbmVkJiZ0LmVsZW1lbnQuY2xvc2UoKX1zdGF0aWMgY2xvc2VDdXJyZW50bHlPcGVuZWQoZT1udWxsKXtpZighZS5jbG9zZXN0KFwiLmFkdmFuY2Utc2VsZWN0LmFjdGl2ZVwiKSYmIWUuY2xvc2VzdChcIltkYXRhLXNlbGVjdC1kcm9wZG93bl0ub3BlbmVkXCIpKXtjb25zdCBlPXdpbmRvdy4kaHNTZWxlY3RDb2xsZWN0aW9uLmZpbHRlcigoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSl8fG51bGw7ZSYmZS5mb3JFYWNoKChlPT57ZS5lbGVtZW50LmNsb3NlKCl9KSl9fXN0YXRpYyBhY2Nlc3NpYmlsaXR5KGUpe2NvbnN0IHQ9d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSk7aWYodCYmYS5TRUxFQ1RfQUNDRVNTSUJJTElUWV9LRVlfU0VULmluY2x1ZGVzKGUuY29kZSkmJiFlLm1ldGFLZXkpc3dpdGNoKGUuY29kZSl7Y2FzZVwiRXNjYXBlXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMub25Fc2NhcGUoKTticmVhaztjYXNlXCJBcnJvd1VwXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vbkFycm93KCk7YnJlYWs7Y2FzZVwiQXJyb3dEb3duXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksdGhpcy5vbkFycm93KCExKTticmVhaztjYXNlXCJUYWJcIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uVGFiKGUuc2hpZnRLZXkpO2JyZWFrO2Nhc2VcIkhvbWVcIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uU3RhcnRFbmQoKTticmVhaztjYXNlXCJFbmRcIjplLnByZXZlbnREZWZhdWx0KCksZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKSx0aGlzLm9uU3RhcnRFbmQoITEpO2JyZWFrO2Nhc2VcIkVudGVyXCI6ZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMub25FbnRlcihlKTticmVhaztjYXNlXCJTcGFjZVwiOmlmKCgwLG8uaXNGb2N1c2VkKSh0LmVsZW1lbnQuc2VhcmNoKSlicmVhaztlLnByZXZlbnREZWZhdWx0KCksdGhpcy5vbkVudGVyKGUpfX1zdGF0aWMgb25Fc2NhcGUoKXtjb25zdCBlPXdpbmRvdy4kaHNTZWxlY3RDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5pc09wZW5lZCkpO2UmJmUuZWxlbWVudC5jbG9zZSgpfXN0YXRpYyBvbkFycm93KGU9ITApe2NvbnN0IHQ9d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSk7aWYodCl7Y29uc3QgaT10LmVsZW1lbnQuZHJvcGRvd247aWYoIWkpcmV0dXJuITE7Y29uc3Qgcz0oZT9BcnJheS5mcm9tKGkucXVlcnlTZWxlY3RvckFsbChcIjpzY29wZSA+ICo6bm90KC5oaWRkZW4pXCIpKS5yZXZlcnNlKCk6QXJyYXkuZnJvbShpLnF1ZXJ5U2VsZWN0b3JBbGwoXCI6c2NvcGUgPiAqOm5vdCguaGlkZGVuKVwiKSkpLmZpbHRlcigoZT0+IWUuY2xhc3NMaXN0LmNvbnRhaW5zKFwiZGlzYWJsZWRcIikpKSxuPWkucXVlcnlTZWxlY3RvcihcIi5zZWxlY3Qtb3B0aW9uLWhpZ2hsaWdodGVkXCIpfHxpLnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0ZWRcIik7bnx8c1swXS5jbGFzc0xpc3QuYWRkKFwic2VsZWN0LW9wdGlvbi1oaWdobGlnaHRlZFwiKTtsZXQgbz1zLmZpbmRJbmRleCgoZT0+ZT09PW4pKTtvKzE8cy5sZW5ndGgmJm8rKyxzW29dLmZvY3VzKCksbiYmbi5jbGFzc0xpc3QucmVtb3ZlKFwic2VsZWN0LW9wdGlvbi1oaWdobGlnaHRlZFwiKSxzW29dLmNsYXNzTGlzdC5hZGQoXCJzZWxlY3Qtb3B0aW9uLWhpZ2hsaWdodGVkXCIpfX1zdGF0aWMgb25UYWIoZT0hMCl7Y29uc3QgdD13aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuaXNPcGVuZWQpKTtpZih0KXtjb25zdCBpPXQuZWxlbWVudC5kcm9wZG93bjtpZighaSlyZXR1cm4hMTtjb25zdCBzPShlP0FycmF5LmZyb20oaS5xdWVyeVNlbGVjdG9yQWxsKFwiOnNjb3BlID4gICo6bm90KC5oaWRkZW4pXCIpKS5yZXZlcnNlKCk6QXJyYXkuZnJvbShpLnF1ZXJ5U2VsZWN0b3JBbGwoXCI6c2NvcGUgPiAgKjpub3QoLmhpZGRlbilcIikpKS5maWx0ZXIoKGU9PiFlLmNsYXNzTGlzdC5jb250YWlucyhcImRpc2FibGVkXCIpKSksbj1pLnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0LW9wdGlvbi1oaWdobGlnaHRlZFwiKXx8aS5xdWVyeVNlbGVjdG9yKFwiLnNlbGVjdGVkXCIpO258fHNbMF0uY2xhc3NMaXN0LmFkZChcInNlbGVjdC1vcHRpb24taGlnaGxpZ2h0ZWRcIik7bGV0IG89cy5maW5kSW5kZXgoKGU9PmU9PT1uKSk7aWYoIShvKzE8cy5sZW5ndGgpKXJldHVybiBuJiZuLmNsYXNzTGlzdC5yZW1vdmUoXCJzZWxlY3Qtb3B0aW9uLWhpZ2hsaWdodGVkXCIpLHQuZWxlbWVudC5jbG9zZSgpLHQuZWxlbWVudC50b2dnbGUuZm9jdXMoKSwhMTtvKyssc1tvXS5mb2N1cygpLG4mJm4uY2xhc3NMaXN0LnJlbW92ZShcInNlbGVjdC1vcHRpb24taGlnaGxpZ2h0ZWRcIiksc1tvXS5jbGFzc0xpc3QuYWRkKFwic2VsZWN0LW9wdGlvbi1oaWdobGlnaHRlZFwiKX19c3RhdGljIG9uU3RhcnRFbmQoZT0hMCl7Y29uc3QgdD13aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuaXNPcGVuZWQpKTtpZih0KXtjb25zdCBpPXQuZWxlbWVudC5kcm9wZG93bjtpZighaSlyZXR1cm4hMTtjb25zdCBzPShlP0FycmF5LmZyb20oaS5xdWVyeVNlbGVjdG9yQWxsKFwiOnNjb3BlID4gICo6bm90KC5oaWRkZW4pXCIpKTpBcnJheS5mcm9tKGkucXVlcnlTZWxlY3RvckFsbChcIjpzY29wZSA+ICAqOm5vdCguaGlkZGVuKVwiKSkucmV2ZXJzZSgpKS5maWx0ZXIoKGU9PiFlLmNsYXNzTGlzdC5jb250YWlucyhcImRpc2FibGVkXCIpKSksbj1pLnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0LW9wdGlvbi1oaWdobGlnaHRlZFwiKTtzLmxlbmd0aCYmKHNbMF0uZm9jdXMoKSxuJiZuLmNsYXNzTGlzdC5yZW1vdmUoXCJzZWxlY3Qtb3B0aW9uLWhpZ2hsaWdodGVkXCIpLHNbMF0uY2xhc3NMaXN0LmFkZChcInNlbGVjdC1vcHRpb24taGlnaGxpZ2h0ZWRcIikpfX1zdGF0aWMgb25FbnRlcihlKXtjb25zdCB0PWUudGFyZ2V0LnByZXZpb3VzU2libGluZztpZih3aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWw9PT10KSkpe2NvbnN0IGU9d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSksaT13aW5kb3cuJGhzU2VsZWN0Q29sbGVjdGlvbi5maW5kKChlPT5lLmVsZW1lbnQuZWw9PT10KSk7ZS5lbGVtZW50LmNsb3NlKCksZSE9PWkmJmkuZWxlbWVudC5vcGVuKCl9ZWxzZXtjb25zdCB0PXdpbmRvdy4kaHNTZWxlY3RDb2xsZWN0aW9uLmZpbmQoKGU9PmUuZWxlbWVudC5pc09wZW5lZCkpO3QmJnQuZWxlbWVudC5vblNlbGVjdE9wdGlvbihlLnRhcmdldC5kYXRhc2V0LnZhbHVlfHxcIlwiKX19fXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCgoKT0+e2MuYXV0b0luaXQoKX0pKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsKCgpPT57aWYoIXdpbmRvdy4kaHNTZWxlY3RDb2xsZWN0aW9uKXJldHVybiExO2NvbnN0IGU9d2luZG93LiRoc1NlbGVjdENvbGxlY3Rpb24uZmluZCgoZT0+ZS5lbGVtZW50LmlzT3BlbmVkKSk7ZSYmZS5lbGVtZW50LnJlY2FsY3VsYXRlRGlyZWN0aW9uKCl9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5IU1NlbGVjdD1jKSx0LmRlZmF1bHQ9Y30sOTc3OmZ1bmN0aW9uKGUsdCxpKXtcbi8qXG4gKiBIU1JhbmdlU2xpZGVyXG4gKiBAdmVyc2lvbjogMy4wLjBcbiAqIEBhdXRob3I6IFByZWxpbmUgTGFicyBMdGQuXG4gKiBAbGljZW5zZTogTGljZW5zZWQgdW5kZXIgTUlUIGFuZCBQcmVsaW5lIFVJIEZhaXIgVXNlIExpY2Vuc2UgKGh0dHBzOi8vcHJlbGluZS5jby9kb2NzL2xpY2Vuc2UuaHRtbClcbiAqIENvcHlyaWdodCAyMDI0IFByZWxpbmUgTGFicyBMdGQuXG4gKi9cbnZhciBzPXRoaXMmJnRoaXMuX19pbXBvcnREZWZhdWx0fHxmdW5jdGlvbihlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19O09iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO2NvbnN0IG49cyhpKDI4NykpO2NsYXNzIG8gZXh0ZW5kcyBuLmRlZmF1bHR7Y29uc3RydWN0b3IoZSx0LGkpe3N1cGVyKGUsdCxpKTtjb25zdCBzPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1yYW5nZS1zbGlkZXJcIiksbj1zP0pTT04ucGFyc2Uocyk6e307dGhpcy5jb25jYXRPcHRpb25zPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LG4pLHQpLHtjc3NDbGFzc2VzOk9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxub1VpU2xpZGVyLmNzc0NsYXNzZXMpLHRoaXMucHJvY2Vzc0NsYXNzZXMobi5jc3NDbGFzc2VzKSl9KSx0aGlzLmluaXQoKX1nZXQgZm9ybWF0dGVkVmFsdWUoKXtjb25zdCBlPXRoaXMuZWwubm9VaVNsaWRlci5nZXQoKTtpZihBcnJheS5pc0FycmF5KGUpJiZ0aGlzLmZvcm1hdCl7Y29uc3QgdD1bXTtyZXR1cm4gZS5mb3JFYWNoKChlPT57dC5wdXNoKHRoaXMuZm9ybWF0LnRvKGUpKX0pKSx0fXJldHVybiB0aGlzLmZvcm1hdD90aGlzLmZvcm1hdC50byhlKTplfXByb2Nlc3NDbGFzc2VzKGUpe2NvbnN0IHQ9e307cmV0dXJuIE9iamVjdC5rZXlzKGUpLmZvckVhY2goKGk9PntpJiYodFtpXT1gJHtub1VpU2xpZGVyLmNzc0NsYXNzZXNbaV19ICR7ZVtpXX1gKX0pKSx0fWluaXQoKXt2YXIgZSx0LGkscyxuLG8sbCxyLGEsYyxkLGgsdTt0aGlzLmNyZWF0ZUNvbGxlY3Rpb24od2luZG93LiRoc1JhbmdlU2xpZGVyQ29sbGVjdGlvbix0aGlzKSwoXCJvYmplY3RcIj09dHlwZW9mKG51bGw9PT0oZT10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1lP3ZvaWQgMDplLmZvcm1hdHRlcik/XCJ0aG91c2FuZHNTZXBhcmF0b3JBbmREZWNpbWFsUG9pbnRzXCI9PT0obnVsbD09PShpPW51bGw9PT0odD10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LmZvcm1hdHRlcil8fHZvaWQgMD09PWk/dm9pZCAwOmkudHlwZSk6XCJ0aG91c2FuZHNTZXBhcmF0b3JBbmREZWNpbWFsUG9pbnRzXCI9PT0obnVsbD09PShzPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PXM/dm9pZCAwOnMuZm9ybWF0dGVyKSk/dGhpcy50aG91c2FuZHNTZXBhcmF0b3JBbmREZWNpbWFsUG9pbnRzRm9ybWF0dGVyKCk6KFwib2JqZWN0XCI9PXR5cGVvZihudWxsPT09KG49dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09bj92b2lkIDA6bi5mb3JtYXR0ZXIpP1wiaW50ZWdlclwiPT09KG51bGw9PT0obD1udWxsPT09KG89dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09bz92b2lkIDA6by5mb3JtYXR0ZXIpfHx2b2lkIDA9PT1sP3ZvaWQgMDpsLnR5cGUpOlwiaW50ZWdlclwiPT09KG51bGw9PT0ocj10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1yP3ZvaWQgMDpyLmZvcm1hdHRlcikpP3RoaXMuaW50ZWdlckZvcm1hdHRlcigpOlwib2JqZWN0XCI9PXR5cGVvZihudWxsPT09KGE9dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09YT92b2lkIDA6YS5mb3JtYXR0ZXIpJiYoKG51bGw9PT0oZD1udWxsPT09KGM9dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09Yz92b2lkIDA6Yy5mb3JtYXR0ZXIpfHx2b2lkIDA9PT1kP3ZvaWQgMDpkLnByZWZpeCl8fChudWxsPT09KHU9bnVsbD09PShoPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PWg/dm9pZCAwOmguZm9ybWF0dGVyKXx8dm9pZCAwPT09dT92b2lkIDA6dS5wb3N0Zml4KSkmJnRoaXMucHJlZml4T3JQb3N0Zml4Rm9ybWF0dGVyKCksbm9VaVNsaWRlci5jcmVhdGUodGhpcy5lbCx0aGlzLmNvbmNhdE9wdGlvbnMpLHRoaXMuY29uY2F0T3B0aW9ucy5kaXNhYmxlZCYmdGhpcy5zZXREaXNhYmxlZCgpfWZvcm1hdFZhbHVlKGUpe3ZhciB0LGkscyxuLG8sbCxyLGEsYztsZXQgZD1cIlwiO3JldHVyblwib2JqZWN0XCI9PXR5cGVvZihudWxsPT09KHQ9dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09dD92b2lkIDA6dC5mb3JtYXR0ZXIpPygobnVsbD09PShzPW51bGw9PT0oaT10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1pP3ZvaWQgMDppLmZvcm1hdHRlcil8fHZvaWQgMD09PXM/dm9pZCAwOnMucHJlZml4KSYmKGQrPW51bGw9PT0obz1udWxsPT09KG49dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09bj92b2lkIDA6bi5mb3JtYXR0ZXIpfHx2b2lkIDA9PT1vP3ZvaWQgMDpvLnByZWZpeCksZCs9ZSwobnVsbD09PShyPW51bGw9PT0obD10aGlzLmNvbmNhdE9wdGlvbnMpfHx2b2lkIDA9PT1sP3ZvaWQgMDpsLmZvcm1hdHRlcil8fHZvaWQgMD09PXI/dm9pZCAwOnIucG9zdGZpeCkmJihkKz1udWxsPT09KGM9bnVsbD09PShhPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PWE/dm9pZCAwOmEuZm9ybWF0dGVyKXx8dm9pZCAwPT09Yz92b2lkIDA6Yy5wb3N0Zml4KSk6ZCs9ZSxkfWludGVnZXJGb3JtYXR0ZXIoKXt2YXIgZTt0aGlzLmZvcm1hdD17dG86ZT0+dGhpcy5mb3JtYXRWYWx1ZShNYXRoLnJvdW5kKGUpKSxmcm9tOmU9Pk1hdGgucm91bmQoK2UpfSwobnVsbD09PShlPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PWU/dm9pZCAwOmUudG9vbHRpcHMpJiYodGhpcy5jb25jYXRPcHRpb25zLnRvb2x0aXBzPXRoaXMuZm9ybWF0KX1wcmVmaXhPclBvc3RmaXhGb3JtYXR0ZXIoKXt2YXIgZTt0aGlzLmZvcm1hdD17dG86ZT0+dGhpcy5mb3JtYXRWYWx1ZShlKSxmcm9tOmU9PitlfSwobnVsbD09PShlPXRoaXMuY29uY2F0T3B0aW9ucyl8fHZvaWQgMD09PWU/dm9pZCAwOmUudG9vbHRpcHMpJiYodGhpcy5jb25jYXRPcHRpb25zLnRvb2x0aXBzPXRoaXMuZm9ybWF0KX10aG91c2FuZHNTZXBhcmF0b3JBbmREZWNpbWFsUG9pbnRzRm9ybWF0dGVyKCl7dmFyIGU7dGhpcy5mb3JtYXQ9e3RvOmU9PnRoaXMuZm9ybWF0VmFsdWUobmV3IEludGwuTnVtYmVyRm9ybWF0KFwiZW4tVVNcIix7bWluaW11bUZyYWN0aW9uRGlnaXRzOjIsbWF4aW11bUZyYWN0aW9uRGlnaXRzOjJ9KS5mb3JtYXQoZSkpLGZyb206ZT0+cGFyc2VGbG9hdChlLnJlcGxhY2UoLywvZyxcIlwiKSl9LChudWxsPT09KGU9dGhpcy5jb25jYXRPcHRpb25zKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS50b29sdGlwcykmJih0aGlzLmNvbmNhdE9wdGlvbnMudG9vbHRpcHM9dGhpcy5mb3JtYXQpfXNldERpc2FibGVkKCl7dGhpcy5lbC5zZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiLFwiZGlzYWJsZWRcIiksdGhpcy5lbC5jbGFzc0xpc3QuYWRkKFwiZGlzYWJsZWRcIil9ZGVzdHJveSgpe3RoaXMuZWwubm9VaVNsaWRlci5kZXN0cm95KCksdGhpcy5mb3JtYXQ9bnVsbCx3aW5kb3cuJGhzUmFuZ2VTbGlkZXJDb2xsZWN0aW9uPXdpbmRvdy4kaHNSYW5nZVNsaWRlckNvbGxlY3Rpb24uZmlsdGVyKCgoe2VsZW1lbnQ6ZX0pPT5lLmVsIT09dGhpcy5lbCkpfXN0YXRpYyBnZXRJbnN0YW5jZShlLHQ9ITEpe2NvbnN0IGk9d2luZG93LiRoc1JhbmdlU2xpZGVyQ29sbGVjdGlvbi5maW5kKCh0PT50LmVsZW1lbnQuZWw9PT0oXCJzdHJpbmdcIj09dHlwZW9mIGU/ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlKTplKSkpO3JldHVybiBpP3Q/aTppLmVsZW1lbnQuZWw6bnVsbH1zdGF0aWMgYXV0b0luaXQoKXt3aW5kb3cuJGhzUmFuZ2VTbGlkZXJDb2xsZWN0aW9ufHwod2luZG93LiRoc1JhbmdlU2xpZGVyQ29sbGVjdGlvbj1bXSksd2luZG93LiRoc1JhbmdlU2xpZGVyQ29sbGVjdGlvbiYmKHdpbmRvdy4kaHNSYW5nZVNsaWRlckNvbGxlY3Rpb249d2luZG93LiRoc1JhbmdlU2xpZGVyQ29sbGVjdGlvbi5maWx0ZXIoKCh7ZWxlbWVudDplfSk9PmRvY3VtZW50LmNvbnRhaW5zKGUuZWwpKSkpLGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1yYW5nZS1zbGlkZXJdOm5vdCguLS1wcmV2ZW50LW9uLWxvYWQtaW5pdClcIikuZm9yRWFjaCgoZT0+e3dpbmRvdy4kaHNSYW5nZVNsaWRlckNvbGxlY3Rpb24uZmluZCgodD0+e3ZhciBpO3JldHVybihudWxsPT09KGk9bnVsbD09dD92b2lkIDA6dC5lbGVtZW50KXx8dm9pZCAwPT09aT92b2lkIDA6aS5lbCk9PT1lfSkpfHxuZXcgbyhlKX0pKX19d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsKCgpPT57by5hdXRvSW5pdCgpfSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuSFNSYW5nZVNsaWRlcj1vKSx0LmRlZmF1bHQ9b319LHQ9e307ZnVuY3Rpb24gaShzKXt2YXIgbj10W3NdO2lmKHZvaWQgMCE9PW4pcmV0dXJuIG4uZXhwb3J0czt2YXIgbz10W3NdPXtleHBvcnRzOnt9fTtyZXR1cm4gZVtzXS5jYWxsKG8uZXhwb3J0cyxvLG8uZXhwb3J0cyxpKSxvLmV4cG9ydHN9cmV0dXJuIGkuZD0oZSx0KT0+e2Zvcih2YXIgcyBpbiB0KWkubyh0LHMpJiYhaS5vKGUscykmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLHMse2VudW1lcmFibGU6ITAsZ2V0OnRbc119KX0saS5vPShlLHQpPT5PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZSx0KSxpLnI9ZT0+e1widW5kZWZpbmVkXCIhPXR5cGVvZiBTeW1ib2wmJlN5bWJvbC50b1N0cmluZ1RhZyYmT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsU3ltYm9sLnRvU3RyaW5nVGFnLHt2YWx1ZTpcIk1vZHVsZVwifSksT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSl9LGkoODAwKX0pKCkpKTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/flyonui/flyonui.js\n"); /***/ }), /***/ "./node_modules/ieee754/index.js": /*!***************************************!*\ !*** ./node_modules/ieee754/index.js ***! \***************************************/ /***/ ((__unused_webpack_module, exports) => { eval("/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsV0FBVzs7QUFFcEI7QUFDQTtBQUNBO0FBQ0EsU0FBUyxXQUFXOztBQUVwQjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLFdBQVc7O0FBRXBCO0FBQ0E7QUFDQSxTQUFTLFVBQVU7O0FBRW5CO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcz9lYmMxIl0sInNvdXJjZXNDb250ZW50IjpbIi8qISBpZWVlNzU0LiBCU0QtMy1DbGF1c2UgTGljZW5zZS4gRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnL29wZW5zb3VyY2U+ICovXG5leHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/ieee754/index.js\n"); /***/ }), /***/ "./node_modules/isarray/index.js": /*!***************************************!*\ !*** ./node_modules/isarray/index.js ***! \***************************************/ /***/ ((module) => { eval("var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIm1hcHBpbmdzIjoiQUFBQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzP2I2OGUiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/isarray/index.js\n"); /***/ }), /***/ "./node_modules/lodash/lodash.js": /*!***************************************!*\ !*** ./node_modules/lodash/lodash.js ***! \***************************************/ /***/ (function(module, exports, __webpack_require__) { eval("/* module decorator */ module = __webpack_require__.nmd(module);\nvar __WEBPACK_AMD_DEFINE_RESULT__;/**\n * @license\n * Lodash \n * Copyright OpenJS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n;(function() {\n\n /** Used as a safe reference for `undefined` in pre-ES5 environments. */\n var undefined;\n\n /** Used as the semantic version number. */\n var VERSION = '4.17.21';\n\n /** Used as the size to enable large array optimizations. */\n var LARGE_ARRAY_SIZE = 200;\n\n /** Error message constants. */\n var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',\n FUNC_ERROR_TEXT = 'Expected a function',\n INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`';\n\n /** Used to stand-in for `undefined` hash values. */\n var HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n /** Used as the maximum memoize cache size. */\n var MAX_MEMOIZE_SIZE = 500;\n\n /** Used as the internal argument placeholder. */\n var PLACEHOLDER = '__lodash_placeholder__';\n\n /** Used to compose bitmasks for cloning. */\n var CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n /** Used to compose bitmasks for value comparisons. */\n var COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n /** Used to compose bitmasks for function metadata. */\n var WRAP_BIND_FLAG = 1,\n WRAP_BIND_KEY_FLAG = 2,\n WRAP_CURRY_BOUND_FLAG = 4,\n WRAP_CURRY_FLAG = 8,\n WRAP_CURRY_RIGHT_FLAG = 16,\n WRAP_PARTIAL_FLAG = 32,\n WRAP_PARTIAL_RIGHT_FLAG = 64,\n WRAP_ARY_FLAG = 128,\n WRAP_REARG_FLAG = 256,\n WRAP_FLIP_FLAG = 512;\n\n /** Used as default options for `_.truncate`. */\n var DEFAULT_TRUNC_LENGTH = 30,\n DEFAULT_TRUNC_OMISSION = '...';\n\n /** Used to detect hot functions by number of calls within a span of milliseconds. */\n var HOT_COUNT = 800,\n HOT_SPAN = 16;\n\n /** Used to indicate the type of lazy iteratees. */\n var LAZY_FILTER_FLAG = 1,\n LAZY_MAP_FLAG = 2,\n LAZY_WHILE_FLAG = 3;\n\n /** Used as references for various `Number` constants. */\n var INFINITY = 1 / 0,\n MAX_SAFE_INTEGER = 9007199254740991,\n MAX_INTEGER = 1.7976931348623157e+308,\n NAN = 0 / 0;\n\n /** Used as references for the maximum length and index of an array. */\n var MAX_ARRAY_LENGTH = 4294967295,\n MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,\n HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;\n\n /** Used to associate wrap methods with their bit flags. */\n var wrapFlags = [\n ['ary', WRAP_ARY_FLAG],\n ['bind', WRAP_BIND_FLAG],\n ['bindKey', WRAP_BIND_KEY_FLAG],\n ['curry', WRAP_CURRY_FLAG],\n ['curryRight', WRAP_CURRY_RIGHT_FLAG],\n ['flip', WRAP_FLIP_FLAG],\n ['partial', WRAP_PARTIAL_FLAG],\n ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],\n ['rearg', WRAP_REARG_FLAG]\n ];\n\n /** `Object#toString` result references. */\n var argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n asyncTag = '[object AsyncFunction]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n domExcTag = '[object DOMException]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n nullTag = '[object Null]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n proxyTag = '[object Proxy]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n undefinedTag = '[object Undefined]',\n weakMapTag = '[object WeakMap]',\n weakSetTag = '[object WeakSet]';\n\n var arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n /** Used to match empty string literals in compiled template source. */\n var reEmptyStringLeading = /\\b__p \\+= '';/g,\n reEmptyStringMiddle = /\\b(__p \\+=) '' \\+/g,\n reEmptyStringTrailing = /(__e\\(.*?\\)|\\b__t\\)) \\+\\n'';/g;\n\n /** Used to match HTML entities and HTML characters. */\n var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,\n reUnescapedHtml = /[&<>\"']/g,\n reHasEscapedHtml = RegExp(reEscapedHtml.source),\n reHasUnescapedHtml = RegExp(reUnescapedHtml.source);\n\n /** Used to match template delimiters. */\n var reEscape = /<%-([\\s\\S]+?)%>/g,\n reEvaluate = /<%([\\s\\S]+?)%>/g,\n reInterpolate = /<%=([\\s\\S]+?)%>/g;\n\n /** Used to match property names within property paths. */\n var reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/,\n rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n /**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\n var reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g,\n reHasRegExpChar = RegExp(reRegExpChar.source);\n\n /** Used to match leading whitespace. */\n var reTrimStart = /^\\s+/;\n\n /** Used to match a single whitespace character. */\n var reWhitespace = /\\s/;\n\n /** Used to match wrap detail comments. */\n var reWrapComment = /\\{(?:\\n\\/\\* \\[wrapped with .+\\] \\*\\/)?\\n?/,\n reWrapDetails = /\\{\\n\\/\\* \\[wrapped with (.+)\\] \\*/,\n reSplitDetails = /,? & /;\n\n /** Used to match words composed of alphanumeric characters. */\n var reAsciiWord = /[^\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7f]+/g;\n\n /**\n * Used to validate the `validate` option in `_.template` variable.\n *\n * Forbids characters which could potentially change the meaning of the function argument definition:\n * - \"(),\" (modification of function parameters)\n * - \"=\" (default value)\n * - \"[]{}\" (destructuring of function parameters)\n * - \"/\" (beginning of a comment)\n * - whitespace\n */\n var reForbiddenIdentifierChars = /[()=,{}\\[\\]\\/\\s]/;\n\n /** Used to match backslashes in property paths. */\n var reEscapeChar = /\\\\(\\\\)?/g;\n\n /**\n * Used to match\n * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).\n */\n var reEsTemplate = /\\$\\{([^\\\\}]*(?:\\\\.[^\\\\}]*)*)\\}/g;\n\n /** Used to match `RegExp` flags from their coerced string values. */\n var reFlags = /\\w*$/;\n\n /** Used to detect bad signed hexadecimal string values. */\n var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n /** Used to detect binary string values. */\n var reIsBinary = /^0b[01]+$/i;\n\n /** Used to detect host constructors (Safari). */\n var reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n /** Used to detect octal string values. */\n var reIsOctal = /^0o[0-7]+$/i;\n\n /** Used to detect unsigned integer values. */\n var reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n /** Used to match Latin Unicode letters (excluding mathematical operators). */\n var reLatin = /[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g;\n\n /** Used to ensure capturing order of template delimiters. */\n var reNoMatch = /($^)/;\n\n /** Used to match unescaped characters in compiled string literals. */\n var reUnescapedString = /['\\n\\r\\u2028\\u2029\\\\]/g;\n\n /** Used to compose unicode character classes. */\n var rsAstralRange = '\\\\ud800-\\\\udfff',\n rsComboMarksRange = '\\\\u0300-\\\\u036f',\n reComboHalfMarksRange = '\\\\ufe20-\\\\ufe2f',\n rsComboSymbolsRange = '\\\\u20d0-\\\\u20ff',\n rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,\n rsDingbatRange = '\\\\u2700-\\\\u27bf',\n rsLowerRange = 'a-z\\\\xdf-\\\\xf6\\\\xf8-\\\\xff',\n rsMathOpRange = '\\\\xac\\\\xb1\\\\xd7\\\\xf7',\n rsNonCharRange = '\\\\x00-\\\\x2f\\\\x3a-\\\\x40\\\\x5b-\\\\x60\\\\x7b-\\\\xbf',\n rsPunctuationRange = '\\\\u2000-\\\\u206f',\n rsSpaceRange = ' \\\\t\\\\x0b\\\\f\\\\xa0\\\\ufeff\\\\n\\\\r\\\\u2028\\\\u2029\\\\u1680\\\\u180e\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200a\\\\u202f\\\\u205f\\\\u3000',\n rsUpperRange = 'A-Z\\\\xc0-\\\\xd6\\\\xd8-\\\\xde',\n rsVarRange = '\\\\ufe0e\\\\ufe0f',\n rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;\n\n /** Used to compose unicode capture groups. */\n var rsApos = \"['\\u2019]\",\n rsAstral = '[' + rsAstralRange + ']',\n rsBreak = '[' + rsBreakRange + ']',\n rsCombo = '[' + rsComboRange + ']',\n rsDigits = '\\\\d+',\n rsDingbat = '[' + rsDingbatRange + ']',\n rsLower = '[' + rsLowerRange + ']',\n rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',\n rsFitz = '\\\\ud83c[\\\\udffb-\\\\udfff]',\n rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',\n rsNonAstral = '[^' + rsAstralRange + ']',\n rsRegional = '(?:\\\\ud83c[\\\\udde6-\\\\uddff]){2}',\n rsSurrPair = '[\\\\ud800-\\\\udbff][\\\\udc00-\\\\udfff]',\n rsUpper = '[' + rsUpperRange + ']',\n rsZWJ = '\\\\u200d';\n\n /** Used to compose unicode regexes. */\n var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',\n rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',\n rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',\n rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',\n reOptMod = rsModifier + '?',\n rsOptVar = '[' + rsVarRange + ']?',\n rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',\n rsOrdLower = '\\\\d*(?:1st|2nd|3rd|(?![123])\\\\dth)(?=\\\\b|[A-Z_])',\n rsOrdUpper = '\\\\d*(?:1ST|2ND|3RD|(?![123])\\\\dTH)(?=\\\\b|[a-z_])',\n rsSeq = rsOptVar + reOptMod + rsOptJoin,\n rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,\n rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';\n\n /** Used to match apostrophes. */\n var reApos = RegExp(rsApos, 'g');\n\n /**\n * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and\n * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).\n */\n var reComboMark = RegExp(rsCombo, 'g');\n\n /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */\n var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');\n\n /** Used to match complex or compound words. */\n var reUnicodeWord = RegExp([\n rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',\n rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',\n rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,\n rsUpper + '+' + rsOptContrUpper,\n rsOrdUpper,\n rsOrdLower,\n rsDigits,\n rsEmoji\n ].join('|'), 'g');\n\n /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */\n var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');\n\n /** Used to detect strings that need a more robust regexp to match words. */\n var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;\n\n /** Used to assign default `context` object properties. */\n var contextProps = [\n 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',\n 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',\n 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',\n 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',\n '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'\n ];\n\n /** Used to make template sourceURLs easier to identify. */\n var templateCounter = -1;\n\n /** Used to identify `toStringTag` values of typed arrays. */\n var typedArrayTags = {};\n typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\n typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\n typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\n typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\n typedArrayTags[uint32Tag] = true;\n typedArrayTags[argsTag] = typedArrayTags[arrayTag] =\n typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\n typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\n typedArrayTags[errorTag] = typedArrayTags[funcTag] =\n typedArrayTags[mapTag] = typedArrayTags[numberTag] =\n typedArrayTags[objectTag] = typedArrayTags[regexpTag] =\n typedArrayTags[setTag] = typedArrayTags[stringTag] =\n typedArrayTags[weakMapTag] = false;\n\n /** Used to identify `toStringTag` values supported by `_.clone`. */\n var cloneableTags = {};\n cloneableTags[argsTag] = cloneableTags[arrayTag] =\n cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\n cloneableTags[boolTag] = cloneableTags[dateTag] =\n cloneableTags[float32Tag] = cloneableTags[float64Tag] =\n cloneableTags[int8Tag] = cloneableTags[int16Tag] =\n cloneableTags[int32Tag] = cloneableTags[mapTag] =\n cloneableTags[numberTag] = cloneableTags[objectTag] =\n cloneableTags[regexpTag] = cloneableTags[setTag] =\n cloneableTags[stringTag] = cloneableTags[symbolTag] =\n cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\n cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\n cloneableTags[errorTag] = cloneableTags[funcTag] =\n cloneableTags[weakMapTag] = false;\n\n /** Used to map Latin Unicode letters to basic Latin letters. */\n var deburredLetters = {\n // Latin-1 Supplement block.\n '\\xc0': 'A', '\\xc1': 'A', '\\xc2': 'A', '\\xc3': 'A', '\\xc4': 'A', '\\xc5': 'A',\n '\\xe0': 'a', '\\xe1': 'a', '\\xe2': 'a', '\\xe3': 'a', '\\xe4': 'a', '\\xe5': 'a',\n '\\xc7': 'C', '\\xe7': 'c',\n '\\xd0': 'D', '\\xf0': 'd',\n '\\xc8': 'E', '\\xc9': 'E', '\\xca': 'E', '\\xcb': 'E',\n '\\xe8': 'e', '\\xe9': 'e', '\\xea': 'e', '\\xeb': 'e',\n '\\xcc': 'I', '\\xcd': 'I', '\\xce': 'I', '\\xcf': 'I',\n '\\xec': 'i', '\\xed': 'i', '\\xee': 'i', '\\xef': 'i',\n '\\xd1': 'N', '\\xf1': 'n',\n '\\xd2': 'O', '\\xd3': 'O', '\\xd4': 'O', '\\xd5': 'O', '\\xd6': 'O', '\\xd8': 'O',\n '\\xf2': 'o', '\\xf3': 'o', '\\xf4': 'o', '\\xf5': 'o', '\\xf6': 'o', '\\xf8': 'o',\n '\\xd9': 'U', '\\xda': 'U', '\\xdb': 'U', '\\xdc': 'U',\n '\\xf9': 'u', '\\xfa': 'u', '\\xfb': 'u', '\\xfc': 'u',\n '\\xdd': 'Y', '\\xfd': 'y', '\\xff': 'y',\n '\\xc6': 'Ae', '\\xe6': 'ae',\n '\\xde': 'Th', '\\xfe': 'th',\n '\\xdf': 'ss',\n // Latin Extended-A block.\n '\\u0100': 'A', '\\u0102': 'A', '\\u0104': 'A',\n '\\u0101': 'a', '\\u0103': 'a', '\\u0105': 'a',\n '\\u0106': 'C', '\\u0108': 'C', '\\u010a': 'C', '\\u010c': 'C',\n '\\u0107': 'c', '\\u0109': 'c', '\\u010b': 'c', '\\u010d': 'c',\n '\\u010e': 'D', '\\u0110': 'D', '\\u010f': 'd', '\\u0111': 'd',\n '\\u0112': 'E', '\\u0114': 'E', '\\u0116': 'E', '\\u0118': 'E', '\\u011a': 'E',\n '\\u0113': 'e', '\\u0115': 'e', '\\u0117': 'e', '\\u0119': 'e', '\\u011b': 'e',\n '\\u011c': 'G', '\\u011e': 'G', '\\u0120': 'G', '\\u0122': 'G',\n '\\u011d': 'g', '\\u011f': 'g', '\\u0121': 'g', '\\u0123': 'g',\n '\\u0124': 'H', '\\u0126': 'H', '\\u0125': 'h', '\\u0127': 'h',\n '\\u0128': 'I', '\\u012a': 'I', '\\u012c': 'I', '\\u012e': 'I', '\\u0130': 'I',\n '\\u0129': 'i', '\\u012b': 'i', '\\u012d': 'i', '\\u012f': 'i', '\\u0131': 'i',\n '\\u0134': 'J', '\\u0135': 'j',\n '\\u0136': 'K', '\\u0137': 'k', '\\u0138': 'k',\n '\\u0139': 'L', '\\u013b': 'L', '\\u013d': 'L', '\\u013f': 'L', '\\u0141': 'L',\n '\\u013a': 'l', '\\u013c': 'l', '\\u013e': 'l', '\\u0140': 'l', '\\u0142': 'l',\n '\\u0143': 'N', '\\u0145': 'N', '\\u0147': 'N', '\\u014a': 'N',\n '\\u0144': 'n', '\\u0146': 'n', '\\u0148': 'n', '\\u014b': 'n',\n '\\u014c': 'O', '\\u014e': 'O', '\\u0150': 'O',\n '\\u014d': 'o', '\\u014f': 'o', '\\u0151': 'o',\n '\\u0154': 'R', '\\u0156': 'R', '\\u0158': 'R',\n '\\u0155': 'r', '\\u0157': 'r', '\\u0159': 'r',\n '\\u015a': 'S', '\\u015c': 'S', '\\u015e': 'S', '\\u0160': 'S',\n '\\u015b': 's', '\\u015d': 's', '\\u015f': 's', '\\u0161': 's',\n '\\u0162': 'T', '\\u0164': 'T', '\\u0166': 'T',\n '\\u0163': 't', '\\u0165': 't', '\\u0167': 't',\n '\\u0168': 'U', '\\u016a': 'U', '\\u016c': 'U', '\\u016e': 'U', '\\u0170': 'U', '\\u0172': 'U',\n '\\u0169': 'u', '\\u016b': 'u', '\\u016d': 'u', '\\u016f': 'u', '\\u0171': 'u', '\\u0173': 'u',\n '\\u0174': 'W', '\\u0175': 'w',\n '\\u0176': 'Y', '\\u0177': 'y', '\\u0178': 'Y',\n '\\u0179': 'Z', '\\u017b': 'Z', '\\u017d': 'Z',\n '\\u017a': 'z', '\\u017c': 'z', '\\u017e': 'z',\n '\\u0132': 'IJ', '\\u0133': 'ij',\n '\\u0152': 'Oe', '\\u0153': 'oe',\n '\\u0149': \"'n\", '\\u017f': 's'\n };\n\n /** Used to map characters to HTML entities. */\n var htmlEscapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n\n /** Used to map HTML entities to characters. */\n var htmlUnescapes = {\n '&': '&',\n '<': '<',\n '>': '>',\n '"': '\"',\n ''': \"'\"\n };\n\n /** Used to escape characters for inclusion in compiled string literals. */\n var stringEscapes = {\n '\\\\': '\\\\',\n \"'\": \"'\",\n '\\n': 'n',\n '\\r': 'r',\n '\\u2028': 'u2028',\n '\\u2029': 'u2029'\n };\n\n /** Built-in method references without a dependency on `root`. */\n var freeParseFloat = parseFloat,\n freeParseInt = parseInt;\n\n /** Detect free variable `global` from Node.js. */\n var freeGlobal = typeof __webpack_require__.g == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g;\n\n /** Detect free variable `self`. */\n var freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n /** Used as a reference to the global object. */\n var root = freeGlobal || freeSelf || Function('return this')();\n\n /** Detect free variable `exports`. */\n var freeExports = true && exports && !exports.nodeType && exports;\n\n /** Detect free variable `module`. */\n var freeModule = freeExports && \"object\" == 'object' && module && !module.nodeType && module;\n\n /** Detect the popular CommonJS extension `module.exports`. */\n var moduleExports = freeModule && freeModule.exports === freeExports;\n\n /** Detect free variable `process` from Node.js. */\n var freeProcess = moduleExports && freeGlobal.process;\n\n /** Used to access faster Node.js helpers. */\n var nodeUtil = (function() {\n try {\n // Use `util.types` for Node.js 10+.\n var types = freeModule && freeModule.require && freeModule.require('util').types;\n\n if (types) {\n return types;\n }\n\n // Legacy `process.binding('util')` for Node.js < 10.\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n }());\n\n /* Node.js helper references. */\n var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,\n nodeIsDate = nodeUtil && nodeUtil.isDate,\n nodeIsMap = nodeUtil && nodeUtil.isMap,\n nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,\n nodeIsSet = nodeUtil && nodeUtil.isSet,\n nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n /*--------------------------------------------------------------------------*/\n\n /**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\n function apply(func, thisArg, args) {\n switch (args.length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n }\n\n /**\n * A specialized version of `baseAggregator` for arrays.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\n function arrayAggregator(array, setter, iteratee, accumulator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n var value = array[index];\n setter(accumulator, value, iteratee(value), array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\n function arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n }\n\n /**\n * A specialized version of `_.forEachRight` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\n function arrayEachRight(array, iteratee) {\n var length = array == null ? 0 : array.length;\n\n while (length--) {\n if (iteratee(array[length], length, array) === false) {\n break;\n }\n }\n return array;\n }\n\n /**\n * A specialized version of `_.every` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`.\n */\n function arrayEvery(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (!predicate(array[index], index, array)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\n function arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `_.includes` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\n function arrayIncludes(array, value) {\n var length = array == null ? 0 : array.length;\n return !!length && baseIndexOf(array, value, 0) > -1;\n }\n\n /**\n * This function is like `arrayIncludes` except that it accepts a comparator.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\n function arrayIncludesWith(array, value, comparator) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (comparator(value, array[index])) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\n function arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n }\n\n /**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\n function arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n }\n\n /**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\n function arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.reduceRight` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the last element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\n function arrayReduceRight(array, iteratee, accumulator, initAccum) {\n var length = array == null ? 0 : array.length;\n if (initAccum && length) {\n accumulator = array[--length];\n }\n while (length--) {\n accumulator = iteratee(accumulator, array[length], length, array);\n }\n return accumulator;\n }\n\n /**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\n function arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets the size of an ASCII `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\n var asciiSize = baseProperty('length');\n\n /**\n * Converts an ASCII `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function asciiToArray(string) {\n return string.split('');\n }\n\n /**\n * Splits an ASCII `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\n function asciiWords(string) {\n return string.match(reAsciiWord) || [];\n }\n\n /**\n * The base implementation of methods like `_.findKey` and `_.findLastKey`,\n * without support for iteratee shorthands, which iterates over `collection`\n * using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the found element or its key, else `undefined`.\n */\n function baseFindKey(collection, predicate, eachFunc) {\n var result;\n eachFunc(collection, function(value, key, collection) {\n if (predicate(value, key, collection)) {\n result = key;\n return false;\n }\n });\n return result;\n }\n\n /**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseIndexOf(array, value, fromIndex) {\n return value === value\n ? strictIndexOf(array, value, fromIndex)\n : baseFindIndex(array, baseIsNaN, fromIndex);\n }\n\n /**\n * This function is like `baseIndexOf` except that it accepts a comparator.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @param {Function} comparator The comparator invoked per element.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function baseIndexOfWith(array, value, fromIndex, comparator) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (comparator(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\n function baseIsNaN(value) {\n return value !== value;\n }\n\n /**\n * The base implementation of `_.mean` and `_.meanBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the mean.\n */\n function baseMean(array, iteratee) {\n var length = array == null ? 0 : array.length;\n return length ? (baseSum(array, iteratee) / length) : NAN;\n }\n\n /**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\n function baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n }\n\n /**\n * The base implementation of `_.propertyOf` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Function} Returns the new accessor function.\n */\n function basePropertyOf(object) {\n return function(key) {\n return object == null ? undefined : object[key];\n };\n }\n\n /**\n * The base implementation of `_.reduce` and `_.reduceRight`, without support\n * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} accumulator The initial value.\n * @param {boolean} initAccum Specify using the first or last element of\n * `collection` as the initial value.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the accumulated value.\n */\n function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n eachFunc(collection, function(value, index, collection) {\n accumulator = initAccum\n ? (initAccum = false, value)\n : iteratee(accumulator, value, index, collection);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.sortBy` which uses `comparer` to define the\n * sort order of `array` and replaces criteria objects with their corresponding\n * values.\n *\n * @private\n * @param {Array} array The array to sort.\n * @param {Function} comparer The function to define sort order.\n * @returns {Array} Returns `array`.\n */\n function baseSortBy(array, comparer) {\n var length = array.length;\n\n array.sort(comparer);\n while (length--) {\n array[length] = array[length].value;\n }\n return array;\n }\n\n /**\n * The base implementation of `_.sum` and `_.sumBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the sum.\n */\n function baseSum(array, iteratee) {\n var result,\n index = -1,\n length = array.length;\n\n while (++index < length) {\n var current = iteratee(array[index]);\n if (current !== undefined) {\n result = result === undefined ? current : (result + current);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\n function baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n }\n\n /**\n * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array\n * of key-value pairs for `object` corresponding to the property names of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the key-value pairs.\n */\n function baseToPairs(object, props) {\n return arrayMap(props, function(key) {\n return [key, object[key]];\n });\n }\n\n /**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\n function baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n }\n\n /**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\n function baseUnary(func) {\n return function(value) {\n return func(value);\n };\n }\n\n /**\n * The base implementation of `_.values` and `_.valuesIn` which creates an\n * array of `object` property values corresponding to the property names\n * of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the array of property values.\n */\n function baseValues(object, props) {\n return arrayMap(props, function(key) {\n return object[key];\n });\n }\n\n /**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function cacheHas(cache, key) {\n return cache.has(key);\n }\n\n /**\n * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the first unmatched string symbol.\n */\n function charsStartIndex(strSymbols, chrSymbols) {\n var index = -1,\n length = strSymbols.length;\n\n while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n return index;\n }\n\n /**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol\n * that is not found in the character symbols.\n *\n * @private\n * @param {Array} strSymbols The string symbols to inspect.\n * @param {Array} chrSymbols The character symbols to find.\n * @returns {number} Returns the index of the last unmatched string symbol.\n */\n function charsEndIndex(strSymbols, chrSymbols) {\n var index = strSymbols.length;\n\n while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}\n return index;\n }\n\n /**\n * Gets the number of `placeholder` occurrences in `array`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} placeholder The placeholder to search for.\n * @returns {number} Returns the placeholder count.\n */\n function countHolders(array, placeholder) {\n var length = array.length,\n result = 0;\n\n while (length--) {\n if (array[length] === placeholder) {\n ++result;\n }\n }\n return result;\n }\n\n /**\n * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A\n * letters to basic Latin letters.\n *\n * @private\n * @param {string} letter The matched letter to deburr.\n * @returns {string} Returns the deburred letter.\n */\n var deburrLetter = basePropertyOf(deburredLetters);\n\n /**\n * Used by `_.escape` to convert characters to HTML entities.\n *\n * @private\n * @param {string} chr The matched character to escape.\n * @returns {string} Returns the escaped character.\n */\n var escapeHtmlChar = basePropertyOf(htmlEscapes);\n\n /**\n * Used by `_.template` to escape characters for inclusion in compiled string literals.\n *\n * @private\n * @param {string} chr The matched character to escape.\n * @returns {string} Returns the escaped character.\n */\n function escapeStringChar(chr) {\n return '\\\\' + stringEscapes[chr];\n }\n\n /**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\n function getValue(object, key) {\n return object == null ? undefined : object[key];\n }\n\n /**\n * Checks if `string` contains Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a symbol is found, else `false`.\n */\n function hasUnicode(string) {\n return reHasUnicode.test(string);\n }\n\n /**\n * Checks if `string` contains a word composed of Unicode symbols.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {boolean} Returns `true` if a word is found, else `false`.\n */\n function hasUnicodeWord(string) {\n return reHasUnicodeWord.test(string);\n }\n\n /**\n * Converts `iterator` to an array.\n *\n * @private\n * @param {Object} iterator The iterator to convert.\n * @returns {Array} Returns the converted array.\n */\n function iteratorToArray(iterator) {\n var data,\n result = [];\n\n while (!(data = iterator.next()).done) {\n result.push(data.value);\n }\n return result;\n }\n\n /**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\n function mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n }\n\n /**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\n function overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n }\n\n /**\n * Replaces all `placeholder` elements in `array` with an internal placeholder\n * and returns an array of their indexes.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {*} placeholder The placeholder to replace.\n * @returns {Array} Returns the new array of placeholder indexes.\n */\n function replaceHolders(array, placeholder) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value === placeholder || value === PLACEHOLDER) {\n array[index] = PLACEHOLDER;\n result[resIndex++] = index;\n }\n }\n return result;\n }\n\n /**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\n function setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n }\n\n /**\n * Converts `set` to its value-value pairs.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the value-value pairs.\n */\n function setToPairs(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = [value, value];\n });\n return result;\n }\n\n /**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * A specialized version of `_.lastIndexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function strictLastIndexOf(array, value, fromIndex) {\n var index = fromIndex + 1;\n while (index--) {\n if (array[index] === value) {\n return index;\n }\n }\n return index;\n }\n\n /**\n * Gets the number of symbols in `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the string size.\n */\n function stringSize(string) {\n return hasUnicode(string)\n ? unicodeSize(string)\n : asciiSize(string);\n }\n\n /**\n * Converts `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function stringToArray(string) {\n return hasUnicode(string)\n ? unicodeToArray(string)\n : asciiToArray(string);\n }\n\n /**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\n function trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n }\n\n /**\n * Used by `_.unescape` to convert HTML entities to characters.\n *\n * @private\n * @param {string} chr The matched character to unescape.\n * @returns {string} Returns the unescaped character.\n */\n var unescapeHtmlChar = basePropertyOf(htmlUnescapes);\n\n /**\n * Gets the size of a Unicode `string`.\n *\n * @private\n * @param {string} string The string inspect.\n * @returns {number} Returns the string size.\n */\n function unicodeSize(string) {\n var result = reUnicode.lastIndex = 0;\n while (reUnicode.test(string)) {\n ++result;\n }\n return result;\n }\n\n /**\n * Converts a Unicode `string` to an array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the converted array.\n */\n function unicodeToArray(string) {\n return string.match(reUnicode) || [];\n }\n\n /**\n * Splits a Unicode `string` into an array of its words.\n *\n * @private\n * @param {string} The string to inspect.\n * @returns {Array} Returns the words of `string`.\n */\n function unicodeWords(string) {\n return string.match(reUnicodeWord) || [];\n }\n\n /*--------------------------------------------------------------------------*/\n\n /**\n * Create a new pristine `lodash` function using the `context` object.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Util\n * @param {Object} [context=root] The context object.\n * @returns {Function} Returns a new `lodash` function.\n * @example\n *\n * _.mixin({ 'foo': _.constant('foo') });\n *\n * var lodash = _.runInContext();\n * lodash.mixin({ 'bar': lodash.constant('bar') });\n *\n * _.isFunction(_.foo);\n * // => true\n * _.isFunction(_.bar);\n * // => false\n *\n * lodash.isFunction(lodash.foo);\n * // => false\n * lodash.isFunction(lodash.bar);\n * // => true\n *\n * // Create a suped-up `defer` in Node.js.\n * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;\n */\n var runInContext = (function runInContext(context) {\n context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));\n\n /** Built-in constructor references. */\n var Array = context.Array,\n Date = context.Date,\n Error = context.Error,\n Function = context.Function,\n Math = context.Math,\n Object = context.Object,\n RegExp = context.RegExp,\n String = context.String,\n TypeError = context.TypeError;\n\n /** Used for built-in method references. */\n var arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n /** Used to detect overreaching core-js shims. */\n var coreJsData = context['__core-js_shared__'];\n\n /** Used to resolve the decompiled source of functions. */\n var funcToString = funcProto.toString;\n\n /** Used to check objects for own properties. */\n var hasOwnProperty = objectProto.hasOwnProperty;\n\n /** Used to generate unique IDs. */\n var idCounter = 0;\n\n /** Used to detect methods masquerading as native. */\n var maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n }());\n\n /**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\n var nativeObjectToString = objectProto.toString;\n\n /** Used to infer the `Object` constructor. */\n var objectCtorString = funcToString.call(Object);\n\n /** Used to restore the original `_` reference in `_.noConflict`. */\n var oldDash = root._;\n\n /** Used to detect if a method is native. */\n var reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n );\n\n /** Built-in value references. */\n var Buffer = moduleExports ? context.Buffer : undefined,\n Symbol = context.Symbol,\n Uint8Array = context.Uint8Array,\n allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice,\n spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,\n symIterator = Symbol ? Symbol.iterator : undefined,\n symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n var defineProperty = (function() {\n try {\n var func = getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n }());\n\n /** Mocked built-ins. */\n var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,\n ctxNow = Date && Date.now !== root.Date.now && Date.now,\n ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;\n\n /* Built-in method references for those with the same name as other `lodash` methods. */\n var nativeCeil = Math.ceil,\n nativeFloor = Math.floor,\n nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeIsFinite = context.isFinite,\n nativeJoin = arrayProto.join,\n nativeKeys = overArg(Object.keys, Object),\n nativeMax = Math.max,\n nativeMin = Math.min,\n nativeNow = Date.now,\n nativeParseInt = context.parseInt,\n nativeRandom = Math.random,\n nativeReverse = arrayProto.reverse;\n\n /* Built-in method references that are verified to be native. */\n var DataView = getNative(context, 'DataView'),\n Map = getNative(context, 'Map'),\n Promise = getNative(context, 'Promise'),\n Set = getNative(context, 'Set'),\n WeakMap = getNative(context, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n /** Used to store function metadata. */\n var metaMap = WeakMap && new WeakMap;\n\n /** Used to lookup unminified function names. */\n var realNames = {};\n\n /** Used to detect maps, sets, and weakmaps. */\n var dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n /** Used to convert symbols to primitives and strings. */\n var symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a `lodash` object which wraps `value` to enable implicit method\n * chain sequences. Methods that operate on and return arrays, collections,\n * and functions can be chained together. Methods that retrieve a single value\n * or may return a primitive value will automatically end the chain sequence\n * and return the unwrapped value. Otherwise, the value must be unwrapped\n * with `_#value`.\n *\n * Explicit chain sequences, which must be unwrapped with `_#value`, may be\n * enabled using `_.chain`.\n *\n * The execution of chained methods is lazy, that is, it's deferred until\n * `_#value` is implicitly or explicitly called.\n *\n * Lazy evaluation allows several methods to support shortcut fusion.\n * Shortcut fusion is an optimization to merge iteratee calls; this avoids\n * the creation of intermediate arrays and can greatly reduce the number of\n * iteratee executions. Sections of a chain sequence qualify for shortcut\n * fusion if the section is applied to an array and iteratees accept only\n * one argument. The heuristic for whether a section qualifies for shortcut\n * fusion is subject to change.\n *\n * Chaining is supported in custom builds as long as the `_#value` method is\n * directly or indirectly included in the build.\n *\n * In addition to lodash methods, wrappers have `Array` and `String` methods.\n *\n * The wrapper `Array` methods are:\n * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`\n *\n * The wrapper `String` methods are:\n * `replace` and `split`\n *\n * The wrapper methods that support shortcut fusion are:\n * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,\n * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,\n * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`\n *\n * The chainable wrapper methods are:\n * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,\n * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,\n * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,\n * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,\n * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,\n * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,\n * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,\n * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,\n * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,\n * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,\n * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,\n * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,\n * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,\n * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,\n * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,\n * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,\n * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,\n * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,\n * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,\n * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,\n * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,\n * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,\n * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,\n * `zipObject`, `zipObjectDeep`, and `zipWith`\n *\n * The wrapper methods that are **not** chainable by default are:\n * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,\n * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,\n * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,\n * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,\n * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,\n * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,\n * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,\n * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,\n * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,\n * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,\n * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,\n * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,\n * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,\n * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,\n * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,\n * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,\n * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,\n * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,\n * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,\n * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,\n * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,\n * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,\n * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,\n * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,\n * `upperFirst`, `value`, and `words`\n *\n * @name _\n * @constructor\n * @category Seq\n * @param {*} value The value to wrap in a `lodash` instance.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var wrapped = _([1, 2, 3]);\n *\n * // Returns an unwrapped value.\n * wrapped.reduce(_.add);\n * // => 6\n *\n * // Returns a wrapped value.\n * var squares = wrapped.map(square);\n *\n * _.isArray(squares);\n * // => false\n *\n * _.isArray(squares.value());\n * // => true\n */\n function lodash(value) {\n if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {\n if (value instanceof LodashWrapper) {\n return value;\n }\n if (hasOwnProperty.call(value, '__wrapped__')) {\n return wrapperClone(value);\n }\n }\n return new LodashWrapper(value);\n }\n\n /**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} proto The object to inherit from.\n * @returns {Object} Returns the new object.\n */\n var baseCreate = (function() {\n function object() {}\n return function(proto) {\n if (!isObject(proto)) {\n return {};\n }\n if (objectCreate) {\n return objectCreate(proto);\n }\n object.prototype = proto;\n var result = new object;\n object.prototype = undefined;\n return result;\n };\n }());\n\n /**\n * The function whose prototype chain sequence wrappers inherit from.\n *\n * @private\n */\n function baseLodash() {\n // No operation performed.\n }\n\n /**\n * The base constructor for creating `lodash` wrapper objects.\n *\n * @private\n * @param {*} value The value to wrap.\n * @param {boolean} [chainAll] Enable explicit method chain sequences.\n */\n function LodashWrapper(value, chainAll) {\n this.__wrapped__ = value;\n this.__actions__ = [];\n this.__chain__ = !!chainAll;\n this.__index__ = 0;\n this.__values__ = undefined;\n }\n\n /**\n * By default, the template delimiters used by lodash are like those in\n * embedded Ruby (ERB) as well as ES2015 template strings. Change the\n * following template settings to use alternative delimiters.\n *\n * @static\n * @memberOf _\n * @type {Object}\n */\n lodash.templateSettings = {\n\n /**\n * Used to detect `data` property values to be HTML-escaped.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'escape': reEscape,\n\n /**\n * Used to detect code to be evaluated.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'evaluate': reEvaluate,\n\n /**\n * Used to detect `data` property values to inject.\n *\n * @memberOf _.templateSettings\n * @type {RegExp}\n */\n 'interpolate': reInterpolate,\n\n /**\n * Used to reference the data object in the template text.\n *\n * @memberOf _.templateSettings\n * @type {string}\n */\n 'variable': '',\n\n /**\n * Used to import variables into the compiled template.\n *\n * @memberOf _.templateSettings\n * @type {Object}\n */\n 'imports': {\n\n /**\n * A reference to the `lodash` function.\n *\n * @memberOf _.templateSettings.imports\n * @type {Function}\n */\n '_': lodash\n }\n };\n\n // Ensure wrappers are instances of `baseLodash`.\n lodash.prototype = baseLodash.prototype;\n lodash.prototype.constructor = lodash;\n\n LodashWrapper.prototype = baseCreate(baseLodash.prototype);\n LodashWrapper.prototype.constructor = LodashWrapper;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.\n *\n * @private\n * @constructor\n * @param {*} value The value to wrap.\n */\n function LazyWrapper(value) {\n this.__wrapped__ = value;\n this.__actions__ = [];\n this.__dir__ = 1;\n this.__filtered__ = false;\n this.__iteratees__ = [];\n this.__takeCount__ = MAX_ARRAY_LENGTH;\n this.__views__ = [];\n }\n\n /**\n * Creates a clone of the lazy wrapper object.\n *\n * @private\n * @name clone\n * @memberOf LazyWrapper\n * @returns {Object} Returns the cloned `LazyWrapper` object.\n */\n function lazyClone() {\n var result = new LazyWrapper(this.__wrapped__);\n result.__actions__ = copyArray(this.__actions__);\n result.__dir__ = this.__dir__;\n result.__filtered__ = this.__filtered__;\n result.__iteratees__ = copyArray(this.__iteratees__);\n result.__takeCount__ = this.__takeCount__;\n result.__views__ = copyArray(this.__views__);\n return result;\n }\n\n /**\n * Reverses the direction of lazy iteration.\n *\n * @private\n * @name reverse\n * @memberOf LazyWrapper\n * @returns {Object} Returns the new reversed `LazyWrapper` object.\n */\n function lazyReverse() {\n if (this.__filtered__) {\n var result = new LazyWrapper(this);\n result.__dir__ = -1;\n result.__filtered__ = true;\n } else {\n result = this.clone();\n result.__dir__ *= -1;\n }\n return result;\n }\n\n /**\n * Extracts the unwrapped value from its lazy wrapper.\n *\n * @private\n * @name value\n * @memberOf LazyWrapper\n * @returns {*} Returns the unwrapped value.\n */\n function lazyValue() {\n var array = this.__wrapped__.value(),\n dir = this.__dir__,\n isArr = isArray(array),\n isRight = dir < 0,\n arrLength = isArr ? array.length : 0,\n view = getView(0, arrLength, this.__views__),\n start = view.start,\n end = view.end,\n length = end - start,\n index = isRight ? end : (start - 1),\n iteratees = this.__iteratees__,\n iterLength = iteratees.length,\n resIndex = 0,\n takeCount = nativeMin(length, this.__takeCount__);\n\n if (!isArr || (!isRight && arrLength == length && takeCount == length)) {\n return baseWrapperValue(array, this.__actions__);\n }\n var result = [];\n\n outer:\n while (length-- && resIndex < takeCount) {\n index += dir;\n\n var iterIndex = -1,\n value = array[index];\n\n while (++iterIndex < iterLength) {\n var data = iteratees[iterIndex],\n iteratee = data.iteratee,\n type = data.type,\n computed = iteratee(value);\n\n if (type == LAZY_MAP_FLAG) {\n value = computed;\n } else if (!computed) {\n if (type == LAZY_FILTER_FLAG) {\n continue outer;\n } else {\n break outer;\n }\n }\n }\n result[resIndex++] = value;\n }\n return result;\n }\n\n // Ensure `LazyWrapper` is an instance of `baseLodash`.\n LazyWrapper.prototype = baseCreate(baseLodash.prototype);\n LazyWrapper.prototype.constructor = LazyWrapper;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\n function hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n }\n\n /**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n }\n\n /**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n }\n\n /**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\n function hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n }\n\n // Add methods to `Hash`.\n Hash.prototype.clear = hashClear;\n Hash.prototype['delete'] = hashDelete;\n Hash.prototype.get = hashGet;\n Hash.prototype.has = hashHas;\n Hash.prototype.set = hashSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\n function listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n }\n\n /**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n }\n\n /**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n }\n\n /**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\n function listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n }\n\n // Add methods to `ListCache`.\n ListCache.prototype.clear = listCacheClear;\n ListCache.prototype['delete'] = listCacheDelete;\n ListCache.prototype.get = listCacheGet;\n ListCache.prototype.has = listCacheHas;\n ListCache.prototype.set = listCacheSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n }\n\n /**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\n function mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n }\n\n /**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n }\n\n /**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function mapCacheGet(key) {\n return getMapData(this, key).get(key);\n }\n\n /**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function mapCacheHas(key) {\n return getMapData(this, key).has(key);\n }\n\n /**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\n function mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n }\n\n // Add methods to `MapCache`.\n MapCache.prototype.clear = mapCacheClear;\n MapCache.prototype['delete'] = mapCacheDelete;\n MapCache.prototype.get = mapCacheGet;\n MapCache.prototype.has = mapCacheHas;\n MapCache.prototype.set = mapCacheSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\n function SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n }\n\n /**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\n function setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n }\n\n /**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\n function setCacheHas(value) {\n return this.__data__.has(value);\n }\n\n // Add methods to `SetCache`.\n SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\n SetCache.prototype.has = setCacheHas;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\n function Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n }\n\n /**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\n function stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n }\n\n /**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\n function stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n }\n\n /**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\n function stackGet(key) {\n return this.__data__.get(key);\n }\n\n /**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\n function stackHas(key) {\n return this.__data__.has(key);\n }\n\n /**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\n function stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n }\n\n // Add methods to `Stack`.\n Stack.prototype.clear = stackClear;\n Stack.prototype['delete'] = stackDelete;\n Stack.prototype.get = stackGet;\n Stack.prototype.has = stackHas;\n Stack.prototype.set = stackSet;\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\n function arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `_.sample` for arrays.\n *\n * @private\n * @param {Array} array The array to sample.\n * @returns {*} Returns the random element.\n */\n function arraySample(array) {\n var length = array.length;\n return length ? array[baseRandom(0, length - 1)] : undefined;\n }\n\n /**\n * A specialized version of `_.sampleSize` for arrays.\n *\n * @private\n * @param {Array} array The array to sample.\n * @param {number} n The number of elements to sample.\n * @returns {Array} Returns the random elements.\n */\n function arraySampleSize(array, n) {\n return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));\n }\n\n /**\n * A specialized version of `_.shuffle` for arrays.\n *\n * @private\n * @param {Array} array The array to shuffle.\n * @returns {Array} Returns the new shuffled array.\n */\n function arrayShuffle(array) {\n return shuffleSelf(copyArray(array));\n }\n\n /**\n * This function is like `assignValue` except that it doesn't assign\n * `undefined` values.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function assignMergeValue(object, key, value) {\n if ((value !== undefined && !eq(object[key], value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n }\n\n /**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n }\n\n /**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\n function assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n }\n\n /**\n * Aggregates elements of `collection` on `accumulator` with keys transformed\n * by `iteratee` and values set by `setter`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform keys.\n * @param {Object} accumulator The initial aggregated object.\n * @returns {Function} Returns `accumulator`.\n */\n function baseAggregator(collection, setter, iteratee, accumulator) {\n baseEach(collection, function(value, key, collection) {\n setter(accumulator, value, iteratee(value), collection);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\n function baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n }\n\n /**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\n function baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n }\n\n /**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\n function baseAssignValue(object, key, value) {\n if (key == '__proto__' && defineProperty) {\n defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n }\n\n /**\n * The base implementation of `_.at` without support for individual paths.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {string[]} paths The property paths to pick.\n * @returns {Array} Returns the picked elements.\n */\n function baseAt(object, paths) {\n var index = -1,\n length = paths.length,\n result = Array(length),\n skip = object == null;\n\n while (++index < length) {\n result[index] = skip ? undefined : get(object, paths[index]);\n }\n return result;\n }\n\n /**\n * The base implementation of `_.clamp` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n */\n function baseClamp(number, lower, upper) {\n if (number === number) {\n if (upper !== undefined) {\n number = number <= upper ? number : upper;\n }\n if (lower !== undefined) {\n number = number >= lower ? number : lower;\n }\n }\n return number;\n }\n\n /**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\n function baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n }\n\n /**\n * The base implementation of `_.conforms` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property predicates to conform to.\n * @returns {Function} Returns the new spec function.\n */\n function baseConforms(source) {\n var props = keys(source);\n return function(object) {\n return baseConformsTo(object, source, props);\n };\n }\n\n /**\n * The base implementation of `_.conformsTo` which accepts `props` to check.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property predicates to conform to.\n * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n */\n function baseConformsTo(object, source, props) {\n var length = props.length;\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (length--) {\n var key = props[length],\n predicate = source[key],\n value = object[key];\n\n if ((value === undefined && !(key in object)) || !predicate(value)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * The base implementation of `_.delay` and `_.defer` which accepts `args`\n * to provide to `func`.\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {Array} args The arguments to provide to `func`.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\n function baseDelay(func, wait, args) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return setTimeout(function() { func.apply(undefined, args); }, wait);\n }\n\n /**\n * The base implementation of methods like `_.difference` without support\n * for excluding multiple arrays or iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Array} values The values to exclude.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n */\n function baseDifference(array, values, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n isCommon = true,\n length = array.length,\n result = [],\n valuesLength = values.length;\n\n if (!length) {\n return result;\n }\n if (iteratee) {\n values = arrayMap(values, baseUnary(iteratee));\n }\n if (comparator) {\n includes = arrayIncludesWith;\n isCommon = false;\n }\n else if (values.length >= LARGE_ARRAY_SIZE) {\n includes = cacheHas;\n isCommon = false;\n values = new SetCache(values);\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee == null ? value : iteratee(value);\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var valuesIndex = valuesLength;\n while (valuesIndex--) {\n if (values[valuesIndex] === computed) {\n continue outer;\n }\n }\n result.push(value);\n }\n else if (!includes(values, computed, comparator)) {\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.forEach` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\n var baseEach = createBaseEach(baseForOwn);\n\n /**\n * The base implementation of `_.forEachRight` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\n var baseEachRight = createBaseEach(baseForOwnRight, true);\n\n /**\n * The base implementation of `_.every` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`\n */\n function baseEvery(collection, predicate) {\n var result = true;\n baseEach(collection, function(value, index, collection) {\n result = !!predicate(value, index, collection);\n return result;\n });\n return result;\n }\n\n /**\n * The base implementation of methods like `_.max` and `_.min` which accepts a\n * `comparator` to determine the extremum value.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The iteratee invoked per iteration.\n * @param {Function} comparator The comparator used to compare values.\n * @returns {*} Returns the extremum value.\n */\n function baseExtremum(array, iteratee, comparator) {\n var index = -1,\n length = array.length;\n\n while (++index < length) {\n var value = array[index],\n current = iteratee(value);\n\n if (current != null && (computed === undefined\n ? (current === current && !isSymbol(current))\n : comparator(current, computed)\n )) {\n var computed = current,\n result = value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.fill` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n */\n function baseFill(array, value, start, end) {\n var length = array.length;\n\n start = toInteger(start);\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = (end === undefined || end > length) ? length : toInteger(end);\n if (end < 0) {\n end += length;\n }\n end = start > end ? 0 : toLength(end);\n while (start < end) {\n array[start++] = value;\n }\n return array;\n }\n\n /**\n * The base implementation of `_.filter` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\n function baseFilter(collection, predicate) {\n var result = [];\n baseEach(collection, function(value, index, collection) {\n if (predicate(value, index, collection)) {\n result.push(value);\n }\n });\n return result;\n }\n\n /**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\n function baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `baseForOwn` which iterates over `object`\n * properties returned by `keysFunc` and invokes `iteratee` for each property.\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\n var baseFor = createBaseFor();\n\n /**\n * This function is like `baseFor` except that it iterates over properties\n * in the opposite order.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @returns {Object} Returns `object`.\n */\n var baseForRight = createBaseFor(true);\n\n /**\n * The base implementation of `_.forOwn` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\n function baseForOwn(object, iteratee) {\n return object && baseFor(object, iteratee, keys);\n }\n\n /**\n * The base implementation of `_.forOwnRight` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\n function baseForOwnRight(object, iteratee) {\n return object && baseForRight(object, iteratee, keys);\n }\n\n /**\n * The base implementation of `_.functions` which creates an array of\n * `object` function property names filtered from `props`.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Array} props The property names to filter.\n * @returns {Array} Returns the function names.\n */\n function baseFunctions(object, props) {\n return arrayFilter(props, function(key) {\n return isFunction(object[key]);\n });\n }\n\n /**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\n function baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n }\n\n /**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n }\n\n /**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\n function baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n }\n\n /**\n * The base implementation of `_.gt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than `other`,\n * else `false`.\n */\n function baseGt(value, other) {\n return value > other;\n }\n\n /**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\n function baseHas(object, key) {\n return object != null && hasOwnProperty.call(object, key);\n }\n\n /**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\n function baseHasIn(object, key) {\n return object != null && key in Object(object);\n }\n\n /**\n * The base implementation of `_.inRange` which doesn't coerce arguments.\n *\n * @private\n * @param {number} number The number to check.\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n */\n function baseInRange(number, start, end) {\n return number >= nativeMin(start, end) && number < nativeMax(start, end);\n }\n\n /**\n * The base implementation of methods like `_.intersection`, without support\n * for iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of shared values.\n */\n function baseIntersection(arrays, iteratee, comparator) {\n var includes = comparator ? arrayIncludesWith : arrayIncludes,\n length = arrays[0].length,\n othLength = arrays.length,\n othIndex = othLength,\n caches = Array(othLength),\n maxLength = Infinity,\n result = [];\n\n while (othIndex--) {\n var array = arrays[othIndex];\n if (othIndex && iteratee) {\n array = arrayMap(array, baseUnary(iteratee));\n }\n maxLength = nativeMin(array.length, maxLength);\n caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))\n ? new SetCache(othIndex && array)\n : undefined;\n }\n array = arrays[0];\n\n var index = -1,\n seen = caches[0];\n\n outer:\n while (++index < length && result.length < maxLength) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (!(seen\n ? cacheHas(seen, computed)\n : includes(result, computed, comparator)\n )) {\n othIndex = othLength;\n while (--othIndex) {\n var cache = caches[othIndex];\n if (!(cache\n ? cacheHas(cache, computed)\n : includes(arrays[othIndex], computed, comparator))\n ) {\n continue outer;\n }\n }\n if (seen) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.invert` and `_.invertBy` which inverts\n * `object` with values transformed by `iteratee` and set by `setter`.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} setter The function to set `accumulator` values.\n * @param {Function} iteratee The iteratee to transform values.\n * @param {Object} accumulator The initial inverted object.\n * @returns {Function} Returns `accumulator`.\n */\n function baseInverter(object, setter, iteratee, accumulator) {\n baseForOwn(object, function(value, key, object) {\n setter(accumulator, iteratee(value), key, object);\n });\n return accumulator;\n }\n\n /**\n * The base implementation of `_.invoke` without support for individual\n * method arguments.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {Array} args The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n */\n function baseInvoke(object, path, args) {\n path = castPath(path, object);\n object = parent(object, path);\n var func = object == null ? object : object[toKey(last(path))];\n return func == null ? undefined : apply(func, object, args);\n }\n\n /**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\n function baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n }\n\n /**\n * The base implementation of `_.isArrayBuffer` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n */\n function baseIsArrayBuffer(value) {\n return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;\n }\n\n /**\n * The base implementation of `_.isDate` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n */\n function baseIsDate(value) {\n return isObjectLike(value) && baseGetTag(value) == dateTag;\n }\n\n /**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\n function baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n }\n\n /**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n }\n\n /**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\n function baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n }\n\n /**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\n function baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\n function baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n }\n\n /**\n * The base implementation of `_.isRegExp` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n */\n function baseIsRegExp(value) {\n return isObjectLike(value) && baseGetTag(value) == regexpTag;\n }\n\n /**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\n function baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n }\n\n /**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\n function baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n }\n\n /**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\n function baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n }\n\n /**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function baseKeysIn(object) {\n if (!isObject(object)) {\n return nativeKeysIn(object);\n }\n var isProto = isPrototype(object),\n result = [];\n\n for (var key in object) {\n if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.lt` which doesn't coerce arguments.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n * else `false`.\n */\n function baseLt(value, other) {\n return value < other;\n }\n\n /**\n * The base implementation of `_.map` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\n function baseMap(collection, iteratee) {\n var index = -1,\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value, key, collection) {\n result[++index] = iteratee(value, key, collection);\n });\n return result;\n }\n\n /**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\n function baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n }\n\n /**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\n function baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n }\n\n /**\n * The base implementation of `_.merge` without support for multiple sources.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} [customizer] The function to customize merged values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\n function baseMerge(object, source, srcIndex, customizer, stack) {\n if (object === source) {\n return;\n }\n baseFor(source, function(srcValue, key) {\n stack || (stack = new Stack);\n if (isObject(srcValue)) {\n baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);\n }\n else {\n var newValue = customizer\n ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)\n : undefined;\n\n if (newValue === undefined) {\n newValue = srcValue;\n }\n assignMergeValue(object, key, newValue);\n }\n }, keysIn);\n }\n\n /**\n * A specialized version of `baseMerge` for arrays and objects which performs\n * deep merges and tracks traversed objects enabling objects with circular\n * references to be merged.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @param {string} key The key of the value to merge.\n * @param {number} srcIndex The index of `source`.\n * @param {Function} mergeFunc The function to merge values.\n * @param {Function} [customizer] The function to customize assigned values.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n */\n function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {\n var objValue = safeGet(object, key),\n srcValue = safeGet(source, key),\n stacked = stack.get(srcValue);\n\n if (stacked) {\n assignMergeValue(object, key, stacked);\n return;\n }\n var newValue = customizer\n ? customizer(objValue, srcValue, (key + ''), object, source, stack)\n : undefined;\n\n var isCommon = newValue === undefined;\n\n if (isCommon) {\n var isArr = isArray(srcValue),\n isBuff = !isArr && isBuffer(srcValue),\n isTyped = !isArr && !isBuff && isTypedArray(srcValue);\n\n newValue = srcValue;\n if (isArr || isBuff || isTyped) {\n if (isArray(objValue)) {\n newValue = objValue;\n }\n else if (isArrayLikeObject(objValue)) {\n newValue = copyArray(objValue);\n }\n else if (isBuff) {\n isCommon = false;\n newValue = cloneBuffer(srcValue, true);\n }\n else if (isTyped) {\n isCommon = false;\n newValue = cloneTypedArray(srcValue, true);\n }\n else {\n newValue = [];\n }\n }\n else if (isPlainObject(srcValue) || isArguments(srcValue)) {\n newValue = objValue;\n if (isArguments(objValue)) {\n newValue = toPlainObject(objValue);\n }\n else if (!isObject(objValue) || isFunction(objValue)) {\n newValue = initCloneObject(srcValue);\n }\n }\n else {\n isCommon = false;\n }\n }\n if (isCommon) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, newValue);\n mergeFunc(newValue, srcValue, srcIndex, customizer, stack);\n stack['delete'](srcValue);\n }\n assignMergeValue(object, key, newValue);\n }\n\n /**\n * The base implementation of `_.nth` which doesn't coerce arguments.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {number} n The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n */\n function baseNth(array, n) {\n var length = array.length;\n if (!length) {\n return;\n }\n n += n < 0 ? length : 0;\n return isIndex(n, length) ? array[n] : undefined;\n }\n\n /**\n * The base implementation of `_.orderBy` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.\n * @param {string[]} orders The sort orders of `iteratees`.\n * @returns {Array} Returns the new sorted array.\n */\n function baseOrderBy(collection, iteratees, orders) {\n if (iteratees.length) {\n iteratees = arrayMap(iteratees, function(iteratee) {\n if (isArray(iteratee)) {\n return function(value) {\n return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);\n }\n }\n return iteratee;\n });\n } else {\n iteratees = [identity];\n }\n\n var index = -1;\n iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n\n var result = baseMap(collection, function(value, key, collection) {\n var criteria = arrayMap(iteratees, function(iteratee) {\n return iteratee(value);\n });\n return { 'criteria': criteria, 'index': ++index, 'value': value };\n });\n\n return baseSortBy(result, function(object, other) {\n return compareMultiple(object, other, orders);\n });\n }\n\n /**\n * The base implementation of `_.pick` without support for individual\n * property identifiers.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @returns {Object} Returns the new object.\n */\n function basePick(object, paths) {\n return basePickBy(object, paths, function(value, path) {\n return hasIn(object, path);\n });\n }\n\n /**\n * The base implementation of `_.pickBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The source object.\n * @param {string[]} paths The property paths to pick.\n * @param {Function} predicate The function invoked per property.\n * @returns {Object} Returns the new object.\n */\n function basePickBy(object, paths, predicate) {\n var index = -1,\n length = paths.length,\n result = {};\n\n while (++index < length) {\n var path = paths[index],\n value = baseGet(object, path);\n\n if (predicate(value, path)) {\n baseSet(result, castPath(path, object), value);\n }\n }\n return result;\n }\n\n /**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\n function basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n }\n\n /**\n * The base implementation of `_.pullAllBy` without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n */\n function basePullAll(array, values, iteratee, comparator) {\n var indexOf = comparator ? baseIndexOfWith : baseIndexOf,\n index = -1,\n length = values.length,\n seen = array;\n\n if (array === values) {\n values = copyArray(values);\n }\n if (iteratee) {\n seen = arrayMap(array, baseUnary(iteratee));\n }\n while (++index < length) {\n var fromIndex = 0,\n value = values[index],\n computed = iteratee ? iteratee(value) : value;\n\n while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {\n if (seen !== array) {\n splice.call(seen, fromIndex, 1);\n }\n splice.call(array, fromIndex, 1);\n }\n }\n return array;\n }\n\n /**\n * The base implementation of `_.pullAt` without support for individual\n * indexes or capturing the removed elements.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {number[]} indexes The indexes of elements to remove.\n * @returns {Array} Returns `array`.\n */\n function basePullAt(array, indexes) {\n var length = array ? indexes.length : 0,\n lastIndex = length - 1;\n\n while (length--) {\n var index = indexes[length];\n if (length == lastIndex || index !== previous) {\n var previous = index;\n if (isIndex(index)) {\n splice.call(array, index, 1);\n } else {\n baseUnset(array, index);\n }\n }\n }\n return array;\n }\n\n /**\n * The base implementation of `_.random` without support for returning\n * floating-point numbers.\n *\n * @private\n * @param {number} lower The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the random number.\n */\n function baseRandom(lower, upper) {\n return lower + nativeFloor(nativeRandom() * (upper - lower + 1));\n }\n\n /**\n * The base implementation of `_.range` and `_.rangeRight` which doesn't\n * coerce arguments.\n *\n * @private\n * @param {number} start The start of the range.\n * @param {number} end The end of the range.\n * @param {number} step The value to increment or decrement by.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the range of numbers.\n */\n function baseRange(start, end, step, fromRight) {\n var index = -1,\n length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),\n result = Array(length);\n\n while (length--) {\n result[fromRight ? length : ++index] = start;\n start += step;\n }\n return result;\n }\n\n /**\n * The base implementation of `_.repeat` which doesn't coerce arguments.\n *\n * @private\n * @param {string} string The string to repeat.\n * @param {number} n The number of times to repeat the string.\n * @returns {string} Returns the repeated string.\n */\n function baseRepeat(string, n) {\n var result = '';\n if (!string || n < 1 || n > MAX_SAFE_INTEGER) {\n return result;\n }\n // Leverage the exponentiation by squaring algorithm for a faster repeat.\n // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.\n do {\n if (n % 2) {\n result += string;\n }\n n = nativeFloor(n / 2);\n if (n) {\n string += string;\n }\n } while (n);\n\n return result;\n }\n\n /**\n * The base implementation of `_.rest` which doesn't validate or coerce arguments.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n */\n function baseRest(func, start) {\n return setToString(overRest(func, start, identity), func + '');\n }\n\n /**\n * The base implementation of `_.sample`.\n *\n * @private\n * @param {Array|Object} collection The collection to sample.\n * @returns {*} Returns the random element.\n */\n function baseSample(collection) {\n return arraySample(values(collection));\n }\n\n /**\n * The base implementation of `_.sampleSize` without param guards.\n *\n * @private\n * @param {Array|Object} collection The collection to sample.\n * @param {number} n The number of elements to sample.\n * @returns {Array} Returns the random elements.\n */\n function baseSampleSize(collection, n) {\n var array = values(collection);\n return shuffleSelf(array, baseClamp(n, 0, array.length));\n }\n\n /**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\n function baseSet(object, path, value, customizer) {\n if (!isObject(object)) {\n return object;\n }\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = toKey(path[index]),\n newValue = value;\n\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n return object;\n }\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject(objValue)\n ? objValue\n : (isIndex(path[index + 1]) ? [] : {});\n }\n }\n assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n }\n\n /**\n * The base implementation of `setData` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\n var baseSetData = !metaMap ? identity : function(func, data) {\n metaMap.set(func, data);\n return func;\n };\n\n /**\n * The base implementation of `setToString` without support for hot loop shorting.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\n var baseSetToString = !defineProperty ? identity : function(func, string) {\n return defineProperty(func, 'toString', {\n 'configurable': true,\n 'enumerable': false,\n 'value': constant(string),\n 'writable': true\n });\n };\n\n /**\n * The base implementation of `_.shuffle`.\n *\n * @private\n * @param {Array|Object} collection The collection to shuffle.\n * @returns {Array} Returns the new shuffled array.\n */\n function baseShuffle(collection) {\n return shuffleSelf(values(collection));\n }\n\n /**\n * The base implementation of `_.slice` without an iteratee call guard.\n *\n * @private\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\n function baseSlice(array, start, end) {\n var index = -1,\n length = array.length;\n\n if (start < 0) {\n start = -start > length ? 0 : (length + start);\n }\n end = end > length ? length : end;\n if (end < 0) {\n end += length;\n }\n length = start > end ? 0 : ((end - start) >>> 0);\n start >>>= 0;\n\n var result = Array(length);\n while (++index < length) {\n result[index] = array[index + start];\n }\n return result;\n }\n\n /**\n * The base implementation of `_.some` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\n function baseSome(collection, predicate) {\n var result;\n\n baseEach(collection, function(value, index, collection) {\n result = predicate(value, index, collection);\n return !result;\n });\n return !!result;\n }\n\n /**\n * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which\n * performs a binary search of `array` to determine the index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\n function baseSortedIndex(array, value, retHighest) {\n var low = 0,\n high = array == null ? low : array.length;\n\n if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {\n while (low < high) {\n var mid = (low + high) >>> 1,\n computed = array[mid];\n\n if (computed !== null && !isSymbol(computed) &&\n (retHighest ? (computed <= value) : (computed < value))) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return high;\n }\n return baseSortedIndexBy(array, value, identity, retHighest);\n }\n\n /**\n * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`\n * which invokes `iteratee` for `value` and each element of `array` to compute\n * their sort ranking. The iteratee is invoked with one argument; (value).\n *\n * @private\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} iteratee The iteratee invoked per element.\n * @param {boolean} [retHighest] Specify returning the highest qualified index.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n */\n function baseSortedIndexBy(array, value, iteratee, retHighest) {\n var low = 0,\n high = array == null ? 0 : array.length;\n if (high === 0) {\n return 0;\n }\n\n value = iteratee(value);\n var valIsNaN = value !== value,\n valIsNull = value === null,\n valIsSymbol = isSymbol(value),\n valIsUndefined = value === undefined;\n\n while (low < high) {\n var mid = nativeFloor((low + high) / 2),\n computed = iteratee(array[mid]),\n othIsDefined = computed !== undefined,\n othIsNull = computed === null,\n othIsReflexive = computed === computed,\n othIsSymbol = isSymbol(computed);\n\n if (valIsNaN) {\n var setLow = retHighest || othIsReflexive;\n } else if (valIsUndefined) {\n setLow = othIsReflexive && (retHighest || othIsDefined);\n } else if (valIsNull) {\n setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);\n } else if (valIsSymbol) {\n setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);\n } else if (othIsNull || othIsSymbol) {\n setLow = false;\n } else {\n setLow = retHighest ? (computed <= value) : (computed < value);\n }\n if (setLow) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n return nativeMin(high, MAX_ARRAY_INDEX);\n }\n\n /**\n * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\n function baseSortedUniq(array, iteratee) {\n var index = -1,\n length = array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n if (!index || !eq(computed, seen)) {\n var seen = computed;\n result[resIndex++] = value === 0 ? 0 : value;\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.toNumber` which doesn't ensure correct\n * conversions of binary, hexadecimal, or octal string values.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n */\n function baseToNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n return +value;\n }\n\n /**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\n function baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n }\n\n /**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\n function baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n }\n\n /**\n * The base implementation of `_.unset`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The property path to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n */\n function baseUnset(object, path) {\n path = castPath(path, object);\n object = parent(object, path);\n return object == null || delete object[toKey(last(path))];\n }\n\n /**\n * The base implementation of `_.update`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to update.\n * @param {Function} updater The function to produce the updated value.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\n function baseUpdate(object, path, updater, customizer) {\n return baseSet(object, path, updater(baseGet(object, path)), customizer);\n }\n\n /**\n * The base implementation of methods like `_.dropWhile` and `_.takeWhile`\n * without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to query.\n * @param {Function} predicate The function invoked per iteration.\n * @param {boolean} [isDrop] Specify dropping elements instead of taking them.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Array} Returns the slice of `array`.\n */\n function baseWhile(array, predicate, isDrop, fromRight) {\n var length = array.length,\n index = fromRight ? length : -1;\n\n while ((fromRight ? index-- : ++index < length) &&\n predicate(array[index], index, array)) {}\n\n return isDrop\n ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))\n : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));\n }\n\n /**\n * The base implementation of `wrapperValue` which returns the result of\n * performing a sequence of actions on the unwrapped `value`, where each\n * successive action is supplied the return value of the previous.\n *\n * @private\n * @param {*} value The unwrapped value.\n * @param {Array} actions Actions to perform to resolve the unwrapped value.\n * @returns {*} Returns the resolved value.\n */\n function baseWrapperValue(value, actions) {\n var result = value;\n if (result instanceof LazyWrapper) {\n result = result.value();\n }\n return arrayReduce(actions, function(result, action) {\n return action.func.apply(action.thisArg, arrayPush([result], action.args));\n }, result);\n }\n\n /**\n * The base implementation of methods like `_.xor`, without support for\n * iteratee shorthands, that accepts an array of arrays to inspect.\n *\n * @private\n * @param {Array} arrays The arrays to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of values.\n */\n function baseXor(arrays, iteratee, comparator) {\n var length = arrays.length;\n if (length < 2) {\n return length ? baseUniq(arrays[0]) : [];\n }\n var index = -1,\n result = Array(length);\n\n while (++index < length) {\n var array = arrays[index],\n othIndex = -1;\n\n while (++othIndex < length) {\n if (othIndex != index) {\n result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);\n }\n }\n }\n return baseUniq(baseFlatten(result, 1), iteratee, comparator);\n }\n\n /**\n * This base implementation of `_.zipObject` which assigns values using `assignFunc`.\n *\n * @private\n * @param {Array} props The property identifiers.\n * @param {Array} values The property values.\n * @param {Function} assignFunc The function to assign values.\n * @returns {Object} Returns the new object.\n */\n function baseZipObject(props, values, assignFunc) {\n var index = -1,\n length = props.length,\n valsLength = values.length,\n result = {};\n\n while (++index < length) {\n var value = index < valsLength ? values[index] : undefined;\n assignFunc(result, props[index], value);\n }\n return result;\n }\n\n /**\n * Casts `value` to an empty array if it's not an array like object.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Array|Object} Returns the cast array-like object.\n */\n function castArrayLikeObject(value) {\n return isArrayLikeObject(value) ? value : [];\n }\n\n /**\n * Casts `value` to `identity` if it's not a function.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Function} Returns cast function.\n */\n function castFunction(value) {\n return typeof value == 'function' ? value : identity;\n }\n\n /**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\n function castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n }\n\n /**\n * A `baseRest` alias which can be replaced with `identity` by module\n * replacement plugins.\n *\n * @private\n * @type {Function}\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\n var castRest = baseRest;\n\n /**\n * Casts `array` to a slice if it's needed.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {number} start The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the cast slice.\n */\n function castSlice(array, start, end) {\n var length = array.length;\n end = end === undefined ? length : end;\n return (!start && end >= length) ? array : baseSlice(array, start, end);\n }\n\n /**\n * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).\n *\n * @private\n * @param {number|Object} id The timer id or timeout object of the timer to clear.\n */\n var clearTimeout = ctxClearTimeout || function(id) {\n return root.clearTimeout(id);\n };\n\n /**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\n function cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var length = buffer.length,\n result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);\n\n buffer.copy(result);\n return result;\n }\n\n /**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\n function cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n }\n\n /**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\n function cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n }\n\n /**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\n function cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n }\n\n /**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\n function cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n }\n\n /**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\n function cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n }\n\n /**\n * Compares values to sort them in ascending order.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {number} Returns the sort order indicator for `value`.\n */\n function compareAscending(value, other) {\n if (value !== other) {\n var valIsDefined = value !== undefined,\n valIsNull = value === null,\n valIsReflexive = value === value,\n valIsSymbol = isSymbol(value);\n\n var othIsDefined = other !== undefined,\n othIsNull = other === null,\n othIsReflexive = other === other,\n othIsSymbol = isSymbol(other);\n\n if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||\n (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||\n (valIsNull && othIsDefined && othIsReflexive) ||\n (!valIsDefined && othIsReflexive) ||\n !valIsReflexive) {\n return 1;\n }\n if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||\n (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||\n (othIsNull && valIsDefined && valIsReflexive) ||\n (!othIsDefined && valIsReflexive) ||\n !othIsReflexive) {\n return -1;\n }\n }\n return 0;\n }\n\n /**\n * Used by `_.orderBy` to compare multiple properties of a value to another\n * and stable sort them.\n *\n * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,\n * specify an order of \"desc\" for descending or \"asc\" for ascending sort order\n * of corresponding values.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {boolean[]|string[]} orders The order to sort by for each property.\n * @returns {number} Returns the sort order indicator for `object`.\n */\n function compareMultiple(object, other, orders) {\n var index = -1,\n objCriteria = object.criteria,\n othCriteria = other.criteria,\n length = objCriteria.length,\n ordersLength = orders.length;\n\n while (++index < length) {\n var result = compareAscending(objCriteria[index], othCriteria[index]);\n if (result) {\n if (index >= ordersLength) {\n return result;\n }\n var order = orders[index];\n return result * (order == 'desc' ? -1 : 1);\n }\n }\n // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications\n // that causes it, under certain circumstances, to provide the same value for\n // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247\n // for more details.\n //\n // This also ensures a stable sort in V8 and other engines.\n // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.\n return object.index - other.index;\n }\n\n /**\n * Creates an array that is the composition of partially applied arguments,\n * placeholders, and provided arguments into a single array of arguments.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to prepend to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\n function composeArgs(args, partials, holders, isCurried) {\n var argsIndex = -1,\n argsLength = args.length,\n holdersLength = holders.length,\n leftIndex = -1,\n leftLength = partials.length,\n rangeLength = nativeMax(argsLength - holdersLength, 0),\n result = Array(leftLength + rangeLength),\n isUncurried = !isCurried;\n\n while (++leftIndex < leftLength) {\n result[leftIndex] = partials[leftIndex];\n }\n while (++argsIndex < holdersLength) {\n if (isUncurried || argsIndex < argsLength) {\n result[holders[argsIndex]] = args[argsIndex];\n }\n }\n while (rangeLength--) {\n result[leftIndex++] = args[argsIndex++];\n }\n return result;\n }\n\n /**\n * This function is like `composeArgs` except that the arguments composition\n * is tailored for `_.partialRight`.\n *\n * @private\n * @param {Array} args The provided arguments.\n * @param {Array} partials The arguments to append to those provided.\n * @param {Array} holders The `partials` placeholder indexes.\n * @params {boolean} [isCurried] Specify composing for a curried function.\n * @returns {Array} Returns the new array of composed arguments.\n */\n function composeArgsRight(args, partials, holders, isCurried) {\n var argsIndex = -1,\n argsLength = args.length,\n holdersIndex = -1,\n holdersLength = holders.length,\n rightIndex = -1,\n rightLength = partials.length,\n rangeLength = nativeMax(argsLength - holdersLength, 0),\n result = Array(rangeLength + rightLength),\n isUncurried = !isCurried;\n\n while (++argsIndex < rangeLength) {\n result[argsIndex] = args[argsIndex];\n }\n var offset = argsIndex;\n while (++rightIndex < rightLength) {\n result[offset + rightIndex] = partials[rightIndex];\n }\n while (++holdersIndex < holdersLength) {\n if (isUncurried || argsIndex < argsLength) {\n result[offset + holders[holdersIndex]] = args[argsIndex++];\n }\n }\n return result;\n }\n\n /**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\n function copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n }\n\n /**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\n function copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n }\n\n /**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\n function copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n }\n\n /**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\n function copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n }\n\n /**\n * Creates a function like `_.groupBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} [initializer] The accumulator object initializer.\n * @returns {Function} Returns the new aggregator function.\n */\n function createAggregator(setter, initializer) {\n return function(collection, iteratee) {\n var func = isArray(collection) ? arrayAggregator : baseAggregator,\n accumulator = initializer ? initializer() : {};\n\n return func(collection, setter, getIteratee(iteratee, 2), accumulator);\n };\n }\n\n /**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\n function createAssigner(assigner) {\n return baseRest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n }\n\n /**\n * Creates a `baseEach` or `baseEachRight` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\n function createBaseEach(eachFunc, fromRight) {\n return function(collection, iteratee) {\n if (collection == null) {\n return collection;\n }\n if (!isArrayLike(collection)) {\n return eachFunc(collection, iteratee);\n }\n var length = collection.length,\n index = fromRight ? length : -1,\n iterable = Object(collection);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (iteratee(iterable[index], index, iterable) === false) {\n break;\n }\n }\n return collection;\n };\n }\n\n /**\n * Creates a base function for methods like `_.forIn` and `_.forOwn`.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\n function createBaseFor(fromRight) {\n return function(object, iteratee, keysFunc) {\n var index = -1,\n iterable = Object(object),\n props = keysFunc(object),\n length = props.length;\n\n while (length--) {\n var key = props[fromRight ? length : ++index];\n if (iteratee(iterable[key], key, iterable) === false) {\n break;\n }\n }\n return object;\n };\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with the optional `this`\n * binding of `thisArg`.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createBind(func, bitmask, thisArg) {\n var isBind = bitmask & WRAP_BIND_FLAG,\n Ctor = createCtor(func);\n\n function wrapper() {\n var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n return fn.apply(isBind ? thisArg : this, arguments);\n }\n return wrapper;\n }\n\n /**\n * Creates a function like `_.lowerFirst`.\n *\n * @private\n * @param {string} methodName The name of the `String` case method to use.\n * @returns {Function} Returns the new case function.\n */\n function createCaseFirst(methodName) {\n return function(string) {\n string = toString(string);\n\n var strSymbols = hasUnicode(string)\n ? stringToArray(string)\n : undefined;\n\n var chr = strSymbols\n ? strSymbols[0]\n : string.charAt(0);\n\n var trailing = strSymbols\n ? castSlice(strSymbols, 1).join('')\n : string.slice(1);\n\n return chr[methodName]() + trailing;\n };\n }\n\n /**\n * Creates a function like `_.camelCase`.\n *\n * @private\n * @param {Function} callback The function to combine each word.\n * @returns {Function} Returns the new compounder function.\n */\n function createCompounder(callback) {\n return function(string) {\n return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');\n };\n }\n\n /**\n * Creates a function that produces an instance of `Ctor` regardless of\n * whether it was invoked as part of a `new` expression or by `call` or `apply`.\n *\n * @private\n * @param {Function} Ctor The constructor to wrap.\n * @returns {Function} Returns the new wrapped function.\n */\n function createCtor(Ctor) {\n return function() {\n // Use a `switch` statement to work with class constructors. See\n // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist\n // for more details.\n var args = arguments;\n switch (args.length) {\n case 0: return new Ctor;\n case 1: return new Ctor(args[0]);\n case 2: return new Ctor(args[0], args[1]);\n case 3: return new Ctor(args[0], args[1], args[2]);\n case 4: return new Ctor(args[0], args[1], args[2], args[3]);\n case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);\n case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);\n case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);\n }\n var thisBinding = baseCreate(Ctor.prototype),\n result = Ctor.apply(thisBinding, args);\n\n // Mimic the constructor's `return` behavior.\n // See https://es5.github.io/#x13.2.2 for more details.\n return isObject(result) ? result : thisBinding;\n };\n }\n\n /**\n * Creates a function that wraps `func` to enable currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {number} arity The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createCurry(func, bitmask, arity) {\n var Ctor = createCtor(func);\n\n function wrapper() {\n var length = arguments.length,\n args = Array(length),\n index = length,\n placeholder = getHolder(wrapper);\n\n while (index--) {\n args[index] = arguments[index];\n }\n var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)\n ? []\n : replaceHolders(args, placeholder);\n\n length -= holders.length;\n if (length < arity) {\n return createRecurry(\n func, bitmask, createHybrid, wrapper.placeholder, undefined,\n args, holders, undefined, undefined, arity - length);\n }\n var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n return apply(fn, this, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a `_.find` or `_.findLast` function.\n *\n * @private\n * @param {Function} findIndexFunc The function to find the collection index.\n * @returns {Function} Returns the new find function.\n */\n function createFind(findIndexFunc) {\n return function(collection, predicate, fromIndex) {\n var iterable = Object(collection);\n if (!isArrayLike(collection)) {\n var iteratee = getIteratee(predicate, 3);\n collection = keys(collection);\n predicate = function(key) { return iteratee(iterable[key], key, iterable); };\n }\n var index = findIndexFunc(collection, predicate, fromIndex);\n return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;\n };\n }\n\n /**\n * Creates a `_.flow` or `_.flowRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new flow function.\n */\n function createFlow(fromRight) {\n return flatRest(function(funcs) {\n var length = funcs.length,\n index = length,\n prereq = LodashWrapper.prototype.thru;\n\n if (fromRight) {\n funcs.reverse();\n }\n while (index--) {\n var func = funcs[index];\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (prereq && !wrapper && getFuncName(func) == 'wrapper') {\n var wrapper = new LodashWrapper([], true);\n }\n }\n index = wrapper ? index : length;\n while (++index < length) {\n func = funcs[index];\n\n var funcName = getFuncName(func),\n data = funcName == 'wrapper' ? getData(func) : undefined;\n\n if (data && isLaziable(data[0]) &&\n data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&\n !data[4].length && data[9] == 1\n ) {\n wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);\n } else {\n wrapper = (func.length == 1 && isLaziable(func))\n ? wrapper[funcName]()\n : wrapper.thru(func);\n }\n }\n return function() {\n var args = arguments,\n value = args[0];\n\n if (wrapper && args.length == 1 && isArray(value)) {\n return wrapper.plant(value).value();\n }\n var index = 0,\n result = length ? funcs[index].apply(this, args) : value;\n\n while (++index < length) {\n result = funcs[index].call(this, result);\n }\n return result;\n };\n });\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with optional `this`\n * binding of `thisArg`, partial application, and currying.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n * the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [partialsRight] The arguments to append to those provided\n * to the new function.\n * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {\n var isAry = bitmask & WRAP_ARY_FLAG,\n isBind = bitmask & WRAP_BIND_FLAG,\n isBindKey = bitmask & WRAP_BIND_KEY_FLAG,\n isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),\n isFlip = bitmask & WRAP_FLIP_FLAG,\n Ctor = isBindKey ? undefined : createCtor(func);\n\n function wrapper() {\n var length = arguments.length,\n args = Array(length),\n index = length;\n\n while (index--) {\n args[index] = arguments[index];\n }\n if (isCurried) {\n var placeholder = getHolder(wrapper),\n holdersCount = countHolders(args, placeholder);\n }\n if (partials) {\n args = composeArgs(args, partials, holders, isCurried);\n }\n if (partialsRight) {\n args = composeArgsRight(args, partialsRight, holdersRight, isCurried);\n }\n length -= holdersCount;\n if (isCurried && length < arity) {\n var newHolders = replaceHolders(args, placeholder);\n return createRecurry(\n func, bitmask, createHybrid, wrapper.placeholder, thisArg,\n args, newHolders, argPos, ary, arity - length\n );\n }\n var thisBinding = isBind ? thisArg : this,\n fn = isBindKey ? thisBinding[func] : func;\n\n length = args.length;\n if (argPos) {\n args = reorder(args, argPos);\n } else if (isFlip && length > 1) {\n args.reverse();\n }\n if (isAry && ary < length) {\n args.length = ary;\n }\n if (this && this !== root && this instanceof wrapper) {\n fn = Ctor || createCtor(fn);\n }\n return fn.apply(thisBinding, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a function like `_.invertBy`.\n *\n * @private\n * @param {Function} setter The function to set accumulator values.\n * @param {Function} toIteratee The function to resolve iteratees.\n * @returns {Function} Returns the new inverter function.\n */\n function createInverter(setter, toIteratee) {\n return function(object, iteratee) {\n return baseInverter(object, setter, toIteratee(iteratee), {});\n };\n }\n\n /**\n * Creates a function that performs a mathematical operation on two values.\n *\n * @private\n * @param {Function} operator The function to perform the operation.\n * @param {number} [defaultValue] The value used for `undefined` arguments.\n * @returns {Function} Returns the new mathematical operation function.\n */\n function createMathOperation(operator, defaultValue) {\n return function(value, other) {\n var result;\n if (value === undefined && other === undefined) {\n return defaultValue;\n }\n if (value !== undefined) {\n result = value;\n }\n if (other !== undefined) {\n if (result === undefined) {\n return other;\n }\n if (typeof value == 'string' || typeof other == 'string') {\n value = baseToString(value);\n other = baseToString(other);\n } else {\n value = baseToNumber(value);\n other = baseToNumber(other);\n }\n result = operator(value, other);\n }\n return result;\n };\n }\n\n /**\n * Creates a function like `_.over`.\n *\n * @private\n * @param {Function} arrayFunc The function to iterate over iteratees.\n * @returns {Function} Returns the new over function.\n */\n function createOver(arrayFunc) {\n return flatRest(function(iteratees) {\n iteratees = arrayMap(iteratees, baseUnary(getIteratee()));\n return baseRest(function(args) {\n var thisArg = this;\n return arrayFunc(iteratees, function(iteratee) {\n return apply(iteratee, thisArg, args);\n });\n });\n });\n }\n\n /**\n * Creates the padding for `string` based on `length`. The `chars` string\n * is truncated if the number of characters exceeds `length`.\n *\n * @private\n * @param {number} length The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padding for `string`.\n */\n function createPadding(length, chars) {\n chars = chars === undefined ? ' ' : baseToString(chars);\n\n var charsLength = chars.length;\n if (charsLength < 2) {\n return charsLength ? baseRepeat(chars, length) : chars;\n }\n var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));\n return hasUnicode(chars)\n ? castSlice(stringToArray(result), 0, length).join('')\n : result.slice(0, length);\n }\n\n /**\n * Creates a function that wraps `func` to invoke it with the `this` binding\n * of `thisArg` and `partials` prepended to the arguments it receives.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} partials The arguments to prepend to those provided to\n * the new function.\n * @returns {Function} Returns the new wrapped function.\n */\n function createPartial(func, bitmask, thisArg, partials) {\n var isBind = bitmask & WRAP_BIND_FLAG,\n Ctor = createCtor(func);\n\n function wrapper() {\n var argsIndex = -1,\n argsLength = arguments.length,\n leftIndex = -1,\n leftLength = partials.length,\n args = Array(leftLength + argsLength),\n fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;\n\n while (++leftIndex < leftLength) {\n args[leftIndex] = partials[leftIndex];\n }\n while (argsLength--) {\n args[leftIndex++] = arguments[++argsIndex];\n }\n return apply(fn, isBind ? thisArg : this, args);\n }\n return wrapper;\n }\n\n /**\n * Creates a `_.range` or `_.rangeRight` function.\n *\n * @private\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new range function.\n */\n function createRange(fromRight) {\n return function(start, end, step) {\n if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {\n end = step = undefined;\n }\n // Ensure the sign of `-0` is preserved.\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);\n return baseRange(start, end, step, fromRight);\n };\n }\n\n /**\n * Creates a function that performs a relational operation on two values.\n *\n * @private\n * @param {Function} operator The function to perform the operation.\n * @returns {Function} Returns the new relational operation function.\n */\n function createRelationalOperation(operator) {\n return function(value, other) {\n if (!(typeof value == 'string' && typeof other == 'string')) {\n value = toNumber(value);\n other = toNumber(other);\n }\n return operator(value, other);\n };\n }\n\n /**\n * Creates a function that wraps `func` to continue currying.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @param {Function} wrapFunc The function to create the `func` wrapper.\n * @param {*} placeholder The placeholder value.\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to prepend to those provided to\n * the new function.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {\n var isCurry = bitmask & WRAP_CURRY_FLAG,\n newHolders = isCurry ? holders : undefined,\n newHoldersRight = isCurry ? undefined : holders,\n newPartials = isCurry ? partials : undefined,\n newPartialsRight = isCurry ? undefined : partials;\n\n bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);\n bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);\n\n if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {\n bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);\n }\n var newData = [\n func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,\n newHoldersRight, argPos, ary, arity\n ];\n\n var result = wrapFunc.apply(undefined, newData);\n if (isLaziable(func)) {\n setData(result, newData);\n }\n result.placeholder = placeholder;\n return setWrapToString(result, func, bitmask);\n }\n\n /**\n * Creates a function like `_.round`.\n *\n * @private\n * @param {string} methodName The name of the `Math` method to use when rounding.\n * @returns {Function} Returns the new round function.\n */\n function createRound(methodName) {\n var func = Math[methodName];\n return function(number, precision) {\n number = toNumber(number);\n precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);\n if (precision && nativeIsFinite(number)) {\n // Shift with exponential notation to avoid floating-point issues.\n // See [MDN](https://mdn.io/round#Examples) for more details.\n var pair = (toString(number) + 'e').split('e'),\n value = func(pair[0] + 'e' + (+pair[1] + precision));\n\n pair = (toString(value) + 'e').split('e');\n return +(pair[0] + 'e' + (+pair[1] - precision));\n }\n return func(number);\n };\n }\n\n /**\n * Creates a set object of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\n var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n };\n\n /**\n * Creates a `_.toPairs` or `_.toPairsIn` function.\n *\n * @private\n * @param {Function} keysFunc The function to get the keys of a given object.\n * @returns {Function} Returns the new pairs function.\n */\n function createToPairs(keysFunc) {\n return function(object) {\n var tag = getTag(object);\n if (tag == mapTag) {\n return mapToArray(object);\n }\n if (tag == setTag) {\n return setToPairs(object);\n }\n return baseToPairs(object, keysFunc(object));\n };\n }\n\n /**\n * Creates a function that either curries or invokes `func` with optional\n * `this` binding and partially applied arguments.\n *\n * @private\n * @param {Function|string} func The function or method name to wrap.\n * @param {number} bitmask The bitmask flags.\n * 1 - `_.bind`\n * 2 - `_.bindKey`\n * 4 - `_.curry` or `_.curryRight` of a bound function\n * 8 - `_.curry`\n * 16 - `_.curryRight`\n * 32 - `_.partial`\n * 64 - `_.partialRight`\n * 128 - `_.rearg`\n * 256 - `_.ary`\n * 512 - `_.flip`\n * @param {*} [thisArg] The `this` binding of `func`.\n * @param {Array} [partials] The arguments to be partially applied.\n * @param {Array} [holders] The `partials` placeholder indexes.\n * @param {Array} [argPos] The argument positions of the new function.\n * @param {number} [ary] The arity cap of `func`.\n * @param {number} [arity] The arity of `func`.\n * @returns {Function} Returns the new wrapped function.\n */\n function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {\n var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;\n if (!isBindKey && typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var length = partials ? partials.length : 0;\n if (!length) {\n bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);\n partials = holders = undefined;\n }\n ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);\n arity = arity === undefined ? arity : toInteger(arity);\n length -= holders ? holders.length : 0;\n\n if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {\n var partialsRight = partials,\n holdersRight = holders;\n\n partials = holders = undefined;\n }\n var data = isBindKey ? undefined : getData(func);\n\n var newData = [\n func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,\n argPos, ary, arity\n ];\n\n if (data) {\n mergeData(newData, data);\n }\n func = newData[0];\n bitmask = newData[1];\n thisArg = newData[2];\n partials = newData[3];\n holders = newData[4];\n arity = newData[9] = newData[9] === undefined\n ? (isBindKey ? 0 : func.length)\n : nativeMax(newData[9] - length, 0);\n\n if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {\n bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);\n }\n if (!bitmask || bitmask == WRAP_BIND_FLAG) {\n var result = createBind(func, bitmask, thisArg);\n } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {\n result = createCurry(func, bitmask, arity);\n } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {\n result = createPartial(func, bitmask, thisArg, partials);\n } else {\n result = createHybrid.apply(undefined, newData);\n }\n var setter = data ? baseSetData : setData;\n return setWrapToString(setter(result, newData), func, bitmask);\n }\n\n /**\n * Used by `_.defaults` to customize its `_.assignIn` use to assign properties\n * of source objects to the destination object for all destination properties\n * that resolve to `undefined`.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to assign.\n * @param {Object} object The parent object of `objValue`.\n * @returns {*} Returns the value to assign.\n */\n function customDefaultsAssignIn(objValue, srcValue, key, object) {\n if (objValue === undefined ||\n (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n return srcValue;\n }\n return objValue;\n }\n\n /**\n * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source\n * objects into destination objects that are passed thru.\n *\n * @private\n * @param {*} objValue The destination value.\n * @param {*} srcValue The source value.\n * @param {string} key The key of the property to merge.\n * @param {Object} object The parent object of `objValue`.\n * @param {Object} source The parent object of `srcValue`.\n * @param {Object} [stack] Tracks traversed source values and their merged\n * counterparts.\n * @returns {*} Returns the value to assign.\n */\n function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {\n if (isObject(objValue) && isObject(srcValue)) {\n // Recursively merge objects and arrays (susceptible to call stack limits).\n stack.set(srcValue, objValue);\n baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);\n stack['delete'](srcValue);\n }\n return objValue;\n }\n\n /**\n * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain\n * objects.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} key The key of the property to inspect.\n * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.\n */\n function customOmitClone(value) {\n return isPlainObject(value) ? undefined : value;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\n function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Check that cyclic values are equal.\n var arrStacked = stack.get(array);\n var othStacked = stack.get(other);\n if (arrStacked && othStacked) {\n return arrStacked == other && othStacked == array;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n }\n\n /**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\n function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Check that cyclic values are equal.\n var objStacked = stack.get(object);\n var othStacked = stack.get(other);\n if (objStacked && othStacked) {\n return objStacked == other && othStacked == object;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n }\n\n /**\n * A specialized version of `baseRest` which flattens the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @returns {Function} Returns the new function.\n */\n function flatRest(func) {\n return setToString(overRest(func, undefined, flatten), func + '');\n }\n\n /**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n }\n\n /**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\n function getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n }\n\n /**\n * Gets metadata for `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {*} Returns the metadata for `func`.\n */\n var getData = !metaMap ? noop : function(func) {\n return metaMap.get(func);\n };\n\n /**\n * Gets the name of `func`.\n *\n * @private\n * @param {Function} func The function to query.\n * @returns {string} Returns the function name.\n */\n function getFuncName(func) {\n var result = (func.name + ''),\n array = realNames[result],\n length = hasOwnProperty.call(realNames, result) ? array.length : 0;\n\n while (length--) {\n var data = array[length],\n otherFunc = data.func;\n if (otherFunc == null || otherFunc == func) {\n return data.name;\n }\n }\n return result;\n }\n\n /**\n * Gets the argument placeholder value for `func`.\n *\n * @private\n * @param {Function} func The function to inspect.\n * @returns {*} Returns the placeholder value.\n */\n function getHolder(func) {\n var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;\n return object.placeholder;\n }\n\n /**\n * Gets the appropriate \"iteratee\" function. If `_.iteratee` is customized,\n * this function returns the custom method, otherwise it returns `baseIteratee`.\n * If arguments are provided, the chosen function is invoked with them and\n * its result is returned.\n *\n * @private\n * @param {*} [value] The value to convert to an iteratee.\n * @param {number} [arity] The arity of the created iteratee.\n * @returns {Function} Returns the chosen function or its result.\n */\n function getIteratee() {\n var result = lodash.iteratee || iteratee;\n result = result === iteratee ? baseIteratee : result;\n return arguments.length ? result(arguments[0], arguments[1]) : result;\n }\n\n /**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\n function getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n }\n\n /**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\n function getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n }\n\n /**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\n function getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n }\n\n /**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\n function getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n }\n\n /**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\n var getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n };\n\n /**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\n var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n };\n\n /**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\n var getTag = baseGetTag;\n\n // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\n if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n }\n\n /**\n * Gets the view, applying any `transforms` to the `start` and `end` positions.\n *\n * @private\n * @param {number} start The start of the view.\n * @param {number} end The end of the view.\n * @param {Array} transforms The transformations to apply to the view.\n * @returns {Object} Returns an object containing the `start` and `end`\n * positions of the view.\n */\n function getView(start, end, transforms) {\n var index = -1,\n length = transforms.length;\n\n while (++index < length) {\n var data = transforms[index],\n size = data.size;\n\n switch (data.type) {\n case 'drop': start += size; break;\n case 'dropRight': end -= size; break;\n case 'take': end = nativeMin(end, start + size); break;\n case 'takeRight': start = nativeMax(start, end - size); break;\n }\n }\n return { 'start': start, 'end': end };\n }\n\n /**\n * Extracts wrapper details from the `source` body comment.\n *\n * @private\n * @param {string} source The source to inspect.\n * @returns {Array} Returns the wrapper details.\n */\n function getWrapDetails(source) {\n var match = source.match(reWrapDetails);\n return match ? match[1].split(reSplitDetails) : [];\n }\n\n /**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\n function hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n }\n\n /**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\n function initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n }\n\n /**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\n function initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n }\n\n /**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\n function initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n }\n\n /**\n * Inserts wrapper `details` in a comment at the top of the `source` body.\n *\n * @private\n * @param {string} source The source to modify.\n * @returns {Array} details The details to insert.\n * @returns {string} Returns the modified source.\n */\n function insertWrapDetails(source, details) {\n var length = details.length;\n if (!length) {\n return source;\n }\n var lastIndex = length - 1;\n details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];\n details = details.join(length > 2 ? ', ' : ' ');\n return source.replace(reWrapComment, '{\\n/* [wrapped with ' + details + '] */\\n');\n }\n\n /**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\n function isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n }\n\n /**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\n function isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n }\n\n /**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\n function isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n }\n\n /**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\n function isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n }\n\n /**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\n function isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n }\n\n /**\n * Checks if `func` has a lazy counterpart.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` has a lazy counterpart,\n * else `false`.\n */\n function isLaziable(func) {\n var funcName = getFuncName(func),\n other = lodash[funcName];\n\n if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {\n return false;\n }\n if (func === other) {\n return true;\n }\n var data = getData(other);\n return !!data && func === data[0];\n }\n\n /**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\n function isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n }\n\n /**\n * Checks if `func` is capable of being masked.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `func` is maskable, else `false`.\n */\n var isMaskable = coreJsData ? isFunction : stubFalse;\n\n /**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\n function isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n }\n\n /**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\n function isStrictComparable(value) {\n return value === value && !isObject(value);\n }\n\n /**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\n function matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n }\n\n /**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\n function memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n }\n\n /**\n * Merges the function metadata of `source` into `data`.\n *\n * Merging metadata reduces the number of wrappers used to invoke a function.\n * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`\n * may be applied regardless of execution order. Methods like `_.ary` and\n * `_.rearg` modify function arguments, making the order in which they are\n * executed important, preventing the merging of metadata. However, we make\n * an exception for a safe combined case where curried functions have `_.ary`\n * and or `_.rearg` applied.\n *\n * @private\n * @param {Array} data The destination metadata.\n * @param {Array} source The source metadata.\n * @returns {Array} Returns `data`.\n */\n function mergeData(data, source) {\n var bitmask = data[1],\n srcBitmask = source[1],\n newBitmask = bitmask | srcBitmask,\n isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);\n\n var isCombo =\n ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||\n ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||\n ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));\n\n // Exit early if metadata can't be merged.\n if (!(isCommon || isCombo)) {\n return data;\n }\n // Use source `thisArg` if available.\n if (srcBitmask & WRAP_BIND_FLAG) {\n data[2] = source[2];\n // Set when currying a bound function.\n newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;\n }\n // Compose partial arguments.\n var value = source[3];\n if (value) {\n var partials = data[3];\n data[3] = partials ? composeArgs(partials, value, source[4]) : value;\n data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];\n }\n // Compose partial right arguments.\n value = source[5];\n if (value) {\n partials = data[5];\n data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;\n data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];\n }\n // Use source `argPos` if available.\n value = source[7];\n if (value) {\n data[7] = value;\n }\n // Use source `ary` if it's smaller.\n if (srcBitmask & WRAP_ARY_FLAG) {\n data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);\n }\n // Use source `arity` if one is not provided.\n if (data[9] == null) {\n data[9] = source[9];\n }\n // Use source `func` and merge bitmasks.\n data[0] = source[0];\n data[1] = newBitmask;\n\n return data;\n }\n\n /**\n * This function is like\n * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * except that it includes inherited enumerable properties.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\n function nativeKeysIn(object) {\n var result = [];\n if (object != null) {\n for (var key in Object(object)) {\n result.push(key);\n }\n }\n return result;\n }\n\n /**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\n function objectToString(value) {\n return nativeObjectToString.call(value);\n }\n\n /**\n * A specialized version of `baseRest` which transforms the rest array.\n *\n * @private\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @param {Function} transform The rest array transform.\n * @returns {Function} Returns the new function.\n */\n function overRest(func, start, transform) {\n start = nativeMax(start === undefined ? (func.length - 1) : start, 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n index = -1;\n var otherArgs = Array(start + 1);\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = transform(array);\n return apply(func, this, otherArgs);\n };\n }\n\n /**\n * Gets the parent value at `path` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} path The path to get the parent value of.\n * @returns {*} Returns the parent value.\n */\n function parent(object, path) {\n return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));\n }\n\n /**\n * Reorder `array` according to the specified indexes where the element at\n * the first index is assigned as the first element, the element at\n * the second index is assigned as the second element, and so on.\n *\n * @private\n * @param {Array} array The array to reorder.\n * @param {Array} indexes The arranged array indexes.\n * @returns {Array} Returns `array`.\n */\n function reorder(array, indexes) {\n var arrLength = array.length,\n length = nativeMin(indexes.length, arrLength),\n oldArray = copyArray(array);\n\n while (length--) {\n var index = indexes[length];\n array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;\n }\n return array;\n }\n\n /**\n * Gets the value at `key`, unless `key` is \"__proto__\" or \"constructor\".\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\n function safeGet(object, key) {\n if (key === 'constructor' && typeof object[key] === 'function') {\n return;\n }\n\n if (key == '__proto__') {\n return;\n }\n\n return object[key];\n }\n\n /**\n * Sets metadata for `func`.\n *\n * **Note:** If this function becomes hot, i.e. is invoked a lot in a short\n * period of time, it will trip its breaker and transition to an identity\n * function to avoid garbage collection pauses in V8. See\n * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)\n * for more details.\n *\n * @private\n * @param {Function} func The function to associate metadata with.\n * @param {*} data The metadata.\n * @returns {Function} Returns `func`.\n */\n var setData = shortOut(baseSetData);\n\n /**\n * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).\n *\n * @private\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @returns {number|Object} Returns the timer id or timeout object.\n */\n var setTimeout = ctxSetTimeout || function(func, wait) {\n return root.setTimeout(func, wait);\n };\n\n /**\n * Sets the `toString` method of `func` to return `string`.\n *\n * @private\n * @param {Function} func The function to modify.\n * @param {Function} string The `toString` result.\n * @returns {Function} Returns `func`.\n */\n var setToString = shortOut(baseSetToString);\n\n /**\n * Sets the `toString` method of `wrapper` to mimic the source of `reference`\n * with wrapper details in a comment at the top of the source body.\n *\n * @private\n * @param {Function} wrapper The function to modify.\n * @param {Function} reference The reference function.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Function} Returns `wrapper`.\n */\n function setWrapToString(wrapper, reference, bitmask) {\n var source = (reference + '');\n return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));\n }\n\n /**\n * Creates a function that'll short out and invoke `identity` instead\n * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`\n * milliseconds.\n *\n * @private\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new shortable function.\n */\n function shortOut(func) {\n var count = 0,\n lastCalled = 0;\n\n return function() {\n var stamp = nativeNow(),\n remaining = HOT_SPAN - (stamp - lastCalled);\n\n lastCalled = stamp;\n if (remaining > 0) {\n if (++count >= HOT_COUNT) {\n return arguments[0];\n }\n } else {\n count = 0;\n }\n return func.apply(undefined, arguments);\n };\n }\n\n /**\n * A specialized version of `_.shuffle` which mutates and sets the size of `array`.\n *\n * @private\n * @param {Array} array The array to shuffle.\n * @param {number} [size=array.length] The size of `array`.\n * @returns {Array} Returns `array`.\n */\n function shuffleSelf(array, size) {\n var index = -1,\n length = array.length,\n lastIndex = length - 1;\n\n size = size === undefined ? length : size;\n while (++index < size) {\n var rand = baseRandom(index, lastIndex),\n value = array[rand];\n\n array[rand] = array[index];\n array[index] = value;\n }\n array.length = size;\n return array;\n }\n\n /**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\n var stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n });\n\n /**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\n function toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n }\n\n /**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\n function toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n }\n\n /**\n * Updates wrapper `details` based on `bitmask` flags.\n *\n * @private\n * @returns {Array} details The details to modify.\n * @param {number} bitmask The bitmask flags. See `createWrap` for more details.\n * @returns {Array} Returns `details`.\n */\n function updateWrapDetails(details, bitmask) {\n arrayEach(wrapFlags, function(pair) {\n var value = '_.' + pair[0];\n if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {\n details.push(value);\n }\n });\n return details.sort();\n }\n\n /**\n * Creates a clone of `wrapper`.\n *\n * @private\n * @param {Object} wrapper The wrapper to clone.\n * @returns {Object} Returns the cloned wrapper.\n */\n function wrapperClone(wrapper) {\n if (wrapper instanceof LazyWrapper) {\n return wrapper.clone();\n }\n var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);\n result.__actions__ = copyArray(wrapper.__actions__);\n result.__index__ = wrapper.__index__;\n result.__values__ = wrapper.__values__;\n return result;\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an array of elements split into groups the length of `size`.\n * If `array` can't be split evenly, the final chunk will be the remaining\n * elements.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to process.\n * @param {number} [size=1] The length of each chunk\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the new array of chunks.\n * @example\n *\n * _.chunk(['a', 'b', 'c', 'd'], 2);\n * // => [['a', 'b'], ['c', 'd']]\n *\n * _.chunk(['a', 'b', 'c', 'd'], 3);\n * // => [['a', 'b', 'c'], ['d']]\n */\n function chunk(array, size, guard) {\n if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {\n size = 1;\n } else {\n size = nativeMax(toInteger(size), 0);\n }\n var length = array == null ? 0 : array.length;\n if (!length || size < 1) {\n return [];\n }\n var index = 0,\n resIndex = 0,\n result = Array(nativeCeil(length / size));\n\n while (index < length) {\n result[resIndex++] = baseSlice(array, index, (index += size));\n }\n return result;\n }\n\n /**\n * Creates an array with all falsey values removed. The values `false`, `null`,\n * `0`, `\"\"`, `undefined`, and `NaN` are falsey.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to compact.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.compact([0, 1, false, 2, '', 3]);\n * // => [1, 2, 3]\n */\n function compact(array) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (value) {\n result[resIndex++] = value;\n }\n }\n return result;\n }\n\n /**\n * Creates a new array concatenating `array` with any additional arrays\n * and/or values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to concatenate.\n * @param {...*} [values] The values to concatenate.\n * @returns {Array} Returns the new concatenated array.\n * @example\n *\n * var array = [1];\n * var other = _.concat(array, 2, [3], [[4]]);\n *\n * console.log(other);\n * // => [1, 2, 3, [4]]\n *\n * console.log(array);\n * // => [1]\n */\n function concat() {\n var length = arguments.length;\n if (!length) {\n return [];\n }\n var args = Array(length - 1),\n array = arguments[0],\n index = length;\n\n while (index--) {\n args[index - 1] = arguments[index];\n }\n return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));\n }\n\n /**\n * Creates an array of `array` values not included in the other given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * **Note:** Unlike `_.pullAll`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.without, _.xor\n * @example\n *\n * _.difference([2, 1], [2, 3]);\n * // => [1]\n */\n var difference = baseRest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))\n : [];\n });\n\n /**\n * This method is like `_.difference` except that it accepts `iteratee` which\n * is invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The order and references of result values are\n * determined by the first array. The iteratee is invoked with one argument:\n * (value).\n *\n * **Note:** Unlike `_.pullAllBy`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\n var differenceBy = baseRest(function(array, values) {\n var iteratee = last(values);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))\n : [];\n });\n\n /**\n * This method is like `_.difference` except that it accepts `comparator`\n * which is invoked to compare elements of `array` to `values`. The order and\n * references of result values are determined by the first array. The comparator\n * is invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.pullAllWith`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...Array} [values] The values to exclude.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n *\n * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }]\n */\n var differenceWith = baseRest(function(array, values) {\n var comparator = last(values);\n if (isArrayLikeObject(comparator)) {\n comparator = undefined;\n }\n return isArrayLikeObject(array)\n ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)\n : [];\n });\n\n /**\n * Creates a slice of `array` with `n` elements dropped from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.drop([1, 2, 3]);\n * // => [2, 3]\n *\n * _.drop([1, 2, 3], 2);\n * // => [3]\n *\n * _.drop([1, 2, 3], 5);\n * // => []\n *\n * _.drop([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\n function drop(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, n < 0 ? 0 : n, length);\n }\n\n /**\n * Creates a slice of `array` with `n` elements dropped from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to drop.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.dropRight([1, 2, 3]);\n * // => [1, 2]\n *\n * _.dropRight([1, 2, 3], 2);\n * // => [1]\n *\n * _.dropRight([1, 2, 3], 5);\n * // => []\n *\n * _.dropRight([1, 2, 3], 0);\n * // => [1, 2, 3]\n */\n function dropRight(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, 0, n < 0 ? 0 : n);\n }\n\n /**\n * Creates a slice of `array` excluding elements dropped from the end.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.dropRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropRightWhile(users, ['active', false]);\n * // => objects for ['barney']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropRightWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\n function dropRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), true, true)\n : [];\n }\n\n /**\n * Creates a slice of `array` excluding elements dropped from the beginning.\n * Elements are dropped until `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.dropWhile(users, function(o) { return !o.active; });\n * // => objects for ['pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.dropWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.dropWhile(users, ['active', false]);\n * // => objects for ['pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.dropWhile(users, 'active');\n * // => objects for ['barney', 'fred', 'pebbles']\n */\n function dropWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), true)\n : [];\n }\n\n /**\n * Fills elements of `array` with `value` from `start` up to, but not\n * including, `end`.\n *\n * **Note:** This method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Array\n * @param {Array} array The array to fill.\n * @param {*} value The value to fill `array` with.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.fill(array, 'a');\n * console.log(array);\n * // => ['a', 'a', 'a']\n *\n * _.fill(Array(3), 2);\n * // => [2, 2, 2]\n *\n * _.fill([4, 6, 8, 10], '*', 1, 3);\n * // => [4, '*', '*', 10]\n */\n function fill(array, value, start, end) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {\n start = 0;\n end = length;\n }\n return baseFill(array, value, start, end);\n }\n\n /**\n * This method is like `_.find` except that it returns the index of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.findIndex(users, function(o) { return o.user == 'barney'; });\n * // => 0\n *\n * // The `_.matches` iteratee shorthand.\n * _.findIndex(users, { 'user': 'fred', 'active': false });\n * // => 1\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findIndex(users, ['active', false]);\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.findIndex(users, 'active');\n * // => 2\n */\n function findIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseFindIndex(array, getIteratee(predicate, 3), index);\n }\n\n /**\n * This method is like `_.findIndex` except that it iterates over elements\n * of `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the found element, else `-1`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });\n * // => 2\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastIndex(users, { 'user': 'barney', 'active': true });\n * // => 0\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastIndex(users, ['active', false]);\n * // => 2\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastIndex(users, 'active');\n * // => 0\n */\n function findLastIndex(array, predicate, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = length - 1;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = fromIndex < 0\n ? nativeMax(length + index, 0)\n : nativeMin(index, length - 1);\n }\n return baseFindIndex(array, getIteratee(predicate, 3), index, true);\n }\n\n /**\n * Flattens `array` a single level deep.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flatten([1, [2, [3, [4]], 5]]);\n * // => [1, 2, [3, [4]], 5]\n */\n function flatten(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, 1) : [];\n }\n\n /**\n * Recursively flattens `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * _.flattenDeep([1, [2, [3, [4]], 5]]);\n * // => [1, 2, 3, 4, 5]\n */\n function flattenDeep(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseFlatten(array, INFINITY) : [];\n }\n\n /**\n * Recursively flatten `array` up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Array\n * @param {Array} array The array to flatten.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * var array = [1, [2, [3, [4]], 5]];\n *\n * _.flattenDepth(array, 1);\n * // => [1, 2, [3, [4]], 5]\n *\n * _.flattenDepth(array, 2);\n * // => [1, 2, 3, [4], 5]\n */\n function flattenDepth(array, depth) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(array, depth);\n }\n\n /**\n * The inverse of `_.toPairs`; this method returns an object composed\n * from key-value `pairs`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} pairs The key-value pairs.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.fromPairs([['a', 1], ['b', 2]]);\n * // => { 'a': 1, 'b': 2 }\n */\n function fromPairs(pairs) {\n var index = -1,\n length = pairs == null ? 0 : pairs.length,\n result = {};\n\n while (++index < length) {\n var pair = pairs[index];\n result[pair[0]] = pair[1];\n }\n return result;\n }\n\n /**\n * Gets the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias first\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the first element of `array`.\n * @example\n *\n * _.head([1, 2, 3]);\n * // => 1\n *\n * _.head([]);\n * // => undefined\n */\n function head(array) {\n return (array && array.length) ? array[0] : undefined;\n }\n\n /**\n * Gets the index at which the first occurrence of `value` is found in `array`\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. If `fromIndex` is negative, it's used as the\n * offset from the end of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.indexOf([1, 2, 1, 2], 2);\n * // => 1\n *\n * // Search from the `fromIndex`.\n * _.indexOf([1, 2, 1, 2], 2, 2);\n * // => 3\n */\n function indexOf(array, value, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = fromIndex == null ? 0 : toInteger(fromIndex);\n if (index < 0) {\n index = nativeMax(length + index, 0);\n }\n return baseIndexOf(array, value, index);\n }\n\n /**\n * Gets all but the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.initial([1, 2, 3]);\n * // => [1, 2]\n */\n function initial(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseSlice(array, 0, -1) : [];\n }\n\n /**\n * Creates an array of unique values that are included in all given arrays\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons. The order and references of result values are\n * determined by the first array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersection([2, 1], [2, 3]);\n * // => [2]\n */\n var intersection = baseRest(function(arrays) {\n var mapped = arrayMap(arrays, castArrayLikeObject);\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped)\n : [];\n });\n\n /**\n * This method is like `_.intersection` except that it accepts `iteratee`\n * which is invoked for each element of each `arrays` to generate the criterion\n * by which they're compared. The order and references of result values are\n * determined by the first array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [2.1]\n *\n * // The `_.property` iteratee shorthand.\n * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }]\n */\n var intersectionBy = baseRest(function(arrays) {\n var iteratee = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n if (iteratee === last(mapped)) {\n iteratee = undefined;\n } else {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, getIteratee(iteratee, 2))\n : [];\n });\n\n /**\n * This method is like `_.intersection` except that it accepts `comparator`\n * which is invoked to compare elements of `arrays`. The order and references\n * of result values are determined by the first array. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of intersecting values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.intersectionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }]\n */\n var intersectionWith = baseRest(function(arrays) {\n var comparator = last(arrays),\n mapped = arrayMap(arrays, castArrayLikeObject);\n\n comparator = typeof comparator == 'function' ? comparator : undefined;\n if (comparator) {\n mapped.pop();\n }\n return (mapped.length && mapped[0] === arrays[0])\n ? baseIntersection(mapped, undefined, comparator)\n : [];\n });\n\n /**\n * Converts all elements in `array` into a string separated by `separator`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to convert.\n * @param {string} [separator=','] The element separator.\n * @returns {string} Returns the joined string.\n * @example\n *\n * _.join(['a', 'b', 'c'], '~');\n * // => 'a~b~c'\n */\n function join(array, separator) {\n return array == null ? '' : nativeJoin.call(array, separator);\n }\n\n /**\n * Gets the last element of `array`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {*} Returns the last element of `array`.\n * @example\n *\n * _.last([1, 2, 3]);\n * // => 3\n */\n function last(array) {\n var length = array == null ? 0 : array.length;\n return length ? array[length - 1] : undefined;\n }\n\n /**\n * This method is like `_.indexOf` except that it iterates over elements of\n * `array` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=array.length-1] The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.lastIndexOf([1, 2, 1, 2], 2);\n * // => 3\n *\n * // Search from the `fromIndex`.\n * _.lastIndexOf([1, 2, 1, 2], 2, 2);\n * // => 1\n */\n function lastIndexOf(array, value, fromIndex) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return -1;\n }\n var index = length;\n if (fromIndex !== undefined) {\n index = toInteger(fromIndex);\n index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);\n }\n return value === value\n ? strictLastIndexOf(array, value, index)\n : baseFindIndex(array, baseIsNaN, index, true);\n }\n\n /**\n * Gets the element at index `n` of `array`. If `n` is negative, the nth\n * element from the end is returned.\n *\n * @static\n * @memberOf _\n * @since 4.11.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=0] The index of the element to return.\n * @returns {*} Returns the nth element of `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n *\n * _.nth(array, 1);\n * // => 'b'\n *\n * _.nth(array, -2);\n * // => 'c';\n */\n function nth(array, n) {\n return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;\n }\n\n /**\n * Removes all given values from `array` using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`\n * to remove elements from an array by predicate.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...*} [values] The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n *\n * _.pull(array, 'a', 'c');\n * console.log(array);\n * // => ['b', 'b']\n */\n var pull = baseRest(pullAll);\n\n /**\n * This method is like `_.pull` except that it accepts an array of values to remove.\n *\n * **Note:** Unlike `_.difference`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = ['a', 'b', 'c', 'a', 'b', 'c'];\n *\n * _.pullAll(array, ['a', 'c']);\n * console.log(array);\n * // => ['b', 'b']\n */\n function pullAll(array, values) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values)\n : array;\n }\n\n /**\n * This method is like `_.pullAll` except that it accepts `iteratee` which is\n * invoked for each element of `array` and `values` to generate the criterion\n * by which they're compared. The iteratee is invoked with one argument: (value).\n *\n * **Note:** Unlike `_.differenceBy`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];\n *\n * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');\n * console.log(array);\n * // => [{ 'x': 2 }]\n */\n function pullAllBy(array, values, iteratee) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, getIteratee(iteratee, 2))\n : array;\n }\n\n /**\n * This method is like `_.pullAll` except that it accepts `comparator` which\n * is invoked to compare elements of `array` to `values`. The comparator is\n * invoked with two arguments: (arrVal, othVal).\n *\n * **Note:** Unlike `_.differenceWith`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Array} values The values to remove.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];\n *\n * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);\n * console.log(array);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]\n */\n function pullAllWith(array, values, comparator) {\n return (array && array.length && values && values.length)\n ? basePullAll(array, values, undefined, comparator)\n : array;\n }\n\n /**\n * Removes elements from `array` corresponding to `indexes` and returns an\n * array of removed elements.\n *\n * **Note:** Unlike `_.at`, this method mutates `array`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {...(number|number[])} [indexes] The indexes of elements to remove.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = ['a', 'b', 'c', 'd'];\n * var pulled = _.pullAt(array, [1, 3]);\n *\n * console.log(array);\n * // => ['a', 'c']\n *\n * console.log(pulled);\n * // => ['b', 'd']\n */\n var pullAt = flatRest(function(array, indexes) {\n var length = array == null ? 0 : array.length,\n result = baseAt(array, indexes);\n\n basePullAt(array, arrayMap(indexes, function(index) {\n return isIndex(index, length) ? +index : index;\n }).sort(compareAscending));\n\n return result;\n });\n\n /**\n * Removes all elements from `array` that `predicate` returns truthy for\n * and returns an array of the removed elements. The predicate is invoked\n * with three arguments: (value, index, array).\n *\n * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`\n * to pull elements from an array by value.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new array of removed elements.\n * @example\n *\n * var array = [1, 2, 3, 4];\n * var evens = _.remove(array, function(n) {\n * return n % 2 == 0;\n * });\n *\n * console.log(array);\n * // => [1, 3]\n *\n * console.log(evens);\n * // => [2, 4]\n */\n function remove(array, predicate) {\n var result = [];\n if (!(array && array.length)) {\n return result;\n }\n var index = -1,\n indexes = [],\n length = array.length;\n\n predicate = getIteratee(predicate, 3);\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result.push(value);\n indexes.push(index);\n }\n }\n basePullAt(array, indexes);\n return result;\n }\n\n /**\n * Reverses `array` so that the first element becomes the last, the second\n * element becomes the second to last, and so on.\n *\n * **Note:** This method mutates `array` and is based on\n * [`Array#reverse`](https://mdn.io/Array/reverse).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to modify.\n * @returns {Array} Returns `array`.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _.reverse(array);\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\n function reverse(array) {\n return array == null ? array : nativeReverse.call(array);\n }\n\n /**\n * Creates a slice of `array` from `start` up to, but not including, `end`.\n *\n * **Note:** This method is used instead of\n * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are\n * returned.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to slice.\n * @param {number} [start=0] The start position.\n * @param {number} [end=array.length] The end position.\n * @returns {Array} Returns the slice of `array`.\n */\n function slice(array, start, end) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {\n start = 0;\n end = length;\n }\n else {\n start = start == null ? 0 : toInteger(start);\n end = end === undefined ? length : toInteger(end);\n }\n return baseSlice(array, start, end);\n }\n\n /**\n * Uses a binary search to determine the lowest index at which `value`\n * should be inserted into `array` in order to maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedIndex([30, 50], 40);\n * // => 1\n */\n function sortedIndex(array, value) {\n return baseSortedIndex(array, value);\n }\n\n /**\n * This method is like `_.sortedIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var objects = [{ 'x': 4 }, { 'x': 5 }];\n *\n * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n * // => 0\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedIndexBy(objects, { 'x': 4 }, 'x');\n * // => 0\n */\n function sortedIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));\n }\n\n /**\n * This method is like `_.indexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedIndexOf([4, 5, 5, 5, 6], 5);\n * // => 1\n */\n function sortedIndexOf(array, value) {\n var length = array == null ? 0 : array.length;\n if (length) {\n var index = baseSortedIndex(array, value);\n if (index < length && eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * This method is like `_.sortedIndex` except that it returns the highest\n * index at which `value` should be inserted into `array` in order to\n * maintain its sort order.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * _.sortedLastIndex([4, 5, 5, 5, 6], 5);\n * // => 4\n */\n function sortedLastIndex(array, value) {\n return baseSortedIndex(array, value, true);\n }\n\n /**\n * This method is like `_.sortedLastIndex` except that it accepts `iteratee`\n * which is invoked for `value` and each element of `array` to compute their\n * sort ranking. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The sorted array to inspect.\n * @param {*} value The value to evaluate.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {number} Returns the index at which `value` should be inserted\n * into `array`.\n * @example\n *\n * var objects = [{ 'x': 4 }, { 'x': 5 }];\n *\n * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });\n * // => 1\n *\n * // The `_.property` iteratee shorthand.\n * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');\n * // => 1\n */\n function sortedLastIndexBy(array, value, iteratee) {\n return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);\n }\n\n /**\n * This method is like `_.lastIndexOf` except that it performs a binary\n * search on a sorted `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n * @example\n *\n * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);\n * // => 3\n */\n function sortedLastIndexOf(array, value) {\n var length = array == null ? 0 : array.length;\n if (length) {\n var index = baseSortedIndex(array, value, true) - 1;\n if (eq(array[index], value)) {\n return index;\n }\n }\n return -1;\n }\n\n /**\n * This method is like `_.uniq` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniq([1, 1, 2]);\n * // => [1, 2]\n */\n function sortedUniq(array) {\n return (array && array.length)\n ? baseSortedUniq(array)\n : [];\n }\n\n /**\n * This method is like `_.uniqBy` except that it's designed and optimized\n * for sorted arrays.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);\n * // => [1.1, 2.3]\n */\n function sortedUniqBy(array, iteratee) {\n return (array && array.length)\n ? baseSortedUniq(array, getIteratee(iteratee, 2))\n : [];\n }\n\n /**\n * Gets all but the first element of `array`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.tail([1, 2, 3]);\n * // => [2, 3]\n */\n function tail(array) {\n var length = array == null ? 0 : array.length;\n return length ? baseSlice(array, 1, length) : [];\n }\n\n /**\n * Creates a slice of `array` with `n` elements taken from the beginning.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.take([1, 2, 3]);\n * // => [1]\n *\n * _.take([1, 2, 3], 2);\n * // => [1, 2]\n *\n * _.take([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.take([1, 2, 3], 0);\n * // => []\n */\n function take(array, n, guard) {\n if (!(array && array.length)) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n return baseSlice(array, 0, n < 0 ? 0 : n);\n }\n\n /**\n * Creates a slice of `array` with `n` elements taken from the end.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {number} [n=1] The number of elements to take.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * _.takeRight([1, 2, 3]);\n * // => [3]\n *\n * _.takeRight([1, 2, 3], 2);\n * // => [2, 3]\n *\n * _.takeRight([1, 2, 3], 5);\n * // => [1, 2, 3]\n *\n * _.takeRight([1, 2, 3], 0);\n * // => []\n */\n function takeRight(array, n, guard) {\n var length = array == null ? 0 : array.length;\n if (!length) {\n return [];\n }\n n = (guard || n === undefined) ? 1 : toInteger(n);\n n = length - n;\n return baseSlice(array, n < 0 ? 0 : n, length);\n }\n\n /**\n * Creates a slice of `array` with elements taken from the end. Elements are\n * taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': false }\n * ];\n *\n * _.takeRightWhile(users, function(o) { return !o.active; });\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });\n * // => objects for ['pebbles']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeRightWhile(users, ['active', false]);\n * // => objects for ['fred', 'pebbles']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeRightWhile(users, 'active');\n * // => []\n */\n function takeRightWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3), false, true)\n : [];\n }\n\n /**\n * Creates a slice of `array` with elements taken from the beginning. Elements\n * are taken until `predicate` returns falsey. The predicate is invoked with\n * three arguments: (value, index, array).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Array\n * @param {Array} array The array to query.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the slice of `array`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'active': false },\n * { 'user': 'fred', 'active': false },\n * { 'user': 'pebbles', 'active': true }\n * ];\n *\n * _.takeWhile(users, function(o) { return !o.active; });\n * // => objects for ['barney', 'fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.takeWhile(users, { 'user': 'barney', 'active': false });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.takeWhile(users, ['active', false]);\n * // => objects for ['barney', 'fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.takeWhile(users, 'active');\n * // => []\n */\n function takeWhile(array, predicate) {\n return (array && array.length)\n ? baseWhile(array, getIteratee(predicate, 3))\n : [];\n }\n\n /**\n * Creates an array of unique values, in order, from all given arrays using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.union([2], [1, 2]);\n * // => [2, 1]\n */\n var union = baseRest(function(arrays) {\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));\n });\n\n /**\n * This method is like `_.union` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which uniqueness is computed. Result values are chosen from the first\n * array in which the value occurs. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * _.unionBy([2.1], [1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\n var unionBy = baseRest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));\n });\n\n /**\n * This method is like `_.union` except that it accepts `comparator` which\n * is invoked to compare elements of `arrays`. Result values are chosen from\n * the first array in which the value occurs. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of combined values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.unionWith(objects, others, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\n var unionWith = baseRest(function(arrays) {\n var comparator = last(arrays);\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);\n });\n\n /**\n * Creates a duplicate-free version of an array, using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons, in which only the first occurrence of each element\n * is kept. The order of result values is determined by the order they occur\n * in the array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniq([2, 1, 2]);\n * // => [2, 1]\n */\n function uniq(array) {\n return (array && array.length) ? baseUniq(array) : [];\n }\n\n /**\n * This method is like `_.uniq` except that it accepts `iteratee` which is\n * invoked for each element in `array` to generate the criterion by which\n * uniqueness is computed. The order of result values is determined by the\n * order they occur in the array. The iteratee is invoked with one argument:\n * (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * _.uniqBy([2.1, 1.2, 2.3], Math.floor);\n * // => [2.1, 1.2]\n *\n * // The `_.property` iteratee shorthand.\n * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 1 }, { 'x': 2 }]\n */\n function uniqBy(array, iteratee) {\n return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];\n }\n\n /**\n * This method is like `_.uniq` except that it accepts `comparator` which\n * is invoked to compare elements of `array`. The order of result values is\n * determined by the order they occur in the array.The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.uniqWith(objects, _.isEqual);\n * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]\n */\n function uniqWith(array, comparator) {\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return (array && array.length) ? baseUniq(array, undefined, comparator) : [];\n }\n\n /**\n * This method is like `_.zip` except that it accepts an array of grouped\n * elements and creates an array regrouping the elements to their pre-zip\n * configuration.\n *\n * @static\n * @memberOf _\n * @since 1.2.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);\n * // => [['a', 1, true], ['b', 2, false]]\n *\n * _.unzip(zipped);\n * // => [['a', 'b'], [1, 2], [true, false]]\n */\n function unzip(array) {\n if (!(array && array.length)) {\n return [];\n }\n var length = 0;\n array = arrayFilter(array, function(group) {\n if (isArrayLikeObject(group)) {\n length = nativeMax(group.length, length);\n return true;\n }\n });\n return baseTimes(length, function(index) {\n return arrayMap(array, baseProperty(index));\n });\n }\n\n /**\n * This method is like `_.unzip` except that it accepts `iteratee` to specify\n * how regrouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {Array} array The array of grouped elements to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * regrouped values.\n * @returns {Array} Returns the new array of regrouped elements.\n * @example\n *\n * var zipped = _.zip([1, 2], [10, 20], [100, 200]);\n * // => [[1, 10, 100], [2, 20, 200]]\n *\n * _.unzipWith(zipped, _.add);\n * // => [3, 30, 300]\n */\n function unzipWith(array, iteratee) {\n if (!(array && array.length)) {\n return [];\n }\n var result = unzip(array);\n if (iteratee == null) {\n return result;\n }\n return arrayMap(result, function(group) {\n return apply(iteratee, undefined, group);\n });\n }\n\n /**\n * Creates an array excluding all given values using\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * **Note:** Unlike `_.pull`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {Array} array The array to inspect.\n * @param {...*} [values] The values to exclude.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.xor\n * @example\n *\n * _.without([2, 1, 2, 3], 1, 2);\n * // => [3]\n */\n var without = baseRest(function(array, values) {\n return isArrayLikeObject(array)\n ? baseDifference(array, values)\n : [];\n });\n\n /**\n * Creates an array of unique values that is the\n * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)\n * of the given arrays. The order of result values is determined by the order\n * they occur in the arrays.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @returns {Array} Returns the new array of filtered values.\n * @see _.difference, _.without\n * @example\n *\n * _.xor([2, 1], [2, 3]);\n * // => [1, 3]\n */\n var xor = baseRest(function(arrays) {\n return baseXor(arrayFilter(arrays, isArrayLikeObject));\n });\n\n /**\n * This method is like `_.xor` except that it accepts `iteratee` which is\n * invoked for each element of each `arrays` to generate the criterion by\n * which by which they're compared. The order of result values is determined\n * by the order they occur in the arrays. The iteratee is invoked with one\n * argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);\n * // => [1.2, 3.4]\n *\n * // The `_.property` iteratee shorthand.\n * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');\n * // => [{ 'x': 2 }]\n */\n var xorBy = baseRest(function(arrays) {\n var iteratee = last(arrays);\n if (isArrayLikeObject(iteratee)) {\n iteratee = undefined;\n }\n return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));\n });\n\n /**\n * This method is like `_.xor` except that it accepts `comparator` which is\n * invoked to compare elements of `arrays`. The order of result values is\n * determined by the order they occur in the arrays. The comparator is invoked\n * with two arguments: (arrVal, othVal).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Array\n * @param {...Array} [arrays] The arrays to inspect.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new array of filtered values.\n * @example\n *\n * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];\n * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];\n *\n * _.xorWith(objects, others, _.isEqual);\n * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]\n */\n var xorWith = baseRest(function(arrays) {\n var comparator = last(arrays);\n comparator = typeof comparator == 'function' ? comparator : undefined;\n return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);\n });\n\n /**\n * Creates an array of grouped elements, the first of which contains the\n * first elements of the given arrays, the second of which contains the\n * second elements of the given arrays, and so on.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zip(['a', 'b'], [1, 2], [true, false]);\n * // => [['a', 1, true], ['b', 2, false]]\n */\n var zip = baseRest(unzip);\n\n /**\n * This method is like `_.fromPairs` except that it accepts two arrays,\n * one of property identifiers and one of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 0.4.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObject(['a', 'b'], [1, 2]);\n * // => { 'a': 1, 'b': 2 }\n */\n function zipObject(props, values) {\n return baseZipObject(props || [], values || [], assignValue);\n }\n\n /**\n * This method is like `_.zipObject` except that it supports property paths.\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Array\n * @param {Array} [props=[]] The property identifiers.\n * @param {Array} [values=[]] The property values.\n * @returns {Object} Returns the new object.\n * @example\n *\n * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);\n * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }\n */\n function zipObjectDeep(props, values) {\n return baseZipObject(props || [], values || [], baseSet);\n }\n\n /**\n * This method is like `_.zip` except that it accepts `iteratee` to specify\n * how grouped values should be combined. The iteratee is invoked with the\n * elements of each group: (...group).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Array\n * @param {...Array} [arrays] The arrays to process.\n * @param {Function} [iteratee=_.identity] The function to combine\n * grouped values.\n * @returns {Array} Returns the new array of grouped elements.\n * @example\n *\n * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {\n * return a + b + c;\n * });\n * // => [111, 222]\n */\n var zipWith = baseRest(function(arrays) {\n var length = arrays.length,\n iteratee = length > 1 ? arrays[length - 1] : undefined;\n\n iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;\n return unzipWith(arrays, iteratee);\n });\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates a `lodash` wrapper instance that wraps `value` with explicit method\n * chain sequences enabled. The result of such sequences must be unwrapped\n * with `_#value`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Seq\n * @param {*} value The value to wrap.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'pebbles', 'age': 1 }\n * ];\n *\n * var youngest = _\n * .chain(users)\n * .sortBy('age')\n * .map(function(o) {\n * return o.user + ' is ' + o.age;\n * })\n * .head()\n * .value();\n * // => 'pebbles is 1'\n */\n function chain(value) {\n var result = lodash(value);\n result.__chain__ = true;\n return result;\n }\n\n /**\n * This method invokes `interceptor` and returns `value`. The interceptor\n * is invoked with one argument; (value). The purpose of this method is to\n * \"tap into\" a method chain sequence in order to modify intermediate results.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @param {*} value The value to provide to `interceptor`.\n * @param {Function} interceptor The function to invoke.\n * @returns {*} Returns `value`.\n * @example\n *\n * _([1, 2, 3])\n * .tap(function(array) {\n * // Mutate input array.\n * array.pop();\n * })\n * .reverse()\n * .value();\n * // => [2, 1]\n */\n function tap(value, interceptor) {\n interceptor(value);\n return value;\n }\n\n /**\n * This method is like `_.tap` except that it returns the result of `interceptor`.\n * The purpose of this method is to \"pass thru\" values replacing intermediate\n * results in a method chain sequence.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Seq\n * @param {*} value The value to provide to `interceptor`.\n * @param {Function} interceptor The function to invoke.\n * @returns {*} Returns the result of `interceptor`.\n * @example\n *\n * _(' abc ')\n * .chain()\n * .trim()\n * .thru(function(value) {\n * return [value];\n * })\n * .value();\n * // => ['abc']\n */\n function thru(value, interceptor) {\n return interceptor(value);\n }\n\n /**\n * This method is the wrapper version of `_.at`.\n *\n * @name at\n * @memberOf _\n * @since 1.0.0\n * @category Seq\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n *\n * _(object).at(['a[0].b.c', 'a[1]']).value();\n * // => [3, 4]\n */\n var wrapperAt = flatRest(function(paths) {\n var length = paths.length,\n start = length ? paths[0] : 0,\n value = this.__wrapped__,\n interceptor = function(object) { return baseAt(object, paths); };\n\n if (length > 1 || this.__actions__.length ||\n !(value instanceof LazyWrapper) || !isIndex(start)) {\n return this.thru(interceptor);\n }\n value = value.slice(start, +start + (length ? 1 : 0));\n value.__actions__.push({\n 'func': thru,\n 'args': [interceptor],\n 'thisArg': undefined\n });\n return new LodashWrapper(value, this.__chain__).thru(function(array) {\n if (length && !array.length) {\n array.push(undefined);\n }\n return array;\n });\n });\n\n /**\n * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.\n *\n * @name chain\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 40 }\n * ];\n *\n * // A sequence without explicit chaining.\n * _(users).head();\n * // => { 'user': 'barney', 'age': 36 }\n *\n * // A sequence with explicit chaining.\n * _(users)\n * .chain()\n * .head()\n * .pick('user')\n * .value();\n * // => { 'user': 'barney' }\n */\n function wrapperChain() {\n return chain(this);\n }\n\n /**\n * Executes the chain sequence and returns the wrapped result.\n *\n * @name commit\n * @memberOf _\n * @since 3.2.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var array = [1, 2];\n * var wrapped = _(array).push(3);\n *\n * console.log(array);\n * // => [1, 2]\n *\n * wrapped = wrapped.commit();\n * console.log(array);\n * // => [1, 2, 3]\n *\n * wrapped.last();\n * // => 3\n *\n * console.log(array);\n * // => [1, 2, 3]\n */\n function wrapperCommit() {\n return new LodashWrapper(this.value(), this.__chain__);\n }\n\n /**\n * Gets the next value on a wrapped object following the\n * [iterator protocol](https://mdn.io/iteration_protocols#iterator).\n *\n * @name next\n * @memberOf _\n * @since 4.0.0\n * @category Seq\n * @returns {Object} Returns the next iterator value.\n * @example\n *\n * var wrapped = _([1, 2]);\n *\n * wrapped.next();\n * // => { 'done': false, 'value': 1 }\n *\n * wrapped.next();\n * // => { 'done': false, 'value': 2 }\n *\n * wrapped.next();\n * // => { 'done': true, 'value': undefined }\n */\n function wrapperNext() {\n if (this.__values__ === undefined) {\n this.__values__ = toArray(this.value());\n }\n var done = this.__index__ >= this.__values__.length,\n value = done ? undefined : this.__values__[this.__index__++];\n\n return { 'done': done, 'value': value };\n }\n\n /**\n * Enables the wrapper to be iterable.\n *\n * @name Symbol.iterator\n * @memberOf _\n * @since 4.0.0\n * @category Seq\n * @returns {Object} Returns the wrapper object.\n * @example\n *\n * var wrapped = _([1, 2]);\n *\n * wrapped[Symbol.iterator]() === wrapped;\n * // => true\n *\n * Array.from(wrapped);\n * // => [1, 2]\n */\n function wrapperToIterator() {\n return this;\n }\n\n /**\n * Creates a clone of the chain sequence planting `value` as the wrapped value.\n *\n * @name plant\n * @memberOf _\n * @since 3.2.0\n * @category Seq\n * @param {*} value The value to plant.\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var wrapped = _([1, 2]).map(square);\n * var other = wrapped.plant([3, 4]);\n *\n * other.value();\n * // => [9, 16]\n *\n * wrapped.value();\n * // => [1, 4]\n */\n function wrapperPlant(value) {\n var result,\n parent = this;\n\n while (parent instanceof baseLodash) {\n var clone = wrapperClone(parent);\n clone.__index__ = 0;\n clone.__values__ = undefined;\n if (result) {\n previous.__wrapped__ = clone;\n } else {\n result = clone;\n }\n var previous = clone;\n parent = parent.__wrapped__;\n }\n previous.__wrapped__ = value;\n return result;\n }\n\n /**\n * This method is the wrapper version of `_.reverse`.\n *\n * **Note:** This method mutates the wrapped array.\n *\n * @name reverse\n * @memberOf _\n * @since 0.1.0\n * @category Seq\n * @returns {Object} Returns the new `lodash` wrapper instance.\n * @example\n *\n * var array = [1, 2, 3];\n *\n * _(array).reverse().value()\n * // => [3, 2, 1]\n *\n * console.log(array);\n * // => [3, 2, 1]\n */\n function wrapperReverse() {\n var value = this.__wrapped__;\n if (value instanceof LazyWrapper) {\n var wrapped = value;\n if (this.__actions__.length) {\n wrapped = new LazyWrapper(this);\n }\n wrapped = wrapped.reverse();\n wrapped.__actions__.push({\n 'func': thru,\n 'args': [reverse],\n 'thisArg': undefined\n });\n return new LodashWrapper(wrapped, this.__chain__);\n }\n return this.thru(reverse);\n }\n\n /**\n * Executes the chain sequence to resolve the unwrapped value.\n *\n * @name value\n * @memberOf _\n * @since 0.1.0\n * @alias toJSON, valueOf\n * @category Seq\n * @returns {*} Returns the resolved unwrapped value.\n * @example\n *\n * _([1, 2, 3]).value();\n * // => [1, 2, 3]\n */\n function wrapperValue() {\n return baseWrapperValue(this.__wrapped__, this.__actions__);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the number of times the key was returned by `iteratee`. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * _.countBy([6.1, 4.2, 6.3], Math.floor);\n * // => { '4': 1, '6': 2 }\n *\n * // The `_.property` iteratee shorthand.\n * _.countBy(['one', 'two', 'three'], 'length');\n * // => { '3': 2, '5': 1 }\n */\n var countBy = createAggregator(function(result, value, key) {\n if (hasOwnProperty.call(result, key)) {\n ++result[key];\n } else {\n baseAssignValue(result, key, 1);\n }\n });\n\n /**\n * Checks if `predicate` returns truthy for **all** elements of `collection`.\n * Iteration is stopped once `predicate` returns falsey. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * **Note:** This method returns `true` for\n * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because\n * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of\n * elements of empty collections.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if all elements pass the predicate check,\n * else `false`.\n * @example\n *\n * _.every([true, 1, null, 'yes'], Boolean);\n * // => false\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.every(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.every(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.every(users, 'active');\n * // => false\n */\n function every(collection, predicate, guard) {\n var func = isArray(collection) ? arrayEvery : baseEvery;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Iterates over elements of `collection`, returning an array of all elements\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * **Note:** Unlike `_.remove`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.reject\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * _.filter(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.filter(users, { 'age': 36, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.filter(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.filter(users, 'active');\n * // => objects for ['barney']\n *\n * // Combining several predicates using `_.overEvery` or `_.overSome`.\n * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));\n * // => objects for ['fred', 'barney']\n */\n function filter(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Iterates over elements of `collection`, returning the first element\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=0] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false },\n * { 'user': 'pebbles', 'age': 1, 'active': true }\n * ];\n *\n * _.find(users, function(o) { return o.age < 40; });\n * // => object for 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.find(users, { 'age': 1, 'active': true });\n * // => object for 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.find(users, ['active', false]);\n * // => object for 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.find(users, 'active');\n * // => object for 'barney'\n */\n var find = createFind(findIndex);\n\n /**\n * This method is like `_.find` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param {number} [fromIndex=collection.length-1] The index to search from.\n * @returns {*} Returns the matched element, else `undefined`.\n * @example\n *\n * _.findLast([1, 2, 3, 4], function(n) {\n * return n % 2 == 1;\n * });\n * // => 3\n */\n var findLast = createFind(findLastIndex);\n\n /**\n * Creates a flattened array of values by running each element in `collection`\n * thru `iteratee` and flattening the mapped results. The iteratee is invoked\n * with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [n, n];\n * }\n *\n * _.flatMap([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\n function flatMap(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), 1);\n }\n\n /**\n * This method is like `_.flatMap` except that it recursively flattens the\n * mapped results.\n *\n * @static\n * @memberOf _\n * @since 4.7.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [[[n, n]]];\n * }\n *\n * _.flatMapDeep([1, 2], duplicate);\n * // => [1, 1, 2, 2]\n */\n function flatMapDeep(collection, iteratee) {\n return baseFlatten(map(collection, iteratee), INFINITY);\n }\n\n /**\n * This method is like `_.flatMap` except that it recursively flattens the\n * mapped results up to `depth` times.\n *\n * @static\n * @memberOf _\n * @since 4.7.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {number} [depth=1] The maximum recursion depth.\n * @returns {Array} Returns the new flattened array.\n * @example\n *\n * function duplicate(n) {\n * return [[[n, n]]];\n * }\n *\n * _.flatMapDepth([1, 2], duplicate, 2);\n * // => [[1, 1], [2, 2]]\n */\n function flatMapDepth(collection, iteratee, depth) {\n depth = depth === undefined ? 1 : toInteger(depth);\n return baseFlatten(map(collection, iteratee), depth);\n }\n\n /**\n * Iterates over elements of `collection` and invokes `iteratee` for each element.\n * The iteratee is invoked with three arguments: (value, index|key, collection).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n * property are iterated like arrays. To avoid this behavior use `_.forIn`\n * or `_.forOwn` for object iteration.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias each\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEachRight\n * @example\n *\n * _.forEach([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `1` then `2`.\n *\n * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\n function forEach(collection, iteratee) {\n var func = isArray(collection) ? arrayEach : baseEach;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.forEach` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @alias eachRight\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEach\n * @example\n *\n * _.forEachRight([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `2` then `1`.\n */\n function forEachRight(collection, iteratee) {\n var func = isArray(collection) ? arrayEachRight : baseEachRight;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The order of grouped values\n * is determined by the order they occur in `collection`. The corresponding\n * value of each key is an array of elements responsible for generating the\n * key. The iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * _.groupBy([6.1, 4.2, 6.3], Math.floor);\n * // => { '4': [4.2], '6': [6.1, 6.3] }\n *\n * // The `_.property` iteratee shorthand.\n * _.groupBy(['one', 'two', 'three'], 'length');\n * // => { '3': ['one', 'two'], '5': ['three'] }\n */\n var groupBy = createAggregator(function(result, value, key) {\n if (hasOwnProperty.call(result, key)) {\n result[key].push(value);\n } else {\n baseAssignValue(result, key, [value]);\n }\n });\n\n /**\n * Checks if `value` is in `collection`. If `collection` is a string, it's\n * checked for a substring of `value`, otherwise\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * is used for equality comparisons. If `fromIndex` is negative, it's used as\n * the offset from the end of `collection`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @param {*} value The value to search for.\n * @param {number} [fromIndex=0] The index to search from.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {boolean} Returns `true` if `value` is found, else `false`.\n * @example\n *\n * _.includes([1, 2, 3], 1);\n * // => true\n *\n * _.includes([1, 2, 3], 1, 2);\n * // => false\n *\n * _.includes({ 'a': 1, 'b': 2 }, 1);\n * // => true\n *\n * _.includes('abcd', 'bc');\n * // => true\n */\n function includes(collection, value, fromIndex, guard) {\n collection = isArrayLike(collection) ? collection : values(collection);\n fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;\n\n var length = collection.length;\n if (fromIndex < 0) {\n fromIndex = nativeMax(length + fromIndex, 0);\n }\n return isString(collection)\n ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)\n : (!!length && baseIndexOf(collection, value, fromIndex) > -1);\n }\n\n /**\n * Invokes the method at `path` of each element in `collection`, returning\n * an array of the results of each invoked method. Any additional arguments\n * are provided to each invoked method. If `path` is a function, it's invoked\n * for, and `this` bound to, each element in `collection`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Array|Function|string} path The path of the method to invoke or\n * the function invoked per iteration.\n * @param {...*} [args] The arguments to invoke each method with.\n * @returns {Array} Returns the array of results.\n * @example\n *\n * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');\n * // => [[1, 5, 7], [1, 2, 3]]\n *\n * _.invokeMap([123, 456], String.prototype.split, '');\n * // => [['1', '2', '3'], ['4', '5', '6']]\n */\n var invokeMap = baseRest(function(collection, path, args) {\n var index = -1,\n isFunc = typeof path == 'function',\n result = isArrayLike(collection) ? Array(collection.length) : [];\n\n baseEach(collection, function(value) {\n result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);\n });\n return result;\n });\n\n /**\n * Creates an object composed of keys generated from the results of running\n * each element of `collection` thru `iteratee`. The corresponding value of\n * each key is the last element responsible for generating the key. The\n * iteratee is invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The iteratee to transform keys.\n * @returns {Object} Returns the composed aggregate object.\n * @example\n *\n * var array = [\n * { 'dir': 'left', 'code': 97 },\n * { 'dir': 'right', 'code': 100 }\n * ];\n *\n * _.keyBy(array, function(o) {\n * return String.fromCharCode(o.code);\n * });\n * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }\n *\n * _.keyBy(array, 'dir');\n * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }\n */\n var keyBy = createAggregator(function(result, value, key) {\n baseAssignValue(result, key, value);\n });\n\n /**\n * Creates an array of values by running each element in `collection` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.\n *\n * The guarded methods are:\n * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,\n * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,\n * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,\n * `template`, `trim`, `trimEnd`, `trimStart`, and `words`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n * @example\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * _.map([4, 8], square);\n * // => [16, 64]\n *\n * _.map({ 'a': 4, 'b': 8 }, square);\n * // => [16, 64] (iteration order is not guaranteed)\n *\n * var users = [\n * { 'user': 'barney' },\n * { 'user': 'fred' }\n * ];\n *\n * // The `_.property` iteratee shorthand.\n * _.map(users, 'user');\n * // => ['barney', 'fred']\n */\n function map(collection, iteratee) {\n var func = isArray(collection) ? arrayMap : baseMap;\n return func(collection, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.sortBy` except that it allows specifying the sort\n * orders of the iteratees to sort by. If `orders` is unspecified, all values\n * are sorted in ascending order. Otherwise, specify an order of \"desc\" for\n * descending or \"asc\" for ascending sort order of corresponding values.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @param {string[]} [orders] The sort orders of `iteratees`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 34 },\n * { 'user': 'fred', 'age': 40 },\n * { 'user': 'barney', 'age': 36 }\n * ];\n *\n * // Sort by `user` in ascending order and by `age` in descending order.\n * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]\n */\n function orderBy(collection, iteratees, orders, guard) {\n if (collection == null) {\n return [];\n }\n if (!isArray(iteratees)) {\n iteratees = iteratees == null ? [] : [iteratees];\n }\n orders = guard ? undefined : orders;\n if (!isArray(orders)) {\n orders = orders == null ? [] : [orders];\n }\n return baseOrderBy(collection, iteratees, orders);\n }\n\n /**\n * Creates an array of elements split into two groups, the first of which\n * contains elements `predicate` returns truthy for, the second of which\n * contains elements `predicate` returns falsey for. The predicate is\n * invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the array of grouped elements.\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': true },\n * { 'user': 'pebbles', 'age': 1, 'active': false }\n * ];\n *\n * _.partition(users, function(o) { return o.active; });\n * // => objects for [['fred'], ['barney', 'pebbles']]\n *\n * // The `_.matches` iteratee shorthand.\n * _.partition(users, { 'age': 1, 'active': false });\n * // => objects for [['pebbles'], ['barney', 'fred']]\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.partition(users, ['active', false]);\n * // => objects for [['barney', 'pebbles'], ['fred']]\n *\n * // The `_.property` iteratee shorthand.\n * _.partition(users, 'active');\n * // => objects for [['fred'], ['barney', 'pebbles']]\n */\n var partition = createAggregator(function(result, value, key) {\n result[key ? 0 : 1].push(value);\n }, function() { return [[], []]; });\n\n /**\n * Reduces `collection` to a value which is the accumulated result of running\n * each element in `collection` thru `iteratee`, where each successive\n * invocation is supplied the return value of the previous. If `accumulator`\n * is not given, the first element of `collection` is used as the initial\n * value. The iteratee is invoked with four arguments:\n * (accumulator, value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.reduce`, `_.reduceRight`, and `_.transform`.\n *\n * The guarded methods are:\n * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n * and `sortBy`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduceRight\n * @example\n *\n * _.reduce([1, 2], function(sum, n) {\n * return sum + n;\n * }, 0);\n * // => 3\n *\n * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * return result;\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n */\n function reduce(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduce : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n }\n\n /**\n * This method is like `_.reduce` except that it iterates over elements of\n * `collection` from right to left.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduce\n * @example\n *\n * var array = [[0, 1], [2, 3], [4, 5]];\n *\n * _.reduceRight(array, function(flattened, other) {\n * return flattened.concat(other);\n * }, []);\n * // => [4, 5, 2, 3, 0, 1]\n */\n function reduceRight(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduceRight : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);\n }\n\n /**\n * The opposite of `_.filter`; this method returns the elements of `collection`\n * that `predicate` does **not** return truthy for.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.filter\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': false },\n * { 'user': 'fred', 'age': 40, 'active': true }\n * ];\n *\n * _.reject(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.reject(users, { 'age': 40, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.reject(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.reject(users, 'active');\n * // => objects for ['barney']\n */\n function reject(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, negate(getIteratee(predicate, 3)));\n }\n\n /**\n * Gets a random element from `collection`.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to sample.\n * @returns {*} Returns the random element.\n * @example\n *\n * _.sample([1, 2, 3, 4]);\n * // => 2\n */\n function sample(collection) {\n var func = isArray(collection) ? arraySample : baseSample;\n return func(collection);\n }\n\n /**\n * Gets `n` random elements at unique keys from `collection` up to the\n * size of `collection`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Collection\n * @param {Array|Object} collection The collection to sample.\n * @param {number} [n=1] The number of elements to sample.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Array} Returns the random elements.\n * @example\n *\n * _.sampleSize([1, 2, 3], 2);\n * // => [3, 1]\n *\n * _.sampleSize([1, 2, 3], 4);\n * // => [2, 3, 1]\n */\n function sampleSize(collection, n, guard) {\n if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {\n n = 1;\n } else {\n n = toInteger(n);\n }\n var func = isArray(collection) ? arraySampleSize : baseSampleSize;\n return func(collection, n);\n }\n\n /**\n * Creates an array of shuffled values, using a version of the\n * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to shuffle.\n * @returns {Array} Returns the new shuffled array.\n * @example\n *\n * _.shuffle([1, 2, 3, 4]);\n * // => [4, 1, 3, 2]\n */\n function shuffle(collection) {\n var func = isArray(collection) ? arrayShuffle : baseShuffle;\n return func(collection);\n }\n\n /**\n * Gets the size of `collection` by returning its length for array-like\n * values or the number of own enumerable string keyed properties for objects.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object|string} collection The collection to inspect.\n * @returns {number} Returns the collection size.\n * @example\n *\n * _.size([1, 2, 3]);\n * // => 3\n *\n * _.size({ 'a': 1, 'b': 2 });\n * // => 2\n *\n * _.size('pebbles');\n * // => 7\n */\n function size(collection) {\n if (collection == null) {\n return 0;\n }\n if (isArrayLike(collection)) {\n return isString(collection) ? stringSize(collection) : collection.length;\n }\n var tag = getTag(collection);\n if (tag == mapTag || tag == setTag) {\n return collection.size;\n }\n return baseKeys(collection).length;\n }\n\n /**\n * Checks if `predicate` returns truthy for **any** element of `collection`.\n * Iteration is stopped once `predicate` returns truthy. The predicate is\n * invoked with three arguments: (value, index|key, collection).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n * @example\n *\n * _.some([null, 0, 'yes', false], Boolean);\n * // => true\n *\n * var users = [\n * { 'user': 'barney', 'active': true },\n * { 'user': 'fred', 'active': false }\n * ];\n *\n * // The `_.matches` iteratee shorthand.\n * _.some(users, { 'user': 'barney', 'active': false });\n * // => false\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.some(users, ['active', false]);\n * // => true\n *\n * // The `_.property` iteratee shorthand.\n * _.some(users, 'active');\n * // => true\n */\n function some(collection, predicate, guard) {\n var func = isArray(collection) ? arraySome : baseSome;\n if (guard && isIterateeCall(collection, predicate, guard)) {\n predicate = undefined;\n }\n return func(collection, getIteratee(predicate, 3));\n }\n\n /**\n * Creates an array of elements, sorted in ascending order by the results of\n * running each element in a collection thru each iteratee. This method\n * performs a stable sort, that is, it preserves the original sort order of\n * equal elements. The iteratees are invoked with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {...(Function|Function[])} [iteratees=[_.identity]]\n * The iteratees to sort by.\n * @returns {Array} Returns the new sorted array.\n * @example\n *\n * var users = [\n * { 'user': 'fred', 'age': 48 },\n * { 'user': 'barney', 'age': 36 },\n * { 'user': 'fred', 'age': 30 },\n * { 'user': 'barney', 'age': 34 }\n * ];\n *\n * _.sortBy(users, [function(o) { return o.user; }]);\n * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]\n *\n * _.sortBy(users, ['user', 'age']);\n * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]\n */\n var sortBy = baseRest(function(collection, iteratees) {\n if (collection == null) {\n return [];\n }\n var length = iteratees.length;\n if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {\n iteratees = [];\n } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {\n iteratees = [iteratees[0]];\n }\n return baseOrderBy(collection, baseFlatten(iteratees, 1), []);\n });\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\n var now = ctxNow || function() {\n return root.Date.now();\n };\n\n /*------------------------------------------------------------------------*/\n\n /**\n * The opposite of `_.before`; this method creates a function that invokes\n * `func` once it's called `n` or more times.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {number} n The number of calls before `func` is invoked.\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * var saves = ['profile', 'settings'];\n *\n * var done = _.after(saves.length, function() {\n * console.log('done saving!');\n * });\n *\n * _.forEach(saves, function(type) {\n * asyncSave({ 'type': type, 'complete': done });\n * });\n * // => Logs 'done saving!' after the two async saves have completed.\n */\n function after(n, func) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n n = toInteger(n);\n return function() {\n if (--n < 1) {\n return func.apply(this, arguments);\n }\n };\n }\n\n /**\n * Creates a function that invokes `func`, with up to `n` arguments,\n * ignoring any additional arguments.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @param {number} [n=func.length] The arity cap.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.ary(parseInt, 1));\n * // => [6, 8, 10]\n */\n function ary(func, n, guard) {\n n = guard ? undefined : n;\n n = (func && n == null) ? func.length : n;\n return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);\n }\n\n /**\n * Creates a function that invokes `func`, with the `this` binding and arguments\n * of the created function, while it's called less than `n` times. Subsequent\n * calls to the created function return the result of the last `func` invocation.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {number} n The number of calls at which `func` is no longer invoked.\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * jQuery(element).on('click', _.before(5, addContactToList));\n * // => Allows adding up to 4 contacts to the list.\n */\n function before(n, func) {\n var result;\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n n = toInteger(n);\n return function() {\n if (--n > 0) {\n result = func.apply(this, arguments);\n }\n if (n <= 1) {\n func = undefined;\n }\n return result;\n };\n }\n\n /**\n * Creates a function that invokes `func` with the `this` binding of `thisArg`\n * and `partials` prepended to the arguments it receives.\n *\n * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for partially applied arguments.\n *\n * **Note:** Unlike native `Function#bind`, this method doesn't set the \"length\"\n * property of bound functions.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to bind.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new bound function.\n * @example\n *\n * function greet(greeting, punctuation) {\n * return greeting + ' ' + this.user + punctuation;\n * }\n *\n * var object = { 'user': 'fred' };\n *\n * var bound = _.bind(greet, object, 'hi');\n * bound('!');\n * // => 'hi fred!'\n *\n * // Bound with placeholders.\n * var bound = _.bind(greet, object, _, '!');\n * bound('hi');\n * // => 'hi fred!'\n */\n var bind = baseRest(function(func, thisArg, partials) {\n var bitmask = WRAP_BIND_FLAG;\n if (partials.length) {\n var holders = replaceHolders(partials, getHolder(bind));\n bitmask |= WRAP_PARTIAL_FLAG;\n }\n return createWrap(func, bitmask, thisArg, partials, holders);\n });\n\n /**\n * Creates a function that invokes the method at `object[key]` with `partials`\n * prepended to the arguments it receives.\n *\n * This method differs from `_.bind` by allowing bound functions to reference\n * methods that may be redefined or don't yet exist. See\n * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)\n * for more details.\n *\n * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Function\n * @param {Object} object The object to invoke the method on.\n * @param {string} key The key of the method.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new bound function.\n * @example\n *\n * var object = {\n * 'user': 'fred',\n * 'greet': function(greeting, punctuation) {\n * return greeting + ' ' + this.user + punctuation;\n * }\n * };\n *\n * var bound = _.bindKey(object, 'greet', 'hi');\n * bound('!');\n * // => 'hi fred!'\n *\n * object.greet = function(greeting, punctuation) {\n * return greeting + 'ya ' + this.user + punctuation;\n * };\n *\n * bound('!');\n * // => 'hiya fred!'\n *\n * // Bound with placeholders.\n * var bound = _.bindKey(object, 'greet', _, '!');\n * bound('hi');\n * // => 'hiya fred!'\n */\n var bindKey = baseRest(function(object, key, partials) {\n var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;\n if (partials.length) {\n var holders = replaceHolders(partials, getHolder(bindKey));\n bitmask |= WRAP_PARTIAL_FLAG;\n }\n return createWrap(key, bitmask, object, partials, holders);\n });\n\n /**\n * Creates a function that accepts arguments of `func` and either invokes\n * `func` returning its result, if at least `arity` number of arguments have\n * been provided, or returns a function that accepts the remaining `func`\n * arguments, and so on. The arity of `func` may be specified if `func.length`\n * is not sufficient.\n *\n * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,\n * may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n * return [a, b, c];\n * };\n *\n * var curried = _.curry(abc);\n *\n * curried(1)(2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2)(3);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(1)(_, 3)(2);\n * // => [1, 2, 3]\n */\n function curry(func, arity, guard) {\n arity = guard ? undefined : arity;\n var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n result.placeholder = curry.placeholder;\n return result;\n }\n\n /**\n * This method is like `_.curry` except that arguments are applied to `func`\n * in the manner of `_.partialRight` instead of `_.partial`.\n *\n * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for provided arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of curried functions.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to curry.\n * @param {number} [arity=func.length] The arity of `func`.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the new curried function.\n * @example\n *\n * var abc = function(a, b, c) {\n * return [a, b, c];\n * };\n *\n * var curried = _.curryRight(abc);\n *\n * curried(3)(2)(1);\n * // => [1, 2, 3]\n *\n * curried(2, 3)(1);\n * // => [1, 2, 3]\n *\n * curried(1, 2, 3);\n * // => [1, 2, 3]\n *\n * // Curried with placeholders.\n * curried(3)(1, _)(2);\n * // => [1, 2, 3]\n */\n function curryRight(func, arity, guard) {\n arity = guard ? undefined : arity;\n var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);\n result.placeholder = curryRight.placeholder;\n return result;\n }\n\n /**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\n function debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n }\n\n /**\n * Defers invoking the `func` until the current call stack has cleared. Any\n * additional arguments are provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to defer.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.defer(function(text) {\n * console.log(text);\n * }, 'deferred');\n * // => Logs 'deferred' after one millisecond.\n */\n var defer = baseRest(function(func, args) {\n return baseDelay(func, 1, args);\n });\n\n /**\n * Invokes `func` after `wait` milliseconds. Any additional arguments are\n * provided to `func` when it's invoked.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to delay.\n * @param {number} wait The number of milliseconds to delay invocation.\n * @param {...*} [args] The arguments to invoke `func` with.\n * @returns {number} Returns the timer id.\n * @example\n *\n * _.delay(function(text) {\n * console.log(text);\n * }, 1000, 'later');\n * // => Logs 'later' after one second.\n */\n var delay = baseRest(function(func, wait, args) {\n return baseDelay(func, toNumber(wait) || 0, args);\n });\n\n /**\n * Creates a function that invokes `func` with arguments reversed.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to flip arguments for.\n * @returns {Function} Returns the new flipped function.\n * @example\n *\n * var flipped = _.flip(function() {\n * return _.toArray(arguments);\n * });\n *\n * flipped('a', 'b', 'c', 'd');\n * // => ['d', 'c', 'b', 'a']\n */\n function flip(func) {\n return createWrap(func, WRAP_FLIP_FLAG);\n }\n\n /**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\n function memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || MapCache);\n return memoized;\n }\n\n // Expose `MapCache`.\n memoize.Cache = MapCache;\n\n /**\n * Creates a function that negates the result of the predicate `func`. The\n * `func` predicate is invoked with the `this` binding and arguments of the\n * created function.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} predicate The predicate to negate.\n * @returns {Function} Returns the new negated function.\n * @example\n *\n * function isEven(n) {\n * return n % 2 == 0;\n * }\n *\n * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));\n * // => [1, 3, 5]\n */\n function negate(predicate) {\n if (typeof predicate != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n return function() {\n var args = arguments;\n switch (args.length) {\n case 0: return !predicate.call(this);\n case 1: return !predicate.call(this, args[0]);\n case 2: return !predicate.call(this, args[0], args[1]);\n case 3: return !predicate.call(this, args[0], args[1], args[2]);\n }\n return !predicate.apply(this, args);\n };\n }\n\n /**\n * Creates a function that is restricted to invoking `func` once. Repeat calls\n * to the function return the value of the first invocation. The `func` is\n * invoked with the `this` binding and arguments of the created function.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to restrict.\n * @returns {Function} Returns the new restricted function.\n * @example\n *\n * var initialize = _.once(createApplication);\n * initialize();\n * initialize();\n * // => `createApplication` is invoked once\n */\n function once(func) {\n return before(2, func);\n }\n\n /**\n * Creates a function that invokes `func` with its arguments transformed.\n *\n * @static\n * @since 4.0.0\n * @memberOf _\n * @category Function\n * @param {Function} func The function to wrap.\n * @param {...(Function|Function[])} [transforms=[_.identity]]\n * The argument transforms.\n * @returns {Function} Returns the new function.\n * @example\n *\n * function doubled(n) {\n * return n * 2;\n * }\n *\n * function square(n) {\n * return n * n;\n * }\n *\n * var func = _.overArgs(function(x, y) {\n * return [x, y];\n * }, [square, doubled]);\n *\n * func(9, 3);\n * // => [81, 6]\n *\n * func(10, 5);\n * // => [100, 10]\n */\n var overArgs = castRest(function(func, transforms) {\n transforms = (transforms.length == 1 && isArray(transforms[0]))\n ? arrayMap(transforms[0], baseUnary(getIteratee()))\n : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));\n\n var funcsLength = transforms.length;\n return baseRest(function(args) {\n var index = -1,\n length = nativeMin(args.length, funcsLength);\n\n while (++index < length) {\n args[index] = transforms[index].call(this, args[index]);\n }\n return apply(func, this, args);\n });\n });\n\n /**\n * Creates a function that invokes `func` with `partials` prepended to the\n * arguments it receives. This method is like `_.bind` except it does **not**\n * alter the `this` binding.\n *\n * The `_.partial.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 0.2.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n * return greeting + ' ' + name;\n * }\n *\n * var sayHelloTo = _.partial(greet, 'hello');\n * sayHelloTo('fred');\n * // => 'hello fred'\n *\n * // Partially applied with placeholders.\n * var greetFred = _.partial(greet, _, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n */\n var partial = baseRest(function(func, partials) {\n var holders = replaceHolders(partials, getHolder(partial));\n return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);\n });\n\n /**\n * This method is like `_.partial` except that partially applied arguments\n * are appended to the arguments it receives.\n *\n * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic\n * builds, may be used as a placeholder for partially applied arguments.\n *\n * **Note:** This method doesn't set the \"length\" property of partially\n * applied functions.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Function\n * @param {Function} func The function to partially apply arguments to.\n * @param {...*} [partials] The arguments to be partially applied.\n * @returns {Function} Returns the new partially applied function.\n * @example\n *\n * function greet(greeting, name) {\n * return greeting + ' ' + name;\n * }\n *\n * var greetFred = _.partialRight(greet, 'fred');\n * greetFred('hi');\n * // => 'hi fred'\n *\n * // Partially applied with placeholders.\n * var sayHelloTo = _.partialRight(greet, 'hello', _);\n * sayHelloTo('fred');\n * // => 'hello fred'\n */\n var partialRight = baseRest(function(func, partials) {\n var holders = replaceHolders(partials, getHolder(partialRight));\n return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);\n });\n\n /**\n * Creates a function that invokes `func` with arguments arranged according\n * to the specified `indexes` where the argument value at the first index is\n * provided as the first argument, the argument value at the second index is\n * provided as the second argument, and so on.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Function\n * @param {Function} func The function to rearrange arguments for.\n * @param {...(number|number[])} indexes The arranged argument indexes.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var rearged = _.rearg(function(a, b, c) {\n * return [a, b, c];\n * }, [2, 0, 1]);\n *\n * rearged('b', 'c', 'a')\n * // => ['a', 'b', 'c']\n */\n var rearg = flatRest(function(func, indexes) {\n return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);\n });\n\n /**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\n function rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = start === undefined ? start : toInteger(start);\n return baseRest(func, start);\n }\n\n /**\n * Creates a function that invokes `func` with the `this` binding of the\n * create function and an array of arguments much like\n * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).\n *\n * **Note:** This method is based on the\n * [spread operator](https://mdn.io/spread_operator).\n *\n * @static\n * @memberOf _\n * @since 3.2.0\n * @category Function\n * @param {Function} func The function to spread arguments over.\n * @param {number} [start=0] The start position of the spread.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.spread(function(who, what) {\n * return who + ' says ' + what;\n * });\n *\n * say(['fred', 'hello']);\n * // => 'fred says hello'\n *\n * var numbers = Promise.all([\n * Promise.resolve(40),\n * Promise.resolve(36)\n * ]);\n *\n * numbers.then(_.spread(function(x, y) {\n * return x + y;\n * }));\n * // => a Promise of 76\n */\n function spread(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = start == null ? 0 : nativeMax(toInteger(start), 0);\n return baseRest(function(args) {\n var array = args[start],\n otherArgs = castSlice(args, 0, start);\n\n if (array) {\n arrayPush(otherArgs, array);\n }\n return apply(func, this, otherArgs);\n });\n }\n\n /**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide `options` to indicate whether `func`\n * should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\n function throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n }\n\n /**\n * Creates a function that accepts up to one argument, ignoring any\n * additional arguments.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n * @example\n *\n * _.map(['6', '8', '10'], _.unary(parseInt));\n * // => [6, 8, 10]\n */\n function unary(func) {\n return ary(func, 1);\n }\n\n /**\n * Creates a function that provides `value` to `wrapper` as its first\n * argument. Any additional arguments provided to the function are appended\n * to those provided to the `wrapper`. The wrapper is invoked with the `this`\n * binding of the created function.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {*} value The value to wrap.\n * @param {Function} [wrapper=identity] The wrapper function.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var p = _.wrap(_.escape, function(func, text) {\n * return '

' + func(text) + '

';\n * });\n *\n * p('fred, barney, & pebbles');\n * // => '

fred, barney, & pebbles

'\n */\n function wrap(value, wrapper) {\n return partial(castFunction(wrapper), value);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Casts `value` as an array if it's not one.\n *\n * @static\n * @memberOf _\n * @since 4.4.0\n * @category Lang\n * @param {*} value The value to inspect.\n * @returns {Array} Returns the cast array.\n * @example\n *\n * _.castArray(1);\n * // => [1]\n *\n * _.castArray({ 'a': 1 });\n * // => [{ 'a': 1 }]\n *\n * _.castArray('abc');\n * // => ['abc']\n *\n * _.castArray(null);\n * // => [null]\n *\n * _.castArray(undefined);\n * // => [undefined]\n *\n * _.castArray();\n * // => []\n *\n * var array = [1, 2, 3];\n * console.log(_.castArray(array) === array);\n * // => true\n */\n function castArray() {\n if (!arguments.length) {\n return [];\n }\n var value = arguments[0];\n return isArray(value) ? value : [value];\n }\n\n /**\n * Creates a shallow clone of `value`.\n *\n * **Note:** This method is loosely based on the\n * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)\n * and supports cloning arrays, array buffers, booleans, date objects, maps,\n * numbers, `Object` objects, regexes, sets, strings, symbols, and typed\n * arrays. The own enumerable properties of `arguments` objects are cloned\n * as plain objects. An empty object is returned for uncloneable values such\n * as error objects, functions, DOM nodes, and WeakMaps.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to clone.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeep\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var shallow = _.clone(objects);\n * console.log(shallow[0] === objects[0]);\n * // => true\n */\n function clone(value) {\n return baseClone(value, CLONE_SYMBOLS_FLAG);\n }\n\n /**\n * This method is like `_.clone` except that it accepts `customizer` which\n * is invoked to produce the cloned value. If `customizer` returns `undefined`,\n * cloning is handled by the method instead. The `customizer` is invoked with\n * up to four arguments; (value [, index|key, object, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the cloned value.\n * @see _.cloneDeepWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(false);\n * }\n * }\n *\n * var el = _.cloneWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 0\n */\n function cloneWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);\n }\n\n /**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\n function cloneDeep(value) {\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);\n }\n\n /**\n * This method is like `_.cloneWith` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @param {Function} [customizer] The function to customize cloning.\n * @returns {*} Returns the deep cloned value.\n * @see _.cloneWith\n * @example\n *\n * function customizer(value) {\n * if (_.isElement(value)) {\n * return value.cloneNode(true);\n * }\n * }\n *\n * var el = _.cloneDeepWith(document.body, customizer);\n *\n * console.log(el === document.body);\n * // => false\n * console.log(el.nodeName);\n * // => 'BODY'\n * console.log(el.childNodes.length);\n * // => 20\n */\n function cloneDeepWith(value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);\n }\n\n /**\n * Checks if `object` conforms to `source` by invoking the predicate\n * properties of `source` with the corresponding property values of `object`.\n *\n * **Note:** This method is equivalent to `_.conforms` when `source` is\n * partially applied.\n *\n * @static\n * @memberOf _\n * @since 4.14.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property predicates to conform to.\n * @returns {boolean} Returns `true` if `object` conforms, else `false`.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n *\n * _.conformsTo(object, { 'b': function(n) { return n > 1; } });\n * // => true\n *\n * _.conformsTo(object, { 'b': function(n) { return n > 2; } });\n * // => false\n */\n function conformsTo(object, source) {\n return source == null || baseConformsTo(object, source, keys(source));\n }\n\n /**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\n function eq(value, other) {\n return value === other || (value !== value && other !== other);\n }\n\n /**\n * Checks if `value` is greater than `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than `other`,\n * else `false`.\n * @see _.lt\n * @example\n *\n * _.gt(3, 1);\n * // => true\n *\n * _.gt(3, 3);\n * // => false\n *\n * _.gt(1, 3);\n * // => false\n */\n var gt = createRelationalOperation(baseGt);\n\n /**\n * Checks if `value` is greater than or equal to `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is greater than or equal to\n * `other`, else `false`.\n * @see _.lte\n * @example\n *\n * _.gte(3, 1);\n * // => true\n *\n * _.gte(3, 3);\n * // => true\n *\n * _.gte(1, 3);\n * // => false\n */\n var gte = createRelationalOperation(function(value, other) {\n return value >= other;\n });\n\n /**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\n var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n };\n\n /**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\n var isArray = Array.isArray;\n\n /**\n * Checks if `value` is classified as an `ArrayBuffer` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.\n * @example\n *\n * _.isArrayBuffer(new ArrayBuffer(2));\n * // => true\n *\n * _.isArrayBuffer(new Array(2));\n * // => false\n */\n var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;\n\n /**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\n function isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n }\n\n /**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\n function isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n }\n\n /**\n * Checks if `value` is classified as a boolean primitive or object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.\n * @example\n *\n * _.isBoolean(false);\n * // => true\n *\n * _.isBoolean(null);\n * // => false\n */\n function isBoolean(value) {\n return value === true || value === false ||\n (isObjectLike(value) && baseGetTag(value) == boolTag);\n }\n\n /**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\n var isBuffer = nativeIsBuffer || stubFalse;\n\n /**\n * Checks if `value` is classified as a `Date` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a date object, else `false`.\n * @example\n *\n * _.isDate(new Date);\n * // => true\n *\n * _.isDate('Mon April 23 2012');\n * // => false\n */\n var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;\n\n /**\n * Checks if `value` is likely a DOM element.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.\n * @example\n *\n * _.isElement(document.body);\n * // => true\n *\n * _.isElement('');\n * // => false\n */\n function isElement(value) {\n return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);\n }\n\n /**\n * Checks if `value` is an empty object, collection, map, or set.\n *\n * Objects are considered empty if they have no own enumerable string keyed\n * properties.\n *\n * Array-like values such as `arguments` objects, arrays, buffers, strings, or\n * jQuery-like collections are considered empty if they have a `length` of `0`.\n * Similarly, maps and sets are considered empty if they have a `size` of `0`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is empty, else `false`.\n * @example\n *\n * _.isEmpty(null);\n * // => true\n *\n * _.isEmpty(true);\n * // => true\n *\n * _.isEmpty(1);\n * // => true\n *\n * _.isEmpty([1, 2, 3]);\n * // => false\n *\n * _.isEmpty({ 'a': 1 });\n * // => false\n */\n function isEmpty(value) {\n if (value == null) {\n return true;\n }\n if (isArrayLike(value) &&\n (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||\n isBuffer(value) || isTypedArray(value) || isArguments(value))) {\n return !value.length;\n }\n var tag = getTag(value);\n if (tag == mapTag || tag == setTag) {\n return !value.size;\n }\n if (isPrototype(value)) {\n return !baseKeys(value).length;\n }\n for (var key in value) {\n if (hasOwnProperty.call(value, key)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\n function isEqual(value, other) {\n return baseIsEqual(value, other);\n }\n\n /**\n * This method is like `_.isEqual` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with up to\n * six arguments: (objValue, othValue [, index|key, object, other, stack]).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, othValue) {\n * if (isGreeting(objValue) && isGreeting(othValue)) {\n * return true;\n * }\n * }\n *\n * var array = ['hello', 'goodbye'];\n * var other = ['hi', 'goodbye'];\n *\n * _.isEqualWith(array, other, customizer);\n * // => true\n */\n function isEqualWith(value, other, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n var result = customizer ? customizer(value, other) : undefined;\n return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;\n }\n\n /**\n * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,\n * `SyntaxError`, `TypeError`, or `URIError` object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an error object, else `false`.\n * @example\n *\n * _.isError(new Error);\n * // => true\n *\n * _.isError(Error);\n * // => false\n */\n function isError(value) {\n if (!isObjectLike(value)) {\n return false;\n }\n var tag = baseGetTag(value);\n return tag == errorTag || tag == domExcTag ||\n (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));\n }\n\n /**\n * Checks if `value` is a finite primitive number.\n *\n * **Note:** This method is based on\n * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n * @example\n *\n * _.isFinite(3);\n * // => true\n *\n * _.isFinite(Number.MIN_VALUE);\n * // => true\n *\n * _.isFinite(Infinity);\n * // => false\n *\n * _.isFinite('3');\n * // => false\n */\n function isFinite(value) {\n return typeof value == 'number' && nativeIsFinite(value);\n }\n\n /**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\n function isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n }\n\n /**\n * Checks if `value` is an integer.\n *\n * **Note:** This method is based on\n * [`Number.isInteger`](https://mdn.io/Number/isInteger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an integer, else `false`.\n * @example\n *\n * _.isInteger(3);\n * // => true\n *\n * _.isInteger(Number.MIN_VALUE);\n * // => false\n *\n * _.isInteger(Infinity);\n * // => false\n *\n * _.isInteger('3');\n * // => false\n */\n function isInteger(value) {\n return typeof value == 'number' && value == toInteger(value);\n }\n\n /**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\n function isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\n function isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n }\n\n /**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\n function isObjectLike(value) {\n return value != null && typeof value == 'object';\n }\n\n /**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\n var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\n /**\n * Performs a partial deep comparison between `object` and `source` to\n * determine if `object` contains equivalent property values.\n *\n * **Note:** This method is equivalent to `_.matches` when `source` is\n * partially applied.\n *\n * Partial comparisons will match empty array and empty object `source`\n * values against any array or object value, respectively. See `_.isEqual`\n * for a list of supported value comparisons.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n *\n * _.isMatch(object, { 'b': 2 });\n * // => true\n *\n * _.isMatch(object, { 'b': 1 });\n * // => false\n */\n function isMatch(object, source) {\n return object === source || baseIsMatch(object, source, getMatchData(source));\n }\n\n /**\n * This method is like `_.isMatch` except that it accepts `customizer` which\n * is invoked to compare values. If `customizer` returns `undefined`, comparisons\n * are handled by the method instead. The `customizer` is invoked with five\n * arguments: (objValue, srcValue, index|key, object, source).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n * @example\n *\n * function isGreeting(value) {\n * return /^h(?:i|ello)$/.test(value);\n * }\n *\n * function customizer(objValue, srcValue) {\n * if (isGreeting(objValue) && isGreeting(srcValue)) {\n * return true;\n * }\n * }\n *\n * var object = { 'greeting': 'hello' };\n * var source = { 'greeting': 'hi' };\n *\n * _.isMatchWith(object, source, customizer);\n * // => true\n */\n function isMatchWith(object, source, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return baseIsMatch(object, source, getMatchData(source), customizer);\n }\n\n /**\n * Checks if `value` is `NaN`.\n *\n * **Note:** This method is based on\n * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as\n * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for\n * `undefined` and other non-number values.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n * @example\n *\n * _.isNaN(NaN);\n * // => true\n *\n * _.isNaN(new Number(NaN));\n * // => true\n *\n * isNaN(undefined);\n * // => true\n *\n * _.isNaN(undefined);\n * // => false\n */\n function isNaN(value) {\n // An `NaN` primitive is the only value that is not equal to itself.\n // Perform the `toStringTag` check first to avoid errors with some\n // ActiveX objects in IE.\n return isNumber(value) && value != +value;\n }\n\n /**\n * Checks if `value` is a pristine native function.\n *\n * **Note:** This method can't reliably detect native functions in the presence\n * of the core-js package because core-js circumvents this kind of detection.\n * Despite multiple requests, the core-js maintainer has made it clear: any\n * attempt to fix the detection will be obstructed. As a result, we're left\n * with little choice but to throw an error. Unfortunately, this also affects\n * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),\n * which rely on core-js.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n * @example\n *\n * _.isNative(Array.prototype.push);\n * // => true\n *\n * _.isNative(_);\n * // => false\n */\n function isNative(value) {\n if (isMaskable(value)) {\n throw new Error(CORE_ERROR_TEXT);\n }\n return baseIsNative(value);\n }\n\n /**\n * Checks if `value` is `null`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `null`, else `false`.\n * @example\n *\n * _.isNull(null);\n * // => true\n *\n * _.isNull(void 0);\n * // => false\n */\n function isNull(value) {\n return value === null;\n }\n\n /**\n * Checks if `value` is `null` or `undefined`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is nullish, else `false`.\n * @example\n *\n * _.isNil(null);\n * // => true\n *\n * _.isNil(void 0);\n * // => true\n *\n * _.isNil(NaN);\n * // => false\n */\n function isNil(value) {\n return value == null;\n }\n\n /**\n * Checks if `value` is classified as a `Number` primitive or object.\n *\n * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n * classified as numbers, use the `_.isFinite` method.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n * @example\n *\n * _.isNumber(3);\n * // => true\n *\n * _.isNumber(Number.MIN_VALUE);\n * // => true\n *\n * _.isNumber(Infinity);\n * // => true\n *\n * _.isNumber('3');\n * // => false\n */\n function isNumber(value) {\n return typeof value == 'number' ||\n (isObjectLike(value) && baseGetTag(value) == numberTag);\n }\n\n /**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\n function isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n }\n\n /**\n * Checks if `value` is classified as a `RegExp` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.\n * @example\n *\n * _.isRegExp(/abc/);\n * // => true\n *\n * _.isRegExp('/abc/');\n * // => false\n */\n var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;\n\n /**\n * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754\n * double precision number which isn't the result of a rounded unsafe integer.\n *\n * **Note:** This method is based on\n * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.\n * @example\n *\n * _.isSafeInteger(3);\n * // => true\n *\n * _.isSafeInteger(Number.MIN_VALUE);\n * // => false\n *\n * _.isSafeInteger(Infinity);\n * // => false\n *\n * _.isSafeInteger('3');\n * // => false\n */\n function isSafeInteger(value) {\n return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\n var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\n /**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a string, else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\n function isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);\n }\n\n /**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\n function isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n }\n\n /**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\n var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n /**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\n function isUndefined(value) {\n return value === undefined;\n }\n\n /**\n * Checks if `value` is classified as a `WeakMap` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.\n * @example\n *\n * _.isWeakMap(new WeakMap);\n * // => true\n *\n * _.isWeakMap(new Map);\n * // => false\n */\n function isWeakMap(value) {\n return isObjectLike(value) && getTag(value) == weakMapTag;\n }\n\n /**\n * Checks if `value` is classified as a `WeakSet` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.\n * @example\n *\n * _.isWeakSet(new WeakSet);\n * // => true\n *\n * _.isWeakSet(new Set);\n * // => false\n */\n function isWeakSet(value) {\n return isObjectLike(value) && baseGetTag(value) == weakSetTag;\n }\n\n /**\n * Checks if `value` is less than `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than `other`,\n * else `false`.\n * @see _.gt\n * @example\n *\n * _.lt(1, 3);\n * // => true\n *\n * _.lt(3, 3);\n * // => false\n *\n * _.lt(3, 1);\n * // => false\n */\n var lt = createRelationalOperation(baseLt);\n\n /**\n * Checks if `value` is less than or equal to `other`.\n *\n * @static\n * @memberOf _\n * @since 3.9.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if `value` is less than or equal to\n * `other`, else `false`.\n * @see _.gte\n * @example\n *\n * _.lte(1, 3);\n * // => true\n *\n * _.lte(3, 3);\n * // => true\n *\n * _.lte(3, 1);\n * // => false\n */\n var lte = createRelationalOperation(function(value, other) {\n return value <= other;\n });\n\n /**\n * Converts `value` to an array.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Array} Returns the converted array.\n * @example\n *\n * _.toArray({ 'a': 1, 'b': 2 });\n * // => [1, 2]\n *\n * _.toArray('abc');\n * // => ['a', 'b', 'c']\n *\n * _.toArray(1);\n * // => []\n *\n * _.toArray(null);\n * // => []\n */\n function toArray(value) {\n if (!value) {\n return [];\n }\n if (isArrayLike(value)) {\n return isString(value) ? stringToArray(value) : copyArray(value);\n }\n if (symIterator && value[symIterator]) {\n return iteratorToArray(value[symIterator]());\n }\n var tag = getTag(value),\n func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);\n\n return func(value);\n }\n\n /**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\n function toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n }\n\n /**\n * Converts `value` to an integer.\n *\n * **Note:** This method is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\n function toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n }\n\n /**\n * Converts `value` to an integer suitable for use as the length of an\n * array-like object.\n *\n * **Note:** This method is based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toLength(3.2);\n * // => 3\n *\n * _.toLength(Number.MIN_VALUE);\n * // => 0\n *\n * _.toLength(Infinity);\n * // => 4294967295\n *\n * _.toLength('3.2');\n * // => 3\n */\n function toLength(value) {\n return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;\n }\n\n /**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\n function toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n }\n\n /**\n * Converts `value` to a plain object flattening inherited enumerable string\n * keyed properties of `value` to own properties of the plain object.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {Object} Returns the converted plain object.\n * @example\n *\n * function Foo() {\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.assign({ 'a': 1 }, new Foo);\n * // => { 'a': 1, 'b': 2 }\n *\n * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));\n * // => { 'a': 1, 'b': 2, 'c': 3 }\n */\n function toPlainObject(value) {\n return copyObject(value, keysIn(value));\n }\n\n /**\n * Converts `value` to a safe integer. A safe integer can be compared and\n * represented correctly.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toSafeInteger(3.2);\n * // => 3\n *\n * _.toSafeInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toSafeInteger(Infinity);\n * // => 9007199254740991\n *\n * _.toSafeInteger('3.2');\n * // => 3\n */\n function toSafeInteger(value) {\n return value\n ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)\n : (value === 0 ? value : 0);\n }\n\n /**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\n function toString(value) {\n return value == null ? '' : baseToString(value);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assign({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3 }\n */\n var assign = createAssigner(function(object, source) {\n if (isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n });\n\n /**\n * This method is like `_.assign` except that it iterates over own and\n * inherited source properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extend\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assign\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * function Bar() {\n * this.c = 3;\n * }\n *\n * Foo.prototype.b = 2;\n * Bar.prototype.d = 4;\n *\n * _.assignIn({ 'a': 0 }, new Foo, new Bar);\n * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }\n */\n var assignIn = createAssigner(function(object, source) {\n copyObject(source, keysIn(source), object);\n });\n\n /**\n * This method is like `_.assignIn` except that it accepts `customizer`\n * which is invoked to produce the assigned values. If `customizer` returns\n * `undefined`, assignment is handled by the method instead. The `customizer`\n * is invoked with five arguments: (objValue, srcValue, key, object, source).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias extendWith\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @see _.assignWith\n * @example\n *\n * function customizer(objValue, srcValue) {\n * return _.isUndefined(objValue) ? srcValue : objValue;\n * }\n *\n * var defaults = _.partialRight(_.assignInWith, customizer);\n *\n * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {\n copyObject(source, keysIn(source), object, customizer);\n });\n\n /**\n * This method is like `_.assign` except that it accepts `customizer`\n * which is invoked to produce the assigned values. If `customizer` returns\n * `undefined`, assignment is handled by the method instead. The `customizer`\n * is invoked with five arguments: (objValue, srcValue, key, object, source).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @see _.assignInWith\n * @example\n *\n * function customizer(objValue, srcValue) {\n * return _.isUndefined(objValue) ? srcValue : objValue;\n * }\n *\n * var defaults = _.partialRight(_.assignWith, customizer);\n *\n * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var assignWith = createAssigner(function(object, source, srcIndex, customizer) {\n copyObject(source, keys(source), object, customizer);\n });\n\n /**\n * Creates an array of values corresponding to `paths` of `object`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Array} Returns the picked values.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };\n *\n * _.at(object, ['a[0].b.c', 'a[1]']);\n * // => [3, 4]\n */\n var at = flatRest(baseAt);\n\n /**\n * Creates an object that inherits from the `prototype` object. If a\n * `properties` object is given, its own enumerable string keyed properties\n * are assigned to the created object.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Object\n * @param {Object} prototype The object to inherit from.\n * @param {Object} [properties] The properties to assign to the object.\n * @returns {Object} Returns the new object.\n * @example\n *\n * function Shape() {\n * this.x = 0;\n * this.y = 0;\n * }\n *\n * function Circle() {\n * Shape.call(this);\n * }\n *\n * Circle.prototype = _.create(Shape.prototype, {\n * 'constructor': Circle\n * });\n *\n * var circle = new Circle;\n * circle instanceof Circle;\n * // => true\n *\n * circle instanceof Shape;\n * // => true\n */\n function create(prototype, properties) {\n var result = baseCreate(prototype);\n return properties == null ? result : baseAssign(result, properties);\n }\n\n /**\n * Assigns own and inherited enumerable string keyed properties of source\n * objects to the destination object for all destination properties that\n * resolve to `undefined`. Source objects are applied from left to right.\n * Once a property is set, additional values of the same property are ignored.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaultsDeep\n * @example\n *\n * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });\n * // => { 'a': 1, 'b': 2 }\n */\n var defaults = baseRest(function(object, sources) {\n object = Object(object);\n\n var index = -1;\n var length = sources.length;\n var guard = length > 2 ? sources[2] : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n length = 1;\n }\n\n while (++index < length) {\n var source = sources[index];\n var props = keysIn(source);\n var propsIndex = -1;\n var propsLength = props.length;\n\n while (++propsIndex < propsLength) {\n var key = props[propsIndex];\n var value = object[key];\n\n if (value === undefined ||\n (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {\n object[key] = source[key];\n }\n }\n }\n\n return object;\n });\n\n /**\n * This method is like `_.defaults` except that it recursively assigns\n * default properties.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.defaults\n * @example\n *\n * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });\n * // => { 'a': { 'b': 2, 'c': 3 } }\n */\n var defaultsDeep = baseRest(function(args) {\n args.push(undefined, customDefaultsMerge);\n return apply(mergeWith, undefined, args);\n });\n\n /**\n * This method is like `_.find` except that it returns the key of the first\n * element `predicate` returns truthy for instead of the element itself.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {string|undefined} Returns the key of the matched element,\n * else `undefined`.\n * @example\n *\n * var users = {\n * 'barney': { 'age': 36, 'active': true },\n * 'fred': { 'age': 40, 'active': false },\n * 'pebbles': { 'age': 1, 'active': true }\n * };\n *\n * _.findKey(users, function(o) { return o.age < 40; });\n * // => 'barney' (iteration order is not guaranteed)\n *\n * // The `_.matches` iteratee shorthand.\n * _.findKey(users, { 'age': 1, 'active': true });\n * // => 'pebbles'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findKey(users, ['active', false]);\n * // => 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.findKey(users, 'active');\n * // => 'barney'\n */\n function findKey(object, predicate) {\n return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);\n }\n\n /**\n * This method is like `_.findKey` except that it iterates over elements of\n * a collection in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {string|undefined} Returns the key of the matched element,\n * else `undefined`.\n * @example\n *\n * var users = {\n * 'barney': { 'age': 36, 'active': true },\n * 'fred': { 'age': 40, 'active': false },\n * 'pebbles': { 'age': 1, 'active': true }\n * };\n *\n * _.findLastKey(users, function(o) { return o.age < 40; });\n * // => returns 'pebbles' assuming `_.findKey` returns 'barney'\n *\n * // The `_.matches` iteratee shorthand.\n * _.findLastKey(users, { 'age': 36, 'active': true });\n * // => 'barney'\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.findLastKey(users, ['active', false]);\n * // => 'fred'\n *\n * // The `_.property` iteratee shorthand.\n * _.findLastKey(users, 'active');\n * // => 'pebbles'\n */\n function findLastKey(object, predicate) {\n return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);\n }\n\n /**\n * Iterates over own and inherited enumerable string keyed properties of an\n * object and invokes `iteratee` for each property. The iteratee is invoked\n * with three arguments: (value, key, object). Iteratee functions may exit\n * iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 0.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forInRight\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forIn(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).\n */\n function forIn(object, iteratee) {\n return object == null\n ? object\n : baseFor(object, getIteratee(iteratee, 3), keysIn);\n }\n\n /**\n * This method is like `_.forIn` except that it iterates over properties of\n * `object` in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forIn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forInRight(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.\n */\n function forInRight(object, iteratee) {\n return object == null\n ? object\n : baseForRight(object, getIteratee(iteratee, 3), keysIn);\n }\n\n /**\n * Iterates over own enumerable string keyed properties of an object and\n * invokes `iteratee` for each property. The iteratee is invoked with three\n * arguments: (value, key, object). Iteratee functions may exit iteration\n * early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 0.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forOwnRight\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forOwn(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\n function forOwn(object, iteratee) {\n return object && baseForOwn(object, getIteratee(iteratee, 3));\n }\n\n /**\n * This method is like `_.forOwn` except that it iterates over properties of\n * `object` in the opposite order.\n *\n * @static\n * @memberOf _\n * @since 2.0.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns `object`.\n * @see _.forOwn\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.forOwnRight(new Foo, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.\n */\n function forOwnRight(object, iteratee) {\n return object && baseForOwnRight(object, getIteratee(iteratee, 3));\n }\n\n /**\n * Creates an array of function property names from own enumerable properties\n * of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to inspect.\n * @returns {Array} Returns the function names.\n * @see _.functionsIn\n * @example\n *\n * function Foo() {\n * this.a = _.constant('a');\n * this.b = _.constant('b');\n * }\n *\n * Foo.prototype.c = _.constant('c');\n *\n * _.functions(new Foo);\n * // => ['a', 'b']\n */\n function functions(object) {\n return object == null ? [] : baseFunctions(object, keys(object));\n }\n\n /**\n * Creates an array of function property names from own and inherited\n * enumerable properties of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to inspect.\n * @returns {Array} Returns the function names.\n * @see _.functions\n * @example\n *\n * function Foo() {\n * this.a = _.constant('a');\n * this.b = _.constant('b');\n * }\n *\n * Foo.prototype.c = _.constant('c');\n *\n * _.functionsIn(new Foo);\n * // => ['a', 'b', 'c']\n */\n function functionsIn(object) {\n return object == null ? [] : baseFunctions(object, keysIn(object));\n }\n\n /**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\n function get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n }\n\n /**\n * Checks if `path` is a direct property of `object`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = { 'a': { 'b': 2 } };\n * var other = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.has(object, 'a');\n * // => true\n *\n * _.has(object, 'a.b');\n * // => true\n *\n * _.has(object, ['a', 'b']);\n * // => true\n *\n * _.has(other, 'a');\n * // => false\n */\n function has(object, path) {\n return object != null && hasPath(object, path, baseHas);\n }\n\n /**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\n function hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n }\n\n /**\n * Creates an object composed of the inverted keys and values of `object`.\n * If `object` contains duplicate values, subsequent values overwrite\n * property assignments of previous values.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Object\n * @param {Object} object The object to invert.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invert(object);\n * // => { '1': 'c', '2': 'b' }\n */\n var invert = createInverter(function(result, value, key) {\n if (value != null &&\n typeof value.toString != 'function') {\n value = nativeObjectToString.call(value);\n }\n\n result[value] = key;\n }, constant(identity));\n\n /**\n * This method is like `_.invert` except that the inverted object is generated\n * from the results of running each element of `object` thru `iteratee`. The\n * corresponding inverted value of each inverted key is an array of keys\n * responsible for generating the inverted value. The iteratee is invoked\n * with one argument: (value).\n *\n * @static\n * @memberOf _\n * @since 4.1.0\n * @category Object\n * @param {Object} object The object to invert.\n * @param {Function} [iteratee=_.identity] The iteratee invoked per element.\n * @returns {Object} Returns the new inverted object.\n * @example\n *\n * var object = { 'a': 1, 'b': 2, 'c': 1 };\n *\n * _.invertBy(object);\n * // => { '1': ['a', 'c'], '2': ['b'] }\n *\n * _.invertBy(object, function(value) {\n * return 'group' + value;\n * });\n * // => { 'group1': ['a', 'c'], 'group2': ['b'] }\n */\n var invertBy = createInverter(function(result, value, key) {\n if (value != null &&\n typeof value.toString != 'function') {\n value = nativeObjectToString.call(value);\n }\n\n if (hasOwnProperty.call(result, value)) {\n result[value].push(key);\n } else {\n result[value] = [key];\n }\n }, getIteratee);\n\n /**\n * Invokes the method at `path` of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the method to invoke.\n * @param {...*} [args] The arguments to invoke the method with.\n * @returns {*} Returns the result of the invoked method.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };\n *\n * _.invoke(object, 'a[0].b.c.slice', 1, 3);\n * // => [2, 3]\n */\n var invoke = baseRest(baseInvoke);\n\n /**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\n function keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n }\n\n /**\n * Creates an array of the own and inherited enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keysIn(new Foo);\n * // => ['a', 'b', 'c'] (iteration order is not guaranteed)\n */\n function keysIn(object) {\n return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);\n }\n\n /**\n * The opposite of `_.mapValues`; this method creates an object with the\n * same values as `object` and keys generated by running each own enumerable\n * string keyed property of `object` thru `iteratee`. The iteratee is invoked\n * with three arguments: (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 3.8.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapValues\n * @example\n *\n * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {\n * return key + value;\n * });\n * // => { 'a1': 1, 'b2': 2 }\n */\n function mapKeys(object, iteratee) {\n var result = {};\n iteratee = getIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, iteratee(value, key, object), value);\n });\n return result;\n }\n\n /**\n * Creates an object with the same keys as `object` and values generated\n * by running each own enumerable string keyed property of `object` thru\n * `iteratee`. The iteratee is invoked with three arguments:\n * (value, key, object).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Object} Returns the new mapped object.\n * @see _.mapKeys\n * @example\n *\n * var users = {\n * 'fred': { 'user': 'fred', 'age': 40 },\n * 'pebbles': { 'user': 'pebbles', 'age': 1 }\n * };\n *\n * _.mapValues(users, function(o) { return o.age; });\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n *\n * // The `_.property` iteratee shorthand.\n * _.mapValues(users, 'age');\n * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)\n */\n function mapValues(object, iteratee) {\n var result = {};\n iteratee = getIteratee(iteratee, 3);\n\n baseForOwn(object, function(value, key, object) {\n baseAssignValue(result, key, iteratee(value, key, object));\n });\n return result;\n }\n\n /**\n * This method is like `_.assign` except that it recursively merges own and\n * inherited enumerable string keyed properties of source objects into the\n * destination object. Source properties that resolve to `undefined` are\n * skipped if a destination value exists. Array and plain object properties\n * are merged recursively. Other objects and value types are overridden by\n * assignment. Source objects are applied from left to right. Subsequent\n * sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 0.5.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {\n * 'a': [{ 'b': 2 }, { 'd': 4 }]\n * };\n *\n * var other = {\n * 'a': [{ 'c': 3 }, { 'e': 5 }]\n * };\n *\n * _.merge(object, other);\n * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }\n */\n var merge = createAssigner(function(object, source, srcIndex) {\n baseMerge(object, source, srcIndex);\n });\n\n /**\n * This method is like `_.merge` except that it accepts `customizer` which\n * is invoked to produce the merged values of the destination and source\n * properties. If `customizer` returns `undefined`, merging is handled by the\n * method instead. The `customizer` is invoked with six arguments:\n * (objValue, srcValue, key, object, source, stack).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} sources The source objects.\n * @param {Function} customizer The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * function customizer(objValue, srcValue) {\n * if (_.isArray(objValue)) {\n * return objValue.concat(srcValue);\n * }\n * }\n *\n * var object = { 'a': [1], 'b': [2] };\n * var other = { 'a': [3], 'b': [4] };\n *\n * _.mergeWith(object, other, customizer);\n * // => { 'a': [1, 3], 'b': [2, 4] }\n */\n var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {\n baseMerge(object, source, srcIndex, customizer);\n });\n\n /**\n * The opposite of `_.pick`; this method creates an object composed of the\n * own and inherited enumerable property paths of `object` that are not omitted.\n *\n * **Note:** This method is considerably slower than `_.pick`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to omit.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omit(object, ['a', 'c']);\n * // => { 'b': '2' }\n */\n var omit = flatRest(function(object, paths) {\n var result = {};\n if (object == null) {\n return result;\n }\n var isDeep = false;\n paths = arrayMap(paths, function(path) {\n path = castPath(path, object);\n isDeep || (isDeep = path.length > 1);\n return path;\n });\n copyObject(object, getAllKeysIn(object), result);\n if (isDeep) {\n result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);\n }\n var length = paths.length;\n while (length--) {\n baseUnset(result, paths[length]);\n }\n return result;\n });\n\n /**\n * The opposite of `_.pickBy`; this method creates an object composed of\n * the own and inherited enumerable string keyed properties of `object` that\n * `predicate` doesn't return truthy for. The predicate is invoked with two\n * arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.omitBy(object, _.isNumber);\n * // => { 'b': '2' }\n */\n function omitBy(object, predicate) {\n return pickBy(object, negate(getIteratee(predicate)));\n }\n\n /**\n * Creates an object composed of the picked `object` properties.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The source object.\n * @param {...(string|string[])} [paths] The property paths to pick.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pick(object, ['a', 'c']);\n * // => { 'a': 1, 'c': 3 }\n */\n var pick = flatRest(function(object, paths) {\n return object == null ? {} : basePick(object, paths);\n });\n\n /**\n * Creates an object composed of the `object` properties `predicate` returns\n * truthy for. The predicate is invoked with two arguments: (value, key).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The source object.\n * @param {Function} [predicate=_.identity] The function invoked per property.\n * @returns {Object} Returns the new object.\n * @example\n *\n * var object = { 'a': 1, 'b': '2', 'c': 3 };\n *\n * _.pickBy(object, _.isNumber);\n * // => { 'a': 1, 'c': 3 }\n */\n function pickBy(object, predicate) {\n if (object == null) {\n return {};\n }\n var props = arrayMap(getAllKeysIn(object), function(prop) {\n return [prop];\n });\n predicate = getIteratee(predicate);\n return basePickBy(object, props, function(value, path) {\n return predicate(value, path[0]);\n });\n }\n\n /**\n * This method is like `_.get` except that if the resolved value is a\n * function it's invoked with the `this` binding of its parent object and\n * its result is returned.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to resolve.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };\n *\n * _.result(object, 'a[0].b.c1');\n * // => 3\n *\n * _.result(object, 'a[0].b.c2');\n * // => 4\n *\n * _.result(object, 'a[0].b.c3', 'default');\n * // => 'default'\n *\n * _.result(object, 'a[0].b.c3', _.constant('default'));\n * // => 'default'\n */\n function result(object, path, defaultValue) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length;\n\n // Ensure the loop is entered when path is empty.\n if (!length) {\n length = 1;\n object = undefined;\n }\n while (++index < length) {\n var value = object == null ? undefined : object[toKey(path[index])];\n if (value === undefined) {\n index = length;\n value = defaultValue;\n }\n object = isFunction(value) ? value.call(object) : value;\n }\n return object;\n }\n\n /**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\n function set(object, path, value) {\n return object == null ? object : baseSet(object, path, value);\n }\n\n /**\n * This method is like `_.set` except that it accepts `customizer` which is\n * invoked to produce the objects of `path`. If `customizer` returns `undefined`\n * path creation is handled by the method instead. The `customizer` is invoked\n * with three arguments: (nsValue, key, nsObject).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {};\n *\n * _.setWith(object, '[0][1]', 'a', Object);\n * // => { '0': { '1': 'a' } }\n */\n function setWith(object, path, value, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return object == null ? object : baseSet(object, path, value, customizer);\n }\n\n /**\n * Creates an array of own enumerable string keyed-value pairs for `object`\n * which can be consumed by `_.fromPairs`. If `object` is a map or set, its\n * entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entries\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairs(new Foo);\n * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)\n */\n var toPairs = createToPairs(keys);\n\n /**\n * Creates an array of own and inherited enumerable string keyed-value pairs\n * for `object` which can be consumed by `_.fromPairs`. If `object` is a map\n * or set, its entries are returned.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @alias entriesIn\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the key-value pairs.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.toPairsIn(new Foo);\n * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)\n */\n var toPairsIn = createToPairs(keysIn);\n\n /**\n * An alternative to `_.reduce`; this method transforms `object` to a new\n * `accumulator` object which is the result of running each of its own\n * enumerable string keyed properties thru `iteratee`, with each invocation\n * potentially mutating the `accumulator` object. If `accumulator` is not\n * provided, a new object with the same `[[Prototype]]` will be used. The\n * iteratee is invoked with four arguments: (accumulator, value, key, object).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * @static\n * @memberOf _\n * @since 1.3.0\n * @category Object\n * @param {Object} object The object to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The custom accumulator value.\n * @returns {*} Returns the accumulated value.\n * @example\n *\n * _.transform([2, 3, 4], function(result, n) {\n * result.push(n *= n);\n * return n % 2 == 0;\n * }, []);\n * // => [4, 9]\n *\n * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] }\n */\n function transform(object, iteratee, accumulator) {\n var isArr = isArray(object),\n isArrLike = isArr || isBuffer(object) || isTypedArray(object);\n\n iteratee = getIteratee(iteratee, 4);\n if (accumulator == null) {\n var Ctor = object && object.constructor;\n if (isArrLike) {\n accumulator = isArr ? new Ctor : [];\n }\n else if (isObject(object)) {\n accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};\n }\n else {\n accumulator = {};\n }\n }\n (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {\n return iteratee(accumulator, value, index, object);\n });\n return accumulator;\n }\n\n /**\n * Removes the property at `path` of `object`.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to unset.\n * @returns {boolean} Returns `true` if the property is deleted, else `false`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 7 } }] };\n * _.unset(object, 'a[0].b.c');\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n *\n * _.unset(object, ['a', '0', 'b', 'c']);\n * // => true\n *\n * console.log(object);\n * // => { 'a': [{ 'b': {} }] };\n */\n function unset(object, path) {\n return object == null ? true : baseUnset(object, path);\n }\n\n /**\n * This method is like `_.set` except that accepts `updater` to produce the\n * value to set. Use `_.updateWith` to customize `path` creation. The `updater`\n * is invoked with one argument: (value).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {Function} updater The function to produce the updated value.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.update(object, 'a[0].b.c', function(n) { return n * n; });\n * console.log(object.a[0].b.c);\n * // => 9\n *\n * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });\n * console.log(object.x[0].y.z);\n * // => 0\n */\n function update(object, path, updater) {\n return object == null ? object : baseUpdate(object, path, castFunction(updater));\n }\n\n /**\n * This method is like `_.update` except that it accepts `customizer` which is\n * invoked to produce the objects of `path`. If `customizer` returns `undefined`\n * path creation is handled by the method instead. The `customizer` is invoked\n * with three arguments: (nsValue, key, nsObject).\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 4.6.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {Function} updater The function to produce the updated value.\n * @param {Function} [customizer] The function to customize assigned values.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = {};\n *\n * _.updateWith(object, '[0][1]', _.constant('a'), Object);\n * // => { '0': { '1': 'a' } }\n */\n function updateWith(object, path, updater, customizer) {\n customizer = typeof customizer == 'function' ? customizer : undefined;\n return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);\n }\n\n /**\n * Creates an array of the own enumerable string keyed property values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.values(new Foo);\n * // => [1, 2] (iteration order is not guaranteed)\n *\n * _.values('hi');\n * // => ['h', 'i']\n */\n function values(object) {\n return object == null ? [] : baseValues(object, keys(object));\n }\n\n /**\n * Creates an array of the own and inherited enumerable string keyed property\n * values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.valuesIn(new Foo);\n * // => [1, 2, 3] (iteration order is not guaranteed)\n */\n function valuesIn(object) {\n return object == null ? [] : baseValues(object, keysIn(object));\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Clamps `number` within the inclusive `lower` and `upper` bounds.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Number\n * @param {number} number The number to clamp.\n * @param {number} [lower] The lower bound.\n * @param {number} upper The upper bound.\n * @returns {number} Returns the clamped number.\n * @example\n *\n * _.clamp(-10, -5, 5);\n * // => -5\n *\n * _.clamp(10, -5, 5);\n * // => 5\n */\n function clamp(number, lower, upper) {\n if (upper === undefined) {\n upper = lower;\n lower = undefined;\n }\n if (upper !== undefined) {\n upper = toNumber(upper);\n upper = upper === upper ? upper : 0;\n }\n if (lower !== undefined) {\n lower = toNumber(lower);\n lower = lower === lower ? lower : 0;\n }\n return baseClamp(toNumber(number), lower, upper);\n }\n\n /**\n * Checks if `n` is between `start` and up to, but not including, `end`. If\n * `end` is not specified, it's set to `start` with `start` then set to `0`.\n * If `start` is greater than `end` the params are swapped to support\n * negative ranges.\n *\n * @static\n * @memberOf _\n * @since 3.3.0\n * @category Number\n * @param {number} number The number to check.\n * @param {number} [start=0] The start of the range.\n * @param {number} end The end of the range.\n * @returns {boolean} Returns `true` if `number` is in the range, else `false`.\n * @see _.range, _.rangeRight\n * @example\n *\n * _.inRange(3, 2, 4);\n * // => true\n *\n * _.inRange(4, 8);\n * // => true\n *\n * _.inRange(4, 2);\n * // => false\n *\n * _.inRange(2, 2);\n * // => false\n *\n * _.inRange(1.2, 2);\n * // => true\n *\n * _.inRange(5.2, 4);\n * // => false\n *\n * _.inRange(-3, -2, -6);\n * // => true\n */\n function inRange(number, start, end) {\n start = toFinite(start);\n if (end === undefined) {\n end = start;\n start = 0;\n } else {\n end = toFinite(end);\n }\n number = toNumber(number);\n return baseInRange(number, start, end);\n }\n\n /**\n * Produces a random number between the inclusive `lower` and `upper` bounds.\n * If only one argument is provided a number between `0` and the given number\n * is returned. If `floating` is `true`, or either `lower` or `upper` are\n * floats, a floating-point number is returned instead of an integer.\n *\n * **Note:** JavaScript follows the IEEE-754 standard for resolving\n * floating-point values which can produce unexpected results.\n *\n * @static\n * @memberOf _\n * @since 0.7.0\n * @category Number\n * @param {number} [lower=0] The lower bound.\n * @param {number} [upper=1] The upper bound.\n * @param {boolean} [floating] Specify returning a floating-point number.\n * @returns {number} Returns the random number.\n * @example\n *\n * _.random(0, 5);\n * // => an integer between 0 and 5\n *\n * _.random(5);\n * // => also an integer between 0 and 5\n *\n * _.random(5, true);\n * // => a floating-point number between 0 and 5\n *\n * _.random(1.2, 5.2);\n * // => a floating-point number between 1.2 and 5.2\n */\n function random(lower, upper, floating) {\n if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {\n upper = floating = undefined;\n }\n if (floating === undefined) {\n if (typeof upper == 'boolean') {\n floating = upper;\n upper = undefined;\n }\n else if (typeof lower == 'boolean') {\n floating = lower;\n lower = undefined;\n }\n }\n if (lower === undefined && upper === undefined) {\n lower = 0;\n upper = 1;\n }\n else {\n lower = toFinite(lower);\n if (upper === undefined) {\n upper = lower;\n lower = 0;\n } else {\n upper = toFinite(upper);\n }\n }\n if (lower > upper) {\n var temp = lower;\n lower = upper;\n upper = temp;\n }\n if (floating || lower % 1 || upper % 1) {\n var rand = nativeRandom();\n return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);\n }\n return baseRandom(lower, upper);\n }\n\n /*------------------------------------------------------------------------*/\n\n /**\n * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the camel cased string.\n * @example\n *\n * _.camelCase('Foo Bar');\n * // => 'fooBar'\n *\n * _.camelCase('--foo-bar--');\n * // => 'fooBar'\n *\n * _.camelCase('__FOO_BAR__');\n * // => 'fooBar'\n */\n var camelCase = createCompounder(function(result, word, index) {\n word = word.toLowerCase();\n return result + (index ? capitalize(word) : word);\n });\n\n /**\n * Converts the first character of `string` to upper case and the remaining\n * to lower case.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to capitalize.\n * @returns {string} Returns the capitalized string.\n * @example\n *\n * _.capitalize('FRED');\n * // => 'Fred'\n */\n function capitalize(string) {\n return upperFirst(toString(string).toLowerCase());\n }\n\n /**\n * Deburrs `string` by converting\n * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)\n * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)\n * letters to basic Latin letters and removing\n * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to deburr.\n * @returns {string} Returns the deburred string.\n * @example\n *\n * _.deburr('déjà vu');\n * // => 'deja vu'\n */\n function deburr(string) {\n string = toString(string);\n return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');\n }\n\n /**\n * Checks if `string` ends with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=string.length] The position to search up to.\n * @returns {boolean} Returns `true` if `string` ends with `target`,\n * else `false`.\n * @example\n *\n * _.endsWith('abc', 'c');\n * // => true\n *\n * _.endsWith('abc', 'b');\n * // => false\n *\n * _.endsWith('abc', 'b', 2);\n * // => true\n */\n function endsWith(string, target, position) {\n string = toString(string);\n target = baseToString(target);\n\n var length = string.length;\n position = position === undefined\n ? length\n : baseClamp(toInteger(position), 0, length);\n\n var end = position;\n position -= target.length;\n return position >= 0 && string.slice(position, end) == target;\n }\n\n /**\n * Converts the characters \"&\", \"<\", \">\", '\"', and \"'\" in `string` to their\n * corresponding HTML entities.\n *\n * **Note:** No other characters are escaped. To escape additional\n * characters use a third-party library like [_he_](https://mths.be/he).\n *\n * Though the \">\" character is escaped for symmetry, characters like\n * \">\" and \"/\" don't need escaping in HTML and have no special meaning\n * unless they're part of a tag or unquoted attribute value. See\n * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)\n * (under \"semi-related fun fact\") for more details.\n *\n * When working with HTML you should always\n * [quote attribute values](http://wonko.com/post/html-escaping) to reduce\n * XSS vectors.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escape('fred, barney, & pebbles');\n * // => 'fred, barney, & pebbles'\n */\n function escape(string) {\n string = toString(string);\n return (string && reHasUnescapedHtml.test(string))\n ? string.replace(reUnescapedHtml, escapeHtmlChar)\n : string;\n }\n\n /**\n * Escapes the `RegExp` special characters \"^\", \"$\", \"\\\", \".\", \"*\", \"+\",\n * \"?\", \"(\", \")\", \"[\", \"]\", \"{\", \"}\", and \"|\" in `string`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to escape.\n * @returns {string} Returns the escaped string.\n * @example\n *\n * _.escapeRegExp('[lodash](https://lodash.com/)');\n * // => '\\[lodash\\]\\(https://lodash\\.com/\\)'\n */\n function escapeRegExp(string) {\n string = toString(string);\n return (string && reHasRegExpChar.test(string))\n ? string.replace(reRegExpChar, '\\\\$&')\n : string;\n }\n\n /**\n * Converts `string` to\n * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the kebab cased string.\n * @example\n *\n * _.kebabCase('Foo Bar');\n * // => 'foo-bar'\n *\n * _.kebabCase('fooBar');\n * // => 'foo-bar'\n *\n * _.kebabCase('__FOO_BAR__');\n * // => 'foo-bar'\n */\n var kebabCase = createCompounder(function(result, word, index) {\n return result + (index ? '-' : '') + word.toLowerCase();\n });\n\n /**\n * Converts `string`, as space separated words, to lower case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the lower cased string.\n * @example\n *\n * _.lowerCase('--Foo-Bar--');\n * // => 'foo bar'\n *\n * _.lowerCase('fooBar');\n * // => 'foo bar'\n *\n * _.lowerCase('__FOO_BAR__');\n * // => 'foo bar'\n */\n var lowerCase = createCompounder(function(result, word, index) {\n return result + (index ? ' ' : '') + word.toLowerCase();\n });\n\n /**\n * Converts the first character of `string` to lower case.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.lowerFirst('Fred');\n * // => 'fred'\n *\n * _.lowerFirst('FRED');\n * // => 'fRED'\n */\n var lowerFirst = createCaseFirst('toLowerCase');\n\n /**\n * Pads `string` on the left and right sides if it's shorter than `length`.\n * Padding characters are truncated if they can't be evenly divided by `length`.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.pad('abc', 8);\n * // => ' abc '\n *\n * _.pad('abc', 8, '_-');\n * // => '_-abc_-_'\n *\n * _.pad('abc', 3);\n * // => 'abc'\n */\n function pad(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n if (!length || strLength >= length) {\n return string;\n }\n var mid = (length - strLength) / 2;\n return (\n createPadding(nativeFloor(mid), chars) +\n string +\n createPadding(nativeCeil(mid), chars)\n );\n }\n\n /**\n * Pads `string` on the right side if it's shorter than `length`. Padding\n * characters are truncated if they exceed `length`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.padEnd('abc', 6);\n * // => 'abc '\n *\n * _.padEnd('abc', 6, '_-');\n * // => 'abc_-_'\n *\n * _.padEnd('abc', 3);\n * // => 'abc'\n */\n function padEnd(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n return (length && strLength < length)\n ? (string + createPadding(length - strLength, chars))\n : string;\n }\n\n /**\n * Pads `string` on the left side if it's shorter than `length`. Padding\n * characters are truncated if they exceed `length`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to pad.\n * @param {number} [length=0] The padding length.\n * @param {string} [chars=' '] The string used as padding.\n * @returns {string} Returns the padded string.\n * @example\n *\n * _.padStart('abc', 6);\n * // => ' abc'\n *\n * _.padStart('abc', 6, '_-');\n * // => '_-_abc'\n *\n * _.padStart('abc', 3);\n * // => 'abc'\n */\n function padStart(string, length, chars) {\n string = toString(string);\n length = toInteger(length);\n\n var strLength = length ? stringSize(string) : 0;\n return (length && strLength < length)\n ? (createPadding(length - strLength, chars) + string)\n : string;\n }\n\n /**\n * Converts `string` to an integer of the specified radix. If `radix` is\n * `undefined` or `0`, a `radix` of `10` is used unless `value` is a\n * hexadecimal, in which case a `radix` of `16` is used.\n *\n * **Note:** This method aligns with the\n * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.\n *\n * @static\n * @memberOf _\n * @since 1.1.0\n * @category String\n * @param {string} string The string to convert.\n * @param {number} [radix=10] The radix to interpret `value` by.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.parseInt('08');\n * // => 8\n *\n * _.map(['6', '08', '10'], _.parseInt);\n * // => [6, 8, 10]\n */\n function parseInt(string, radix, guard) {\n if (guard || radix == null) {\n radix = 0;\n } else if (radix) {\n radix = +radix;\n }\n return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);\n }\n\n /**\n * Repeats the given string `n` times.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to repeat.\n * @param {number} [n=1] The number of times to repeat the string.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {string} Returns the repeated string.\n * @example\n *\n * _.repeat('*', 3);\n * // => '***'\n *\n * _.repeat('abc', 2);\n * // => 'abcabc'\n *\n * _.repeat('abc', 0);\n * // => ''\n */\n function repeat(string, n, guard) {\n if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {\n n = 1;\n } else {\n n = toInteger(n);\n }\n return baseRepeat(toString(string), n);\n }\n\n /**\n * Replaces matches for `pattern` in `string` with `replacement`.\n *\n * **Note:** This method is based on\n * [`String#replace`](https://mdn.io/String/replace).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to modify.\n * @param {RegExp|string} pattern The pattern to replace.\n * @param {Function|string} replacement The match replacement.\n * @returns {string} Returns the modified string.\n * @example\n *\n * _.replace('Hi Fred', 'Fred', 'Barney');\n * // => 'Hi Barney'\n */\n function replace() {\n var args = arguments,\n string = toString(args[0]);\n\n return args.length < 3 ? string : string.replace(args[1], args[2]);\n }\n\n /**\n * Converts `string` to\n * [snake case](https://en.wikipedia.org/wiki/Snake_case).\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the snake cased string.\n * @example\n *\n * _.snakeCase('Foo Bar');\n * // => 'foo_bar'\n *\n * _.snakeCase('fooBar');\n * // => 'foo_bar'\n *\n * _.snakeCase('--FOO-BAR--');\n * // => 'foo_bar'\n */\n var snakeCase = createCompounder(function(result, word, index) {\n return result + (index ? '_' : '') + word.toLowerCase();\n });\n\n /**\n * Splits `string` by `separator`.\n *\n * **Note:** This method is based on\n * [`String#split`](https://mdn.io/String/split).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category String\n * @param {string} [string=''] The string to split.\n * @param {RegExp|string} separator The separator pattern to split by.\n * @param {number} [limit] The length to truncate results to.\n * @returns {Array} Returns the string segments.\n * @example\n *\n * _.split('a-b-c', '-', 2);\n * // => ['a', 'b']\n */\n function split(string, separator, limit) {\n if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {\n separator = limit = undefined;\n }\n limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;\n if (!limit) {\n return [];\n }\n string = toString(string);\n if (string && (\n typeof separator == 'string' ||\n (separator != null && !isRegExp(separator))\n )) {\n separator = baseToString(separator);\n if (!separator && hasUnicode(string)) {\n return castSlice(stringToArray(string), 0, limit);\n }\n }\n return string.split(separator, limit);\n }\n\n /**\n * Converts `string` to\n * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).\n *\n * @static\n * @memberOf _\n * @since 3.1.0\n * @category String\n * @param {string} [string=''] The string to convert.\n * @returns {string} Returns the start cased string.\n * @example\n *\n * _.startCase('--foo-bar--');\n * // => 'Foo Bar'\n *\n * _.startCase('fooBar');\n * // => 'Foo Bar'\n *\n * _.startCase('__FOO_BAR__');\n * // => 'FOO BAR'\n */\n var startCase = createCompounder(function(result, word, index) {\n return result + (index ? ' ' : '') + upperFirst(word);\n });\n\n /**\n * Checks if `string` starts with the given target string.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category String\n * @param {string} [string=''] The string to inspect.\n * @param {string} [target] The string to search for.\n * @param {number} [position=0] The position to search from.\n * @returns {boolean} Returns `true` if `string` starts with `target`,\n * else `false`.\n * @example\n *\n * _.startsWith('abc', 'a');\n * // => true\n *\n * _.startsWith('abc', 'b');\n * // => false\n *\n * _.startsWith('abc', 'b', 1);\n * // => true\n */\n function startsWith(string, target, position) {\n string = toString(string);\n position = position == null\n ? 0\n : baseClamp(toInteger(position), 0, string.length);\n\n target = baseToString(target);\n return string.slice(position, position + target.length) == target;\n }\n\n /**\n * Creates a compiled template function that can interpolate data properties\n * in \"interpolate\" delimiters, HTML-escape interpolated data properties in\n * \"escape\" delimiters, and execute JavaScript in \"evaluate\" delimiters. Data\n * properties may be accessed as free variables in the template. If a setting\n * object is given, it takes precedence over `_.templateSettings` values.\n *\n * **Note:** In the development build `_.template` utilizes\n * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)\n * for easier debugging.\n *\n * For more information on precompiling templates see\n * [lodash's custom builds documentation](https://lodash.com/custom-builds).\n *\n * For more information on Chrome extension sandboxes see\n * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category String\n * @param {string} [string=''] The template string.\n * @param {Object} [options={}] The options object.\n * @param {RegExp} [options.escape=_.templateSettings.escape]\n * The HTML \"escape\" delimiter.\n * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]\n * The \"evaluate\" delimiter.\n * @param {Object} [options.imports=_.templateSettings.imports]\n * An object to import into the template as free variables.\n * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]\n * The \"interpolate\" delimiter.\n * @param {string} [options.sourceURL='lodash.templateSources[n]']\n * The sourceURL of the compiled template.\n * @param {string} [options.variable='obj']\n * The data object variable name.\n * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.\n * @returns {Function} Returns the compiled template function.\n * @example\n *\n * // Use the \"interpolate\" delimiter to create a compiled template.\n * var compiled = _.template('hello <%= user %>!');\n * compiled({ 'user': 'fred' });\n * // => 'hello fred!'\n *\n * // Use the HTML \"escape\" delimiter to escape data property values.\n * var compiled = _.template('<%- value %>');\n * compiled({ 'value': '